diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 9fb14c7c9..280a64a31 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -5314,5 +5314,7 @@ "alreadyInCourseWithID": "You are already in a course with this plan. Do you want to create a course with the same plan, or go to the existing course?", "goToExistingCourse": "Go to existing course", "emojiView": "Emoji view", - "feedbackDialogDesc": "I make mistakes too! Anything to help me improve?" -} + "feedbackDialogDesc": "I make mistakes too! Anything to help me improve?", + "getStartedFriendsButton": "Invite a friend", + "contactHasBeenInvitedToTheCourse": "Contact has been invited to the course" +} \ No newline at end of file diff --git a/lib/pangea/chat_list/utils/chat_list_handle_space_tap.dart b/lib/pangea/chat_list/utils/chat_list_handle_space_tap.dart index 3557806d5..d877b0d6d 100644 --- a/lib/pangea/chat_list/utils/chat_list_handle_space_tap.dart +++ b/lib/pangea/chat_list/utils/chat_list_handle_space_tap.dart @@ -5,43 +5,80 @@ import 'package:matrix/matrix.dart'; import 'package:fluffychat/l10n/l10n.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; -import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart'; +import 'package:fluffychat/utils/localized_exception_extension.dart'; +import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart'; import 'package:fluffychat/widgets/future_loading_dialog.dart'; import 'package:fluffychat/widgets/matrix.dart'; import '../../common/utils/error_handler.dart'; Future showInviteDialog(Room room, BuildContext context) async { if (room.membership != Membership.invite) return; - final acceptInvite = await showOkCancelAlertDialog( - context: context, - title: L10n.of(context).youreInvited, - message: room.isSpace - ? L10n.of(context).invitedToSpace(room.name, room.creatorId ?? "???") - : L10n.of(context).invitedToChat(room.name, room.creatorId ?? "???"), - okLabel: L10n.of(context).accept, - cancelLabel: L10n.of(context).decline, - ); - final resp = await showFutureLoadingDialog( + final theme = Theme.of(context); + final action = await showAdaptiveDialog( + barrierDismissible: true, + context: context, + builder: (context) => AlertDialog.adaptive( + title: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 256), + child: Center( + child: Text( + L10n.of(context).youreInvited, + textAlign: TextAlign.center, + ), + ), + ), + content: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 256, maxHeight: 256), + child: Text( + room.isSpace + ? L10n.of(context) + .invitedToSpace(room.name, room.creatorId ?? "???") + : L10n.of(context) + .invitedToChat(room.name, room.creatorId ?? "???"), + textAlign: TextAlign.center, + ), + ), + actions: [ + AdaptiveDialogAction( + onPressed: () => + Navigator.of(context).pop(CourseInviteAction.decline), + bigButtons: true, + child: Text( + L10n.of(context).decline, + style: TextStyle(color: theme.colorScheme.error), + ), + ), + AdaptiveDialogAction( + onPressed: () => Navigator.of(context).pop(CourseInviteAction.accept), + bigButtons: true, + child: Text(L10n.of(context).accept), + ), + ], + ), + ); + switch (action) { + case null: + return; + case CourseInviteAction.accept: + break; + case CourseInviteAction.decline: + await room.leave(); + return; + } + + final joinResult = await showFutureLoadingDialog( context: context, future: () async { - if (acceptInvite == OkCancelResult.ok) { - await room.join(); - context.go( - room.isSpace - ? "/rooms/spaces/${room.id}/details" - : "/rooms/${room.id}", - ); - return room.id; - } else if (acceptInvite == OkCancelResult.cancel) { - await room.leave(); - } + await room.join(); }, + exceptionContext: ExceptionContext.joinRoom, ); + if (joinResult.error != null) return; - if (!resp.isError && resp.result is String) { - context.go("/rooms/spaces/${resp.result}/details"); - } + context.go( + room.isSpace ? "/rooms/spaces/${room.id}/details" : "/rooms/${room.id}", + ); } // ignore: curly_braces_in_flow_control_structures @@ -100,3 +137,5 @@ void chatListHandleSpaceTap( break; } } + +enum CourseInviteAction { accept, decline } diff --git a/lib/pangea/chat_settings/pages/pangea_invitation_selection.dart b/lib/pangea/chat_settings/pages/pangea_invitation_selection.dart index a78b0286e..f36406701 100644 --- a/lib/pangea/chat_settings/pages/pangea_invitation_selection.dart +++ b/lib/pangea/chat_settings/pages/pangea_invitation_selection.dart @@ -402,7 +402,11 @@ class PangeaInvitationSelectionController ScaffoldMessenger.of(context).hideCurrentSnackBar(); ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: Text(L10n.of(context).contactHasBeenInvitedToTheChat), + content: Text( + room.isSpace + ? L10n.of(context).contactHasBeenInvitedToTheCourse + : L10n.of(context).contactHasBeenInvitedToTheChat, + ), ), ); } diff --git a/lib/widgets/navigation_rail.dart b/lib/widgets/navigation_rail.dart index 8c50b0581..c191f3b9b 100644 --- a/lib/widgets/navigation_rail.dart +++ b/lib/widgets/navigation_rail.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:badges/badges.dart' as b; import 'package:go_router/go_router.dart'; import 'package:matrix/matrix.dart'; @@ -224,17 +225,36 @@ class SpacesNavigationRail extends StatelessWidget { // AppConfig.borderRadius / 2, // ), // ), - icon: ClipPath( - clipper: MapClipper(), - child: Avatar( - mxContent: rootSpaces[i].avatar, - name: displayname, - border: BorderSide( - width: 1, - color: Theme.of(context).dividerColor, + icon: b.Badge( + showBadge: + rootSpaces[i].membership == Membership.invite, + badgeStyle: b.BadgeStyle( + badgeColor: Theme.of(context).colorScheme.error, + elevation: 4, + borderSide: BorderSide.none, + padding: const EdgeInsetsGeometry.all(0), + ), + badgeContent: Icon( + Icons.error_outline, + color: Theme.of(context).colorScheme.onPrimary, + size: 16, + ), + position: b.BadgePosition.topEnd( + top: -5, + end: -7, + ), + child: ClipPath( + clipper: MapClipper(), + child: Avatar( + mxContent: rootSpaces[i].avatar, + name: displayname, + border: BorderSide( + width: 1, + color: Theme.of(context).dividerColor, + ), + borderRadius: BorderRadius.circular(0), + size: width - (isColumnMode ? 32.0 : 24.0), ), - borderRadius: BorderRadius.circular(0), - size: width - (isColumnMode ? 32.0 : 24.0), ), ), // Pangea#