refactor: Implement own adaptive dialogs and remove package

pull/1517/head
krille-chan 7 months ago
parent dea29161c8
commit 8819c40ebd
No known key found for this signature in database

@ -123,11 +123,6 @@ abstract class FluffyThemes {
),
),
),
dialogTheme: DialogTheme(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppConfig.borderRadius),
),
),
snackBarTheme: const SnackBarThemeData(
behavior: SnackBarBehavior.floating,
),

@ -1,10 +1,10 @@
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart';
import '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';

@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:matrix/encryption.dart';
@ -11,6 +10,7 @@ import 'package:fluffychat/utils/error_reporter.dart';
import 'package:fluffychat/utils/fluffy_share.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import '../../utils/adaptive_bottom_sheet.dart';
import '../key_verification/key_verification_dialog.dart';
@ -366,7 +366,6 @@ class BootstrapDialogState extends State<BootstrapDialog> {
.verifyOtherDeviceDescription,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
fullyCapitalizedForMaterial: false,
);
if (consent != OkCancelResult.ok) return;
final req = await showFutureLoadingDialog(
@ -404,7 +403,7 @@ class BootstrapDialogState extends State<BootstrapDialog> {
message: L10n.of(context).wipeChatBackup,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
isDestructiveAction: true,
isDestructive: true,
)) {
setState(() => _createBootstrap(true));
}

