Update-sample-course (#3823)
* chore(courses): update test/sample coures * feat(activity_planner): addition of goals, location, and description to activities * formatting * added activity ids and renamed bookMarkId to activityId * formatting --------- Co-authored-by: ggurdin <ggurdin@gmail.com>
This commit is contained in:
parent
077bbb13f5
commit
4e3f82331c
14 changed files with 3224 additions and 5269 deletions
|
|
@ -221,7 +221,7 @@ class ActivityGeneratorState extends State<ActivityGenerator> {
|
|||
vocab: activity.vocab,
|
||||
imageURL: imageUrl,
|
||||
roles: activity.roles,
|
||||
bookmarkId: activity.bookmarkId,
|
||||
activityId: activity.activityId,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ class ActivityPlanCard extends StatelessWidget {
|
|||
width: 24.0,
|
||||
height: 24.0,
|
||||
cacheKey: controller
|
||||
.updatedActivity.bookmarkId,
|
||||
.updatedActivity.activityId,
|
||||
fit: BoxFit.cover,
|
||||
)
|
||||
: CachedNetworkImage(
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@ import 'package:fluffychat/pangea/activity_planner/activity_plan_request.dart';
|
|||
import 'package:fluffychat/pangea/common/constants/model_keys.dart';
|
||||
|
||||
class ActivityPlanModel {
|
||||
final String bookmarkId;
|
||||
final String activityId;
|
||||
final ActivityPlanRequest req;
|
||||
final String title;
|
||||
final String description;
|
||||
final String learningObjective;
|
||||
final String instructions;
|
||||
final List<Vocab> vocab;
|
||||
|
|
@ -18,15 +19,21 @@ class ActivityPlanModel {
|
|||
ActivityPlanModel({
|
||||
required this.req,
|
||||
required this.title,
|
||||
// TODO: when we bring back user's being able to make their own activity,
|
||||
// then this should be required
|
||||
String? description,
|
||||
required this.learningObjective,
|
||||
required this.instructions,
|
||||
required this.vocab,
|
||||
required this.bookmarkId,
|
||||
required this.activityId,
|
||||
Map<String, ActivityRole>? roles,
|
||||
this.imageURL,
|
||||
this.endAt,
|
||||
this.duration,
|
||||
}) : _roles = roles;
|
||||
}) : description = (description == null || description.isEmpty)
|
||||
? learningObjective
|
||||
: description,
|
||||
_roles = roles;
|
||||
|
||||
Map<String, ActivityRole> get roles {
|
||||
if (_roles != null) return _roles!;
|
||||
|
|
@ -35,6 +42,7 @@ class ActivityPlanModel {
|
|||
defaultRoles['role_$i'] = ActivityRole(
|
||||
id: 'role_$i',
|
||||
name: 'Participant',
|
||||
goal: learningObjective,
|
||||
avatarUrl: null,
|
||||
);
|
||||
}
|
||||
|
|
@ -43,6 +51,7 @@ class ActivityPlanModel {
|
|||
|
||||
ActivityPlanModel copyWith({
|
||||
String? title,
|
||||
String? description,
|
||||
String? learningObjective,
|
||||
String? instructions,
|
||||
List<Vocab>? vocab,
|
||||
|
|
@ -54,6 +63,7 @@ class ActivityPlanModel {
|
|||
return ActivityPlanModel(
|
||||
req: req,
|
||||
title: title ?? this.title,
|
||||
description: description ?? this.description,
|
||||
learningObjective: learningObjective ?? this.learningObjective,
|
||||
instructions: instructions ?? this.instructions,
|
||||
vocab: vocab ?? this.vocab,
|
||||
|
|
@ -61,7 +71,7 @@ class ActivityPlanModel {
|
|||
endAt: endAt ?? this.endAt,
|
||||
duration: duration ?? this.duration,
|
||||
roles: roles ?? _roles,
|
||||
bookmarkId: bookmarkId,
|
||||
activityId: activityId,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -87,6 +97,8 @@ class ActivityPlanModel {
|
|||
instructions: json[ModelKey.activityPlanInstructions],
|
||||
req: req,
|
||||
title: json[ModelKey.activityPlanTitle],
|
||||
description: json[ModelKey.activityPlanDescription] ??
|
||||
json[ModelKey.activityPlanLearningObjective],
|
||||
learningObjective: json[ModelKey.activityPlanLearningObjective],
|
||||
vocab: List<Vocab>.from(
|
||||
json[ModelKey.activityPlanVocab].map((vocab) => Vocab.fromJson(vocab)),
|
||||
|
|
@ -102,17 +114,18 @@ class ActivityPlanModel {
|
|||
)
|
||||
: null,
|
||||
roles: roles,
|
||||
bookmarkId: json[ModelKey.activityPlanBookmarkId] ?? json["bookmark_id"],
|
||||
activityId: json[ModelKey.activityId] ?? json["bookmark_id"],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
ModelKey.activityPlanBookmarkId: bookmarkId,
|
||||
ModelKey.activityId: activityId,
|
||||
ModelKey.activityPlanImageURL: imageURL,
|
||||
ModelKey.activityPlanInstructions: instructions,
|
||||
ModelKey.activityPlanRequest: req.toJson(),
|
||||
ModelKey.activityPlanTitle: title,
|
||||
ModelKey.activityPlanDescription: description,
|
||||
ModelKey.activityPlanLearningObjective: learningObjective,
|
||||
ModelKey.activityPlanVocab: vocab.map((vocab) => vocab.toJson()).toList(),
|
||||
ModelKey.activityPlanEndAt: endAt?.toIso8601String(),
|
||||
|
|
@ -154,6 +167,7 @@ class ActivityPlanModel {
|
|||
other.title == title &&
|
||||
other.learningObjective == learningObjective &&
|
||||
other.instructions == instructions &&
|
||||
other.description == description &&
|
||||
listEquals(other.vocab, vocab) &&
|
||||
other.imageURL == imageURL;
|
||||
}
|
||||
|
|
@ -163,6 +177,7 @@ class ActivityPlanModel {
|
|||
req.hashCode ^
|
||||
title.hashCode ^
|
||||
learningObjective.hashCode ^
|
||||
description.hashCode ^
|
||||
instructions.hashCode ^
|
||||
Object.hashAll(vocab) ^
|
||||
imageURL.hashCode;
|
||||
|
|
@ -205,11 +220,13 @@ class Vocab {
|
|||
class ActivityRole {
|
||||
final String id;
|
||||
final String name;
|
||||
final String goal;
|
||||
final String? avatarUrl;
|
||||
|
||||
ActivityRole({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.goal,
|
||||
this.avatarUrl,
|
||||
});
|
||||
|
||||
|
|
@ -223,6 +240,7 @@ class ActivityRole {
|
|||
return ActivityRole(
|
||||
id: json['id'],
|
||||
name: json['name'],
|
||||
goal: json['goal'],
|
||||
avatarUrl: avatarUrl,
|
||||
);
|
||||
}
|
||||
|
|
@ -231,6 +249,7 @@ class ActivityRole {
|
|||
return {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'goal': goal,
|
||||
'avatar_url': avatarUrl,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ class ActivityPlanRequest {
|
|||
final String topic;
|
||||
final String mode;
|
||||
final String objective;
|
||||
final String location;
|
||||
final MediaEnum media;
|
||||
LanguageLevelTypeEnum cefrLevel;
|
||||
final String languageOfInstructions;
|
||||
|
|
@ -21,6 +22,7 @@ class ActivityPlanRequest {
|
|||
required this.cefrLevel,
|
||||
required this.languageOfInstructions,
|
||||
required this.targetLanguage,
|
||||
this.location = "any",
|
||||
this.count = 3,
|
||||
required this.numberOfParticipants,
|
||||
});
|
||||
|
|
@ -36,6 +38,7 @@ class ActivityPlanRequest {
|
|||
ModelKey.activityRequestTargetLanguage: targetLanguage,
|
||||
ModelKey.activityRequestCount: count,
|
||||
ModelKey.activityRequestNumberOfParticipants: numberOfParticipants,
|
||||
ModelKey.activityPlanLocation: location,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -56,6 +59,7 @@ class ActivityPlanRequest {
|
|||
count: json[ModelKey.activityRequestCount],
|
||||
numberOfParticipants:
|
||||
json[ModelKey.activityRequestNumberOfParticipants],
|
||||
location: json[ModelKey.activityPlanLocation] ?? "any",
|
||||
);
|
||||
|
||||
String get storageKey =>
|
||||
|
|
@ -73,6 +77,7 @@ class ActivityPlanRequest {
|
|||
other.cefrLevel == cefrLevel &&
|
||||
other.languageOfInstructions == languageOfInstructions &&
|
||||
other.targetLanguage == targetLanguage &&
|
||||
other.location == location &&
|
||||
other.count == count &&
|
||||
other.numberOfParticipants == numberOfParticipants;
|
||||
}
|
||||
|
|
@ -87,5 +92,6 @@ class ActivityPlanRequest {
|
|||
languageOfInstructions.hashCode ^
|
||||
targetLanguage.hashCode ^
|
||||
count.hashCode ^
|
||||
location.hashCode ^
|
||||
numberOfParticipants.hashCode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ class ActivityPlannerBuilderState extends State<ActivityPlannerBuilder> {
|
|||
vocab: vocab,
|
||||
imageURL: imageURL,
|
||||
roles: widget.initialActivity.roles,
|
||||
bookmarkId: widget.initialActivity.bookmarkId,
|
||||
activityId: widget.initialActivity.activityId,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -283,7 +283,7 @@ class ActivityPlannerBuilderState extends State<ActivityPlannerBuilder> {
|
|||
MatrixState.pangeaController.userController;
|
||||
|
||||
bool get isBookmarked =>
|
||||
_userController.isBookmarked(updatedActivity.bookmarkId);
|
||||
_userController.isBookmarked(updatedActivity.activityId);
|
||||
|
||||
Future<void> toggleBookmarkedActivity() async {
|
||||
isBookmarked
|
||||
|
|
@ -294,7 +294,7 @@ class ActivityPlannerBuilderState extends State<ActivityPlannerBuilder> {
|
|||
|
||||
Future<void> _addBookmarkedActivity() async {
|
||||
await _userController.addBookmarkedActivity(
|
||||
activityId: updatedActivity.bookmarkId,
|
||||
activityId: updatedActivity.activityId,
|
||||
);
|
||||
await ActivityPlanRepo.set(updatedActivity);
|
||||
}
|
||||
|
|
@ -309,17 +309,17 @@ class ActivityPlannerBuilderState extends State<ActivityPlannerBuilder> {
|
|||
updatedActivity,
|
||||
).then((resp) {
|
||||
_userController.updateBookmarkedActivity(
|
||||
activityId: widget.initialActivity.bookmarkId,
|
||||
newActivityId: resp.bookmarkId,
|
||||
activityId: widget.initialActivity.activityId,
|
||||
newActivityId: resp.activityId,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _removeBookmarkedActivity() async {
|
||||
await _userController.removeBookmarkedActivity(
|
||||
activityId: updatedActivity.bookmarkId,
|
||||
activityId: updatedActivity.activityId,
|
||||
);
|
||||
await ActivityPlanRepo.remove(updatedActivity.bookmarkId);
|
||||
await ActivityPlanRepo.remove(updatedActivity.activityId);
|
||||
}
|
||||
|
||||
Future<List<String>> launchToSpace() async {
|
||||
|
|
@ -343,7 +343,7 @@ class ActivityPlannerBuilderState extends State<ActivityPlannerBuilder> {
|
|||
final roomID = await Matrix.of(context).client.createRoom(
|
||||
creationContent: {
|
||||
'type':
|
||||
"${PangeaRoomTypes.activitySession}:${updatedActivity.bookmarkId}",
|
||||
"${PangeaRoomTypes.activitySession}:${updatedActivity.activityId}",
|
||||
},
|
||||
visibility: Visibility.private,
|
||||
name: "${updatedActivity.title} ${index + 1}",
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class ActivityFinishedStatusMessage extends StatelessWidget {
|
|||
throw L10n.of(context).noCourseFound;
|
||||
}
|
||||
|
||||
final activityId = controller.room.activityPlan!.bookmarkId;
|
||||
final activityId = controller.room.activityPlan!.activityId;
|
||||
final topicId = coursePlan.topicID(activityId);
|
||||
if (topicId == null) {
|
||||
throw L10n.of(context).activityNotFoundForCourse;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class ActivityPlanRepo {
|
|||
}
|
||||
|
||||
static Future<void> _setCached(ActivityPlanModel response) =>
|
||||
_activityPlanStorage.write(response.bookmarkId, response.toJson());
|
||||
_activityPlanStorage.write(response.activityId, response.toJson());
|
||||
|
||||
static Future<void> _removeCached(String id) =>
|
||||
_activityPlanStorage.remove(id);
|
||||
|
|
@ -62,14 +62,14 @@ class ActivityPlanRepo {
|
|||
);
|
||||
|
||||
final Response res = await req.patch(
|
||||
url: "${PApiUrls.activityPlan}/${update.bookmarkId}",
|
||||
url: "${PApiUrls.activityPlan}/${update.activityId}",
|
||||
body: update.toJson(),
|
||||
);
|
||||
|
||||
final decodedBody = jsonDecode(utf8.decode(res.bodyBytes));
|
||||
final response = ActivityPlanModel.fromJson(decodedBody["plan"]);
|
||||
|
||||
_removeCached(update.bookmarkId);
|
||||
_removeCached(update.activityId);
|
||||
_setCached(response);
|
||||
|
||||
return response;
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class ActivitySuggestionCard extends StatelessWidget {
|
|||
uri: Uri.parse(activity.imageURL!),
|
||||
width: width,
|
||||
height: width,
|
||||
cacheKey: activity.bookmarkId,
|
||||
cacheKey: activity.activityId,
|
||||
fit: BoxFit.cover,
|
||||
)
|
||||
: CachedNetworkImage(
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ class _ActivitySuggestionDialogImage extends StatelessWidget {
|
|||
),
|
||||
width: width / 2,
|
||||
height: 200,
|
||||
cacheKey: activityController.updatedActivity.bookmarkId,
|
||||
cacheKey: activityController.updatedActivity.activityId,
|
||||
fit: BoxFit.cover,
|
||||
)
|
||||
: CachedNetworkImage(
|
||||
|
|
@ -624,7 +624,7 @@ class _ActivitySuggestionLaunchContent extends StatelessWidget {
|
|||
),
|
||||
width: 24.0,
|
||||
height: 24.0,
|
||||
cacheKey: activityController.updatedActivity.bookmarkId,
|
||||
cacheKey: activityController.updatedActivity.activityId,
|
||||
fit: BoxFit.cover,
|
||||
)
|
||||
: CachedNetworkImage(
|
||||
|
|
|
|||
|
|
@ -159,11 +159,13 @@ class ModelKey {
|
|||
// activity plan
|
||||
static const String activityPlanRequest = "req";
|
||||
static const String activityPlanTitle = "title";
|
||||
static const String activityPlanDescription = "description";
|
||||
static const String activityPlanLocation = "location";
|
||||
static const String activityPlanLearningObjective = "learning_objective";
|
||||
static const String activityPlanInstructions = "instructions";
|
||||
static const String activityPlanVocab = "vocab";
|
||||
static const String activityPlanImageURL = "image_url";
|
||||
static const String activityPlanBookmarkId = "activity_id";
|
||||
static const String activityId = "activity_id";
|
||||
static const String activityPlanEndAt = "end_at";
|
||||
static const String activityPlanDuration = "duration";
|
||||
static const String activityPlanTopicId = "topic_id";
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ class CourseChatsView extends StatelessWidget {
|
|||
for (final joinedRoom in joinedRooms) {
|
||||
if (joinedRoom.isActivitySession) {
|
||||
if (topic == null ||
|
||||
activityIds.contains(joinedRoom.activityPlan?.bookmarkId)) {
|
||||
activityIds.contains(joinedRoom.activityPlan?.activityId)) {
|
||||
joinedSessions.add(joinedRoom);
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class Topic {
|
|||
title: json['title'] as String,
|
||||
description: json['description'] as String,
|
||||
location: json['location'] as String? ?? "Unknown",
|
||||
uuid: json['uuid'] as String,
|
||||
uuid: json['id'] as String,
|
||||
activities: (json['activities'] as List<dynamic>?)
|
||||
?.map(
|
||||
(e) => ActivityPlanModel.fromJson(e as Map<String, dynamic>),
|
||||
|
|
@ -45,13 +45,13 @@ class Topic {
|
|||
'title': title,
|
||||
'description': description,
|
||||
'location': location,
|
||||
'uuid': uuid,
|
||||
'id': uuid,
|
||||
'activities': activities.map((e) => e.toJson()).toList(),
|
||||
'image_url': imageUrl,
|
||||
};
|
||||
}
|
||||
|
||||
List<String> get activityIds => activities.map((e) => e.bookmarkId).toList();
|
||||
List<String> get activityIds => activities.map((e) => e.activityId).toList();
|
||||
}
|
||||
|
||||
/// Represents a course plan in the course planner response.
|
||||
|
|
@ -99,7 +99,7 @@ class CoursePlanModel {
|
|||
String? topicID(String activityID) {
|
||||
for (final topic in topics) {
|
||||
for (final activity in topic.activities) {
|
||||
if (activity.bookmarkId == activityID) {
|
||||
if (activity.activityId == activityID) {
|
||||
return topic.uuid;
|
||||
}
|
||||
}
|
||||
|
|
@ -115,7 +115,7 @@ class CoursePlanModel {
|
|||
cefrLevel: LanguageLevelTypeEnumExtension.fromString(json['cefr_level']),
|
||||
title: json['title'] as String,
|
||||
description: json['description'] as String,
|
||||
uuid: json['uuid'] as String,
|
||||
uuid: json['id'] as String,
|
||||
topics: (json['topics'] as List<dynamic>?)
|
||||
?.map((e) => Topic.fromJson(e as Map<String, dynamic>))
|
||||
.toList() ??
|
||||
|
|
@ -132,7 +132,7 @@ class CoursePlanModel {
|
|||
'cefr_level': cefrLevel.string,
|
||||
'title': title,
|
||||
'description': description,
|
||||
'uuid': uuid,
|
||||
'id': uuid,
|
||||
'topics': topics.map((e) => e.toJson()).toList(),
|
||||
'image_url': imageUrl,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ extension CoursePlanRoomExtension on Room {
|
|||
}
|
||||
|
||||
final activityIds =
|
||||
course.topics[topicIndex].activities.map((a) => a.bookmarkId).toList();
|
||||
course.topics[topicIndex].activities.map((a) => a.activityId).toList();
|
||||
return state.completedActivities(topicID).toSet().containsAll(activityIds);
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue