5759 if session filled redirect from choose role (#5815)
* move activity session page bottom section into its own widget * activity session full mode * fix loading of activity session preview on open app via course ping
This commit is contained in:
parent
e1b9a21e1c
commit
1caa74c668
5 changed files with 339 additions and 327 deletions
|
|
@ -5353,5 +5353,8 @@
|
|||
"denyKnockChat": "User will be rejected from chat, however they may attempt to rejoin any time later.",
|
||||
"banFromSpace": "Ban from course",
|
||||
"unbanFromSpace": "Unban from course",
|
||||
"cannotJoinBannedRoom": "Banned. Unable to join."
|
||||
"cannotJoinBannedRoom": "Banned. Unable to join.",
|
||||
"sessionFull": "Too late! This activity is full.",
|
||||
"returnToCourse": "Return to course",
|
||||
"returnHome": "Return home"
|
||||
}
|
||||
|
|
|
|||
188
lib/pangea/activity_sessions/activity_session_button_widget.dart
Normal file
188
lib/pangea/activity_sessions/activity_session_button_widget.dart
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_session_start/activity_session_start_page.dart';
|
||||
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
|
||||
|
||||
class ActivitySessionButtonWidget extends StatelessWidget {
|
||||
final ActivitySessionStartController controller;
|
||||
|
||||
const ActivitySessionButtonWidget({super.key, required this.controller});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
return AnimatedSize(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(top: BorderSide(color: theme.dividerColor)),
|
||||
color: theme.colorScheme.surface,
|
||||
),
|
||||
padding: const EdgeInsets.all(24.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Flexible(
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: FluffyThemes.maxTimelineWidth,
|
||||
),
|
||||
child: Column(
|
||||
spacing: 16.0,
|
||||
children: [
|
||||
if (controller.descriptionText != null)
|
||||
Text(
|
||||
controller.descriptionText!,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
switch (controller.state) {
|
||||
SessionState.notStarted => _ActivityStartButtons(
|
||||
controller,
|
||||
),
|
||||
SessionState.confirmedRole =>
|
||||
_ActivityRoleConfirmedButtons(controller: controller),
|
||||
SessionState.selectedSessionFull => _CTAButton(
|
||||
controller.courseParent != null
|
||||
? L10n.of(context).returnToCourse
|
||||
: L10n.of(context).returnHome,
|
||||
controller.returnFromFullSession,
|
||||
),
|
||||
_ => _CTAButton(
|
||||
controller.activityRoom?.isRoomAdmin ?? true
|
||||
? L10n.of(context).start
|
||||
: L10n.of(context).confirm,
|
||||
controller.confirmRoleSelection,
|
||||
),
|
||||
},
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ActivityStartButtons extends StatelessWidget {
|
||||
final ActivitySessionStartController controller;
|
||||
const _ActivityStartButtons(this.controller);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final hasActiveSession = controller.canJoinExistingSession;
|
||||
|
||||
return FutureBuilder(
|
||||
future: controller.neededCourseParticipants(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return const LinearProgressIndicator();
|
||||
}
|
||||
|
||||
final int neededParticipants = snapshot.data ?? 0;
|
||||
final bool hasEnoughParticipants = neededParticipants <= 0;
|
||||
return Column(
|
||||
spacing: 16.0,
|
||||
children: [
|
||||
if (!hasEnoughParticipants) ...[
|
||||
Text(
|
||||
neededParticipants > 1
|
||||
? L10n.of(context).activityNeedsMembers(neededParticipants)
|
||||
: L10n.of(context).activityNeedsOneMember,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
_CTAButton(
|
||||
L10n.of(context).inviteFriendsToCourse,
|
||||
controller.inviteToCourse,
|
||||
),
|
||||
_CTAButton(
|
||||
L10n.of(context).pickDifferentActivity,
|
||||
controller.goToCourse,
|
||||
),
|
||||
] else if (controller.joinedActivityRoomId != null) ...[
|
||||
_CTAButton(
|
||||
L10n.of(context).continueText,
|
||||
controller.goToJoinedActivity,
|
||||
),
|
||||
] else ...[
|
||||
_CTAButton(
|
||||
hasActiveSession
|
||||
? L10n.of(context).startNewSession
|
||||
: L10n.of(context).start,
|
||||
controller.startNewActivity,
|
||||
),
|
||||
if (hasActiveSession)
|
||||
_CTAButton(
|
||||
L10n.of(context).joinOpenSession,
|
||||
controller.joinExistingSession,
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ActivityRoleConfirmedButtons extends StatelessWidget {
|
||||
final ActivitySessionStartController controller;
|
||||
const _ActivityRoleConfirmedButtons({required this.controller});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final showPingCourse = controller.courseParent != null;
|
||||
final canPingCourse = controller.canPingParticipants;
|
||||
|
||||
final showInviteOptions = controller.activityRoom?.isRoomAdmin == true;
|
||||
final showPlayWithBot = !controller.isBotRoomMember;
|
||||
|
||||
return Column(
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
if (showPingCourse)
|
||||
_CTAButton(
|
||||
L10n.of(context).pingParticipants,
|
||||
canPingCourse ? controller.pingCourse : null,
|
||||
),
|
||||
if (showInviteOptions && showPlayWithBot)
|
||||
_CTAButton(L10n.of(context).playWithBot, controller.playWithBot),
|
||||
if (showInviteOptions)
|
||||
_CTAButton(L10n.of(context).inviteFriends, controller.inviteFriends),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _CTAButton extends StatelessWidget {
|
||||
final String text;
|
||||
final VoidCallback? onPressed;
|
||||
|
||||
const _CTAButton(this.text, this.onPressed);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
return ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: theme.colorScheme.primaryContainer,
|
||||
foregroundColor: theme.colorScheme.onPrimaryContainer,
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20.0),
|
||||
),
|
||||
),
|
||||
onPressed: onPressed,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [Flexible(child: Text(text, textAlign: TextAlign.center))],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -33,6 +33,9 @@ enum SessionState {
|
|||
/// The room has been created but the user hasn't selected a role yet. Non-admins haven't joined yet.
|
||||
notSelectedRole,
|
||||
|
||||
/// The room has been created and all roles are full. The user cannot get a role in this session.
|
||||
selectedSessionFull,
|
||||
|
||||
/// The user has selected a role but hasn't confirmed yet. Non-admins haven't joined yet.
|
||||
selectedRole,
|
||||
|
||||
|
|
@ -86,9 +89,7 @@ class ActivitySessionStartController extends State<ActivitySessionStartPage>
|
|||
_selectedRoleId = null;
|
||||
showInstructions = false;
|
||||
});
|
||||
}
|
||||
|
||||
if (oldWidget.activityId != widget.activityId) {
|
||||
_load();
|
||||
}
|
||||
}
|
||||
|
|
@ -115,22 +116,31 @@ class ActivitySessionStartController extends State<ActivitySessionStartPage>
|
|||
false;
|
||||
|
||||
SessionState get state {
|
||||
// the room exists and user has set their role
|
||||
if (activityRoom?.membership == Membership.join &&
|
||||
activityRoom?.hasPickedRole == true) {
|
||||
return SessionState.confirmedRole;
|
||||
}
|
||||
|
||||
// the user has selected a role but hasn't confirmed yet
|
||||
if (_selectedRoleId != null) {
|
||||
return SessionState.selectedRole;
|
||||
}
|
||||
|
||||
// the room either doesn't exist or the user hasn't joined it yet
|
||||
if (activityRoom == null || activityRoom!.membership != Membership.join) {
|
||||
// If the room does exist or is being created, then user needs to select a role.
|
||||
// Else (room doesn't exist and user hasn't started creating it), then not started.
|
||||
return widget.roomId != null || widget.launch
|
||||
? SessionState.notSelectedRole
|
||||
? canSelectRole
|
||||
? SessionState.notSelectedRole
|
||||
: SessionState.selectedSessionFull
|
||||
: SessionState.notStarted;
|
||||
}
|
||||
|
||||
return SessionState.notSelectedRole;
|
||||
return canSelectRole
|
||||
? SessionState.notSelectedRole
|
||||
: SessionState.selectedSessionFull;
|
||||
}
|
||||
|
||||
String? get descriptionText {
|
||||
|
|
@ -151,12 +161,11 @@ class ActivitySessionStartController extends State<ActivitySessionStartPage>
|
|||
return activityRoom?.isRoomAdmin ?? false
|
||||
? L10n.of(context).chooseRole
|
||||
: L10n.of(context).chooseRoleToParticipate;
|
||||
case SessionState.selectedSessionFull:
|
||||
return L10n.of(context).sessionFull;
|
||||
}
|
||||
}
|
||||
|
||||
bool get enableButtons =>
|
||||
[SessionState.notStarted, SessionState.selectedRole].contains(state);
|
||||
|
||||
Map<String, ActivityRoleModel> get assignedRoles {
|
||||
if (activityRoom != null && activityRoom!.membership == Membership.join) {
|
||||
return activityRoom!.assignedRoles ?? {};
|
||||
|
|
@ -164,6 +173,12 @@ class ActivitySessionStartController extends State<ActivitySessionStartPage>
|
|||
return roomSummaries?[widget.roomId]?.joinedUsersWithRoles ?? {};
|
||||
}
|
||||
|
||||
bool get canSelectRole {
|
||||
final assigned = assignedRoles.length;
|
||||
final total = activity?.roles.length ?? 0;
|
||||
return assigned < total;
|
||||
}
|
||||
|
||||
bool canSelectParticipant(String id) {
|
||||
if (state == SessionState.confirmedRole ||
|
||||
state == SessionState.notStarted) {
|
||||
|
|
@ -311,13 +326,19 @@ class ActivitySessionStartController extends State<ActivitySessionStartPage>
|
|||
}
|
||||
|
||||
Future<void> _loadSummary() async {
|
||||
if (courseParent == null) return;
|
||||
await loadRoomSummaries(
|
||||
courseParent!.spaceChildren
|
||||
.map((c) => c.roomId)
|
||||
.whereType<String>()
|
||||
.toList(),
|
||||
);
|
||||
final Set<String> roomIds = {};
|
||||
if (widget.roomId != null) {
|
||||
roomIds.add(widget.roomId!);
|
||||
}
|
||||
|
||||
if (courseParent != null) {
|
||||
roomIds.addAll(
|
||||
courseParent!.spaceChildren.map((c) => c.roomId).whereType<String>(),
|
||||
);
|
||||
}
|
||||
|
||||
if (roomIds.isEmpty) return;
|
||||
await loadRoomSummaries(roomIds.toList());
|
||||
}
|
||||
|
||||
Future<void> _loadActivity() async {
|
||||
|
|
@ -412,7 +433,18 @@ class ActivitySessionStartController extends State<ActivitySessionStartPage>
|
|||
}
|
||||
}
|
||||
|
||||
Future<String> joinExistingSession() async {
|
||||
Future<void> joinExistingSession() async {
|
||||
final resp = await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: _joinExistingSession,
|
||||
);
|
||||
|
||||
if (!resp.isError) {
|
||||
NavigationUtil.goToSpaceRoute(resp.result, [], context);
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> _joinExistingSession() async {
|
||||
if (!canJoinExistingSession) {
|
||||
throw Exception("No existing session to join");
|
||||
}
|
||||
|
|
@ -476,7 +508,10 @@ class ActivitySessionStartController extends State<ActivitySessionStartPage>
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> pingCourse() async {
|
||||
Future<void> pingCourse() =>
|
||||
showFutureLoadingDialog(context: context, future: _pingCourse);
|
||||
|
||||
Future<void> _pingCourse() async {
|
||||
if (activityRoom?.courseParent == null) {
|
||||
throw Exception("Activity is not part of a course");
|
||||
}
|
||||
|
|
@ -546,6 +581,34 @@ class ActivitySessionStartController extends State<ActivitySessionStartPage>
|
|||
await future.timeout(const Duration(seconds: 5));
|
||||
}
|
||||
|
||||
void inviteFriends() {
|
||||
if (activityRoom == null) return;
|
||||
NavigationUtil.goToSpaceRoute(activityRoom!.id, ['invite'], context);
|
||||
}
|
||||
|
||||
void inviteToCourse() {
|
||||
if (courseParent == null) return;
|
||||
context.push("/rooms/spaces/${courseParent!.id}/invite");
|
||||
}
|
||||
|
||||
void goToCourse() {
|
||||
if (courseParent == null) return;
|
||||
context.push("/rooms/spaces/${courseParent!.id}/details?tab=course");
|
||||
}
|
||||
|
||||
void goToJoinedActivity() {
|
||||
if (joinedActivityRoomId == null) return;
|
||||
NavigationUtil.goToSpaceRoute(joinedActivityRoomId!, [], context);
|
||||
}
|
||||
|
||||
void returnFromFullSession() {
|
||||
if (courseParent != null) {
|
||||
goToCourse();
|
||||
} else {
|
||||
NavigationUtil.goToSpaceRoute(null, [], context);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => ActivitySessionStartView(this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
|
|
@ -10,6 +9,7 @@ import 'package:fluffychat/pangea/activity_feedback/activity_feedback_repo.dart'
|
|||
import 'package:fluffychat/pangea/activity_feedback/activity_feedback_request.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_role_model.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_room_extension.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_session_button_widget.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_session_start/activity_session_start_page.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_summary_widget.dart';
|
||||
import 'package:fluffychat/pangea/chat_settings/utils/room_summary_extension.dart';
|
||||
|
|
@ -20,7 +20,6 @@ import 'package:fluffychat/pangea/course_chats/open_roles_indicator.dart';
|
|||
import 'package:fluffychat/pangea/course_plans/course_activities/activity_summaries_provider.dart';
|
||||
import 'package:fluffychat/pangea/course_plans/course_activities/course_activity_repo.dart';
|
||||
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
|
||||
import 'package:fluffychat/pangea/navigation/navigation_util.dart';
|
||||
import 'package:fluffychat/utils/stream_extension.dart';
|
||||
import 'package:fluffychat/widgets/future_loading_dialog.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
|
|
@ -30,16 +29,60 @@ class ActivitySessionStartView extends StatelessWidget {
|
|||
final ActivitySessionStartController controller;
|
||||
const ActivitySessionStartView(this.controller, {super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final buttonStyle = ElevatedButton.styleFrom(
|
||||
backgroundColor: theme.colorScheme.primaryContainer,
|
||||
foregroundColor: theme.colorScheme.onPrimaryContainer,
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
|
||||
Future<void> _submitActivityFeedback(BuildContext context) async {
|
||||
final feedback = await showDialog<String?>(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return FeedbackDialog(
|
||||
title: L10n.of(context).feedbackTitle,
|
||||
onSubmit: (feedback) {
|
||||
Navigator.of(context).pop(feedback);
|
||||
},
|
||||
scrollable: false,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (feedback == null || feedback.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
final resp = await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () => ActivityFeedbackRepo.submitFeedback(
|
||||
ActivityFeedbackRequest(
|
||||
activityId: controller.widget.activityId,
|
||||
feedbackText: feedback,
|
||||
userId: Matrix.of(context).client.userID!,
|
||||
userL1: MatrixState.pangeaController.userController.userL1Code!,
|
||||
userL2: MatrixState.pangeaController.userController.userL2Code!,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (resp.isError) {
|
||||
return;
|
||||
}
|
||||
|
||||
CourseActivityRepo.setSentFeedback(
|
||||
controller.widget.activityId,
|
||||
MatrixState.pangeaController.userController.userL1Code!,
|
||||
);
|
||||
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return FeedbackResponseDialog(
|
||||
title: L10n.of(context).feedbackTitle,
|
||||
feedback: resp.result!.userFriendlyResponse,
|
||||
description: L10n.of(context).feedbackRespDesc,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StreamBuilder(
|
||||
stream: Matrix.of(
|
||||
context,
|
||||
|
|
@ -73,63 +116,7 @@ class ActivitySessionStartView extends StatelessWidget {
|
|||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.flag_outlined),
|
||||
onPressed: () async {
|
||||
final feedback = await showDialog<String?>(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return FeedbackDialog(
|
||||
title: L10n.of(context).feedbackTitle,
|
||||
onSubmit: (feedback) {
|
||||
Navigator.of(context).pop(feedback);
|
||||
},
|
||||
scrollable: false,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (feedback == null || feedback.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
final resp = await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () => ActivityFeedbackRepo.submitFeedback(
|
||||
ActivityFeedbackRequest(
|
||||
activityId: controller.widget.activityId,
|
||||
feedbackText: feedback,
|
||||
userId: Matrix.of(context).client.userID!,
|
||||
userL1: MatrixState
|
||||
.pangeaController
|
||||
.userController
|
||||
.userL1Code!,
|
||||
userL2: MatrixState
|
||||
.pangeaController
|
||||
.userController
|
||||
.userL2Code!,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (resp.isError) {
|
||||
return;
|
||||
}
|
||||
|
||||
CourseActivityRepo.setSentFeedback(
|
||||
controller.widget.activityId,
|
||||
MatrixState.pangeaController.userController.userL1Code!,
|
||||
);
|
||||
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return FeedbackResponseDialog(
|
||||
title: L10n.of(context).feedbackTitle,
|
||||
feedback: resp.result!.userFriendlyResponse,
|
||||
description: L10n.of(context).feedbackRespDesc,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
onPressed: () => _submitActivityFeedback(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
@ -180,142 +167,7 @@ class ActivitySessionStartView extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
AnimatedSize(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
top: BorderSide(color: theme.dividerColor),
|
||||
),
|
||||
color: theme.colorScheme.surface,
|
||||
),
|
||||
padding: const EdgeInsets.all(24.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Flexible(
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: FluffyThemes.maxTimelineWidth,
|
||||
),
|
||||
child: Column(
|
||||
spacing: 16.0,
|
||||
children: [
|
||||
if (controller.descriptionText != null)
|
||||
Text(
|
||||
controller.descriptionText!,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
if (controller.state ==
|
||||
SessionState.notStarted)
|
||||
_ActivityStartButtons(
|
||||
controller,
|
||||
buttonStyle,
|
||||
)
|
||||
else if (controller.state ==
|
||||
SessionState.confirmedRole) ...[
|
||||
if (controller.courseParent != null)
|
||||
ElevatedButton(
|
||||
style: buttonStyle,
|
||||
onPressed:
|
||||
controller.canPingParticipants
|
||||
? () {
|
||||
showFutureLoadingDialog(
|
||||
context: context,
|
||||
future:
|
||||
controller.pingCourse,
|
||||
);
|
||||
}
|
||||
: null,
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
Flexible(
|
||||
child: Text(
|
||||
L10n.of(
|
||||
context,
|
||||
).pingParticipants,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (controller
|
||||
.activityRoom!
|
||||
.isRoomAdmin) ...[
|
||||
if (!controller.isBotRoomMember)
|
||||
ElevatedButton(
|
||||
style: buttonStyle,
|
||||
onPressed: controller.playWithBot,
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
L10n.of(
|
||||
context,
|
||||
).playWithBot,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
ElevatedButton(
|
||||
style: buttonStyle,
|
||||
onPressed: () {
|
||||
NavigationUtil.goToSpaceRoute(
|
||||
controller.activityRoom!.id,
|
||||
['invite'],
|
||||
context,
|
||||
);
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
L10n.of(
|
||||
context,
|
||||
).inviteFriends,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
] else
|
||||
ElevatedButton(
|
||||
style: buttonStyle,
|
||||
onPressed: controller.enableButtons
|
||||
? controller.confirmRoleSelection
|
||||
: null,
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
controller
|
||||
.activityRoom
|
||||
?.isRoomAdmin ??
|
||||
true
|
||||
? L10n.of(context).start
|
||||
: L10n.of(context).confirm,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
ActivitySessionButtonWidget(controller: controller),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
@ -325,113 +177,6 @@ class ActivitySessionStartView extends StatelessWidget {
|
|||
}
|
||||
}
|
||||
|
||||
class _ActivityStartButtons extends StatelessWidget {
|
||||
final ActivitySessionStartController controller;
|
||||
final ButtonStyle buttonStyle;
|
||||
const _ActivityStartButtons(this.controller, this.buttonStyle);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final hasActiveSession = controller.canJoinExistingSession;
|
||||
final joinedActivityRoom = controller.joinedActivityRoomId;
|
||||
|
||||
return FutureBuilder(
|
||||
future: controller.neededCourseParticipants(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return const LinearProgressIndicator();
|
||||
}
|
||||
|
||||
final int neededParticipants = snapshot.data ?? 0;
|
||||
final bool hasEnoughParticipants = neededParticipants <= 0;
|
||||
return Column(
|
||||
spacing: 16.0,
|
||||
children: [
|
||||
if (!hasEnoughParticipants) ...[
|
||||
Text(
|
||||
neededParticipants > 1
|
||||
? L10n.of(context).activityNeedsMembers(neededParticipants)
|
||||
: L10n.of(context).activityNeedsOneMember,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
ElevatedButton(
|
||||
style: buttonStyle,
|
||||
onPressed: controller.courseParent?.canInvite ?? false
|
||||
? () => context.push(
|
||||
"/rooms/spaces/${controller.courseParent!.id}/invite",
|
||||
)
|
||||
: null,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [Text(L10n.of(context).inviteFriendsToCourse)],
|
||||
),
|
||||
),
|
||||
ElevatedButton(
|
||||
style: buttonStyle,
|
||||
onPressed: () => context.push(
|
||||
"/rooms/spaces/${controller.courseParent!.id}/details?tab=course",
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [Text(L10n.of(context).pickDifferentActivity)],
|
||||
),
|
||||
),
|
||||
] else if (joinedActivityRoom != null) ...[
|
||||
ElevatedButton(
|
||||
style: buttonStyle,
|
||||
onPressed: () {
|
||||
NavigationUtil.goToSpaceRoute(
|
||||
joinedActivityRoom,
|
||||
[],
|
||||
context,
|
||||
);
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [Text(L10n.of(context).continueText)],
|
||||
),
|
||||
),
|
||||
] else ...[
|
||||
ElevatedButton(
|
||||
style: buttonStyle,
|
||||
onPressed: controller.startNewActivity,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
hasActiveSession
|
||||
? L10n.of(context).startNewSession
|
||||
: L10n.of(context).start,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (hasActiveSession)
|
||||
ElevatedButton(
|
||||
style: buttonStyle,
|
||||
onPressed: () async {
|
||||
final resp = await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: controller.joinExistingSession,
|
||||
);
|
||||
|
||||
if (!resp.isError) {
|
||||
NavigationUtil.goToSpaceRoute(resp.result, [], context);
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [Text(L10n.of(context).joinOpenSession)],
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ActivityStatuses extends StatelessWidget {
|
||||
final Map<ActivitySummaryStatus, Map<String, RoomSummaryResponse>> statuses;
|
||||
final Room space;
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ class BackgroundPush {
|
|||
// Handle notifications when app is opened from terminated/background state
|
||||
FirebaseMessaging.instance.getInitialMessage().then(_onOpenNotification);
|
||||
FirebaseMessaging.onMessageOpenedApp.listen(_onOpenNotification);
|
||||
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
|
||||
// Pangea#
|
||||
mainIsolateReceivePort?.listen((message) async {
|
||||
try {
|
||||
|
|
@ -631,3 +632,15 @@ class UPFunctions extends UnifiedPushFunctions {
|
|||
await UnifiedPush.saveDistributor(distributor);
|
||||
}
|
||||
}
|
||||
|
||||
// #Pangea
|
||||
@pragma('vm:entry-point')
|
||||
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
||||
// Required for background isolate
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
final instance = BackgroundPush._instance;
|
||||
if (instance == null) return;
|
||||
await instance._onOpenNotification(message);
|
||||
}
|
||||
|
||||
// Pangea#
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue