update activity launch page buttons, sort activities in topics by number of participants (#3974)
This commit is contained in:
parent
7348e655f4
commit
94e55d9940
4 changed files with 140 additions and 54 deletions
|
|
@ -5234,5 +5234,14 @@
|
|||
"moreLabel": "more",
|
||||
"promoCodeInfo": "Promo codes can be entered on the next page",
|
||||
"editsComingSoon": "The ability to edit cities and activities is coming soon.",
|
||||
"editing": "Editing"
|
||||
"editing": "Editing",
|
||||
"activityNeedsMembers": "Uh oh! This activity needs {num} more people.",
|
||||
"@activityNeedsMembers": {
|
||||
"placeholders": {
|
||||
"num": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"inviteFriendsToCourse": "Invite friends to my course"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,6 +177,28 @@ class ActivitySessionStartController extends State<ActivitySessionStartPage> {
|
|||
if (mounted) setState(() => _selectedRoleId = id);
|
||||
}
|
||||
|
||||
Future<bool> courseHasEnoughParticipants() async {
|
||||
final roomParticipants = widget.room?.getParticipants() ?? [];
|
||||
final courseParticipants = await parent?.requestParticipants(
|
||||
[Membership.join, Membership.invite, Membership.knock],
|
||||
false,
|
||||
true,
|
||||
) ??
|
||||
[];
|
||||
|
||||
final botInRoom = roomParticipants.any(
|
||||
(p) => p.id == BotName.byEnvironment,
|
||||
);
|
||||
final botInCourse = courseParticipants.any(
|
||||
(p) => p.id == BotName.byEnvironment,
|
||||
);
|
||||
|
||||
final addBotToAvailableUsers = !botInCourse && !botInRoom;
|
||||
final availableParticipants =
|
||||
courseParticipants.length + (addBotToAvailableUsers ? 1 : 0);
|
||||
return availableParticipants >= (activity?.req.numberOfParticipants ?? 0);
|
||||
}
|
||||
|
||||
Future<void> _loadActivity() async {
|
||||
try {
|
||||
setState(() {
|
||||
|
|
|
|||
|
|
@ -127,54 +127,12 @@ class ActivitySessionStartView extends StatelessWidget {
|
|||
textAlign: TextAlign.center,
|
||||
),
|
||||
if (controller.state ==
|
||||
SessionState.notStarted) ...[
|
||||
ElevatedButton(
|
||||
style: buttonStyle,
|
||||
onPressed: () => context.go(
|
||||
"/rooms/spaces/${controller.widget.parentId}/activity/${controller.widget.activityId}?new=true",
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
L10n.of(context)
|
||||
.startNewSession,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
ElevatedButton(
|
||||
style: buttonStyle,
|
||||
onPressed: controller
|
||||
.canJoinExistingSession
|
||||
? () async {
|
||||
final resp =
|
||||
await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: controller
|
||||
.joinExistingSession,
|
||||
);
|
||||
|
||||
if (!resp.isError) {
|
||||
context.go(
|
||||
"/rooms/spaces/${controller.widget.parentId}/${resp.result}",
|
||||
);
|
||||
}
|
||||
}
|
||||
: null,
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
L10n.of(context)
|
||||
.joinOpenSession,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
] else if (controller.state ==
|
||||
SessionState.notStarted)
|
||||
_ActivityStartButtons(
|
||||
controller,
|
||||
buttonStyle,
|
||||
)
|
||||
else if (controller.state ==
|
||||
SessionState.confirmedRole) ...[
|
||||
if (controller.room!.courseParent !=
|
||||
null)
|
||||
|
|
@ -280,3 +238,96 @@ 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;
|
||||
return FutureBuilder(
|
||||
future: controller.courseHasEnoughParticipants(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return const LinearProgressIndicator();
|
||||
}
|
||||
|
||||
final bool hasEnoughParticipants = snapshot.data ?? true;
|
||||
return Column(
|
||||
spacing: 16.0,
|
||||
children: [
|
||||
if (!hasEnoughParticipants) ...[
|
||||
Text(
|
||||
L10n.of(context).activityNeedsMembers(
|
||||
(controller.activity?.req.numberOfParticipants ?? 2) - 1,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
if (controller.parent?.canInvite ?? false)
|
||||
ElevatedButton(
|
||||
style: buttonStyle,
|
||||
onPressed: () => context.go(
|
||||
"/rooms/spaces/${controller.parent!.id}/invite",
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
L10n.of(context).inviteFriendsToCourse,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
] else ...[
|
||||
ElevatedButton(
|
||||
style: buttonStyle,
|
||||
onPressed: () => context.go(
|
||||
"/rooms/spaces/${controller.widget.parentId}/activity/${controller.widget.activityId}?new=true",
|
||||
),
|
||||
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) {
|
||||
context.go(
|
||||
"/rooms/spaces/${controller.widget.parentId}/${resp.result}",
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
L10n.of(context).joinOpenSession,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,12 @@ class CourseSettings extends StatelessWidget {
|
|||
children: course.loadedTopics.mapIndexed((index, topic) {
|
||||
final unlocked = index <= currentTopicIndex;
|
||||
final usersInTopic = topicsToUsers[topic.uuid] ?? [];
|
||||
final activities = topic.loadedActivities;
|
||||
activities.sort(
|
||||
(a, b) => a.req.numberOfParticipants.compareTo(
|
||||
b.req.numberOfParticipants,
|
||||
),
|
||||
);
|
||||
return AbsorbPointer(
|
||||
absorbing: !unlocked,
|
||||
child: Opacity(
|
||||
|
|
@ -168,10 +174,9 @@ class CourseSettings extends StatelessWidget {
|
|||
height: isColumnMode ? 290.0 : 210.0,
|
||||
child: ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: topic.loadedActivities.length,
|
||||
itemCount: activities.length,
|
||||
itemBuilder: (context, index) {
|
||||
final activityId =
|
||||
topic.loadedActivities[index].activityId;
|
||||
final activityId = activities[index].activityId;
|
||||
|
||||
final complete = room.hasCompletedActivity(
|
||||
room.client.userID!,
|
||||
|
|
@ -182,8 +187,7 @@ class CourseSettings extends StatelessWidget {
|
|||
activityId,
|
||||
);
|
||||
|
||||
final activity = topic.loadedActivities[index];
|
||||
|
||||
final activity = activities[index];
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(right: 24.0),
|
||||
child: MouseRegion(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue