Merge branch 'main' of krille-chan/fluffychat

This commit is contained in:
Alexey 2026-03-25 14:39:04 +03:00
commit b93b263427
200 changed files with 1285 additions and 943 deletions

View file

@ -23,8 +23,6 @@ jobs:
run: git diff --exit-code pubspec.lock
- name: Check formatting
run: dart format lib/ test/ --set-exit-if-changed
- name: Check import formatting
run: dart run import_sorter:main --no-comments --exit-if-changed
- name: Check license compliance
run: dart run license_checker check-licenses -c licenses.yaml --problematic
- run: flutter analyze
@ -107,7 +105,7 @@ jobs:
steps:
- uses: actions/checkout@v6
- name: Install dependencies
run: sudo apt-get update && sudo apt-get install git wget 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 libwebkit2gtk-4.1-dev -y
run: sudo apt-get update && sudo apt-get install git wget curl clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev liblzma-dev libjsoncpp-dev cmake-data libsecret-1-dev libsecret-1-0 librhash0 libssl-dev libwebkit2gtk-4.1-dev -y
- run: echo "FLUTTER_VERSION=$(yq '.environment.flutter' < .tool_versions.yaml)" >> $GITHUB_ENV
- name: Install Flutter
run: |

View file

@ -114,7 +114,7 @@ jobs:
steps:
- uses: actions/checkout@v6
- name: Install dependencies
run: sudo apt-get update && sudo apt-get install curl clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev liblzma-dev libjsoncpp-dev cmake-data libsecret-1-dev libsecret-1-0 librhash0 libwebkit2gtk-4.1-dev -y
run: sudo apt-get update && sudo apt-get install curl clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev liblzma-dev libjsoncpp-dev cmake-data libsecret-1-dev libsecret-1-0 librhash0 libssl-dev libwebkit2gtk-4.1-dev -y
- run: echo "FLUTTER_VERSION=$(yq '.environment.flutter' < .tool_versions.yaml)" >> $GITHUB_ENV
- name: Install Flutter
run: |

View file

@ -1,2 +1,2 @@
environment:
flutter: 3.41.4
flutter: 3.41.5 # Keep in sync with snap/snapcraft.yaml

View file

