fluffychat merge

This commit is contained in:
ggurdin 2026-02-03 11:13:01 -05:00
commit 082ca6d1de
No known key found for this signature in database
GPG key ID: A01CB41737CBB478
15 changed files with 71 additions and 136 deletions

View file

@ -6,7 +6,6 @@ import 'package:fluffychat/pages/invitation_selection/invitation_selection_view.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:integration_test/integration_test.dart';
import 'package:fluffychat/main.dart' as app;
@ -28,10 +27,6 @@ void main() {
SharedPreferences.setMockInitialValues({
SettingKeys.showNoGoogle: false,
});
try {
Hive.deleteFromDisk();
Hive.initFlutter();
} catch (_) {}
},
);

View file

@ -3242,6 +3242,7 @@
"displayNavigationRail": "Show navigation rail on mobile",
"customReaction": "Custom reaction",
"moreEvents": "More events",
"declineInvitation": "Decline invitation",
"ignore": "Block",
"ignoredUsers": "Blocked users",
"writeAMessageLangCodes": "Type in {l1} or {l2}...",

View file

@ -141,6 +141,7 @@ class ChatListController extends State<ChatList>
void onChatTap(Room room) async {
if (room.membership == Membership.invite) {
// #Pangea
final theme = Theme.of(context);
final inviteEvent = room.getState(
EventTypes.RoomMember,
@ -148,9 +149,7 @@ class ChatListController extends State<ChatList>
);
final matrixLocals = MatrixLocals(L10n.of(context));
final action = await showAdaptiveDialog<InviteAction>(
// #Pangea
barrierDismissible: true,
// Pangea#
context: context,
builder: (context) => AlertDialog.adaptive(
title: ConstrainedBox(
@ -220,6 +219,7 @@ class ChatListController extends State<ChatList>
return;
}
if (!mounted) return;
// Pangea#
final joinResult = await showFutureLoadingDialog(
context: context,
future: () async {
@ -1071,34 +1071,34 @@ class ChatListController extends State<ChatList>
});
// #Pangea
// if (client.userDeviceKeys[client.userID!]?.deviceKeys.values
// .any((device) => !device.verified && !device.blocked) ??
// false) {
// late final ScaffoldFeatureController controller;
// final theme = Theme.of(context);
// controller = ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// duration: const Duration(seconds: 15),
// showCloseIcon: true,
// backgroundColor: theme.colorScheme.errorContainer,
// closeIconColor: theme.colorScheme.onErrorContainer,
// content: Text(
// L10n.of(context).oneOfYourDevicesIsNotVerified,
// style: TextStyle(
// color: theme.colorScheme.onErrorContainer,
// ),
// ),
// action: SnackBarAction(
// onPressed: () {
// controller.close();
// router.go('/rooms/settings/devices');
// },
// textColor: theme.colorScheme.onErrorContainer,
// label: L10n.of(context).settings,
// if (client.userDeviceKeys[client.userID!]?.deviceKeys.values
// .any((device) => !device.verified && !device.blocked) ??
// false) {
// late final ScaffoldFeatureController controller;
// final theme = Theme.of(context);
// controller = ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// duration: const Duration(seconds: 15),
// showCloseIcon: true,
// backgroundColor: theme.colorScheme.errorContainer,
// closeIconColor: theme.colorScheme.onErrorContainer,
// content: Text(
// L10n.of(context).oneOfYourDevicesIsNotVerified,
// style: TextStyle(
// color: theme.colorScheme.onErrorContainer,
// ),
// ),
// );
// }
// action: SnackBarAction(
// onPressed: () {
// controller.close();
// router.go('/rooms/settings/devices');
// },
// textColor: theme.colorScheme.onErrorContainer,
// label: L10n.of(context).settings,
// ),
// ),
// );
// }
// Pangea#
}
@ -1245,6 +1245,9 @@ enum ChatContextAction {
delete,
endActivity,
// Pangea#
block,
}
// #Pangea
enum InviteAction { accept, decline, block }
// Pangea#

View file

@ -43,40 +43,6 @@ class ChatListItem extends StatelessWidget {
// Pangea#
});
Future<bool> archiveAction(BuildContext context) async {
{
if ([Membership.leave, Membership.ban].contains(room.membership)) {
final forgetResult = await showFutureLoadingDialog(
context: context,
future: () => room.forget(),
);
return forgetResult.isValue;
}
final confirmed = await showOkCancelAlertDialog(
context: context,
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).leave,
cancelLabel: L10n.of(context).cancel,
// #Pangea
// message: L10n.of(context).archiveRoomDescription,
message: room.isSpace
? L10n.of(context).leaveSpaceDescription
: L10n.of(context).leaveRoomDescription,
// Pangea#
isDestructive: true,
);
if (confirmed != OkCancelResult.ok) return false;
final leaveResult = await showFutureLoadingDialog(
context: context,
// #Pangea
// future: () => room.leave(),
future: () => room.isSpace ? room.leaveSpace() : room.leave(),
// Pangea#
);
return leaveResult.isValue;
}
}
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
@ -85,7 +51,7 @@ class ChatListItem extends StatelessWidget {
final typingText = room.getLocalizedTypingText(context);
final lastEvent = room.lastEvent;
final ownMessage = lastEvent?.senderId == room.client.userID;
final unread = room.isUnread || room.membership == Membership.invite;
final unread = room.isUnread;
final directChatMatrixId = room.directChatMatrixID;
final isDirectChat = directChatMatrixId != null;
final unreadBubbleSize = unread || room.hasNewMessages
@ -414,8 +380,7 @@ class ChatListItem extends StatelessWidget {
room.notificationCount.toString().length +
9,
decoration: BoxDecoration(
color: room.highlightCount > 0 ||
room.membership == Membership.invite
color: room.highlightCount > 0
? theme.colorScheme.error
: hasNotifications || room.markedUnread
? theme.colorScheme.primary
@ -426,8 +391,7 @@ class ChatListItem extends StatelessWidget {
? Text(
room.notificationCount.toString(),
style: TextStyle(
color: room.highlightCount > 0 ||
room.membership == Membership.invite
color: room.highlightCount > 0
? theme.colorScheme.onError
: hasNotifications
? theme.colorScheme.onPrimary
@ -443,7 +407,28 @@ class ChatListItem extends StatelessWidget {
),
onTap: onTap,
trailing: onForget == null
? null
? room.membership == Membership.invite
? IconButton(
tooltip: L10n.of(context).declineInvitation,
icon: const Icon(Icons.delete_forever_outlined),
color: theme.colorScheme.error,
onPressed: () async {
final consent = await showOkCancelAlertDialog(
context: context,
title: L10n.of(context).declineInvitation,
message: L10n.of(context).areYouSure,
okLabel: L10n.of(context).yes,
isDestructive: true,
);
if (consent != OkCancelResult.ok) return;
if (!context.mounted) return;
await showFutureLoadingDialog(
context: context,
future: room.leave,
);
},
)
: null
: IconButton(
icon: const Icon(Icons.delete_outlined),
onPressed: onForget,

View file

@ -6,7 +6,6 @@ import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
import 'package:flutter_web_auth_2/flutter_web_auth_2.dart';
import 'package:go_router/go_router.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:matrix/matrix.dart';
import 'package:universal_html/html.dart' as html;
import 'package:url_launcher/url_launcher_string.dart';
@ -45,17 +44,6 @@ class HomeserverPickerController extends State<HomeserverPicker> {
Future<void> _checkTorBrowser() async {
if (!kIsWeb) return;
Hive.openBox('test').then((value) => null).catchError(
(e, s) async {
await showOkAlertDialog(
context: context,
title: L10n.of(context).indexedDbErrorTitle,
message: L10n.of(context).indexedDbErrorLong,
);
_checkTorBrowser();
},
);
final isTor = await TorBrowserDetector.isTorBrowser;
isTorBrowser = isTor;
}

View file

@ -236,6 +236,15 @@ void chatContextMenuAction(
),
);
return;
case ChatContextAction.block:
final inviteEvent = room.getState(
EventTypes.RoomMember,
room.client.userID!,
);
context.go(
'/rooms/settings/security/ignorelist',
extra: inviteEvent?.senderId,
);
case ChatContextAction.leave:
final confirmed = await showOkCancelAlertDialog(
context: context,

View file

@ -6,10 +6,8 @@ import 'package:collection/collection.dart';
import 'package:desktop_notifications/desktop_notifications.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_vodozemac/flutter_vodozemac.dart' as vod;
import 'package:hive_flutter/hive_flutter.dart';
import 'package:matrix/encryption/utils/key_verification.dart';
import 'package:matrix/matrix.dart';
import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:universal_html/html.dart' as html;
@ -30,14 +28,6 @@ abstract class ClientManager {
bool initialize = true,
required SharedPreferences store,
}) async {
Logs().i('Getting clients from store');
if (PlatformInfos.isLinux) {
Hive.init((await getApplicationSupportDirectory()).path);
} else {
await Hive.initFlutter();
}
final clientNames = <String>{};
try {
final clientNamesList = store.getStringList(clientNamespace) ?? [];

View file

@ -15,7 +15,6 @@
#include <gtk/gtk_plugin.h>
#include <handy_window/handy_window_plugin.h>
#include <open_file_linux/open_file_linux_plugin.h>
#include <pasteboard/pasteboard_plugin.h>
#include <record_linux/record_linux_plugin.h>
#include <sentry_flutter/sentry_flutter_plugin.h>
#include <sqlcipher_flutter_libs/sqlite3_flutter_libs_plugin.h>
@ -50,9 +49,6 @@ void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) open_file_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "OpenFileLinuxPlugin");
open_file_linux_plugin_register_with_registrar(open_file_linux_registrar);
g_autoptr(FlPluginRegistrar) pasteboard_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "PasteboardPlugin");
pasteboard_plugin_register_with_registrar(pasteboard_registrar);
g_autoptr(FlPluginRegistrar) record_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "RecordLinuxPlugin");
record_linux_plugin_register_with_registrar(record_linux_registrar);

View file

@ -12,7 +12,6 @@ list(APPEND FLUTTER_PLUGIN_LIST
gtk
handy_window
open_file_linux
pasteboard
record_linux
sentry_flutter
sqlcipher_flutter_libs

View file

@ -28,7 +28,6 @@ import in_app_purchase_storekit
import just_audio
import open_file_mac
import package_info_plus
import pasteboard
import path_provider_foundation
import purchases_flutter
import record_macos
@ -68,7 +67,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin"))
OpenFilePlugin.register(with: registry.registrar(forPlugin: "OpenFilePlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
PasteboardPlugin.register(with: registry.registrar(forPlugin: "PasteboardPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
PurchasesFlutterPlugin.register(with: registry.registrar(forPlugin: "PurchasesFlutterPlugin"))
RecordMacOsPlugin.register(with: registry.registrar(forPlugin: "RecordMacOsPlugin"))

View file

@ -718,7 +718,7 @@ packages:
source: sdk
version: "0.0.0"
flutter_cache_manager:
dependency: "direct main"
dependency: transitive
description:
name: flutter_cache_manager
sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386"
@ -1185,22 +1185,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.1.1"
hive:
dependency: "direct main"
description:
name: hive
sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941"
url: "https://pub.dev"
source: hosted
version: "2.2.3"
hive_flutter:
dependency: "direct main"
description:
name: hive_flutter
sha256: dca1da446b1d808a51689fb5d0c6c9510c0a2ba01e22805d492c73b68e33eecc
url: "https://pub.dev"
source: hosted
version: "1.1.0"
html:
dependency: "direct main"
description:
@ -1727,14 +1711,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.21.45"
pasteboard:
dependency: "direct main"
description:
name: pasteboard
sha256: "1c8b6a8b3f1d12e55d4e9404433cda1b4abe66db6b17bc2d2fb5965772c04674"
url: "https://pub.dev"
source: hosted
version: "0.2.0"
path:
dependency: "direct main"
description:

View file

@ -36,7 +36,6 @@ dependencies:
file_selector: ^1.0.3
flutter:
sdk: flutter
flutter_cache_manager: ^3.4.1
flutter_foreground_task: ^6.1.3
flutter_highlighter: ^0.1.1
flutter_linkify: ^6.0.0
@ -58,8 +57,6 @@ dependencies:
geolocator: ^13.0.1
go_router: ^15.1.2
handy_window: ^0.4.0
hive: ^2.2.3
hive_flutter: ^1.1.0
html: ^0.15.4
http: ^1.2.0
image: ^4.1.7
@ -79,7 +76,6 @@ dependencies:
native_imaging: ^0.2.0
opus_caf_converter_dart: ^1.0.1
package_info_plus: ^8.1.1
pasteboard: ^0.2.0
path: ^1.9.0
path_provider: ^2.1.2
permission_handler: ^11.4.0

View file

@ -1,7 +1,7 @@
name: fluffychat
title: FluffyChat
base: core24
version: 1.27.0
adopt-info: fluffychat
license: AGPL-3.0
summary: The cutest messenger in the Matrix network
description: |
@ -82,6 +82,8 @@ parts:
# Workaround for Flutter build error:
rm -rf build
craftctl set version="$(yq e '.version' pubspec.yaml | sed 's/\(.*\)+.*/\1/')"
flutter build linux --release -v
mkdir -p $CRAFT_PART_INSTALL/bin/
cp -r build/linux/*/release/bundle/* $CRAFT_PART_INSTALL/bin/
@ -93,6 +95,7 @@ parts:
- libpciaccess-dev
build-snaps:
- rustup
- yq
stage-packages:
- libsecret-1-0
- libjsoncpp25

View file

@ -16,7 +16,6 @@
#include <flutter_tts/flutter_tts_plugin.h>
#include <flutter_webrtc/flutter_web_r_t_c_plugin.h>
#include <geolocator_windows/geolocator_windows.h>
#include <pasteboard/pasteboard_plugin.h>
#include <permission_handler_windows/permission_handler_windows_plugin.h>
#include <record_windows/record_windows_plugin_c_api.h>
#include <rive_common/rive_plugin.h>
@ -47,8 +46,6 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("FlutterWebRTCPlugin"));
GeolocatorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("GeolocatorWindows"));
PasteboardPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PasteboardPlugin"));
PermissionHandlerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
RecordWindowsPluginCApiRegisterWithRegistrar(

View file

@ -13,7 +13,6 @@ list(APPEND FLUTTER_PLUGIN_LIST
flutter_tts
flutter_webrtc
geolocator_windows
pasteboard
permission_handler_windows
record_windows
rive_common