@ -5,7 +5,6 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:collection/collection.dart';
import 'package:desktop_drop/desktop_drop.dart';
import 'package:device_info_plus/device_info_plus.dart';
@ -33,6 +32,9 @@ import 'package:fluffychat/utils/matrix_sdk_extensions/filtered_timeline_extensi
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/utils/show_scaffold_dialog.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_modal_action_popup.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:fluffychat/widgets/matrix.dart';
import 'package:fluffychat/widgets/share_scaffold_dialog.dart';
@ -691,23 +693,22 @@ class ChatController extends State<ChatPageWithRoom>
void reportEventAction() async {
final event = selectedEvents.single;
final score = await showConfirmationDialog<int>(
final score = await showModalActionPopup<int>(
context: context,
title: L10n.of(context).reportMessage,
message: L10n.of(context).howOffensiveIsThisContent,
cancelLabel: L10n.of(context).cancel,
okLabel: L10n.of(context).ok,
actions: [
AlertDialogAction(
key: -100,
AdaptiveModalAction(
value: -100,
label: L10n.of(context).extremeOffensive,
),
AlertDialogAction(
key: -50,
AdaptiveModalAction(
value: -50,
label: L10n.of(context).offensive,
),
AlertDialogAction(
key: 0,
AdaptiveModalAction(
value: 0,
label: L10n.of(context).inoffensive,
),
],
@ -718,15 +719,15 @@ class ChatController extends State<ChatPageWithRoom>
title: L10n.of(context).whyDoYouWantToReportThis,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
textFields: [DialogTextField(hintText: L10n.of(context).reason)],
hintText: L10n.of(context).reason,
);
if (reason == null || reason.single.isEmpty) return;
if (reason == null || reason.isEmpty) return;
final result = await showFutureLoadingDialog(
context: context,
future: () => Matrix.of(context).client.reportContent(
event.roomId!,
event.eventId,
reason: reason.single,
reason: reason,
score: score,
),
);
@ -765,18 +766,14 @@ class ChatController extends State<ChatPageWithRoom>
context: context,
title: L10n.of(context).redactMessage,
message: L10n.of(context).redactMessageDescription,
isDestructiveAction: true,
textFields: [
DialogTextField(
hintText: L10n.of(context).optionalRedactReason,
),
],
isDestructive: true,
hintText: L10n.of(context).optionalRedactReason,
okLabel: L10n.of(context).remove,
cancelLabel: L10n.of(context).cancel,
)
: <String>[];
: null;
if (reasonInput == null) return;
final reason = reasonInput.single.isEmpty ? null : reasonInput.single;
final reason = reasonInput.isEmpty ? null : reasonInput;
for (final event in selectedEvents) {
await showFutureLoadingDialog(
context: context,
@ -1243,21 +1240,21 @@ class ChatController extends State<ChatPageWithRoom>
}
});
}
final callType = await showModalActionSheet<CallType>(
final callType = await showModalActionPopup<CallType>(
context: context,
title: L10n.of(context).warning,
message: L10n.of(context).videoCallsBetaWarning,
cancelLabel: L10n.of(context).cancel,
actions: [
SheetAction(
AdaptiveModalAction(
label: L10n.of(context).voiceCall,
icon: Icons.phone_outlined,
key: CallType.kVoice,
icon: const Icon(Icons.phone_outlined),
value: CallType.kVoice,
),
SheetAction(
AdaptiveModalAction(
label: L10n.of(context).videoCall,
icon: Icons.video_call_outlined,
key: CallType.kVideo,
icon: const Icon(Icons.video_call_outlined),
value: CallType.kVideo,
),
],
);

@ -2,13 +2,13 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart';
import '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';
class PinnedEvents extends StatelessWidget {
@ -30,13 +30,15 @@ class PinnedEvents extends StatelessWidget {
final eventId = events.length == 1
? events.single?.eventId
: await showConfirmationDialog<String>(
: await showModalActionPopup<String>(
context: context,
title: L10n.of(context).pinMessage,
title: L10n.of(context).pin,
cancelLabel: L10n.of(context).cancel,
actions: events
.map(
(event) => AlertDialogAction(
key: event?.eventId ?? '',
(event) => AdaptiveModalAction(
value: event?.eventId ?? '',
icon: const Icon(Icons.push_pin_outlined),
label: event?.calcLocalizedBodyFallback(
MatrixLocals(L10n.of(context)),
withSenderNamePrefix: true,

@ -14,7 +14,7 @@ import 'package:fluffychat/utils/localized_exception_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_file_extension.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/utils/size_string.dart';
import 'package:fluffychat/widgets/adaptive_dialog_action.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart';
import '../../utils/resize_video.dart';
class SendFileDialog extends StatefulWidget {

@ -8,7 +8,7 @@ import 'package:geolocator/geolocator.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/pages/chat/events/map_bubble.dart';
import 'package:fluffychat/widgets/adaptive_dialog_action.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
class SendLocationDialog extends StatefulWidget {

@ -1,11 +1,13 @@
import 'package:flutter/material.dart' hide Visibility;
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/pages/chat_access_settings/chat_access_settings_page.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_modal_action_popup.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:fluffychat/widgets/matrix.dart';
@ -149,14 +151,15 @@ class ChatAccessSettingsController extends State<ChatAccessSettings> {
);
final capabilities = capabilitiesResult.result;
if (capabilities == null) return;
final newVersion = await showConfirmationDialog<String>(
final newVersion = await showModalActionPopup<String>(
context: context,
title: L10n.of(context).replaceRoomWithNewerVersion,
cancelLabel: L10n.of(context).cancel,
actions: capabilities.mRoomVersions!.available.entries
.where((r) => r.key != roomVersion)
.map(
(version) => AlertDialogAction(
key: version.key,
(version) => AdaptiveModalAction(
value: version.key,
label:
'${version.key} (${version.value.toString().split('.').last})',
),
@ -172,7 +175,7 @@ class ChatAccessSettingsController extends State<ChatAccessSettings> {
cancelLabel: L10n.of(context).cancel,
title: L10n.of(context).areYouSure,
message: L10n.of(context).roomUpgradeDescription,
isDestructiveAction: true,
isDestructive: true,
)) {
return;
}
@ -191,15 +194,11 @@ class ChatAccessSettingsController extends State<ChatAccessSettings> {
final input = await showTextInputDialog(
context: context,
title: L10n.of(context).editRoomAliases,
textFields: [
DialogTextField(
prefixText: '#',
suffixText: domain,
hintText: L10n.of(context).alias,
),
],
prefixText: '#',
suffixText: domain,
hintText: L10n.of(context).alias,
);
final aliasLocalpart = input?.singleOrNull?.trim();
final aliasLocalpart = input?.trim();
if (aliasLocalpart == null || aliasLocalpart.isEmpty) return;
final alias = '#$aliasLocalpart:$domain';

@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:collection/collection.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:go_router/go_router.dart';
@ -12,6 +11,8 @@ import 'package:fluffychat/pages/settings/settings.dart';
import 'package:fluffychat/utils/file_selector.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/platform_infos.dart';
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';
@ -46,20 +47,16 @@ class ChatDetailsController extends State<ChatDetails> {
title: L10n.of(context).changeTheNameOfTheGroup,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
textFields: [
DialogTextField(
initialText: room.getLocalizedDisplayname(
MatrixLocals(
L10n.of(context),
),
),
initialText: room.getLocalizedDisplayname(
MatrixLocals(
L10n.of(context),
),
],
),
);
if (input == null) return;
final success = await showFutureLoadingDialog(
context: context,
future: () => room.setName(input.single),
future: () => room.setName(input),
);
if (success.error == null) {
ScaffoldMessenger.of(context).showSnackBar(
@ -75,19 +72,15 @@ class ChatDetailsController extends State<ChatDetails> {
title: L10n.of(context).setChatDescription,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
textFields: [
DialogTextField(
hintText: L10n.of(context).noChatDescriptionYet,
initialText: room.topic,
minLines: 4,
maxLines: 8,
),
],
hintText: L10n.of(context).noChatDescriptionYet,
initialText: room.topic,
minLines: 4,
maxLines: 8,
);
if (input == null) return;
final success = await showFutureLoadingDialog(
context: context,
future: () => room.setDescription(input.single),
future: () => room.setDescription(input),
);
if (success.error == null) {
ScaffoldMessenger.of(context).showSnackBar(
@ -116,30 +109,31 @@ class ChatDetailsController extends State<ChatDetails> {
final room = Matrix.of(context).client.getRoomById(roomId!);
final actions = [
if (PlatformInfos.isMobile)
SheetAction(
key: AvatarAction.camera,
AdaptiveModalAction(
value: AvatarAction.camera,
label: L10n.of(context).openCamera,
isDefaultAction: true,
icon: Icons.camera_alt_outlined,
icon: const Icon(Icons.camera_alt_outlined),
),
SheetAction(
key: AvatarAction.file,
AdaptiveModalAction(
value: AvatarAction.file,
label: L10n.of(context).openGallery,
icon: Icons.photo_outlined,
icon: const Icon(Icons.photo_outlined),
),
if (room?.avatar != null)
SheetAction(
key: AvatarAction.remove,
AdaptiveModalAction(
value: AvatarAction.remove,
label: L10n.of(context).delete,
isDestructiveAction: true,
icon: Icons.delete_outlined,
isDestructive: true,
icon: const Icon(Icons.delete_outlined),
),
];
final action = actions.length == 1
? actions.single.key
: await showModalActionSheet<AvatarAction>(
? actions.single.value
: await showModalActionPopup<AvatarAction>(
context: context,
title: L10n.of(context).editRoomAvatar,
cancelLabel: L10n.of(context).cancel,
actions: actions,
);
if (action == null) return;

@ -1,12 +1,12 @@
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/encryption.dart';
import 'package:matrix/matrix.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 '../key_verification/key_verification_dialog.dart';
@ -76,7 +76,6 @@ class ChatEncryptionSettingsController extends State<ChatEncryptionSettings> {
message: L10n.of(context).verifyOtherUserDescription,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
fullyCapitalizedForMaterial: false,
);
if (consent != OkCancelResult.ok) return;
final req = await room.client.userDeviceKeys[room.directChatMatrixID]!

@ -4,7 +4,6 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:cross_file/cross_file.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:flutter_shortcuts/flutter_shortcuts.dart';
@ -21,6 +20,9 @@ import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/utils/show_scaffold_dialog.dart';
import 'package:fluffychat/utils/show_update_snackbar.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_modal_action_popup.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/avatar.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/share_scaffold_dialog.dart';
@ -188,23 +190,19 @@ class ChatListController extends State<ChatList>
context: context,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
textFields: [
DialogTextField(
prefixText: 'https://',
hintText: Matrix.of(context).client.homeserver?.host,
initialText: searchServer,
keyboardType: TextInputType.url,
autocorrect: false,
validator: (server) => server?.contains('.') == true
? null
: L10n.of(context).invalidServerName,
),
],
prefixText: 'https://',
hintText: Matrix.of(context).client.homeserver?.host,
initialText: searchServer,
keyboardType: TextInputType.url,
autocorrect: false,
validator: (server) => server.contains('.') == true
? null
: L10n.of(context).invalidServerName,
);
if (newServer == null) return;
Matrix.of(context).store.setString(_serverStoreNamespace, newServer.single);
Matrix.of(context).store.setString(_serverStoreNamespace, newServer);
setState(() {
searchServer = newServer.single;
searchServer = newServer;
});
_coolDown?.cancel();
_coolDown = Timer(const Duration(milliseconds: 500), _search);
@ -668,7 +666,7 @@ class ChatListController extends State<ChatList>
message: L10n.of(context).archiveRoomDescription,
okLabel: L10n.of(context).leave,
cancelLabel: L10n.of(context).cancel,
isDestructiveAction: true,
isDestructive: true,
);
if (confirmed == OkCancelResult.cancel) return;
if (!mounted) return;
@ -677,13 +675,13 @@ class ChatListController extends State<ChatList>
return;
case ChatContextAction.addToSpace:
final space = await showConfirmationDialog(
final space = await showModalActionPopup(
context: context,
title: L10n.of(context).space,
actions: spacesWithPowerLevels
.map(
(space) => AlertDialogAction(
key: space,
(space) => AdaptiveModalAction(
value: space,
label: space
.getLocalizedDisplayname(MatrixLocals(L10n.of(context))),
),
@ -724,15 +722,11 @@ class ChatListController extends State<ChatList>
message: L10n.of(context).leaveEmptyToClearStatus,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
textFields: [
DialogTextField(
hintText: L10n.of(context).statusExampleMessage,
maxLines: 6,
minLines: 1,
maxLength: 255,
initialText: currentPresence.statusMsg,
),
],
hintText: L10n.of(context).statusExampleMessage,
maxLines: 6,
minLines: 1,
maxLength: 255,
initialText: currentPresence.statusMsg,
);
if (input == null) return;
if (!mounted) return;
@ -741,7 +735,7 @@ class ChatListController extends State<ChatList>
future: () => client.setPresence(
client.userID!,
PresenceType.online,
statusMsg: input.single,
statusMsg: input,
),
);
}
@ -834,17 +828,18 @@ class ChatListController extends State<ChatList>
final client = Matrix.of(context)
.widget
.clients[Matrix.of(context).getClientIndexByMatrixId(userId!)];
final action = await showConfirmationDialog<EditBundleAction>(
final action = await showModalActionPopup<EditBundleAction>(
context: context,
title: L10n.of(context).editBundlesForAccount,
cancelLabel: L10n.of(context).cancel,
actions: [
AlertDialogAction(
key: EditBundleAction.addToBundle,
AdaptiveModalAction(
value: EditBundleAction.addToBundle,
label: L10n.of(context).addToBundle,
),
if (activeBundle != client.userID)
AlertDialogAction(
key: EditBundleAction.removeFromBundle,
AdaptiveModalAction(
value: EditBundleAction.removeFromBundle,
label: L10n.of(context).removeFromBundle,
),
],
@ -855,12 +850,12 @@ class ChatListController extends State<ChatList>
final bundle = await showTextInputDialog(
context: context,
title: l10n.bundleName,
textFields: [DialogTextField(hintText: l10n.bundleName)],
hintText: l10n.bundleName,
);
if (bundle == null || bundle.isEmpty || bundle.single.isEmpty) return;
if (bundle == null || bundle.isEmpty || bundle.isEmpty) return;
await showFutureLoadingDialog(
context: context,
future: () => client.setAccountBundle(bundle.single),
future: () => client.setAccountBundle(bundle),
);
break;
case EditBundleAction.removeFromBundle:

@ -1,12 +1,12 @@
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
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 '../../config/themes.dart';
@ -51,7 +51,7 @@ class ChatListItem extends StatelessWidget {
okLabel: L10n.of(context).leave,
cancelLabel: L10n.of(context).cancel,
message: L10n.of(context).archiveRoomDescription,
isDestructiveAction: true,
isDestructive: true,
);
if (confirmed != OkCancelResult.ok) return false;
final leaveResult = await showFutureLoadingDialog(

@ -1,10 +1,10 @@
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.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 '../../utils/fluffy_share.dart';

@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:collection/collection.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:go_router/go_router.dart';
@ -13,6 +12,9 @@ import 'package:fluffychat/pages/chat_list/search_title.dart';
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
import 'package:fluffychat/utils/stream_extension.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_modal_action_popup.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/avatar.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';
@ -136,7 +138,7 @@ class _SpaceViewState extends State<SpaceView> {
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
message: L10n.of(context).archiveRoomDescription,
isDestructiveAction: true,
isDestructive: true,
);
if (!mounted) return;
if (confirmed != OkCancelResult.ok) return;
@ -152,16 +154,16 @@ class _SpaceViewState extends State<SpaceView> {
}
void _addChatOrSubspace() async {
final roomType = await showConfirmationDialog(
final roomType = await showModalActionPopup(
context: context,
title: L10n.of(context).addChatOrSubSpace,
actions: [
AlertDialogAction(
key: AddRoomType.subspace,
AdaptiveModalAction(
value: AddRoomType.subspace,
label: L10n.of(context).createNewSpace,
),
AlertDialogAction(
key: AddRoomType.chat,
AdaptiveModalAction(
value: AddRoomType.chat,
label: L10n.of(context).createGroup,
),
],
@ -173,28 +175,18 @@ class _SpaceViewState extends State<SpaceView> {
title: roomType == AddRoomType.subspace
? L10n.of(context).createNewSpace
: L10n.of(context).createGroup,
textFields: [
DialogTextField(
hintText: roomType == AddRoomType.subspace
? L10n.of(context).spaceName
: L10n.of(context).groupName,
minLines: 1,
maxLines: 1,
maxLength: 64,
validator: (text) {
if (text == null || text.isEmpty) {
return L10n.of(context).pleaseChoose;
}
return null;
},
),
DialogTextField(
hintText: L10n.of(context).chatDescription,
minLines: 4,
maxLines: 8,
maxLength: 255,
),
],
hintText: roomType == AddRoomType.subspace
? L10n.of(context).spaceName
: L10n.of(context).groupName,
minLines: 1,
maxLines: 1,
maxLength: 64,
validator: (text) {
if (text.isEmpty) {
return L10n.of(context).pleaseChoose;
}
return null;
},
okLabel: L10n.of(context).create,
cancelLabel: L10n.of(context).cancel,
);
@ -209,29 +201,20 @@ class _SpaceViewState extends State<SpaceView> {
if (roomType == AddRoomType.subspace) {
roomId = await client.createSpace(
name: names.first,
topic: names.last.isEmpty ? null : names.last,
name: names,
visibility: activeSpace.joinRules == JoinRules.public
? sdk.Visibility.public
: sdk.Visibility.private,
);
} else {
roomId = await client.createGroupChat(
groupName: names.first,
groupName: names,
preset: activeSpace.joinRules == JoinRules.public
? CreateRoomPreset.publicChat
: CreateRoomPreset.privateChat,
visibility: activeSpace.joinRules == JoinRules.public
? sdk.Visibility.public
: sdk.Visibility.private,
initialState: names.length > 1 && names.last.isNotEmpty
? [
StateEvent(
type: EventTypes.RoomTopic,
content: {'topic': names.last},
),
]
: null,
);
}
await activeSpace.setSpaceChild(roomId);

@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:collection/collection.dart' show IterableExtension;
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/encryption/utils/key_verification.dart';
@ -8,6 +7,8 @@ import 'package:matrix/matrix.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 '../../widgets/matrix.dart';
@ -54,9 +55,10 @@ class DevicesSettingsController extends State<DevicesSettings> {
if (await showOkCancelAlertDialog(
context: context,
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).yes,
okLabel: L10n.of(context).remove,
cancelLabel: L10n.of(context).cancel,
message: L10n.of(context).removeDevicesDescription,
isDestructive: true,
) ==
OkCancelResult.cancel) return;
final matrix = Matrix.of(context);
@ -84,18 +86,14 @@ class DevicesSettingsController extends State<DevicesSettings> {
title: L10n.of(context).changeDeviceName,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
textFields: [
DialogTextField(
hintText: device.displayName,
),
],
hintText: device.displayName,
);
if (displayName == null) return;
final success = await showFutureLoadingDialog(
context: context,
future: () => Matrix.of(context)
.client
.updateDevice(device.deviceId, displayName: displayName.single),
.updateDevice(device.deviceId, displayName: displayName),
);
if (success.error == null) {
reload();
@ -109,7 +107,6 @@ class DevicesSettingsController extends State<DevicesSettings> {
message: L10n.of(context).verifyOtherDeviceDescription,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
fullyCapitalizedForMaterial: false,
);
if (consent != OkCancelResult.ok) return;
final req = await Matrix.of(context)

@ -1,10 +1,10 @@
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_modal_action_popup.dart';
import '../../utils/date_time_extension.dart';
import '../../utils/matrix_sdk_extensions/device_extension.dart';
import '../../widgets/matrix.dart';
@ -49,37 +49,43 @@ class UserDeviceListItem extends StatelessWidget {
clipBehavior: Clip.hardEdge,
child: ListTile(
onTap: () async {
final action = await showModalActionSheet<UserDeviceListItemAction>(
final action = await showModalActionPopup<UserDeviceListItemAction>(
context: context,
title: '${userDevice.displayName} (${userDevice.deviceId})',
cancelLabel: L10n.of(context).cancel,
actions: [
SheetAction(
key: UserDeviceListItemAction.rename,
AdaptiveModalAction(
value: UserDeviceListItemAction.rename,
icon: const Icon(Icons.edit_outlined),
label: L10n.of(context).changeDeviceName,
),
if (!isOwnDevice && keys != null) ...{
SheetAction(
key: UserDeviceListItemAction.verify,
AdaptiveModalAction(
value: UserDeviceListItemAction.verify,
icon: const Icon(Icons.verified_outlined),
label: L10n.of(context).verifyStart,
),
if (!keys.blocked)
SheetAction(
key: UserDeviceListItemAction.block,
AdaptiveModalAction(
value: UserDeviceListItemAction.block,
icon: const Icon(Icons.block_outlined),
label: L10n.of(context).blockDevice,
isDestructiveAction: true,
isDestructive: true,
),
if (keys.blocked)
SheetAction(
key: UserDeviceListItemAction.unblock,
AdaptiveModalAction(
value: UserDeviceListItemAction.unblock,
icon: const Icon(Icons.block),
label: L10n.of(context).unblockDevice,
isDestructiveAction: true,
isDestructive: true,
),
},
if (!isOwnDevice)
SheetAction(
key: UserDeviceListItemAction.remove,
AdaptiveModalAction(
value: UserDeviceListItemAction.remove,
icon: const Icon(Icons.delete_outlined),
label: L10n.of(context).delete,
isDestructiveAction: true,
isDestructive: true,
),
],
);

@ -3,7 +3,6 @@ import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:collection/collection.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:flutter_web_auth_2/flutter_web_auth_2.dart';
@ -17,6 +16,7 @@ import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pages/homeserver_picker/homeserver_picker_view.dart';
import 'package:fluffychat/utils/file_selector.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';
import '../../utils/localized_exception_extension.dart';

@ -6,7 +6,7 @@ import 'package:url_launcher/url_launcher.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/widgets/adaptive_dialog_action.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart';
import 'package:fluffychat/widgets/layouts/login_scaffold.dart';
import 'package:fluffychat/widgets/matrix.dart';
import '../../config/themes.dart';

@ -4,12 +4,12 @@ import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/encryption.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/widgets/adaptive_dialog_action.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
@ -88,7 +88,7 @@ class KeyVerificationPageState extends State<KeyVerificationDialog> {
await showOkAlertDialog(
useRootNavigator: false,
context: context,
message: L10n.of(context).incorrectPassphraseOrKey,
title: L10n.of(context).incorrectPassphraseOrKey,
);
}
}

@ -2,11 +2,12 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/utils/localized_exception_extension.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:fluffychat/widgets/matrix.dart';
import '../../utils/platform_infos.dart';
@ -128,7 +129,7 @@ class LoginController extends State<Login> {
final dialogResult = await showOkCancelAlertDialog(
context: context,
useRootNavigator: false,
message: L10n.of(context).noMatrixServer(newDomain, oldHomeserver!),
title: L10n.of(context).noMatrixServer(newDomain, oldHomeserver!),
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
);
@ -162,15 +163,10 @@ class LoginController extends State<Login> {
message: L10n.of(context).enterAnEmailAddress,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
fullyCapitalizedForMaterial: false,
textFields: [
DialogTextField(
initialText:
usernameController.text.isEmail ? usernameController.text : '',
hintText: L10n.of(context).enterAnEmailAddress,
keyboardType: TextInputType.emailAddress,
),
],
initialText:
usernameController.text.isEmail ? usernameController.text : '',
hintText: L10n.of(context).enterAnEmailAddress,
keyboardType: TextInputType.emailAddress,
);
if (input == null) return;
final clientSecret = DateTime.now().millisecondsSinceEpoch.toString();
@ -179,7 +175,7 @@ class LoginController extends State<Login> {
future: () =>
Matrix.of(context).getLoginClient().requestTokenToResetPasswordEmail(
clientSecret,
input.single,
input,
sendAttempt++,
),
);
@ -191,15 +187,10 @@ class LoginController extends State<Login> {
message: L10n.of(context).chooseAStrongPassword,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
fullyCapitalizedForMaterial: false,
textFields: [
const DialogTextField(
hintText: '******',
obscureText: true,
minLines: 1,
maxLines: 1,
),
],
hintText: '******',
obscureText: true,
minLines: 1,
maxLines: 1,
);
if (password == null) return;
final ok = await showOkAlertDialog(
@ -208,11 +199,10 @@ class LoginController extends State<Login> {
title: L10n.of(context).weSentYouAnEmail,
message: L10n.of(context).pleaseClickOnLink,
okLabel: L10n.of(context).iHaveClickedOnLink,
fullyCapitalizedForMaterial: false,
);
if (ok != OkCancelResult.ok) return;
final data = <String, dynamic>{
'new_password': password.single,
'new_password': password,
'logout_devices': false,
"auth": AuthenticationThreePidCreds(
type: AuthenticationTypes.emailIdentity,
@ -234,8 +224,8 @@ class LoginController extends State<Login> {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(L10n.of(context).passwordHasBeenChanged)),
);
usernameController.text = input.single;
passwordController.text = password.single;
usernameController.text = input;
passwordController.text = password;
login();
}
}

@ -2,7 +2,6 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:collection/collection.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:image_picker/image_picker.dart';
@ -10,6 +9,9 @@ import 'package:matrix/matrix.dart';
import 'package:fluffychat/utils/file_selector.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_modal_action_popup.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 '../../widgets/matrix.dart';
import '../bootstrap/bootstrap_dialog.dart';
@ -39,19 +41,14 @@ class SettingsController extends State<Settings> {
title: L10n.of(context).editDisplayname,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
textFields: [
DialogTextField(
initialText: profile?.displayName ??
Matrix.of(context).client.userID!.localpart,
),
],
initialText:
profile?.displayName ?? Matrix.of(context).client.userID!.localpart,
);
if (input == null) return;
final matrix = Matrix.of(context);
final success = await showFutureLoadingDialog(
context: context,
future: () =>
matrix.client.setDisplayName(matrix.client.userID!, input.single),
future: () => matrix.client.setDisplayName(matrix.client.userID!, input),
);
if (success.error == null) {
updateProfile();
@ -65,7 +62,7 @@ class SettingsController extends State<Settings> {
context: context,
title: L10n.of(context).areYouSureYouWantToLogout,
message: L10n.of(context).noBackupWarning,
isDestructiveAction: noBackup,
isDestructive: noBackup,
okLabel: L10n.of(context).logout,
cancelLabel: L10n.of(context).cancel,
) ==
@ -83,30 +80,31 @@ class SettingsController extends State<Settings> {
final profile = await profileFuture;
final actions = [
if (PlatformInfos.isMobile)
SheetAction(
key: AvatarAction.camera,
AdaptiveModalAction(
value: AvatarAction.camera,
label: L10n.of(context).openCamera,
isDefaultAction: true,
icon: Icons.camera_alt_outlined,
icon: const Icon(Icons.camera_alt_outlined),
),
SheetAction(
key: AvatarAction.file,
AdaptiveModalAction(
value: AvatarAction.file,
label: L10n.of(context).openGallery,
icon: Icons.photo_outlined,
icon: const Icon(Icons.photo_outlined),
),
if (profile?.avatarUrl != null)
SheetAction(
key: AvatarAction.remove,
AdaptiveModalAction(
value: AvatarAction.remove,
label: L10n.of(context).removeYourAvatar,
isDestructiveAction: true,
icon: Icons.delete_outlined,
isDestructive: true,
icon: const Icon(Icons.delete_outlined),
),
];
final action = actions.length == 1
? actions.single.key
: await showModalActionSheet<AvatarAction>(
? actions.single.value
: await showModalActionPopup<AvatarAction>(
context: context,
title: L10n.of(context).changeYourAvatar,
cancelLabel: L10n.of(context).cancel,
actions: actions,
);
if (action == null) return;

@ -1,9 +1,10 @@
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart';
import '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:fluffychat/widgets/matrix.dart';
import 'settings_3pid_view.dart';
@ -25,12 +26,8 @@ class Settings3PidController extends State<Settings3Pid> {
title: L10n.of(context).enterAnEmailAddress,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
textFields: [
DialogTextField(
hintText: L10n.of(context).enterAnEmailAddress,
keyboardType: TextInputType.emailAddress,
),
],
hintText: L10n.of(context).enterAnEmailAddress,
keyboardType: TextInputType.emailAddress,
);
if (input == null) return;
final clientSecret = DateTime.now().millisecondsSinceEpoch.toString();
@ -38,7 +35,7 @@ class Settings3PidController extends State<Settings3Pid> {
context: context,
future: () => Matrix.of(context).client.requestTokenToRegisterEmail(
clientSecret,
input.single,
input,
Settings3Pid.sendAttempt++,
),
);

@ -3,7 +3,6 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:archive/archive.dart';
import 'package:collection/collection.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
@ -11,6 +10,7 @@ import 'package:matrix/matrix.dart';
import 'package:fluffychat/pages/settings_emotes/settings_emotes.dart';
import 'package:fluffychat/utils/client_manager.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';
class ImportEmoteArchiveDialog extends StatefulWidget {

@ -3,7 +3,6 @@ import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:collection/collection.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:go_router/go_router.dart';
@ -13,6 +12,7 @@ import 'package:matrix/matrix.dart';
import 'package:fluffychat/utils/client_manager.dart';
import 'package:fluffychat/utils/file_selector.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_file_extension.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import '../../widgets/matrix.dart';
import 'import_archive_dialog.dart';
@ -139,7 +139,7 @@ class EmotesSettingsController extends State<EmotesSettings> {
showOkAlertDialog(
useRootNavigator: false,
context: context,
message: L10n.of(context).emoteExists,
title: L10n.of(context).emoteExists,
okLabel: L10n.of(context).ok,
);
return;
@ -149,7 +149,7 @@ class EmotesSettingsController extends State<EmotesSettings> {
showOkAlertDialog(
useRootNavigator: false,
context: context,
message: L10n.of(context).emoteInvalid,
title: L10n.of(context).emoteInvalid,
okLabel: L10n.of(context).ok,
);
return;
@ -185,7 +185,7 @@ class EmotesSettingsController extends State<EmotesSettings> {
await showOkAlertDialog(
useRootNavigator: false,
context: context,
message: L10n.of(context).emoteWarnNeedToPick,
title: L10n.of(context).emoteWarnNeedToPick,
okLabel: L10n.of(context).ok,
);
return;
@ -195,7 +195,7 @@ class EmotesSettingsController extends State<EmotesSettings> {
await showOkAlertDialog(
useRootNavigator: false,
context: context,
message: L10n.of(context).emoteExists,
title: L10n.of(context).emoteExists,
okLabel: L10n.of(context).ok,
);
return;
@ -204,7 +204,7 @@ class EmotesSettingsController extends State<EmotesSettings> {
await showOkAlertDialog(
useRootNavigator: false,
context: context,
message: L10n.of(context).emoteInvalid,
title: L10n.of(context).emoteInvalid,
okLabel: L10n.of(context).ok,
);
return;

@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:collection/collection.dart' show IterableExtension;
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_modal_action_popup.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import '../../widgets/matrix.dart';
import 'settings_notifications_view.dart';
@ -138,15 +138,16 @@ class SettingsNotificationsController extends State<SettingsNotifications> {
}
void onPusherTap(Pusher pusher) async {
final delete = await showModalActionSheet<bool>(
final delete = await showModalActionPopup<bool>(
context: context,
title: pusher.deviceDisplayName,
message: '${pusher.appDisplayName} (${pusher.appId})',
cancelLabel: L10n.of(context).cancel,
actions: [
SheetAction(
AdaptiveModalAction(
label: L10n.of(context).delete,
isDestructiveAction: true,
key: true,
isDestructive: true,
value: true,
),
],
);

@ -1,9 +1,10 @@
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart';
import '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/app_lock.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';
@ -28,25 +29,20 @@ class SettingsSecurityController extends State<SettingsSecurity> {
title: L10n.of(context).pleaseChooseAPasscode,
message: L10n.of(context).pleaseEnter4Digits,
cancelLabel: L10n.of(context).cancel,
textFields: [
DialogTextField(
validator: (text) {
if (text!.isEmpty ||
(text.length == 4 && int.tryParse(text)! >= 0)) {
return null;
}
return L10n.of(context).pleaseEnter4Digits;
},
keyboardType: TextInputType.number,
obscureText: true,
maxLines: 1,
minLines: 1,
maxLength: 4,
),
],
validator: (text) {
if (text.isEmpty || (text.length == 4 && int.tryParse(text)! >= 0)) {
return null;
}
return L10n.of(context).pleaseEnter4Digits;
},
keyboardType: TextInputType.number,
obscureText: true,
maxLines: 1,
minLines: 1,
maxLength: 4,
);
if (newLock != null) {
await AppLock.of(context).changePincode(newLock.single);
await AppLock.of(context).changePincode(newLock);
}
}
@ -58,7 +54,7 @@ class SettingsSecurityController extends State<SettingsSecurity> {
message: L10n.of(context).deactivateAccountWarning,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
isDestructiveAction: true,
isDestructive: true,
) ==
OkCancelResult.cancel) {
return;
@ -68,18 +64,14 @@ class SettingsSecurityController extends State<SettingsSecurity> {
useRootNavigator: false,
context: context,
title: L10n.of(context).confirmMatrixId,
textFields: [
DialogTextField(
validator: (text) => text == supposedMxid
? null
: L10n.of(context).supposedMxid(supposedMxid),
),
],
isDestructiveAction: true,
validator: (text) => text == supposedMxid
? null
: L10n.of(context).supposedMxid(supposedMxid),
isDestructive: true,
okLabel: L10n.of(context).delete,
cancelLabel: L10n.of(context).cancel,
);
if (mxids == null || mxids.length != 1 || mxids.single != supposedMxid) {
if (mxids == null || mxids.length != 1 || mxids != supposedMxid) {
return;
}
final input = await showTextInputDialog(
@ -88,22 +80,18 @@ class SettingsSecurityController extends State<SettingsSecurity> {
title: L10n.of(context).pleaseEnterYourPassword,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
isDestructiveAction: true,
textFields: [
const DialogTextField(
obscureText: true,
hintText: '******',
minLines: 1,
maxLines: 1,
),
],
isDestructive: true,
obscureText: true,
hintText: '******',
minLines: 1,
maxLines: 1,
);
if (input == null) return;
await showFutureLoadingDialog(
context: context,
future: () => Matrix.of(context).client.deactivateAccount(
auth: AuthenticationPassword(
password: input.single,
password: input,
identifier: AuthenticationUserIdentifier(
user: Matrix.of(context).client.userID!,
),

@ -1,11 +1,13 @@
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_modal_action_popup.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:fluffychat/widgets/permission_slider_dialog.dart';
import '../../widgets/matrix.dart';
@ -96,23 +98,22 @@ class UserBottomSheetController extends State<UserBottomSheet> {
case UserBottomSheetAction.report:
if (user == null) throw ('User must not be null for this action!');
final score = await showConfirmationDialog<int>(
final score = await showModalActionPopup<int>(
context: context,
title: L10n.of(context).reportUser,
message: L10n.of(context).howOffensiveIsThisContent,
cancelLabel: L10n.of(context).cancel,
okLabel: L10n.of(context).ok,
actions: [
AlertDialogAction(
key: -100,
AdaptiveModalAction(
value: -100,
label: L10n.of(context).extremeOffensive,
),
AlertDialogAction(
key: -50,
AdaptiveModalAction(
value: -50,
label: L10n.of(context).offensive,
),
AlertDialogAction(
key: 0,
AdaptiveModalAction(
value: 0,
label: L10n.of(context).inoffensive,
),
],
@ -124,16 +125,16 @@ class UserBottomSheetController extends State<UserBottomSheet> {
title: L10n.of(context).whyDoYouWantToReportThis,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
textFields: [DialogTextField(hintText: L10n.of(context).reason)],
hintText: L10n.of(context).reason,
);
if (reason == null || reason.single.isEmpty) return;
if (reason == null || reason.isEmpty) return;
final result = await showFutureLoadingDialog(
context: context,
future: () => Matrix.of(widget.outerContext).client.reportContent(
user.room.id,
user.id,
reason: reason.single,
reason: reason,
score: score,
),
);

@ -8,7 +8,7 @@ import 'package:matrix/matrix.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/widgets/adaptive_dialog_action.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart';
class ErrorReporter {
final BuildContext context;

@ -1,8 +1,9 @@
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_text_input_dialog.dart';
Widget markdownContextBuilder(
BuildContext context,
EditableTextState editableTextState,
@ -26,27 +27,21 @@ Widget markdownContextBuilder(
title: l10n.addLink,
okLabel: l10n.ok,
cancelLabel: l10n.cancel,
textFields: [
DialogTextField(
validator: (text) {
if (text == null || text.isEmpty) {
return l10n.pleaseFillOut;
}
try {
text.startsWith('http')
? Uri.parse(text)
: Uri.https(text);
} catch (_) {
return l10n.invalidUrl;
}
return null;
},
hintText: 'www...',
keyboardType: TextInputType.url,
),
],
validator: (text) {
if (text.isEmpty) {
return l10n.pleaseFillOut;
}
try {
text.startsWith('http') ? Uri.parse(text) : Uri.https(text);
} catch (_) {
return l10n.invalidUrl;
}
return null;
},
hintText: 'www...',
keyboardType: TextInputType.url,
);
final urlString = input?.singleOrNull;
final urlString = input;
if (urlString == null) return;
final url = urlString.startsWith('http')
? Uri.parse(urlString)

@ -1,10 +1,11 @@
import 'dart:async';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:matrix/matrix.dart';
import 'package:url_launcher/url_launcher_string.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/fluffy_chat_app.dart';
import 'package:fluffychat/widgets/matrix.dart';
@ -30,16 +31,11 @@ extension UiaRequestManager on MatrixState {
title: l10n.pleaseEnterYourPassword,
okLabel: l10n.ok,
cancelLabel: l10n.cancel,
textFields: [
const DialogTextField(
minLines: 1,
maxLines: 1,
obscureText: true,
hintText: '******',
),
],
))
?.single;
minLines: 1,
maxLines: 1,
obscureText: true,
hintText: '******',
));
if (input == null || input.isEmpty) {
return uiaRequest.cancel();
}
@ -91,7 +87,7 @@ extension UiaRequestManager on MatrixState {
if (OkCancelResult.ok ==
await showOkCancelAlertDialog(
useRootNavigator: false,
message: l10n.pleaseFollowInstructionsOnWeb,
title: l10n.pleaseFollowInstructionsOnWeb,
context: navigatorContext,
okLabel: l10n.next,
cancelLabel: l10n.cancel,

@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:collection/collection.dart' show IterableExtension;
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:go_router/go_router.dart';
@ -11,6 +10,7 @@ import 'package:url_launcher/url_launcher_string.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart';
import 'package:fluffychat/utils/adaptive_bottom_sheet.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:fluffychat/widgets/public_room_bottom_sheet.dart';

@ -0,0 +1,116 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
Future<T?> showModalActionPopup<T>({
required BuildContext context,
required List<AdaptiveModalAction<T>> actions,
String? title,
String? message,
String? cancelLabel,
bool useRootNavigator = true,
}) {
final theme = Theme.of(context);
switch (theme.platform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.windows:
case TargetPlatform.linux:
return showModalBottomSheet(
isScrollControlled: true,
useRootNavigator: useRootNavigator,
context: context,
clipBehavior: Clip.hardEdge,
constraints: BoxConstraints(
maxWidth: 512,
maxHeight: MediaQuery.of(context).size.height - 32,
),
builder: (context) => ListView(
shrinkWrap: true,
children: [
if (title != null || message != null) ...[
ListTile(
title: title == null
? null
: Text(
title,
style: theme.textTheme.labelSmall,
),
subtitle: message == null ? null : Text(message),
),
const Divider(height: 1),
],
...actions.map(
(action) => ListTile(
leading: action.icon,
title: Text(
action.label,
maxLines: 1,
style: action.isDestructive
? TextStyle(
color: theme.colorScheme.error,
fontWeight:
action.isDefaultAction ? FontWeight.bold : null,
)
: null,
),
onTap: () => Navigator.of(context).pop<T>(action.value),
),
),
if (cancelLabel != null) ...[
const Divider(height: 1),
ListTile(
title: Text(cancelLabel),
onTap: () => Navigator.of(context).pop(null),
),
],
],
),
);
case TargetPlatform.iOS:
case TargetPlatform.macOS:
return showCupertinoModalPopup<T>(
context: context,
useRootNavigator: useRootNavigator,
builder: (context) => ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 512),
child: CupertinoActionSheet(
title: title == null ? null : Text(title),
message: message == null ? null : Text(message),
cancelButton: cancelLabel == null
? null
: CupertinoActionSheetAction(
onPressed: () => Navigator.of(context).pop(null),
child: Text(cancelLabel),
),
actions: actions
.map(
(action) => CupertinoActionSheetAction(
isDestructiveAction: action.isDestructive,
isDefaultAction: action.isDefaultAction,
onPressed: () => Navigator.of(context).pop<T>(action.value),
child: Text(action.label, maxLines: 1),
),
)
.toList(),
),
),
);
}
}
class AdaptiveModalAction<T> {
final String label;
final T value;
Icon? icon;
final bool isDefaultAction;
final bool isDestructive;
AdaptiveModalAction({
required this.label,
required this.value,
this.icon,
this.isDefaultAction = false,
this.isDestructive = false,
});
}

@ -0,0 +1,77 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart';
enum OkCancelResult { ok, cancel }
Future<OkCancelResult?> showOkCancelAlertDialog({
required BuildContext context,
required String title,
String? message,
String? okLabel,
String? cancelLabel,
bool isDestructive = false,
bool useRootNavigator = true,
}) =>
showAdaptiveDialog<OkCancelResult>(
context: context,
useRootNavigator: useRootNavigator,
builder: (context) => AlertDialog.adaptive(
title: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 256),
child: Text(title),
),
content: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 256),
child: message == null ? null : Text(message),
),
actions: [
AdaptiveDialogAction(
onPressed: () => Navigator.of(context)
.pop<OkCancelResult>(OkCancelResult.cancel),
child: Text(cancelLabel ?? L10n.of(context).cancel),
),
AdaptiveDialogAction(
onPressed: () =>
Navigator.of(context).pop<OkCancelResult>(OkCancelResult.ok),
child: Text(
okLabel ?? L10n.of(context).ok,
style: isDestructive
? TextStyle(color: Theme.of(context).colorScheme.error)
: null,
),
),
],
),
);
Future<OkCancelResult?> showOkAlertDialog({
required BuildContext context,
required String title,
String? message,
String? okLabel,
bool useRootNavigator = true,
}) =>
showAdaptiveDialog<OkCancelResult>(
context: context,
useRootNavigator: useRootNavigator,
builder: (context) => AlertDialog.adaptive(
title: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 256),
child: Text(title),
),
content: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 256),
child: message == null ? null : Text(message),
),
actions: [
AdaptiveDialogAction(
onPressed: () =>
Navigator.of(context).pop<OkCancelResult>(OkCancelResult.ok),
child: Text(okLabel ?? L10n.of(context).close),
),
],
),
);

@ -0,0 +1,101 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart';
Future<String?> showTextInputDialog({
required BuildContext context,
required String title,
String? message,
String? okLabel,
String? cancelLabel,
bool useRootNavigator = true,
String? hintText,
String? labelText,
String? initialText,
String? prefixText,
String? suffixText,
bool obscureText = false,
bool isDestructive = false,
int? minLines,
int? maxLines,
String? Function(String input)? validator,
TextInputType? keyboardType,
int? maxLength,
bool autocorrect = true,
}) =>
showAdaptiveDialog<String>(
context: context,
useRootNavigator: useRootNavigator,
builder: (context) {
final controller = TextEditingController(text: initialText);
final error = ValueNotifier<String?>(null);
return ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 512),
child: AlertDialog.adaptive(
title: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 256),
child: Text(title),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (message != null)
Padding(
padding: const EdgeInsets.only(bottom: 16.0),
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 256),
child: Text(message),
),
),
ValueListenableBuilder<String?>(
valueListenable: error,
builder: (context, error, _) {
return TextField(
controller: controller,
obscureText: obscureText,
minLines: minLines,
maxLines: maxLines,
maxLength: maxLength,
keyboardType: keyboardType,
autocorrect: autocorrect,
decoration: InputDecoration(
errorText: error,
hintText: hintText,
labelText: labelText,
prefixText: prefixText,
suffixText: suffixText,
),
);
},
),
],
),
actions: [
AdaptiveDialogAction(
onPressed: () => Navigator.of(context).pop(null),
child: Text(cancelLabel ?? L10n.of(context).cancel),
),
AdaptiveDialogAction(
onPressed: () {
final input = controller.text;
final errorText = validator?.call(input);
if (errorText != null) {
error.value = errorText;
return;
}
Navigator.of(context).pop<String>(input);
},
child: Text(
okLabel ?? L10n.of(context).ok,
style: isDestructive
? TextStyle(color: Theme.of(context).colorScheme.error)
: null,
),
),
],
),
);
},
);

@ -2,11 +2,11 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'matrix.dart';
@ -62,7 +62,7 @@ class ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
message: L10n.of(context).archiveRoomDescription,
isDestructiveAction: true,
isDestructive: true,
);
if (confirmed == OkCancelResult.ok) {
final success = await showFutureLoadingDialog(

@ -6,7 +6,7 @@ import 'package:async/async.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
import 'package:fluffychat/widgets/adaptive_dialog_action.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart';
/// Displays a loading dialog which reacts to the given [future]. The dialog
/// will be dismissed and the value will be returned when the future completes.

@ -4,7 +4,6 @@ import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:collection/collection.dart';
import 'package:desktop_notifications/desktop_notifications.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
@ -24,6 +23,7 @@ import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_file_extension.dar
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/utils/uia_request_manager.dart';
import 'package:fluffychat/utils/voip_plugin.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
import 'package:fluffychat/widgets/fluffy_chat_app.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import '../config/app_config.dart';
@ -344,13 +344,11 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
this,
onFcmError: (errorMsg, {Uri? link}) async {
final result = await showOkCancelAlertDialog(
barrierDismissible: true,
context: FluffyChatApp
.router.routerDelegate.navigatorKey.currentContext ??
context,
title: L10n.of(context).pushNotificationsNotAvailable,
message: errorMsg,
fullyCapitalizedForMaterial: false,
okLabel:
link == null ? L10n.of(context).ok : L10n.of(context).learnMore,
cancelLabel: L10n.of(context).doNotShowAgain,
@ -470,7 +468,7 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
Future<void> dehydrateAction(BuildContext context) async {
final response = await showOkCancelAlertDialog(
context: context,
isDestructiveAction: true,
isDestructive: true,
title: L10n.of(context).dehydrate,
message: L10n.of(context).dehydrateWarning,
);

@ -1,9 +1,10 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_text_input_dialog.dart';
Future<int?> showPermissionChooser(
BuildContext context, {
int currentLevel = 0,
@ -11,24 +12,20 @@ Future<int?> showPermissionChooser(
final customLevel = await showTextInputDialog(
context: context,
title: L10n.of(context).setPermissionsLevel,
textFields: [
DialogTextField(
initialText: currentLevel.toString(),
keyboardType: TextInputType.number,
autocorrect: false,
validator: (text) {
if (text == null) {
return L10n.of(context).pleaseEnterANumber;
}
final level = int.tryParse(text);
if (level == null) {
return L10n.of(context).pleaseEnterANumber;
}
return null;
},
),
],
initialText: currentLevel.toString(),
keyboardType: TextInputType.number,
autocorrect: false,
validator: (text) {
if (text.isEmpty) {
return L10n.of(context).pleaseEnterANumber;
}
final level = int.tryParse(text);
if (level == null) {
return L10n.of(context).pleaseEnterANumber;
}
return null;
},
);
if (customLevel == null) return null;
return int.tryParse(customLevel.first);
return int.tryParse(customLevel);
}

@ -5,7 +5,6 @@
import FlutterMacOS
import Foundation
import appkit_ui_element_colors
import audio_session
import desktop_drop
import device_info_plus
@ -19,8 +18,6 @@ import flutter_web_auth_2
import flutter_webrtc
import geolocator_apple
import just_audio
import macos_ui
import macos_window_utils
import package_info_plus
import pasteboard
import path_provider_foundation
@ -36,7 +33,6 @@ import wakelock_plus
import window_to_front
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
AppkitUiElementColorsPlugin.register(with: registry.registrar(forPlugin: "AppkitUiElementColorsPlugin"))
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
DesktopDropPlugin.register(with: registry.registrar(forPlugin: "DesktopDropPlugin"))
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
@ -50,8 +46,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FlutterWebRTCPlugin.register(with: registry.registrar(forPlugin: "FlutterWebRTCPlugin"))
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin"))
MacOSUiPlugin.register(with: registry.registrar(forPlugin: "MacOSUiPlugin"))
MacOSWindowUtilsPlugin.register(with: registry.registrar(forPlugin: "MacOSWindowUtilsPlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
PasteboardPlugin.register(with: registry.registrar(forPlugin: "PasteboardPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))

@ -14,14 +14,6 @@ packages:
description: dart
source: sdk
version: "0.3.2"
adaptive_dialog:
dependency: "direct main"
description:
name: adaptive_dialog
sha256: b02055729c225c369f90fdbc9564452e183cb919f83a971f512199084474530f
url: "https://pub.dev"
source: hosted
version: "2.2.1+2"
analyzer:
dependency: transitive
description:
@ -46,14 +38,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.3"
appkit_ui_element_colors:
dependency: transitive
description:
name: appkit_ui_element_colors
sha256: c3e50f900aae314d339de489535736238627071457c4a4a2dbbb1545b4f04f22
url: "https://pub.dev"
source: hosted
version: "1.0.0"
archive:
dependency: "direct main"
description:
@ -342,14 +326,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.2.4"
equatable:
dependency: transitive
description:
name: equatable
sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
url: "https://pub.dev"
source: hosted
version: "2.0.5"
fake_async:
dependency: transitive
description:
@ -861,14 +837,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "14.3.0"
gradient_borders:
dependency: transitive
description:
name: gradient_borders
sha256: b1cd969552c83f458ff755aa68e13a0327d09f06c3f42f471b423b01427f21f8
url: "https://pub.dev"
source: hosted
version: "1.0.1"
handy_window:
dependency: "direct main"
description:
@ -1026,14 +994,6 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
intersperse:
dependency: transitive
description:
name: intersperse
sha256: "2f8a905c96f6cbba978644a3d5b31b8d86ddc44917662df7d27a61f3df66a576"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
intl:
dependency: "direct main"
description:
@ -1178,22 +1138,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.0"
macos_ui:
dependency: transitive
description:
name: macos_ui
sha256: "80f6539aba5a3a1182d5225a6c27969a780bcb1d2d8135b4ffb708570cf0c854"
url: "https://pub.dev"
source: hosted
version: "2.0.9"
macos_window_utils:
dependency: transitive
description:
name: macos_window_utils
sha256: "230be594d26f6dee92c5a1544f4242d25138a5bfb9f185b27f14de3949ef0be8"
url: "https://pub.dev"
source: hosted
version: "1.5.0"
macros:
dependency: transitive
description:

@ -8,7 +8,6 @@ environment:
sdk: ">=3.0.0 <4.0.0"
dependencies:
adaptive_dialog: ^2.1.0
animations: ^2.0.11
archive: ^3.4.10
async: ^2.11.0

Loading…
Cancel
Save