@ -1,10 +1,7 @@
{
"emeraldwalk.runonsave": {
"commands": [
{
"match": "\\.dart$",
"cmd": "dart run import_sorter:main --no-comments ${fileBasename}"
}
"[dart]": {
"editor.codeActionsOnSave": [
"source.organizeImports"
]
}
}

View file

@ -11,9 +11,8 @@ To improve the process please make sure that you read the following guidelines c
4. Every Pull Request should change only one thing. For bigger changes it is often better to split them up in multiple Pull Requests.
5. [Sign your commits](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits).
6. Format the commit message as [Conventional Commits](https://www.conventionalcommits.org).
7. Format (`flutter format lib`) and sort impots (`dart run import_sorter:main --no-comments`) in all code files.
8. For bigger or complex changes (more than a couple of code lines) write an issue or refer to an existing issue and ask for approval from the maintainers (@krille-chan) **before** starting to implement it. This way you reduce the risk that your Pull Request get's declined.
9. Prefer simple and easy to maintain solutions over complexity and fancy ones.
7. For bigger or complex changes (more than a couple of code lines) write an issue or refer to an existing issue and ask for approval from the maintainers (@krille-chan) **before** starting to implement it. This way you reduce the risk that your Pull Request get's declined.
8. Prefer simple and easy to maintain solutions over complexity and fancy ones.
# Code Style

View file

@ -2,6 +2,7 @@ include: package:flutter_lints/flutter.yaml
linter:
rules:
- directives_ordering
- avoid_print
- constant_identifier_names
- prefer_final_locals

View file

@ -106,7 +106,7 @@
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="im.fluffychat" android:path="/login"/>
<data android:scheme="im.fluffychat.auth" android:path="/login"/>
</intent-filter>
</activity>

View file

@ -1,9 +1,13 @@
import 'package:fluffychat/pages/sign_in/view_model/model/public_homeserver_data.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import '../data/environment_constants.dart';
import '../utils/fluffy_chat_tester.dart';
Future<void> finalLogout(WidgetTester widgetTester) =>
widgetTester.startFluffyChatTest().then((tester) => tester.logout());
extension AuthFlows on FluffyChatTester {
Future<void> login() async {
await waitFor('Sign in');
@ -18,6 +22,7 @@ extension AuthFlows on FluffyChatTester {
}
Future<void> logout() async {
await ensureLoggedIn();
await tapOn(Key('accounts_and_settings_buttons'));
await tapOn('Settings');
await scrollUntilVisible('Logout');

View file

@ -1,10 +1,9 @@
import 'package:fluffychat/pages/chat_list/chat_list.dart';
import 'package:fluffychat/widgets/chat_settings_popup_menu.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import '../utils/fluffy_chat_tester.dart';
import 'auth_flows.dart';
import 'chat_flows.dart';
Future<void> basicMessaging(WidgetTester widgetTester) => widgetTester
.startFluffyChatTest()
@ -12,31 +11,13 @@ Future<void> basicMessaging(WidgetTester widgetTester) => widgetTester
extension on FluffyChatTester {
Future<void> _basicMessaging() async {
final shouldLogout = await ensureLoggedIn();
await ensureLoggedIn();
await ensureGroupChatCreated();
// Create a new group chat
await tapOn(FloatingActionButton);
await tapOn('Create group');
await enterText(TextField, 'Test Group 01');
await tapOn('Create a group and invite users');
await waitFor('Invite contact');
await goBack();
// Send a message
await tapOn(ChatFlows.groupChatName);
const testMessage = 'Hello from integration test!';
await enterText(Key('chat_input_field'), testMessage);
await tapOn(Key('send_button'));
// Ensure message is visible
await waitFor(testMessage);
// Archive the chat
await tapOn(ChatSettingsPopupMenu);
await tapOn('Leave');
await waitFor('Are you sure?');
await tapOn('Leave');
await waitFor(ChatList);
if (shouldLogout) await logout();
}
}

View file

@ -0,0 +1,35 @@
import 'package:fluffychat/pages/chat_list/chat_list.dart';
import 'package:fluffychat/widgets/chat_settings_popup_menu.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import '../utils/fluffy_chat_tester.dart';
import 'auth_flows.dart';
Future<void> archiveChats(WidgetTester widgetTester) =>
widgetTester.startFluffyChatTest().then((tester) => tester._archiveChats());
extension ChatFlows on FluffyChatTester {
static const String groupChatName = 'Test Group 01';
Future<void> ensureGroupChatCreated() async {
if (await isVisible(groupChatName)) return;
await tapOn(FloatingActionButton);
await tapOn('Create group');
await enterText(TextField, groupChatName);
await tapOn('Create a group and invite users');
await waitFor('Invite contact');
await goBack();
await goBack();
}
Future<void> _archiveChats() async {
await ensureLoggedIn();
await ensureGroupChatCreated();
await tapOn(ChatSettingsPopupMenu);
await tapOn('Leave');
await waitFor('Are you sure?');
await tapOn('Leave');
await waitFor(ChatList);
}
}

View file

@ -1,7 +1,9 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'flows/auth_flows.dart';
import 'flows/basic_messaging.dart';
import 'flows/chat_flows.dart';
import 'flows/login_and_chat_backup.dart';
void main() {
@ -10,5 +12,7 @@ void main() {
group('FluffyChat Integration Tests', () {
testWidgets('Login and logout flow', loginAndChatBackup);
testWidgets('Basic Messaging', basicMessaging);
testWidgets('Archive chats', archiveChats);
testWidgets('Final logout', finalLogout);
});
}

View file

@ -1,6 +1,6 @@
import 'package:fluffychat/main.dart' as app;
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:fluffychat/main.dart' as app;
extension type FluffyChatTester(WidgetTester tester) {
static int _printCounter = 1;
@ -67,10 +67,7 @@ extension type FluffyChatTester(WidgetTester tester) {
await tester.pumpAndSettle();
}
Future<void> goBack() async {
_print('🔙 Going a page back');
await tester.pageBack();
}
Future<void> goBack() => tapOn(find.byTooltip('Back'));
Future<void> enterText(Object object, String text, {int? index}) async {
final finder = await _ensureVisible(object, index: index);

View file

@ -31,6 +31,7 @@ abstract class AppConfig {
'https://fluffychat.im/faq/#how_do_i_get_stickers';
static const String appId = 'im.fluffychat.FluffyChat';
static const String appOpenUrlScheme = 'im.fluffychat';
static const String appSsoUrlScheme = 'im.fluffychat.auth';
static const String sourceCodeUrl =
'https://github.com/krille-chan/fluffychat';

View file

@ -1,10 +1,5 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/pages/archive/archive.dart';
import 'package:fluffychat/pages/bootstrap/bootstrap_dialog.dart';
@ -39,6 +34,9 @@ import 'package:fluffychat/widgets/layouts/two_column_layout.dart';
import 'package:fluffychat/widgets/log_view.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:fluffychat/widgets/share_scaffold_dialog.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
abstract class AppRoutes {
static FutureOr<String?> loggedInRedirect(

View file

@ -1,14 +1,12 @@
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:async/async.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:matrix/matrix_api_lite/utils/logs.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:fluffychat/utils/platform_infos.dart';
enum AppSettings<T> {
textMessageMaxLength<int>('textMessageMaxLength', 16384),
audioRecordingNumChannels<int>('audioRecordingNumChannels', 1),
@ -40,6 +38,8 @@ enum AppSettings<T> {
showPresences<bool>('chat.fluffy.show_presences', true),
displayNavigationRail<bool>('chat.fluffy.display_navigation_rail', false),
experimentalVoip<bool>('chat.fluffy.experimental_voip', false),
jitsiFeature<bool>('chat.fluffy.enable_jitsi', false),
jitsiDomain<String>('chat.fluffy.jitsi_domain', 'meet.jit.si'),
shareKeysWith<String>('chat.fluffy.share_keys_with_2', 'all'),
noEncryptionWarningShown<bool>(
'chat.fluffy.no_encryption_warning_shown',

View file

@ -1,9 +1,8 @@
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'app_config.dart';
abstract class FluffyThemes {
static const double columnWidth = 380.0;

View file

@ -1551,7 +1551,7 @@
"type": "String",
"placeholders": {}
},
"skip": "Überspringe",
"skip": "Überspringen",
"@skip": {
"type": "String",
"placeholders": {}

View file

@ -2794,5 +2794,13 @@
"iDoNotWantToSupport": "I do not want to support",
"iAlreadySupportFluffyChat": "I already support FluffyChat",
"setLowPriority": "Set low priority",
"unsetLowPriority": "Unset low priority"
}
"unsetLowPriority": "Unset low priority",
"removeCallFromChat": "Remove call from chat",
"removeCallFromChatDescription": "Do you want to remove the call from the chat for all members?",
"removeCallForEveryone": "Remove call for everyone",
"startVoiceCall": "Start voice call",
"startVideoCall": "Start video call",
"joinVoiceCall": "Join voice call",
"joinVideoCall": "Join video call",
"live": "Live"
}

View file

@ -2395,7 +2395,7 @@
"gallery": "Galerii",
"files": "Failid",
"swipeRightToLeftToReply": "Vastamiseks viipa paremalt vasakule",
"alwaysUse24HourFormat": "false",
"alwaysUse24HourFormat": "väär",
"@alwaysUse24HourFormat": {
"description": "Set to true to always display time of day in 24 hour format."
},
@ -2800,5 +2800,13 @@
"skipSupportingFluffyChat": "Jäta FluffyChati toetamine vahele",
"iDoNotWantToSupport": "Ma ei soovi toetada",
"setLowPriority": "Märgi vähetähtsaks",
"unsetLowPriority": "Eemalda märkimine vähetähtsaks"
"unsetLowPriority": "Eemalda märkimine vähetähtsaks",
"removeCallFromChat": "Eemalda kõne vestlusest",
"removeCallFromChatDescription": "Kas sa soovid antud kõne selle vestluse kõikidelt kasutajatelt eemaldada?",
"removeCallForEveryone": "Eemalda kõne kõigilt",
"startVoiceCall": "Algata häälkõne",
"startVideoCall": "Algata videokõne",
"joinVoiceCall": "Liitu häälkõnega",
"joinVideoCall": "Liitu videokõnega",
"live": "Reaalajas"
}

View file

@ -36,7 +36,7 @@
"type": "String",
"placeholders": {}
},
"allChats": "همه گپ‌ها",
"allChats": "همه چت ها",
"@allChats": {
"type": "String",
"placeholders": {}
@ -121,7 +121,7 @@
"type": "String",
"placeholders": {}
},
"banFromChat": "محروم کردن از گپ",
"banFromChat": "بن کردن از چت",
"@banFromChat": {
"type": "String",
"placeholders": {}
@ -135,7 +135,7 @@
}
}
},
"areGuestsAllowedToJoin": "آیا مهمانان اجازه پیوستن دارند",
"areGuestsAllowedToJoin": "آیا مهمانان اجازه پیوستن دارند؟",
"@areGuestsAllowedToJoin": {
"type": "String",
"placeholders": {}
@ -151,7 +151,7 @@
"type": "String",
"placeholders": {}
},
"changedTheChatDescriptionTo": "{username} توضیح گپ را به '{description}' تغییر داد",
"changedTheChatDescriptionTo": "{username} توضیح چت را به '{description}' تغییر داد",
"@changedTheChatDescriptionTo": {
"type": "String",
"placeholders": {
@ -163,7 +163,7 @@
}
}
},
"changedTheChatPermissions": "{username} دسترسی‌های گپ را تغییر داد",
"changedTheChatPermissions": "{username} دسترسی‌های چت را تغییر داد",
"@changedTheChatPermissions": {
"type": "String",
"placeholders": {
@ -172,7 +172,7 @@
}
}
},
"changedTheChatNameTo": "{username} نام گپ را به '{chatname}' تغییر داد",
"changedTheChatNameTo": "{username} نام چت را به '{chatname}' تغییر داد",
"@changedTheChatNameTo": {
"type": "String",
"placeholders": {
@ -232,7 +232,7 @@
}
}
},
"changedTheChatAvatar": "{username} نماد گپ را تغییر داد",
"changedTheChatAvatar": "{username} نماد چت را تغییر داد",
"@changedTheChatAvatar": {
"type": "String",
"placeholders": {
@ -259,7 +259,7 @@
}
}
},
"chats": "گپ‌ها",
"chats": "چت ها",
"@chats": {
"type": "String",
"placeholders": {}
@ -362,7 +362,7 @@
"type": "String",
"placeholders": {}
},
"yourChatBackupHasBeenSetUp": "پشتیبان گپ شما تنظیم شد.",
"yourChatBackupHasBeenSetUp": "پشتیبان چت شما تنظیم شد.",
"changeTheme": "تغییر پوسته",
"@changeTheme": {
"type": "String",
@ -384,12 +384,12 @@
"placeholders": {}
},
"clearArchive": "پاک کردن بایگانی",
"commandHint_create": "ساختن یک گپ گروهی خالی\nاز «--no-encryption» برای غیرفعال کردن رمزنگاری استفاده کنید",
"commandHint_create": "ساختن یک چت گروهی خالی\nاز «--no-encryption» برای غیرفعال کردن رمزنگاری استفاده کنید",
"@commandHint_create": {
"type": "String",
"description": "Usage hint for the command /create"
},
"commandHint_dm": "شروع یک گپ مستقیم\nاز «--no-encryption» برای غیرفعال کردن رمزنگاری استفاده کنید",
"commandHint_dm": "شروع یک چت مستقیم\nاز «--no-encryption» برای غیرفعال کردن رمزنگاری استفاده کنید",
"@commandHint_dm": {
"type": "String",
"description": "Usage hint for the command /dm"
@ -409,7 +409,7 @@
}
}
},
"chatDetails": "جزئیات گپ",
"chatDetails": "جزئیات چت",
"@chatDetails": {
"type": "String",
"placeholders": {}
@ -490,12 +490,12 @@
"type": "String",
"placeholders": {}
},
"chat": "گپ",
"chat": "چت",
"@chat": {
"type": "String",
"placeholders": {}
},
"chatBackup": "پشتیبان گپ",
"chatBackup": "پشتیبان چت",
"@chatBackup": {
"type": "String",
"placeholders": {}
@ -765,7 +765,7 @@
"type": "String",
"placeholders": {}
},
"emptyChat": "گپ خالی",
"emptyChat": "چت خالی",
"@emptyChat": {
"type": "String",
"placeholders": {}
@ -775,7 +775,7 @@
"type": "String",
"placeholders": {}
},
"createdTheChat": "💬 {username} گپ را ساخت",
"createdTheChat": "💬 {username} چت را ساخت",
"@createdTheChat": {
"type": "String",
"placeholders": {
@ -789,7 +789,7 @@
"type": "String",
"placeholders": {}
},
"directChats": "گپ‌های مستقیم",
"directChats": "چت های مستقیم",
"@directChats": {
"type": "String",
"placeholders": {}
@ -848,7 +848,7 @@
"type": "String",
"placeholders": {}
},
"configureChat": "پیکربندی گپ",
"configureChat": "تنظیمات چت",
"@configureChat": {
"type": "String",
"placeholders": {}
@ -1091,12 +1091,12 @@
"type": "String",
"placeholders": {}
},
"muteChat": "بی‌صدا کردن گپ",
"muteChat": "بی‌صدا کردن چت",
"@muteChat": {
"type": "String",
"placeholders": {}
},
"newChat": "گپ جدید",
"newChat": "چت جدید",
"@newChat": {
"type": "String",
"placeholders": {}
@ -1258,12 +1258,12 @@
}
}
},
"kickFromChat": "بیرون کردن از گپ",
"kickFromChat": "بیرون کردن از چت",
"@kickFromChat": {
"type": "String",
"placeholders": {}
},
"leftTheChat": "گپ را ترک کرد",
"leftTheChat": "چت را ترک کرد",
"@leftTheChat": {
"type": "String",
"placeholders": {}
@ -1380,7 +1380,7 @@
}
}
},
"joinedTheChat": "👋 {username} به گپ پیوست",
"joinedTheChat": "👋 {username} به چت پیوست",
"@joinedTheChat": {
"type": "String",
"placeholders": {
@ -1551,7 +1551,7 @@
}
}
},
"unbanFromChat": "لغو محرومیت از گپ",
"unbanFromChat": "لغو محرومیت از چت",
"@unbanFromChat": {
"type": "String",
"placeholders": {}
@ -1665,7 +1665,7 @@
}
}
},
"wasDirectChatDisplayName": "گپ خالی (پیش‌تر {oldDisplayName} بود)",
"wasDirectChatDisplayName": "چت خالی (قبلا {oldDisplayName} بود)",
"@wasDirectChatDisplayName": {
"type": "String",
"placeholders": {
@ -1674,15 +1674,15 @@
}
}
},
"newSpaceDescription": "فضاها امکان یکپارچه‌سازی گپ‌ها و ساخت جوامع خصوصی یا عمومی را فراهم می‌کنند.",
"encryptThisChat": "رمزنگاری این گپ",
"newSpaceDescription": "فضاها امکان یکپارچه‌سازی چت ها و ساخت جوامع خصوصی یا عمومی را فراهم می‌کنند.",
"encryptThisChat": "رمزنگاری این چت",
"sorryThatsNotPossible": "متأسفیم... این ممکن نیست",
"deviceKeys": "کلیدهای دستگاه:",
"fileIsTooBigForServer": "نمیتوان فرستاد! سرور تنها از پیوست های تا {max} پشتیبانی میکند.",
"jumpToLastReadMessage": "پرش به آخرین پیام خوانده‌شده",
"doNotShowAgain": "دوباره نمایش نده",
"readUpToHere": "خوانده‌شده تا اینجا",
"noBackupWarning": "هشدار! بدون فعال کردن پشتیبان گپ، دسترسی به پیام‌های رمزنگاری‌شده خود را از دست خواهید داد. پیشنهاد می‌شود پیش از خروج، پشتیبان گپ را فعال کنید.",
"noBackupWarning": "هشدار! بدون فعال کردن پشتیبان چت، دسترسی به پیام‌های رمزنگاری‌شده خود را از دست خواهید داد. پیشنهاد می‌شود پیش از خروج، پشتیبان چت را فعال کنید.",
"noOtherDevicesFound": "دستگاه دیگری پیدا نشد",
"countFiles": "{count} پرونده",
"@countFiles": {
@ -1692,8 +1692,8 @@
}
}
},
"noKeyForThisMessage": "اگر پیام پیش از ورود به حساب در این دستگاه فرستاده شده باشد، این مشکل ممکن است رخ دهد.\n\nهمچنین ممکن است فرستنده دستگاه شما را مسدود کرده باشد یا مشکلی در اتصال اینترنت وجود داشته باشد.\n\nآیا می‌توانید پیام را در نشست دیگری بخوانید؟ در این صورت، می‌توانید آن را منتقل کنید! به تنظیمات > دستگاه‌ها بروید و مطمئن شوید دستگاه‌هایتان یکدیگر را بازبینی کرده‌اند. هنگام باز کردن دوباره اتاق و فعال بودن هر دو نشست، کلیدها به‌صورت خودکار منتقل می‌شوند.\n\nآیا نمی‌خواهید هنگام خروج یا تغییر دستگاه کلیدها را گم کنید؟ مطمئن شوید پشتیبان گپ را در تنظیمات فعال کرده‌اید.",
"disableEncryptionWarning": "به دلایل امنیتی نمی‌توانید رمزنگاری را در گپی که فعال شده غیرفعال کنید.",
"noKeyForThisMessage": "اگر پیام پیش از ورود به حساب در این دستگاه فرستاده شده باشد، این مشکل ممکن است رخ دهد.\n\nهمچنین ممکن است فرستنده دستگاه شما را مسدود کرده باشد یا مشکلی در اتصال اینترنت وجود داشته باشد.\n\nآیا می‌توانید پیام را در نشست دیگری بخوانید؟ در این صورت، می‌توانید آن را منتقل کنید! به تنظیمات > دستگاه‌ها بروید و مطمئن شوید دستگاه‌هایتان یکدیگر را بازبینی کرده‌اند. هنگام باز کردن دوباره اتاق و فعال بودن هر دو نشست، کلیدها به‌صورت خودکار منتقل می‌شوند.\n\nآیا نمی‌خواهید هنگام خروج یا تغییر دستگاه کلیدها را گم کنید؟ مطمئن شوید پشتیبان چت را در تنظیمات فعال کرده‌اید.",
"disableEncryptionWarning": "به دلایل امنیتی نمی‌توانید رمزنگاری را در چتی که فعال شده غیرفعال کنید.",
"newGroup": "گروه جدید",
"foregroundServiceRunning": "این آگاه‌ساز زمانی ظاهر می‌شود که خدمت پیش‌زمینه فعال است.",
"storeSecurlyOnThisDevice": "ذخیره امن در این دستگاه",
@ -1706,8 +1706,8 @@
"custom": "سفارشی",
"screenSharingTitle": "هم‌رسانی صفحه‌نمایش",
"whyIsThisMessageEncrypted": "چرا این پیام خوانا نیست؟",
"reopenChat": "باز کردن دوباره گپ",
"unmuteChat": "فعال کردن صدای گپ",
"reopenChat": "باز کردن دوباره چت",
"unmuteChat": "فعال کردن صدای چت",
"@unmuteChat": {
"type": "String",
"placeholders": {}
@ -1768,7 +1768,7 @@
"type": "String",
"placeholders": {}
},
"youHaveBeenBannedFromThisChat": "شما از این گپ محروم شده‌اید",
"youHaveBeenBannedFromThisChat": "شما از این چت محروم شده‌اید",
"@youHaveBeenBannedFromThisChat": {
"type": "String",
"placeholders": {}
@ -1873,7 +1873,7 @@
"type": "String",
"placeholders": {}
},
"youAreNoLongerParticipatingInThisChat": "شما دیگر در این گپ شرکت نمی‌کنید",
"youAreNoLongerParticipatingInThisChat": "شما دیگر در این چت شرکت نمی‌کنید",
"@youAreNoLongerParticipatingInThisChat": {
"type": "String",
"placeholders": {}
@ -1925,7 +1925,7 @@
"type": "String",
"placeholders": {}
},
"openChat": "باز کردن گپ",
"openChat": "باز کردن چت",
"dismiss": "رد کردن",
"unsupportedAndroidVersion": "نسخه اندروید پشتیبانی‌نشده",
"youUnbannedUser": "شما محرومیت {user} را برداشتید",
@ -1987,7 +1987,7 @@
}
}
},
"userLeftTheChat": "👋 {username} گپ را ترک کرد",
"userLeftTheChat": "👋 {username} چت را ترک کرد",
"@userLeftTheChat": {
"type": "String",
"placeholders": {
@ -2001,7 +2001,7 @@
"type": "String",
"placeholders": {}
},
"visibilityOfTheChatHistory": "قابلیت دیدن تاریخچه گپ",
"visibilityOfTheChatHistory": "قابلیت دیدن تاریخچه چت",
"@visibilityOfTheChatHistory": {
"type": "String",
"placeholders": {}
@ -2016,7 +2016,7 @@
"type": "String",
"placeholders": {}
},
"wipeChatBackup": "برای ایجاد کلید بازیابی جدید، پشتیبان گپ خود را پاک می‌کنید؟",
"wipeChatBackup": "برای ایجاد کلید بازیابی جدید، پشتیبان چت خود را پاک می‌کنید؟",
"@wipeChatBackup": {
"type": "String",
"placeholders": {}
@ -2083,7 +2083,7 @@
"pinMessage": "سنجاق کردن به اتاق",
"emojis": "شکلک‌ها",
"voiceCall": "تماس صوتی",
"youJoinedTheChat": "شما به گپ پیوستید",
"youJoinedTheChat": "شما به چت پیوستید",
"youBannedUser": "شما {user} را محروم کردید",
"@youBannedUser": {
"placeholders": {
@ -2146,8 +2146,8 @@
"appLockDescription": "قفل کردن برنامه با رمز کوتاه هنگام عدم استفاده",
"sendTypingNotifications": "فرستادن آگاه‌سازهای نوشتن",
"swipeRightToLeftToReply": "کشیدن از راست به چپ برای پاسخ",
"noMoreChatsFound": "گپ دیگری پیدا نشد...",
"noChatsFoundHere": "اینجا هنوز گپی پیدا نشد. با استفاده از دکمه زیر گپ جدیدی با کسی شروع کنید. ⤵️",
"noMoreChatsFound": "چت دیگری پیدا نشد...",
"noChatsFoundHere": "اینجا هنوز چتی پیدا نشد. با استفاده از دکمه زیر چت جدیدی با کسی شروع کنید. ⤵️",
"unread": "خوانده‌نشده",
"space": "فضا",
"spaces": "فضاها",
@ -2162,28 +2162,28 @@
}
},
"createGroup": "ساختن گروه",
"chatPermissions": "دسترسی‌های گپ",
"chatPermissions": "دسترسی‌های چت",
"emoteKeyboardNoRecents": "شکلک‌هایی که به تازگی استفاده‌شده اینجا نمایش داده میشوند...",
"@emoteKeyboardNoRecents": {
"type": "String",
"placeholders": {}
},
"globalChatId": "شناسه گپ سراسری",
"globalChatId": "شناسه سراسری چت",
"accessAndVisibility": "دسترسی و قابلیت دید",
"accessAndVisibilityDescription": "چه کسی اجازه پیوستن به این گپ را دارد و گپ چگونه قابل کشف است.",
"accessAndVisibilityDescription": "چه کسی اجازه پیوستن به این چت را دارد و چت چگونه قابل پیدا شدن است.",
"calls": "تماس‌ها",
"customEmojisAndStickers": "شکلک‌ها و برچسب‌های سفارشی",
"customEmojisAndStickersBody": "افزودن یا هم‌رسانی شکلک‌ها یا برچسب‌های سفارشی که در هر گپ قابل استفاده‌اند.",
"chatDescription": "توضیح گپ",
"chatDescriptionHasBeenChanged": "توضیح گپ تغییر کرد",
"customEmojisAndStickersBody": "افزودن یا اشتراک گذاری ایموجی ها یا استیکر های سفارشی که در هر چت قابل استفاده‌اند.",
"chatDescription": "توضیحات چت",
"chatDescriptionHasBeenChanged": "توضیحات چت تغییر کرد",
"hideRedactedMessages": "پنهان کردن پیام‌های ویرایش‌شده",
"hideRedactedMessagesBody": "اگر کسی پیامی را ویرایش کند، دیگر نمیتوان آن پیام را در گپ دید.",
"hideRedactedMessagesBody": "اگر کسی پیامی را ویرایش کند، دیگر نمیتوان آن پیام را در چت دید.",
"hideInvalidOrUnknownMessageFormats": "پنهان کردن قالب‌های پیام نامعتبر یا ناشناخته",
"block": "مسدود کردن",
"blockedUsers": "کاربران مسدود‌شده",
"blockListDescription": "میتوانید کاربرانی که مزاحم شما هستند را مسدود کنید. از کاربران موجود در فهرست مسدود شخصی، پیام یا دعوت به اتاق دریافت نخواهید کرد.",
"blockUsername": "چشم‌پوشی از نام کاربری",
"noChatDescriptionYet": "هنوز توضیح گپی ساخته نشده است.",
"noChatDescriptionYet": "هنوز توضیحات چتی نوشته نشده است.",
"tryAgain": "تلاش دوباره",
"invalidServerName": "نام سرور نامعتبر",
"redactMessageDescription": "پیام برای همه شرکت‌کنندگان در این گفتگو ویرایش خواهد شد. این کار برگشت‌ناپذیر است.",
@ -2201,7 +2201,7 @@
}
}
},
"directChat": "گپ مستقیم",
"directChat": "چت مستقیم",
"redactedByBecause": "ویرایش‌شده به‌دست {username} زیرا: «{reason}»",
"@redactedByBecause": {
"type": "String",
@ -2223,7 +2223,7 @@
}
}
},
"setChatDescription": "تنظیم توضیح گپ",
"setChatDescription": "تنظیم توضیحات چت",
"presencesToggle": "نمایش پیام‌های وضعیت از دیگر کاربران",
"@presencesToggle": {
"type": "String",
@ -2260,7 +2260,7 @@
"hidePresences": "پنهان کردن فهرست وضعیت؟",
"setColorTheme": "تنظیم پوسته رنگی:",
"invite": "دعوت",
"inviteGroupChat": "📨 دعوت به گپ گروهی",
"inviteGroupChat": "📨 دعوت به چت گروهی",
"invalidInput": "ورودی نامعتبر!",
"wrongPinEntered": "رمز کوتاه نادرست وارد شد! {seconds} ثانیه دیگر دوباره تلاش کنید...",
"@wrongPinEntered": {
@ -2272,12 +2272,12 @@
}
},
"pleaseEnterANumber": "لطفاً عددی بزرگ‌تر از ۰ وارد کنید",
"archiveRoomDescription": "گپ به بایگانی خواهد رفت. کاربران دیگر میتوانند ببینند که شما گپ را ترک کرده‌اید.",
"roomUpgradeDescription": "گپ با نگارش جدید اتاق بازسازی خواهد شد. به همه شرکت‌کنندگان آگاهی‌رسانی میشود که باید به گپ جدید بروند. داده‌های بیشتر درباره نگارش‌های اتاق در https://spec.matrix.org/latest/rooms/",
"archiveRoomDescription": "چت به بایگانی خواهد رفت. کاربران دیگر میتوانند ببینند که شما چت را ترک کرده‌اید.",
"roomUpgradeDescription": "چت با نگارش جدید اتاق بازسازی خواهد شد. به همه شرکت‌کنندگان آگاهی‌رسانی میشود که باید به چت جدید بروند. داده‌های بیشتر درباره نگارش‌های اتاق در https://spec.matrix.org/latest/rooms/",
"removeDevicesDescription": "از این دستگاه خارج خواهید شد و دیگر نمیتوانید پیام دریافت کنید.",
"banUserDescription": "کاربر از گپ محروم خواهد شد و تا زمانی که محرومیت برداشته نشود، نمیتواند دوباره وارد گپ شود.",
"unbanUserDescription": "کاربر در صورت تلاش دوباره میتواند وارد گپ شود.",
"kickUserDescription": "کاربر از گپ بیرون میشود اما محروم نمیشود. در گپ‌های عمومی، کاربر میتواند هر زمان دوباره بپیوندد.",
"banUserDescription": "کاربر از چت محروم خواهد شد و تا زمانی که محرومیت برداشته نشود، نمیتواند دوباره وارد چت شود.",
"unbanUserDescription": "کاربر در صورت تلاش دوباره میتواند وارد چت شود.",
"kickUserDescription": "کاربر از چت بیرون میشود اما محروم نمیشود. در چت های عمومی، کاربر میتواند هر زمان دوباره بپیوندد.",
"makeAdminDescription": "پس از مدیر کردن این کاربر، ممکن است نتوانید این کار را لغو کنید، زیرا آن‌ها همان دسترسی‌های شما را خواهند داشت.",
"pushNotificationsNotAvailable": "آگاه‌سازهای فشاری در دسترس نیستند",
"learnMore": "بیشتر بدانید",
@ -2292,7 +2292,7 @@
}
},
"knocking": "در زدن",
"chatCanBeDiscoveredViaSearchOnServer": "گپ با جستجو در {server} قابل کشف است",
"chatCanBeDiscoveredViaSearchOnServer": "چت با جستجو در {server} قابل کشف است",
"@chatCanBeDiscoveredViaSearchOnServer": {
"type": "String",
"placeholders": {
@ -2301,13 +2301,13 @@
}
}
},
"searchChatsRooms": "جستجو برای #گپ‌ها، @کاربران...",
"searchChatsRooms": "جستجو برای #چت ها، @کاربران...",
"nothingFound": "چیزی پیدا نشد...",
"groupName": "نام گروه",
"createGroupAndInviteUsers": "ساختن گروه و دعوت کاربران",
"groupCanBeFoundViaSearch": "گروه با جستجو قابل یافتن است",
"wrongRecoveryKey": "متأسفیم... به نظر میرسد این کلید بازیابی درست نباشد.",
"commandHint_sendraw": "فرستادن JSON خام",
"commandHint_sendraw": "فرستادن json خام",
"databaseMigrationTitle": "پایگاه داده بهینه‌سازی شد",
"databaseMigrationBody": "لطفاً صبر کنید. این ممکن است لحظه‌ای طول بکشد.",
"leaveEmptyToClearStatus": "برای پاک کردن وضعیت، خالی بگذارید.",
@ -2318,13 +2318,13 @@
"pleaseChooseAStrongPassword": "لطفاً یک گذرواژه قوی انتخاب کنید",
"passwordsDoNotMatch": "گذرواژه‌ها هم‌خوانی ندارند",
"passwordIsWrong": "گذرواژه واردشده نادرست است",
"publicChatAddresses": "نشانی‌های گپ عمومی",
"publicChatAddresses": "آدرس های چت عمومی",
"createNewAddress": "ساختن نشانی جدید",
"joinSpace": "پیوستن به فضا",
"publicSpaces": "فضاهای عمومی",
"addChatOrSubSpace": "افزودن گپ یا زیرفضا",
"addChatOrSubSpace": "افزودن چت یا زیرفضا",
"thisDevice": "این دستگاه:",
"searchIn": "جستجو در گپ «{chat}»...",
"searchIn": "جستجو در چت «{chat}»...",
"@searchIn": {
"type": "String",
"placeholders": {
@ -2361,8 +2361,8 @@
}
},
"sendReadReceipts": "فرستادن رسیدهای خواندن",
"sendTypingNotificationsDescription": "دیگر شرکت‌کنندگان در گپ میتوانند ببینند که شما در حال تایپ پیام جدید هستید.",
"sendReadReceiptsDescription": "دیگر شرکت‌کنندگان در گپ میتوانند ببینند که شما پیام را خوانده‌اید.",
"sendTypingNotificationsDescription": "دیگر شرکت‌کنندگان در چت میتوانند ببینند که شما در حال تایپ پیام جدید هستید.",
"sendReadReceiptsDescription": "دیگر شرکت‌کنندگان در چت میتوانند ببینند که شما پیام را خوانده‌اید.",
"formattedMessages": "پیام‌های قالب‌بندی‌شده",
"formattedMessagesDescription": "نمایش محتوای پیام غنی مانند متن پررنگ با استفاده از مارک‌داون.",
"verifyOtherUser": "🔐 بازبینی کاربر دیگر",
@ -2429,7 +2429,7 @@
"discover": "کشف",
"commandHint_ignore": "چشم‌پوشی از شناسه ماتریکس داده‌شده",
"commandHint_unignore": "لغو چشم‌پوشی از شناسه ماتریکس داده‌شده",
"unreadChatsInApp": "{appname}: {unread} گپ خوانده‌نشده",
"unreadChatsInApp": "{appname}: {unread} چت خوانده‌نشده",
"@unreadChatsInApp": {
"type": "String",
"placeholders": {
@ -2482,14 +2482,14 @@
}
}
},
"changeGeneralChatSettings": "تغییر تنظیمات عمومی گپ",
"inviteOtherUsers": "دعوت کاربران دیگر به این گپ",
"changeTheChatPermissions": "تغییر دسترسی‌های گپ",
"changeTheVisibilityOfChatHistory": "تغییر قابلیت دید تاریخچه گپ",
"changeTheCanonicalRoomAlias": "تغییر نشانی اصلی گپ عمومی",
"changeGeneralChatSettings": "تغییر تنظیمات عمومی چت",
"inviteOtherUsers": "دعوت کاربران دیگر به این چت",
"changeTheChatPermissions": "تغییر دسترسی‌های چت",
"changeTheVisibilityOfChatHistory": "تغییر قابلیت دید تاریخچه چت",
"changeTheCanonicalRoomAlias": "تغییر نشانی اصلی چت عمومی",
"sendRoomNotifications": "فرستادن آگاه‌سازهای @room",
"changeTheDescriptionOfTheGroup": "تغییر توضیح گپ",
"chatPermissionsDescription": "مشخص کنید کدام سطح دسترسی برای اقدامات خاصی در این گپ لازم است. سطح‌های دسترسی ۰، ۵۰ و ۱۰۰ معمولاً نشان‌دهنده کاربران، ناظران و مدیران هستند، اما هر درجه‌بندی ممکن است.",
"changeTheDescriptionOfTheGroup": "تغییر توضیح چت",
"chatPermissionsDescription": "مشخص کنید کدام سطح دسترسی برای اقدامات خاصی در این چت لازم است. سطح‌های دسترسی ۰، ۵۰ و ۱۰۰ معمولاً نشان‌دهنده کاربران، ناظران و مدیران هستند، اما هر درجه‌بندی ممکن است.",
"updateInstalled": "🎉 به‌روزرسانی {version} نصب شد!",
"@updateInstalled": {
"type": "String",
@ -2530,9 +2530,9 @@
}
},
"oneOfYourDevicesIsNotVerified": "یکی از دستگاه‌های شما بازبینی نشده است",
"noticeChatBackupDeviceVerification": "توجه: وقتی همه دستگاه‌های خود را به پشتیبان گپ متصل کنید، به‌صورت خودکار بازبینی میشوند.",
"noticeChatBackupDeviceVerification": "توجه: وقتی همه دستگاه‌های خود را به پشتیبان چت متصل کنید، به‌صورت خودکار بازبینی میشوند.",
"continueText": "ادامه",
"welcomeText": "درود درود 👋 این فلافی‌چت است. میتوانید به هر سرور خانگی سازگار با https://matrix.org وارد شوید و با هر کسی گپ بزنید. این یک شبکه پیام‌رسانی غیرمتمرکز بزرگ است!",
"welcomeText": "درود درود 👋 این فلافی‌چت است. میتوانید به هر سرور خانگی سازگار با https://matrix.org وارد شوید و با هر کسی چت کنید. این یک شبکه پیام‌رسانی غیرمتمرکز بزرگ است!",
"blur": "محو کردن:",
"opacity": "شفافیت:",
"setWallpaper": "تنظیم کاغذدیواری",
@ -2552,7 +2552,7 @@
"pleaseFillOut": "لطفاً پر کنید",
"invalidUrl": "نشانی نامعتبر",
"addLink": "افزودن پیوند",
"unableToJoinChat": "ناتوانی در پیوستن به گپ. شاید طرف مقابل گفتگو را بسته است.",
"unableToJoinChat": "ناتوانی در پیوستن به چت. شاید طرف مقابل گفتگو را بسته است.",
"previous": "پیشین",
"otherPartyNotLoggedIn": "طرف مقابل اکنون وارد نشده است و بنابراین نمیتواند پیام دریافت کند!",
"appWantsToUseForLogin": "برای ورود از '{server}' استفاده کنید",
@ -2567,7 +2567,7 @@
"appWantsToUseForLoginDescription": "شما بدین‌وسیله به برنامه و وبگاه اجازه میدهید اطلاعات شما را هم‌رسانی کنند.",
"open": "باز کردن",
"waitingForServer": "در انتظار سرور...",
"newChatRequest": "📩 درخواست گپ جدید",
"newChatRequest": "📩 درخواست چت جدید",
"contentNotificationSettings": "تنظیمات آگاه‌ساز محتوا",
"generalNotificationSettings": "تنظیمات آگاه‌ساز عمومی",
"roomNotificationSettings": "تنظیمات آگاه‌ساز اتاق",
@ -2637,7 +2637,7 @@
"deletePushRuleCanNotBeUndone": "اگر این تنظیم آگاه‌ساز را پاک کنید، این کار برگشت‌ناپذیر است.",
"more": "بیشتر",
"shareKeysWith": "هم‌رسانی کلیدها با...",
"shareKeysWithDescription": "کدام دستگاه‌ها باید مورد اعتماد باشند تا بتوانند پیام‌های شما را در گپ‌های رمزنگاری‌شده بخوانند؟",
"shareKeysWithDescription": "کدام دستگاه‌ها باید مورد اعتماد باشند تا بتوانند پیام‌های شما را در چت های رمزنگاری‌شده بخوانند؟",
"allDevices": "همه دستگاه‌ها",
"crossVerifiedDevicesIfEnabled": "دستگاه‌های بازبینی‌شده متقابل اگر فعال باشد",
"crossVerifiedDevices": "دستگاه‌های بازبینی‌شده متقابل",
@ -2646,7 +2646,7 @@
"recordAVideo": "ضبط ویدئو",
"optionalMessage": "(اختیاری) پیام...",
"notSupportedOnThisDevice": "در این دستگاه پشتیبانی نمیشود",
"enterNewChat": "ورود به گپ جدید",
"enterNewChat": "ورود به چت جدید",
"approve": "پذیرفتن",
"youHaveKnocked": "شما در زده‌اید",
"pleaseWaitUntilInvited": "لطفاً اکنون صبر کنید تا کسی از اتاق شما را دعوت کند.",
@ -2656,9 +2656,148 @@
"customReaction": "واکنش سفارشی",
"moreEvents": "رویدادهای بیشتر",
"initAppError": "خطایی هنگام آغاز برنامه رخ داد",
"changedTheChatDescription": "{username} توضیحات گپ را تغییر داد",
"changedTheChatName": "{username} نام گپ را تغییر داد",
"changedTheChatDescription": "{username} توضیحات چت را تغییر داد",
"changedTheChatName": "{username} نام چت را تغییر داد",
"declineInvitation": "رد کردن دعوت",
"noMessagesYet": "پیامی وجود ندارد",
"longPressToRecordVoiceMessage": "برای ضبط پیام صوتی، انگشت خود را نگه دارید."
}
"longPressToRecordVoiceMessage": "برای ضبط پیام صوتی، انگشت خود را نگه دارید.",
"pause": "توقف",
"resume": "ادامه",
"removeFromSpaceDescription": "این چت از این فضا حذف خواهد شد اما همچنان در لیست چت های شما نمایش داده میشود.",
"countChats": "{chats} چت",
"@countChats": {
"type": "String",
"placeholders": {
"chats": {
"type": "int"
}
}
},
"spaceMemberOf": "عضو فضای {spaces}",
"@spaceMemberOf": {
"type": "String",
"placeholders": {
"spaces": {
"type": "String"
}
}
},
"spaceMemberOfCanKnock": "عضو فضای {spaces} میتواند در بزند",
"@spaceMemberOfCanKnock": {
"type": "String",
"placeholders": {
"spaces": {
"type": "String"
}
}
},
"startedAPoll": "{username} یک نظرسنجی را آغاز کرد.",
"@startedAPoll": {
"type": "String",
"placeholders": {
"username": {
"type": "String"
}
}
},
"poll": "نظرسنجی",
"startPoll": "آغاز نظرسنجی",
"endPoll": "پایان نظرسنجی",
"answersVisible": "پاسخ ها قابل رویت",
"pollQuestion": "سوال نظرسنجی",
"answerOption": "گزینه جواب",
"addAnswerOption": "اضافه کردن گزینه جواب",
"allowMultipleAnswers": "اجازه دادن چند جواب",
"pollHasBeenEnded": "این نظرسنجی پایان یافته است",
"answersWillBeVisibleWhenPollHasEnded": "پاسخ ها وقتی نظرسنجی به پایان برسد نمایش داده خواهند شد",
"replyInThread": "پاسخ در رشته",
"countReplies": "{count} پاسخ دیگر",
"@countReplies": {
"type": "int",
"placeholders": {
"count": {
"type": "int"
}
}
},
"thread": "رشته",
"backToMainChat": "بازگشت به چت اصلی",
"saveChanges": "ذخیره تغییرات",
"createSticker": "ساخت استیکر یا ایموجی",
"useAsSticker": "استفاده به عنوان استیکر",
"useAsEmoji": "استفاده به عنوان ایموجی",
"stickerPackNameAlreadyExists": "نام استیکرپک تکراری است",
"newStickerPack": "استیکر پک جدید",
"stickerPackName": "نام استیکر پک",
"attribution": "نسبت دادن",
"skipChatBackup": "صرف نظر از پشتیبان گیری چت",
"skipChatBackupWarning": "آیا مطمئنید؟ بدون فعال کردن پشتیبان گیری چت ممکن است در صورت تغییر دستگاه دسترسی خود به پیام هایتان را از دست بدهید.",
"loadingMessages": "در حال بارگذاری پیام ها",
"setupChatBackup": "فعالسازی پشتیبان گیری چت",
"noMoreResultsFound": "نتایج دیگری یافت نشد",
"chatSearchedUntil": "چت تا {time} جستجو شد",
"@chatSearchedUntil": {
"type": "String",
"placeholders": {
"time": {
"type": "String"
}
}
},
"federationBaseUrl": "پایه آدرس فدریشن",
"clientWellKnownInformation": "اطلاعات Client-Well-Known:",
"baseUrl": "پایه آدرس",
"identityServer": "سرور احراز هویت:",
"versionWithNumber": "ورژن: {version}",
"@versionWithNumber": {
"type": "String",
"placeholders": {
"version": {
"type": "String"
}
}
},
"logs": "لاگ ها",
"advancedConfigs": "تنظیمات پیشرفته",
"advancedConfigurations": "تنظیمات پیشرفته",
"signIn": "ورود",
"createNewAccount": "ساخت حساب جدید",
"signUpGreeting": "فلافی چت غیرمتمرکز است! یک سرور که میخواهید در آن حسابتان را بسازید را انتخاب کنید و شروع کنید!",
"signInGreeting": "از قبل در ماتریکس حساب کاربری دارید؟ خوش برگشتید! سرور خانه خود را انتخاب و لاگین کنید.",
"appIntro": "فلافی چت یک پیامرسان امن غیرمتمرکز ماتریکس است که با آن میتوانید با دوستانتان چت کنید! برای اطلاعات بیشتر میتوانید به https://matrix.org مراجعه کنید یا اینکه صرفا ثبت نام کنید.",
"theProcessWasCanceled": "فرآیند لغو شد.",
"join": "عضویت",
"searchOrEnterHomeserverAddress": "جستجو یا وارد کردن آدرس سرور خانه",
"matrixId": "شناسه ماتریکس",
"setPowerLevel": "انتخاب سطح قدرت",
"makeModerator": "انتخاب به عنوان ناظر",
"makeAdmin": "انتخاب به عنوان مدیر",
"removeModeratorRights": "حذف دسترسی های نظارتی",
"removeAdminRights": "حذف دسترسی های مدیریتی",
"powerLevel": "سطح قدرت",
"setPowerLevelDescription": "سطح قدرت مشخص میکند که یک کاربر قادر به انجام چه کارهایی در این اتاق است. معمولا یک عدد بین ۰ تا ۱۰۰ می باشد.",
"owner": "صاحب",
"mute": "ساکت",
"@mute": {
"description": "This should be a very short string because there is not much space in the button!"
},
"createNewChat": "ساخت چت جدید",
"reset": "ریست کردن",
"supportFluffyChat": "حمایت از فلافی چت",
"support": "پشتیبانی",
"fluffyChatSupportBannerMessage": "فلافی چت به کمک شما نیاز دارد!\n❤\nفلافی چت همواره رایگان خواهد بود، اما توسعه و نگهداری از آن هزینه بر است.\nآینده این پروژه در گرو حمایت افرادی مثل شماست.",
"skipSupportingFluffyChat": "رد کردن حمایت از فلافی چت",
"iDoNotWantToSupport": "نمیخواهم حمایت کنم",
"iAlreadySupportFluffyChat": "از قبل از فلافی چت حمایت میکنم",
"setLowPriority": "تنظیم اولویت پایین",
"unsetLowPriority": "لغو تنظیم اولویت پایین",
"countVotes": "{count} رای دیگر",
"@countVotes": {
"type": "int",
"placeholders": {
"count": {
"type": "int"
}
}
}
}

View file

@ -2807,4 +2807,4 @@
"iAlreadySupportFluffyChat": "Tacaím le FluffyChat cheana féin",
"setLowPriority": "Socraigh tosaíocht íseal",
"unsetLowPriority": "Díshuiteáil tosaíocht íseal"
}
}

View file

@ -2800,5 +2800,13 @@
"iDoNotWantToSupport": "Non quero axudar",
"iAlreadySupportFluffyChat": "Xa apoiei a FluffyChat",
"setLowPriority": "Establecer prioridade baixa",
"unsetLowPriority": "Non establecer prioridade baixa"
"unsetLowPriority": "Non establecer prioridade baixa",
"removeCallFromChat": "Eliminar a chamada da conversa",
"removeCallFromChatDescription": "Queres eliminar a chamada da conversa para todos os membros?",
"removeCallForEveryone": "Eliminar para todos a chamada",
"startVoiceCall": "Iniciar chamada de voz",
"startVideoCall": "Iniciar chamada de vídeo",
"joinVoiceCall": "Unirse á chamada de voz",
"joinVideoCall": "Unirse á chamada de vídeo",
"live": "En directo"
}

View file

@ -2193,5 +2193,207 @@
"hideInvalidOrUnknownMessageFormats": "無効であるか不明なメッセージ形式を隠す",
"blockListDescription": "迷惑なユーザーをブロックすることができます。あなたの個人的なブロックリストに記載されたユーザーは、あらゆるメッセージやルームへの招待を受け取ることができません。",
"invalidServerName": "無効なサーバー名",
"redactMessageDescription": "メッセージはこの会話のすべての参加者から削除されます。これは取り消すことができません。"
}
"redactMessageDescription": "メッセージはこの会話のすべての参加者から削除されます。これは取り消すことができません。",
"commandHint_op": "ユーザーの権限レベルを付与するデフォルト50",
"@commandHint_op": {
"type": "String",
"description": "Usage hint for the command /op"
},
"optionalRedactReason": "(オプション)メッセージを削除する理由…",
"overview": "概観",
"passwordRecoverySettings": "パスワードの復元設定",
"setChatDescription": "チャットの説明を設定",
"dismiss": "棄却",
"invitedBy": "📩 {user}に招待されました",
"@invitedBy": {
"placeholders": {
"user": {
"type": "String"
}
}
},
"hasKnocked": "🚪 {user}がノックしました",
"@hasKnocked": {
"placeholders": {
"user": {
"type": "String"
}
}
},
"usersMustKnock": "ユーザーはノックする必要があります",
"noOneCanJoin": "誰も参加できません",
"knock": "ノック",
"saveKeyManuallyDescription": "この鍵をシステムの共有ダイアログかクリップボードから手動で保存してください。",
"fileIsTooBigForServer": "送信できません!このサーバーは添付数は{max}個までです。",
"@fileIsTooBigForServer": {
"type": "String",
"placeholders": {
"max": {
"type": "String"
}
}
},
"fileHasBeenSavedAt": "ファイルは {path} に保存されています",
"@fileHasBeenSavedAt": {
"type": "String",
"placeholders": {
"path": {
"type": "String"
}
}
},
"jumpToLastReadMessage": "最後に閲覧したメッセージまで移動する",
"readUpToHere": "ここまで既読です",
"jump": "移動",
"openLinkInBrowser": "リンクをブラウザで開く",
"reportErrorDescription": "😭 おっと。問題が発生しました。必要があれば、このバグを開発者に報告することができます。",
"setColorTheme": "カラーテーマの設定:",
"invite": "招待",
"inviteGroupChat": "📨 グループチャットへ招待する",
"invalidInput": "無効な入力です!",
"wrongPinEntered": "誤ったPINが入力されました{seconds}秒後に再試行してください…",
"@wrongPinEntered": {
"type": "String",
"placeholders": {
"seconds": {
"type": "int"
}
}
},
"pleaseEnterANumber": "0以上の数値を入力してください",
"archiveRoomDescription": "チャットはアーカイブに移動されます。他のユーザーはあなたが退出したチャットを見ることができます。",
"roomUpgradeDescription": "チャットは新しい部屋バージョンで再作成されます。全参加者に新しいチャットへ切り替える必要があることが通知されます。部屋バージョンについては https://spec.matrix.org/latest/rooms/ をご覧ください",
"removeDevicesDescription": "このデバイスからログアウトするとメッセージを受け取ることができません。",
"banUserDescription": "ユーザーをチャットからBANすると、BANを解除されるまで再入室することはできません。",
"unbanUserDescription": "ユーザーが再試行時に再入室することができます。",
"pushNotificationsNotAvailable": "プッシュ通知は利用できません",
"learnMore": "詳しく知る",
"yourGlobalUserIdIs": "あなたのグローバルユーザーID ",
"knocking": "ノックしています",
"searchChatsRooms": "#チャット,@ユーザーで検索…",
"nothingFound": "何も見つかりませんでした…",
"groupName": "グループ名",
"createGroupAndInviteUsers": "グループを作成してユーザーを招待する",
"groupCanBeFoundViaSearch": "グループは検索で見つけることができます",
"commandHint_sendraw": "生のJSONを送信する",
"databaseMigrationTitle": "データベースは最適化されています",
"databaseMigrationBody": "しばらくお待ちください。この操作は時間がかかります。",
"searchForUsers": "@ユーザー で検索…",
"pleaseEnterYourCurrentPassword": "現在のパスワードを入力してください",
"newPassword": "新しいパスワード",
"pleaseChooseAStrongPassword": "強力なパスワードを選択してください",
"markAsUnread": "未読としてマーク",
"userLevel": "{level} - ユーザー",
"@userLevel": {
"type": "String",
"placeholders": {
"level": {
"type": "int"
}
}
},
"moderatorLevel": "{level} - モデレーター",
"@moderatorLevel": {
"type": "String",
"placeholders": {
"level": {
"type": "int"
}
}
},
"adminLevel": "{level} - 管理者",
"@adminLevel": {
"type": "String",
"placeholders": {
"level": {
"type": "int"
}
}
},
"changeGeneralChatSettings": "全体のチャット設定を変更する",
"inviteOtherUsers": "他のユーザーをこのチャットに招待する",
"changeTheChatPermissions": "チャット権限を変更する",
"changeTheDescriptionOfTheGroup": "チャットの説明を変更する",
"updateInstalled": "🎉 アップデート {version} をインストールしました!",
"@updateInstalled": {
"type": "String",
"placeholders": {
"version": {
"type": "String"
}
}
},
"changelog": "変更履歴",
"sendCanceled": "送信を取り消しました",
"loginWithMatrixId": "Matrix-IDでログイン",
"calculatingFileSize": "ファイルサイズを計算しています…",
"prepareSendingAttachment": "送信する添付ファイルを準備しています…",
"sendingAttachment": "添付ファイルを送信しています…",
"generatingVideoThumbnail": "ビデオサムネイルを生成しています…",
"compressVideo": "ビデオを圧縮しています…",
"sendingAttachmentCountOfCount": "{length}個中{index}個の添付ファイルを送信しています…",
"@sendingAttachmentCountOfCount": {
"type": "integer",
"placeholders": {
"index": {
"type": "int"
},
"length": {
"type": "int"
}
}
},
"serverLimitReached": "サーバーのリミットに達しました!{seconds}秒お待ちください…",
"@serverLimitReached": {
"type": "integer",
"placeholders": {
"seconds": {
"type": "int"
}
}
},
"oneOfYourDevicesIsNotVerified": "いずれかのデバイスが認証されていません",
"noticeChatBackupDeviceVerification": "注意:すべてのデバイスをチャットのバックアップに接続している場合、それらは自動的に認証されます。",
"continueText": "続ける",
"blur": "ぼかし:",
"opacity": "透過度:",
"setWallpaper": "壁紙を設定する",
"manageAccount": "アカウント管理",
"noContactInformationProvided": "サーバーから有効な連絡先情報が提供されていません",
"supportPage": "サポートページ",
"serverInformation": "サーバー情報:",
"name": "名前",
"version": "バージョン",
"website": "ウェブサイト",
"compress": "圧縮",
"boldText": "太字",
"italicText": "斜体",
"invalidUrl": "無効なURL",
"addLink": "リンクを追加",
"appWantsToUseForLogin": "'{server}' を使用してログインする",
"@appWantsToUseForLogin": {
"type": "String",
"placeholders": {
"server": {
"type": "String"
}
}
},
"open": "開く",
"waitingForServer": "サーバーを待機中…",
"newChatRequest": "📩 新しいチャットを要求",
"contentNotificationSettings": "コンテンツ通知設定",
"generalNotificationSettings": "全体通知設定",
"roomNotificationSettings": "部屋通知設定",
"userSpecificNotificationSettings": "ユーザー毎の通知設定",
"otherNotificationSettings": "その他の通知設定",
"notificationRuleContainsUserName": "ユーザー名を含む",
"notificationRuleContainsUserNameDescription": "ユーザー名がメッセージに含まれる場合に通知します。",
"notificationRuleMaster": "すべての通知をミュート",
"notificationRuleSuppressNotices": "自動化されたメッセージを控える",
"notificationRuleSuppressNoticesDescription": "Botのような自動化されたクライアントからの通知を抑制します。",
"notificationRuleInviteForMeDescription": "ユーザーが部屋に招待されたときに通知します。",
"notificationRuleMasterDescription": "全ルールを上書きして通知をすべて無効にします。",
"notificationRuleIsUserMention": "ユーザーの言及",
"notificationRuleIsUserMentionDescription": "ユーザーがメッセージ内で直接言及されたときに通知します。"
}

