diff --git a/lib/pangea/course_plans/course_plan_model.dart b/lib/pangea/course_plans/course_plan_model.dart index fe7679843..330448643 100644 --- a/lib/pangea/course_plans/course_plan_model.dart +++ b/lib/pangea/course_plans/course_plan_model.dart @@ -11,6 +11,7 @@ import 'package:fluffychat/pangea/payload_client/models/course_plan/cms_course_p import 'package:fluffychat/pangea/payload_client/models/course_plan/cms_course_plan_media.dart'; import 'package:fluffychat/pangea/payload_client/models/course_plan/cms_course_plan_topic.dart'; import 'package:fluffychat/pangea/payload_client/models/course_plan/cms_course_plan_topic_location.dart'; +import 'package:fluffychat/pangea/payload_client/models/course_plan/cms_course_plan_topic_location_media.dart'; /// Represents a topic in the course planner response. class Topic { @@ -152,6 +153,7 @@ class CoursePlanModel { List? cmsCoursePlanMedias, List? cmsCoursePlanTopics, List? cmsCoursePlanTopicLocations, + List? cmsCoursePlanTopicLocationMedias, List? cmsCoursePlanActivities, List? cmsCoursePlanActivityMedias, ) { @@ -235,6 +237,17 @@ class CoursePlanModel { } } + List? topicLocationMedias; + if (cmsCoursePlanTopicLocationMedias != null) { + for (final media in cmsCoursePlanTopicLocationMedias) { + if (media.coursePlanTopicLocations.contains(topic.id)) { + topicLocationMedias ??= []; + topicLocationMedias.add(media); + } + } + } + // TODO: consume topicLocationMedias to form topic + topics ??= []; topics.add( Topic( diff --git a/lib/pangea/course_plans/course_plans_repo.dart b/lib/pangea/course_plans/course_plans_repo.dart index 5f31fd383..b1b4939c0 100644 --- a/lib/pangea/course_plans/course_plans_repo.dart +++ b/lib/pangea/course_plans/course_plans_repo.dart @@ -10,6 +10,7 @@ import 'package:fluffychat/pangea/payload_client/models/course_plan/cms_course_p import 'package:fluffychat/pangea/payload_client/models/course_plan/cms_course_plan_media.dart'; import 'package:fluffychat/pangea/payload_client/models/course_plan/cms_course_plan_topic.dart'; import 'package:fluffychat/pangea/payload_client/models/course_plan/cms_course_plan_topic_location.dart'; +import 'package:fluffychat/pangea/payload_client/models/course_plan/cms_course_plan_topic_location_media.dart'; import 'package:fluffychat/pangea/payload_client/payload_client.dart'; import 'package:fluffychat/widgets/matrix.dart'; @@ -199,6 +200,7 @@ class CoursePlansRepo { final medias = await _getMedia(cmsCoursePlan); final topics = await _getTopics(cmsCoursePlan); final locations = await _getTopicLocations(topics ?? []); + final locationMedias = await _getTopicLocationMedia(locations ?? []); final activities = await _getTopicActivities(topics ?? []); final activityMedias = await _getActivityMedia(activities ?? []); return CoursePlanModel.fromCmsDocs( @@ -206,6 +208,7 @@ class CoursePlansRepo { medias, topics, locations, + locationMedias, activities, activityMedias, ); @@ -279,6 +282,32 @@ class CoursePlansRepo { return cmsCoursePlanTopicLocationsResult.docs; } + static Future?> _getTopicLocationMedia( + List locations, + ) async { + final List mediaIds = []; + for (final loc in locations) { + if (loc.coursePlanTopicLocationMedia?.docs != null) { + mediaIds.addAll(loc.coursePlanTopicLocationMedia!.docs!); + } + } + if (mediaIds.isEmpty) return null; + + final where = { + "id": {"in": mediaIds.join(",")}, + }; + final limit = mediaIds.length; + final cmsCoursePlanTopicLocationMediasResult = await payload.find( + CmsCoursePlanTopicLocationMedia.slug, + CmsCoursePlanTopicLocationMedia.fromJson, + where: where, + limit: limit, + page: 1, + sort: "createdAt", + ); + return cmsCoursePlanTopicLocationMediasResult.docs; + } + static Future?> _getTopicActivities( List topics, ) async { diff --git a/lib/pangea/payload_client/models/course_plan/cms_course_plan_topic_location.dart b/lib/pangea/payload_client/models/course_plan/cms_course_plan_topic_location.dart index a4d92cd12..ab69a5988 100644 --- a/lib/pangea/payload_client/models/course_plan/cms_course_plan_topic_location.dart +++ b/lib/pangea/payload_client/models/course_plan/cms_course_plan_topic_location.dart @@ -1,3 +1,4 @@ +import 'package:fluffychat/pangea/payload_client/join_field.dart'; import 'package:fluffychat/pangea/payload_client/polymorphic_relationship.dart'; /// Represents a course plan topic location from the CMS API @@ -7,6 +8,7 @@ class CmsCoursePlanTopicLocation { final String name; // [longitude, latitude] - minItems: 2, maxItems: 2 final List? coordinates; + final JoinField? coursePlanTopicLocationMedia; final List coursePlanTopics; final PolymorphicRelationship? createdBy; final PolymorphicRelationship? updatedBy; @@ -17,6 +19,7 @@ class CmsCoursePlanTopicLocation { required this.id, required this.name, this.coordinates, + this.coursePlanTopicLocationMedia, required this.coursePlanTopics, this.createdBy, this.updatedBy, @@ -31,6 +34,9 @@ class CmsCoursePlanTopicLocation { coordinates: (json['coordinates'] as List?) ?.map((coord) => (coord as num).toDouble()) .toList(), + coursePlanTopicLocationMedia: json['coursePlanTopicLocationMedia'] != null + ? JoinField.fromJson(json['coursePlanTopicLocationMedia']) + : null, coursePlanTopics: List.from(json['coursePlanTopics']), createdBy: json['createdBy'] != null ? PolymorphicRelationship.fromJson(json['createdBy']) @@ -49,6 +55,7 @@ class CmsCoursePlanTopicLocation { 'name': name, 'coordinates': coordinates, 'coursePlanTopics': coursePlanTopics, + 'coursePlanTopicLocationMedia': coursePlanTopicLocationMedia?.toJson(), 'createdBy': createdBy?.toJson(), 'updatedBy': updatedBy?.toJson(), 'updatedAt': updatedAt, diff --git a/lib/pangea/payload_client/models/course_plan/cms_course_plan_topic_location_media.dart b/lib/pangea/payload_client/models/course_plan/cms_course_plan_topic_location_media.dart new file mode 100644 index 000000000..19064140d --- /dev/null +++ b/lib/pangea/payload_client/models/course_plan/cms_course_plan_topic_location_media.dart @@ -0,0 +1,92 @@ +import 'package:fluffychat/pangea/payload_client/polymorphic_relationship.dart'; + +/// Represents a course plan topic location from the CMS API +class CmsCoursePlanTopicLocationMedia { + static const String slug = "course-plan-topic-location-media"; + final String id; + final String? alt; + final List coursePlanTopicLocations; + final PolymorphicRelationship? createdBy; + final PolymorphicRelationship? updatedBy; + final String? prefix; + final String updatedAt; + final String createdAt; + final String? url; + final String? thumbnailURL; + final String? filename; + final String? mimeType; + final int? filesize; + final int? width; + final int? height; + final double? focalX; + final double? focalY; + + CmsCoursePlanTopicLocationMedia({ + required this.id, + this.alt, + required this.coursePlanTopicLocations, + this.createdBy, + this.updatedBy, + this.prefix, + required this.updatedAt, + required this.createdAt, + this.url, + this.thumbnailURL, + this.filename, + this.mimeType, + this.filesize, + this.width, + this.height, + this.focalX, + this.focalY, + }); + + factory CmsCoursePlanTopicLocationMedia.fromJson(Map json) { + return CmsCoursePlanTopicLocationMedia( + id: json['id'], + alt: json['alt'], + coursePlanTopicLocations: + List.from(json['coursePlanTopicLocations'] as List), + createdBy: json['createdBy'] != null + ? PolymorphicRelationship.fromJson(json['createdBy']) + : null, + updatedBy: json['updatedBy'] != null + ? PolymorphicRelationship.fromJson(json['updatedBy']) + : null, + prefix: json['prefix'], + updatedAt: json['updatedAt'], + createdAt: json['createdAt'], + url: json['url'], + thumbnailURL: json['thumbnailURL'], + filename: json['filename'], + mimeType: json['mimeType'], + filesize: json['filesize'], + width: json['width'], + height: json['height'], + focalX: json['focalX']?.toDouble(), + focalY: json['focalY']?.toDouble(), + ); + } + + Map toJson() { + return { + 'id': id, + 'alt': alt, + 'coursePlanTopicLocations': coursePlanTopicLocations, + 'createdBy': createdBy?.toJson(), + 'updatedBy': updatedBy?.toJson(), + 'prefix': prefix, + 'updatedAt': updatedAt, + 'createdAt': createdAt, + 'url': url, + 'thumbnailURL': thumbnailURL, + 'filename': filename, + 'mimeType': mimeType, + 'filesize': filesize, + 'width': width, + 'height': height, + 'focalX': focalX, + 'focalY': focalY, + }; + } +}