diff --git a/lib/pangea/course_creation/selected_course_page.dart b/lib/pangea/course_creation/selected_course_page.dart index f43fa3401..1b8b3848e 100644 --- a/lib/pangea/course_creation/selected_course_page.dart +++ b/lib/pangea/course_creation/selected_course_page.dart @@ -13,6 +13,7 @@ import 'package:fluffychat/pangea/course_plans/courses/course_plan_model.dart'; import 'package:fluffychat/pangea/course_plans/courses/course_plan_room_extension.dart'; import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart'; import 'package:fluffychat/pangea/spaces/client_spaces_extension.dart'; +import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart'; import 'package:fluffychat/widgets/matrix.dart'; enum SelectedCourseMode { launch, addToSpace, join } @@ -74,7 +75,9 @@ class SelectedCourseController extends State case SelectedCourseMode.addToSpace: return L10n.of(context).addCoursePlan; case SelectedCourseMode.join: - return L10n.of(context).joinWithClassCode; + return widget.roomChunk?.joinRule == JoinRules.knock.name + ? L10n.of(context).knock + : L10n.of(context).join; } } @@ -152,16 +155,36 @@ class SelectedCourseController extends State } final client = Matrix.of(context).client; - final roomId = await client.joinRoom( - widget.roomChunk!.roomId, - ); - - final room = client.getRoomById(roomId); - if (room == null || room.membership != Membership.join) { - await client.waitForRoomInSync(roomId, join: true); + final r = client.getRoomById(widget.roomChunk!.roomId); + if (r != null && r.membership == Membership.join) { + if (mounted) { + context.go("/rooms/spaces/${r.id}/details"); + } + return; } - if (client.getRoomById(roomId) == null) { + final knock = widget.roomChunk!.joinRule == JoinRules.knock.name; + final roomId = widget.roomChunk != null && knock + ? await client.knockRoom(widget.roomChunk!.roomId) + : await client.joinRoom(widget.roomChunk!.roomId); + + Room? room = client.getRoomById(roomId); + if (!knock && room == null) { + await client.waitForRoomInSync(roomId); + room = client.getRoomById(roomId); + } + + if (knock && room == null) { + Navigator.of(context).pop(); + await showOkAlertDialog( + context: context, + title: L10n.of(context).youHaveKnocked, + message: L10n.of(context).pleaseWaitUntilInvited, + ); + return; + } + + if (room == null) { throw Exception("Failed to join room"); } diff --git a/lib/pangea/course_creation/selected_course_view.dart b/lib/pangea/course_creation/selected_course_view.dart index 463ceb453..6f54c0363 100644 --- a/lib/pangea/course_creation/selected_course_view.dart +++ b/lib/pangea/course_creation/selected_course_view.dart @@ -283,7 +283,8 @@ class SelectedCourseView extends StatelessWidget { ), child: Row( spacing: 8.0, - mainAxisSize: MainAxisSize.min, + mainAxisAlignment: + MainAxisAlignment.center, children: [ const Icon(Icons.map_outlined), Text( diff --git a/lib/pangea/login/pages/public_courses_page.dart b/lib/pangea/login/pages/public_courses_page.dart index db782fcf4..6ffd606c4 100644 --- a/lib/pangea/login/pages/public_courses_page.dart +++ b/lib/pangea/login/pages/public_courses_page.dart @@ -15,6 +15,7 @@ import 'package:fluffychat/pangea/course_plans/courses/get_localized_courses_req import 'package:fluffychat/pangea/languages/language_model.dart'; import 'package:fluffychat/pangea/spaces/public_course_extension.dart'; import 'package:fluffychat/widgets/avatar.dart'; +import 'package:fluffychat/widgets/hover_builder.dart'; import 'package:fluffychat/widgets/matrix.dart'; class PublicCoursesPage extends StatefulWidget { @@ -67,8 +68,7 @@ class PublicCoursesPageState extends State { r.id == c.room.roomId && r.membership == Membership.join, ) && - coursePlans.containsKey(c.courseId) && - c.room.joinRule == 'public', + coursePlans.containsKey(c.courseId), ) .toList(); @@ -83,6 +83,15 @@ class PublicCoursesPageState extends State { ).toList(); } + // sort by join rule, with knock rooms at the end + filtered.sort((a, b) { + final aKnock = a.room.joinRule == JoinRules.knock.name; + final bKnock = b.room.joinRule == JoinRules.knock.name; + if (aKnock && !bKnock) return 1; + if (!aKnock && bKnock) return -1; + return 0; + }); + return filtered; } @@ -333,6 +342,39 @@ class PublicCoursesPageState extends State { style: theme.textTheme.bodyMedium, ), ], + const SizedBox(height: 12.0), + HoverBuilder( + builder: (context, hovered) => + ElevatedButton( + onPressed: () => context.go( + '/${widget.route}/course/public/$courseId', + extra: roomChunk, + ), + style: ElevatedButton.styleFrom( + backgroundColor: theme + .colorScheme.primaryContainer + .withAlpha(hovered ? 255 : 200), + foregroundColor: theme + .colorScheme.onPrimaryContainer, + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(12.0), + ), + ), + child: Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Text( + roomChunk.joinRule == + JoinRules.knock.name + ? L10n.of(context).knock + : L10n.of(context).join, + ), + ], + ), + ), + ), ], ), ),