View file

@ -2177,5 +2177,15 @@
"notificationRuleSuppressEditsDescription": "Kkes ilɣa i yeznan yettwaẓergen.",
"notificationRuleCallDescription": "Azen alɣu i useqdac ɣef isawalen.",
"notificationRuleEncryptedRoomOneToOne": "Taxxamt yettwawgelhen s wudem n yiwen ɣer yiwen",
"notificationRuleRoomOneToOne": "Taxxamt s wudem n yiwen ɣer yiwen"
}
"notificationRuleRoomOneToOne": "Taxxamt s wudem n yiwen ɣer yiwen",
"userLevel": "{level} - Aseqdac",
"@userLevel": {
"type": "String",
"placeholders": {
"level": {
"type": "int"
}
}
},
"startVideoCall": "Bdu asiwel n uvidyu"
}

View file

@ -2807,5 +2807,13 @@
"iDoNotWantToSupport": "Jeg ønsker ikke å støtte",
"iAlreadySupportFluffyChat": "Jeg støtter allerede FluffyChat",
"setLowPriority": "Sett lav prioritet",
"unsetLowPriority": "Fjern lav prioritet"
"unsetLowPriority": "Fjern lav prioritet",
"removeCallFromChat": "Fjern anrop fra chat",
"removeCallFromChatDescription": "Vil du fjerne anropet fra chatten for alle medlemmer?",
"removeCallForEveryone": "Fjern anrop fra alle",
"startVoiceCall": "Start lydsamtale",
"startVideoCall": "Start videosamtale",
"joinVoiceCall": "Bli med i lydsamtale",
"joinVideoCall": "Bli med i videosamtale",
"live": "Direkte"
}

View file

@ -2800,4 +2800,4 @@
"support": "Steunen",
"setLowPriority": "Lage prioriteit instellen",
"unsetLowPriority": "Lage prioriteit uitschakelen"
}
}

View file

@ -2800,5 +2800,13 @@
"iDoNotWantToSupport": "我不想支持",
"iAlreadySupportFluffyChat": "我已支持 FluffyChat",
"setLowPriority": "设置低优先级",
"unsetLowPriority": "取消设置低优先级"
"unsetLowPriority": "取消设置低优先级",
"removeCallFromChat": "从聊天中删除通话",
"removeCallFromChatDescription": "要为所有成员从聊天中删除通话吗?",
"removeCallForEveryone": "为所有人删除通话",
"startVoiceCall": "开始语音通话",
"startVideoCall": "开始视频通话",
"joinVoiceCall": "加入语音通话",
"joinVideoCall": "加入视频通话",
"live": "实时"
}

View file

@ -1,22 +1,21 @@
import 'dart:isolate';
import 'dart:ui';
import 'package:collection/collection.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/utils/client_manager.dart';
import 'package:fluffychat/utils/notification_background_handler.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter_vodozemac/flutter_vodozemac.dart' as vod;
import 'package:just_audio_media_kit/just_audio_media_kit.dart';
import 'package:matrix/matrix.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:universal_html/universal_html.dart' as web;
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/utils/client_manager.dart';
import 'package:fluffychat/utils/notification_background_handler.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:video_player_media_kit/video_player_media_kit.dart';
import 'config/setting_keys.dart';
import 'utils/background_push.dart';
import 'widgets/fluffy_chat_app.dart';

View file

@ -1,12 +1,10 @@
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/archive/archive_view.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
class Archive extends StatefulWidget {
const Archive({super.key});

View file

@ -1,12 +1,10 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/archive/archive.dart';
import 'package:fluffychat/pages/chat_list/chat_list_item.dart';
import 'package:fluffychat/widgets/layouts/max_width_body.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
class ArchiveView extends StatelessWidget {
final ArchiveController controller;

View file

@ -1,10 +1,3 @@
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/encryption.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/error_reporter.dart';
@ -16,6 +9,12 @@ import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/layouts/login_scaffold.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/encryption.dart';
import 'package:matrix/matrix.dart';
import '../key_verification/key_verification_dialog.dart';
class BootstrapDialog extends StatefulWidget {

View file

@ -1,21 +1,11 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:collection/collection.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/file_picker.dart';
import 'package:go_router/go_router.dart';
import 'package:image_picker/image_picker.dart';
import 'package:matrix/matrix.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
import 'package:pasteboard/pasteboard.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
@ -38,6 +28,16 @@ import 'package:fluffychat/widgets/adaptive_dialogs/show_text_input_dialog.dart'
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:fluffychat/widgets/share_scaffold_dialog.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart';
import 'package:image_picker/image_picker.dart';
import 'package:matrix/matrix.dart';
import 'package:mime/mime.dart';
import 'package:pasteboard/pasteboard.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
import '../../utils/account_bundles.dart';
import '../../utils/localized_exception_extension.dart';
import 'send_file_dialog.dart';
@ -554,6 +554,7 @@ class ChatController extends State<ChatPageWithRoom>
timeline?.cancelSubscriptions();
timeline = null;
inputFocus.removeListener(_inputFocusListener);
if (currentlyTyping) room.setTyping(false);
super.dispose();
}
@ -706,7 +707,7 @@ class ChatController extends State<ChatPageWithRoom>
String path,
int duration,
List<int> waveform,
String? fileName,
String fileName,
) async {
final scaffoldMessenger = ScaffoldMessenger.of(context);
final audioFile = XFile(path);
@ -718,9 +719,17 @@ class ChatController extends State<ChatPageWithRoom>
final bytes = bytesResult.result;
if (bytes == null) return;
final mimeType = lookupMimeType(fileName, headerBytes: bytes);
final extension = mimeType == null ? null : extensionFromMime(mimeType);
if (extension != null) {
fileName =
'voice_message_${DateTime.now().millisecondsSinceEpoch}.$extension';
}
final file = MatrixAudioFile(
bytes: bytes,
name: fileName ?? audioFile.path,
name: fileName,
mimeType: mimeType,
);
room
@ -1298,6 +1307,7 @@ class ChatController extends State<ChatPageWithRoom>
if (AppSettings.sendTypingNotifications.value) {
typingCoolDown?.cancel();
typingCoolDown = Timer(const Duration(seconds: 2), () {
if (!mounted) return;
typingCoolDown = null;
currentlyTyping = false;
room.setTyping(false);

View file

@ -1,8 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:fluffychat/utils/url_launcher.dart';
import 'package:flutter/material.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
class ChatAppBarListTile extends StatelessWidget {
final Widget? leading;

View file

@ -1,8 +1,3 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat/chat.dart';
@ -11,6 +6,9 @@ import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/sync_status_localization.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/presence_builder.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
class ChatAppBarTitle extends StatelessWidget {
final ChatController controller;

View file

@ -1,11 +1,10 @@
import 'package:flutter/material.dart';
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat/sticker_picker_dialog.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'chat.dart';
class ChatEmojiPicker extends StatelessWidget {

View file

@ -1,9 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat/chat.dart';
@ -13,6 +8,9 @@ import 'package:fluffychat/pages/chat/typing_indicators.dart';
import 'package:fluffychat/utils/account_config.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/filtered_timeline_extension.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
class ChatEventList extends StatelessWidget {
final ChatController controller;

View file

@ -1,8 +1,4 @@
import 'package:flutter/material.dart';
import 'package:emoji_picker_flutter/locales/default_emoji_set_locale.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat/recording_input_row.dart';
@ -12,6 +8,9 @@ import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/hover_builder.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import '../../config/themes.dart';
import 'chat.dart';
import 'input_bar.dart';

View file

@ -1,11 +1,7 @@
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:badges/badges.dart';
import 'package:desktop_drop/desktop_drop.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
@ -14,6 +10,7 @@ import 'package:fluffychat/pages/chat/chat_app_bar_list_tile.dart';
import 'package:fluffychat/pages/chat/chat_app_bar_title.dart';
import 'package:fluffychat/pages/chat/chat_event_list.dart';
import 'package:fluffychat/pages/chat/encryption_button.dart';
import 'package:fluffychat/pages/chat/jitsi_popup_button.dart';
import 'package:fluffychat/pages/chat/pinned_events.dart';
import 'package:fluffychat/pages/chat/reply_display.dart';
import 'package:fluffychat/utils/account_config.dart';
@ -23,6 +20,9 @@ import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:fluffychat/widgets/mxc_image.dart';
import 'package:fluffychat/widgets/unread_rooms_badge.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import '../../utils/stream_extension.dart';
import 'chat_emoji_picker.dart';
import 'chat_input_row.dart';
@ -224,14 +224,16 @@ class ChatView extends StatelessWidget {
],
),
] else if (!controller.room.isArchived) ...[
if (AppSettings.experimentalVoip.value &&
if ((AppSettings.experimentalVoip.value &&
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,
),
)
else if (AppSettings.jitsiFeature.value)
JitsiPopupButton(controller.room),
EncryptionButton(controller.room),
ChatSettingsPopupMenu(controller.room, true),
],

View file

@ -1,10 +1,9 @@
import 'package:flutter/material.dart';
import 'package:badges/badges.dart' as b;
import 'package:fluffychat/l10n/l10n.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import '../../widgets/matrix.dart';
class EncryptionButton extends StatelessWidget {

View file

@ -1,14 +1,12 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
import 'package:fluffychat/utils/date_time_extension.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
extension EventInfoDialogExtension on Event {
void showInfoDialog(BuildContext context) => showAdaptiveBottomSheet(

View file

@ -1,22 +1,21 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:async/async.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:just_audio/just_audio.dart';
import 'package:matrix/matrix.dart';
import 'package:opus_caf_converter_dart/opus_caf_converter_dart.dart';
import 'package:path_provider/path_provider.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/utils/error_reporter.dart';
import 'package:fluffychat/utils/file_description.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
import 'package:fluffychat/utils/url_launcher.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:just_audio/just_audio.dart';
import 'package:matrix/matrix.dart';
import 'package:opus_caf_converter_dart/opus_caf_converter_dart.dart';
import 'package:path_provider/path_provider.dart';
import '../../../utils/matrix_sdk_extensions/event_extension.dart';
import '../../../widgets/fluffy_chat_app.dart';
import '../../../widgets/matrix.dart';

View file

@ -1,11 +1,9 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
class CuteContent extends StatefulWidget {
final Event event;

View file

@ -1,18 +1,17 @@
import 'package:collection/collection.dart';
import 'package:fluffychat/utils/code_highlight_theme.dart';
import 'package:fluffychat/utils/event_checkbox_extension.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/mxc_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:highlight/highlight.dart' show highlight;
import 'package:html/dom.dart' as dom;
import 'package:html/parser.dart' as parser;
import 'package:matrix/matrix.dart';
import 'package:fluffychat/utils/code_highlight_theme.dart';
import 'package:fluffychat/utils/event_checkbox_extension.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/mxc_image.dart';
import '../../../utils/url_launcher.dart';
class HtmlMessage extends StatelessWidget {

View file

@ -1,13 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/utils/file_description.dart';
import 'package:fluffychat/utils/url_launcher.dart';
import 'package:fluffychat/widgets/mxc_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:matrix/matrix.dart';
import '../../../widgets/blur_hash.dart';
class ImageBubble extends StatelessWidget {

View file

@ -1,12 +1,6 @@
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';
import 'package:matrix/matrix.dart';
import 'package:swipe_to_action/swipe_to_action.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
@ -18,6 +12,11 @@ import 'package:fluffychat/utils/string_color.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:fluffychat/widgets/member_actions_popup_menu_button.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:matrix/matrix.dart';
import 'package:swipe_to_action/swipe_to_action.dart';
import '../../../config/app_config.dart';
import 'message_content.dart';
import 'message_reactions.dart';

View file

@ -1,11 +1,5 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/encryption.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat/events/poll.dart';
@ -16,6 +10,11 @@ import 'package:fluffychat/utils/date_time_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/encryption.dart';
import 'package:matrix/matrix.dart';
import '../../../config/app_config.dart';
import '../../../utils/event_checkbox_extension.dart';
import '../../../utils/platform_infos.dart';

View file

@ -1,13 +1,11 @@
import 'package:flutter/material.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/utils/file_description.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart';
import 'package:fluffychat/utils/url_launcher.dart';
import 'package:flutter/material.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:matrix/matrix.dart';
class MessageDownloadContent extends StatelessWidget {
final Event event;

View file

@ -1,13 +1,11 @@
import 'package:flutter/material.dart';
import 'package:collection/collection.dart' show IterableExtension;
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:fluffychat/widgets/mxc_image.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
class MessageReactions extends StatelessWidget {
final Event event;

View file

@ -1,15 +1,13 @@
import 'package:flutter/material.dart';
import 'package:async/async.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:matrix/matrix.dart' hide Result;
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/url_launcher.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:flutter/material.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:matrix/matrix.dart' hide Result;
class PollWidget extends StatelessWidget {
final Event event;

View file

@ -1,10 +1,9 @@
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import '../../../config/app_config.dart';
class ReplyContent extends StatelessWidget {

View file

@ -1,12 +1,11 @@
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import '../../../config/app_config.dart';
class StateMessage extends StatelessWidget {

View file

@ -1,16 +1,15 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/utils/file_description.dart';
import 'package:fluffychat/utils/url_launcher.dart';
import 'package:fluffychat/widgets/blur_hash.dart';
import 'package:fluffychat/widgets/mxc_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:matrix/matrix.dart';
import '../../image_viewer/image_viewer.dart';
class EventVideoPlayer extends StatelessWidget {

View file

@ -1,15 +1,14 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';
import 'package:matrix/matrix.dart';
import 'package:slugify/slugify.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/markdown_context_builder.dart';
import 'package:fluffychat/widgets/mxc_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:matrix/matrix.dart';
import 'package:slugify/slugify.dart';
import '../../widgets/avatar.dart';
import '../../widgets/matrix.dart';
import 'command_hints.dart';

View file

@ -0,0 +1,175 @@
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:url_launcher/url_launcher.dart';
class JitsiPopupButton extends StatelessWidget {
final Room room;
const JitsiPopupButton(this.room, {super.key});
Future<void> _startCall(BuildContext context, bool isAudioOnly) async {
final l10n = L10n.of(context);
final urlResult = await showFutureLoadingDialog(
context: context,
future: () async {
final conferenceId = room.client.generateUniqueTransactionId();
final domain = AppSettings.jitsiDomain.value;
final uri = Uri(
scheme: 'https',
host: domain,
path: conferenceId,
fragment: isAudioOnly ? 'config.startWithVideoMuted=true' : null,
);
await room.addWidget(
MatrixWidget(
room: room,
name: 'Jitsi Meet',
type: 'jitsi',
url: uri.toString(),
data: {
'domain': domain,
'isAudioOnly': isAudioOnly,
'conferenceId': conferenceId,
'roomName': room.getLocalizedDisplayname(
MatrixLocals(L10n.of(context)),
),
},
),
);
return uri;
},
);
final url = urlResult.result;
if (url == null) return;
await launchUrl(url);
if (!context.mounted) return;
final consent = await showOkCancelAlertDialog(
context: context,
title: l10n.removeCallFromChat,
message: l10n.removeCallFromChatDescription,
okLabel: l10n.remove,
);
if (consent != OkCancelResult.ok) return;
if (!context.mounted) return;
await _endAllCalls(context);
}
Future<void> _endAllCalls(BuildContext context) => showFutureLoadingDialog(
context: context,
future: () async {
final activeJitsiCalls = room.states['im.vector.modular.widgets']?.values
.where((state) => state.content['type'] == 'jitsi');
if (activeJitsiCalls == null) return;
for (final call in activeJitsiCalls) {
await room.deleteWidget(call.stateKey!);
}
},
);
@override
Widget build(BuildContext context) {
final l10n = L10n.of(context);
final activeJitsiCalls = room.widgets
.where((widget) => widget.type == 'jitsi')
.map((widget) {
final isAudioOnly = widget.data?.tryGet<bool>('isAudioOnly') ?? false;
final domain = widget.data?.tryGet<String>('domain');
final conferenceId = widget.data?.tryGet<String>('conferenceId');
return (
isAudioOnly: isAudioOnly,
domain: domain,
conferenceId: conferenceId,
);
})
.toList();
final canEditCalls = room.canChangeStateEvent('im.vector.modular.widgets');
if (activeJitsiCalls.isEmpty && !canEditCalls) {
return const SizedBox.shrink();
}
return PopupMenuButton(
itemBuilder: (context) => [
...activeJitsiCalls.map(
(call) => PopupMenuItem(
onTap: () => launchUrl(
Uri(
scheme: 'https',
host: call.domain,
path: call.conferenceId,
fragment: call.isAudioOnly
? 'config.startWithVideoMuted=true'
: null,
),
),
child: Row(
mainAxisSize: .min,
children: [
Icon(call.isAudioOnly ? Icons.add_call : Icons.video_call),
const SizedBox(width: 12),
Text(
call.isAudioOnly ? l10n.joinVoiceCall : l10n.joinVideoCall,
),
],
),
),
),
if (canEditCalls) ...[
if (activeJitsiCalls.isEmpty) ...[
PopupMenuItem(
onTap: () => _startCall(context, true),
child: Row(
mainAxisSize: .min,
children: [
const Icon(Icons.add_call),
const SizedBox(width: 12),
Text(l10n.startVoiceCall),
],
),
),
PopupMenuItem(
onTap: () => _startCall(context, false),
child: Row(
mainAxisSize: .min,
children: [
const Icon(Icons.video_call),
const SizedBox(width: 12),
Text(l10n.startVideoCall),
],
),
),
] else
PopupMenuItem(
onTap: () => _endAllCalls(context),
child: Row(
mainAxisSize: .min,
children: [
Icon(
Icons.call_end_outlined,
color: Theme.of(context).colorScheme.error,
),
const SizedBox(width: 12),
Text(
l10n.removeCallForEveryone,
style: TextStyle(
color: Theme.of(context).colorScheme.error,
),
),
],
),
),
],
],
icon: Badge(
label: Text(l10n.live),
isLabelVisible: activeJitsiCalls.isNotEmpty,
child: Icon(Icons.video_call_outlined),
),
);
}
}

View file

@ -1,15 +1,13 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat/chat.dart';
import 'package:fluffychat/pages/chat/chat_app_bar_list_tile.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_modal_action_popup.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
class PinnedEvents extends StatelessWidget {
final ChatController controller;

View file

@ -1,13 +1,12 @@
import 'package:flutter/material.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat/chat_input_row.dart';
import 'package:fluffychat/pages/chat/recording_view_model.dart';
import 'package:flutter/material.dart';
class RecordingInputRow extends StatelessWidget {
final RecordingViewModelState state;
final Future<void> Function(String, int, List<int>, String?) onSend;
final Future<void> Function(String, int, List<int>, String) onSend;
const RecordingInputRow({
required this.state,
required this.onSend,

View file

@ -1,20 +1,19 @@
import 'dart:async';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:matrix/matrix.dart';
import 'package:path/path.dart' as path_lib;
import 'package:path_provider/path_provider.dart';
import 'package:record/record.dart';
import 'package:wakelock_plus/wakelock_plus.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
import 'events/audio_player.dart';
class RecordingViewModel extends StatefulWidget {
@ -68,7 +67,7 @@ class RecordingViewModelState extends State<RecordingViewModel> {
? AudioEncoder.opus
: AudioEncoder.aacLc;
fileName =
'recording${DateTime.now().microsecondsSinceEpoch}.${codec.fileExtension}';
'voice_message_${DateTime.now().millisecondsSinceEpoch}.${codec.fileExtension}';
String? path;
if (!kIsWeb) {
final tempDir = await getTemporaryDirectory();
@ -169,7 +168,7 @@ class RecordingViewModelState extends State<RecordingViewModel> {
String path,
int duration,
List<int> waveform,
String? fileName,
String fileName,
)
onSend,
) async {
@ -190,7 +189,7 @@ class RecordingViewModelState extends State<RecordingViewModel> {
isSending = true;
});
try {
await onSend(path, duration.inMilliseconds, waveform, fileName);
await onSend(path, duration.inMilliseconds, waveform, fileName!);
} catch (e, s) {
Logs().e('Unable to send voice message', e, s);
setState(() {

View file

@ -1,9 +1,8 @@
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import '../../config/themes.dart';
import 'chat.dart';
import 'events/reply_content.dart';

View file

@ -1,10 +1,8 @@
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
class SeenByRow extends StatelessWidget {
final Event event;

View file

@ -1,11 +1,5 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:async/async.dart' show Result;
import 'package:cross_file/cross_file.dart';
import 'package:matrix/matrix.dart' hide Result;
import 'package:mime/mime.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
@ -15,6 +9,11 @@ import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/utils/size_string.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/dialog_text_field.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart' hide Result;
import 'package:mime/mime.dart';
import '../../utils/resize_video.dart';
class SendFileDialog extends StatefulWidget {

View file

@ -1,15 +1,13 @@
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat/events/map_bubble.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:matrix/matrix.dart';
class SendLocationDialog extends StatefulWidget {
final Room room;

View file

@ -1,9 +1,7 @@
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
class StartPollBottomSheet extends StatefulWidget {
final Room room;

View file

@ -1,11 +1,10 @@
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/url_launcher.dart';
import 'package:fluffychat/widgets/mxc_image.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import '../../widgets/avatar.dart';
class StickerPickerDialog extends StatefulWidget {

View file

@ -1,12 +1,11 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/pages/chat/chat.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
class TypingIndicators extends StatelessWidget {
final ChatController controller;

View file

@ -1,8 +1,3 @@
import 'package:flutter/material.dart' hide Visibility;
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat_access_settings/chat_access_settings_page.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
@ -11,6 +6,9 @@ import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.
import 'package:fluffychat/widgets/adaptive_dialogs/show_text_input_dialog.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart' hide Visibility;
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
class ChatAccessSettings extends StatefulWidget {
final String roomId;

View file

@ -1,12 +1,10 @@
import 'package:flutter/material.dart' hide Visibility;
import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat_access_settings/chat_access_settings_controller.dart';
import 'package:fluffychat/utils/fluffy_share.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/widgets/layouts/max_width_body.dart';
import 'package:flutter/material.dart' hide Visibility;
import 'package:matrix/matrix.dart';
class ChatAccessSettingsPageView extends StatelessWidget {
final ChatAccessSettingsController controller;

View file

@ -1,10 +1,5 @@
import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
import 'package:file_picker/file_picker.dart';
import 'package:image_picker/image_picker.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat_details/chat_details_view.dart';
import 'package:fluffychat/pages/settings/settings.dart';
@ -15,6 +10,9 @@ import 'package:fluffychat/widgets/adaptive_dialogs/show_modal_action_popup.dart
import 'package:fluffychat/widgets/adaptive_dialogs/show_text_input_dialog.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:matrix/matrix.dart';
class ChatDetails extends StatefulWidget {
final String roomId;

View file

@ -1,9 +1,3 @@
import 'package:flutter/material.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat_details/chat_details.dart';
import 'package:fluffychat/pages/chat_details/participant_list_item.dart';
@ -13,6 +7,11 @@ import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/chat_settings_popup_menu.dart';
import 'package:fluffychat/widgets/layouts/max_width_body.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import '../../utils/url_launcher.dart';
import '../../widgets/mxc_image_viewer.dart';
import '../../widgets/qr_code_viewer.dart';

View file

@ -1,10 +1,9 @@
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/widgets/member_actions_popup_menu_button.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import '../../widgets/avatar.dart';
class ParticipantListItem extends StatelessWidget {

View file

@ -1,14 +1,13 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/encryption.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat_encryption_settings/chat_encryption_settings_view.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/encryption.dart';
import 'package:matrix/matrix.dart';
import '../key_verification/key_verification_dialog.dart';
class ChatEncryptionSettings extends StatefulWidget {

View file

@ -1,16 +1,14 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat_encryption_settings/chat_encryption_settings.dart';
import 'package:fluffychat/utils/beautify_string_extension.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/layouts/max_width_body.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:url_launcher/url_launcher_string.dart';
class ChatEncryptionSettingsView extends StatelessWidget {
final ChatEncryptionSettingsController controller;

View file

@ -1,17 +1,7 @@
import 'dart:async';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:cross_file/cross_file.dart';
import 'package:flutter_shortcuts_new/flutter_shortcuts_new.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart' as sdk;
import 'package:matrix/matrix.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat_list/chat_list_view.dart';
@ -26,6 +16,15 @@ import 'package:fluffychat/widgets/adaptive_dialogs/show_text_input_dialog.dart'
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/share_scaffold_dialog.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_shortcuts_new/flutter_shortcuts_new.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart' as sdk;
import 'package:matrix/matrix.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
import 'package:url_launcher/url_launcher_string.dart';
import '../../../utils/account_bundles.dart';
import '../../config/setting_keys.dart';
import '../../utils/url_launcher.dart';
@ -307,13 +306,11 @@ class ChatListController extends State<ChatList>
void _processIncomingSharedMedia(List<SharedMediaFile> files) {
if (files.isEmpty) return;
inspect(files);
if (files.singleOrNull?.path.startsWith(AppConfig.deepLinkPrefix) == true) {
return;
}
inspect(files);
showScaffoldDialog(
context: context,
builder: (context) => ShareScaffoldDialog(

View file

@ -1,8 +1,3 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat_list/chat_list.dart';
@ -14,6 +9,10 @@ import 'package:fluffychat/pages/chat_list/status_msg_list.dart';
import 'package:fluffychat/utils/stream_extension.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/public_room_dialog.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import '../../config/themes.dart';
import '../../widgets/adaptive_dialogs/user_dialog.dart';
import '../../widgets/matrix.dart';

View file

@ -1,12 +1,11 @@
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat_list/chat_list.dart';
import 'package:fluffychat/pages/chat_list/client_chooser_button.dart';
import 'package:fluffychat/utils/sync_status_localization.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import '../../widgets/matrix.dart';
class ChatListHeader extends StatelessWidget implements PreferredSizeWidget {

View file

@ -1,7 +1,3 @@
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat_list/unread_bubble.dart';
@ -10,6 +6,9 @@ import 'package:fluffychat/utils/room_status_extension.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/hover_builder.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import '../../config/themes.dart';
import '../../utils/date_time_extension.dart';
import '../../widgets/avatar.dart';

View file

@ -1,10 +1,10 @@
import 'package:flutter/material.dart';
import 'package:fluffychat/config/setting_keys.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/pages/chat_list/chat_list.dart';
import 'package:fluffychat/pages/chat_list/start_chat_fab.dart';
import 'package:fluffychat/widgets/navigation_rail.dart';
import 'package:flutter/material.dart';
import 'chat_list_body.dart';
class ChatListView extends StatelessWidget {

View file

@ -1,14 +1,13 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:url_launcher/url_launcher_string.dart';
import '../../utils/fluffy_share.dart';
import 'chat_list.dart';

View file

@ -1,11 +1,10 @@
import 'package:flutter/material.dart';
import 'package:badges/badges.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/widgets/hover_builder.dart';
import 'package:fluffychat/widgets/unread_rooms_badge.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import '../../config/themes.dart';
class NaviRailItem extends StatelessWidget {

View file

@ -1,13 +1,7 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart' as sdk;
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
@ -20,6 +14,10 @@ import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/hover_builder.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart' as sdk;
import 'package:matrix/matrix.dart';
enum SpaceChildAction {
mute,

View file

@ -1,8 +1,6 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
class StartChatFab extends StatelessWidget {
const StartChatFab({super.key});

View file

@ -1,13 +1,12 @@
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/utils/stream_extension.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/hover_builder.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import '../../widgets/adaptive_dialogs/user_dialog.dart';
class StatusMessageList extends StatelessWidget {

View file

@ -1,8 +1,6 @@
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
class UnreadBubble extends StatelessWidget {
final Room room;

View file

@ -1,10 +1,9 @@
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
import '../../widgets/layouts/max_width_body.dart';
import '../../widgets/matrix.dart';
import '../chat_details/participant_list_item.dart';

View file

@ -1,15 +1,11 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat_permissions_settings/chat_permissions_settings_view.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:fluffychat/widgets/permission_slider_dialog.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
class ChatPermissionsSettings extends StatefulWidget {
const ChatPermissionsSettings({super.key});
@ -51,7 +47,6 @@ class ChatPermissionsSettingsController extends State<ChatPermissionsSettings> {
} else {
content[key] = newLevel;
}
inspect(content);
await showFutureLoadingDialog(
context: context,
future: () => room.client.setRoomStateWithKey(

View file

@ -1,12 +1,10 @@
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat_permissions_settings/chat_permissions_settings.dart';
import 'package:fluffychat/pages/chat_permissions_settings/permission_list_tile.dart';
import 'package:fluffychat/widgets/layouts/max_width_body.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
class ChatPermissionsSettingsView extends StatelessWidget {
final ChatPermissionsSettingsController controller;

View file

@ -1,9 +1,7 @@
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
class PermissionsListTile extends StatelessWidget {
final String permissionKey;

View file

@ -1,12 +1,10 @@
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat_search/search_footer.dart';
import 'package:fluffychat/utils/date_time_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
class ChatSearchFilesTab extends StatelessWidget {
final Room room;

View file

@ -1,13 +1,11 @@
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pages/chat/events/video_player.dart';
import 'package:fluffychat/pages/chat_search/search_footer.dart';
import 'package:fluffychat/pages/image_viewer/image_viewer.dart';
import 'package:fluffychat/widgets/mxc_image.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:matrix/matrix.dart';
class ChatSearchImagesTab extends StatelessWidget {
final Room room;

View file

@ -1,15 +1,13 @@
import 'package:flutter/material.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat_search/search_footer.dart';
import 'package:fluffychat/utils/date_time_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/url_launcher.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:flutter/material.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
class ChatSearchMessageTab extends StatelessWidget {
final String searchQuery;

View file

@ -1,9 +1,7 @@
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/pages/chat_search/chat_search_view.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
class ChatSearchPage extends StatefulWidget {
final String roomId;

View file

@ -1,5 +1,3 @@
import 'package:flutter/material.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat_search/chat_search_files_tab.dart';
@ -8,6 +6,7 @@ import 'package:fluffychat/pages/chat_search/chat_search_message_tab.dart';
import 'package:fluffychat/pages/chat_search/chat_search_page.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/widgets/layouts/max_width_body.dart';
import 'package:flutter/material.dart';
class ChatSearchView extends StatelessWidget {
final ChatSearchController controller;

View file

@ -1,7 +1,6 @@
import 'package:flutter/material.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/date_time_extension.dart';
import 'package:flutter/material.dart';
class SearchFooter extends StatelessWidget {
final DateTime? searchedUntil;

View file

@ -1,16 +1,16 @@
import 'package:flutter/material.dart';
import 'package:async/async.dart' show Result;
import 'package:collection/collection.dart' show IterableExtension;
import 'package:matrix/encryption.dart';
import 'package:matrix/matrix.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/device_settings/device_settings_view.dart';
import 'package:fluffychat/pages/key_verification/key_verification_dialog.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_text_input_dialog.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:flutter/material.dart';
import 'package:matrix/encryption.dart';
import 'package:matrix/matrix.dart' hide Result;
import 'package:url_launcher/url_launcher_string.dart';
import '../../widgets/matrix.dart';
class DevicesSettings extends StatefulWidget {
@ -49,8 +49,8 @@ class DevicesSettingsController extends State<DevicesSettings> {
Future<void> removeDevicesAction(List<Device> devices) async {
final client = Matrix.of(context).client;
final wellKnown = await client.getWellknown();
final accountManageUrl = wellKnown.additionalProperties
final wellKnown = await Result.capture(client.getWellknown());
final accountManageUrl = wellKnown.asValue?.value.additionalProperties
.tryGetMap<String, Object?>('org.matrix.msc2965.authentication')
?.tryGet<String>('account');
if (accountManageUrl != null) {

View file

@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/device_settings/device_settings.dart';
import 'package:fluffychat/widgets/layouts/max_width_body.dart';
import 'package:flutter/material.dart';
import 'user_device_list_item.dart';
class DevicesSettingsView extends StatelessWidget {

View file

@ -1,10 +1,9 @@
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_modal_action_popup.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import '../../utils/date_time_extension.dart';
import '../../utils/matrix_sdk_extensions/device_extension.dart';
import '../../widgets/matrix.dart';

View file

@ -19,21 +19,20 @@
import 'dart:async';
import 'dart:math';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/utils/voip/video_renderer.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_foreground_task/flutter_foreground_task.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart' hide VideoRenderer;
import 'package:just_audio/just_audio.dart';
import 'package:matrix/matrix.dart';
import 'package:wakelock_plus/wakelock_plus.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/utils/voip/video_renderer.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'pip/pip_view.dart';
class _StreamView extends StatelessWidget {

View file

@ -1,6 +1,6 @@
import 'package:fluffychat/config/themes.dart';
import 'package:flutter/material.dart';
import 'package:fluffychat/config/themes.dart';
import 'dismiss_keyboard.dart';
class PIPView extends StatefulWidget {

View file

@ -1,13 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/pages/image_viewer/image_viewer_view.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/utils/show_scaffold_dialog.dart';
import 'package:fluffychat/widgets/share_scaffold_dialog.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:matrix/matrix.dart';
import '../../utils/matrix_sdk_extensions/event_extension.dart';
class ImageViewer extends StatefulWidget {

View file

@ -1,12 +1,11 @@
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/image_viewer/video_player.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/widgets/hover_builder.dart';
import 'package:fluffychat/widgets/mxc_image.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'image_viewer.dart';
class ImageViewerView extends StatelessWidget {

View file

@ -1,15 +1,14 @@
import 'dart:io';
import 'package:chewie/chewie.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
import 'package:fluffychat/widgets/blur_hash.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:chewie/chewie.dart';
import 'package:matrix/matrix.dart';
import 'package:path_provider/path_provider.dart';
import 'package:video_player/video_player.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
import 'package:fluffychat/widgets/blur_hash.dart';
import '../../../utils/error_reporter.dart';
import '../../widgets/mxc_image.dart';

Some files were not shown because too many files have changed in this diff Show more