From 027a1b7c411aac9b1dfa6a5e3569f6817a75f3d1 Mon Sep 17 00:00:00 2001 From: ggurdin <46800240+ggurdin@users.noreply.github.com> Date: Fri, 3 Oct 2025 11:22:12 -0400 Subject: [PATCH] fix: refresh expired course cache (#4240) --- lib/l10n/intl_en.arb | 1 + .../activity_feedback_response_dialog.dart | 4 ++ .../activity_sessions_start_view.dart | 5 +++ .../course_plans/course_activity_repo.dart | 45 +++++++++++++++++++ .../course_location_media_repo.dart | 4 ++ .../course_plans/course_location_repo.dart | 4 ++ .../course_plans/course_media_repo.dart | 4 ++ .../course_plans/course_plans_repo.dart | 43 ++++++++++++++++++ .../course_plans/course_topic_repo.dart | 4 ++ lib/pangea/guard/p_vguard.dart | 5 ++- 10 files changed, 117 insertions(+), 2 deletions(-) diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 77a0b19fa..76ea5c819 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -5293,6 +5293,7 @@ "directMessageBotTitle": "Direct message Pangea Bot", "feedbackTitle": "Activity Feedback", "feedbackDesc": "How should the activity be improved? If you can provide some details, we’ll make the change!", + "feedbackRespDesc": "Check back tomorrow for activity updates.", "feedbackHint": "Your feedback", "feedbackButton": "Submit feedback", "directMessageBotDesc": "Talking to humans is more fun but... AI is always ready!", diff --git a/lib/pangea/activity_sessions/activity_session_start/activity_feedback_response_dialog.dart b/lib/pangea/activity_sessions/activity_session_start/activity_feedback_response_dialog.dart index e1962e023..22a944f9d 100644 --- a/lib/pangea/activity_sessions/activity_session_start/activity_feedback_response_dialog.dart +++ b/lib/pangea/activity_sessions/activity_session_start/activity_feedback_response_dialog.dart @@ -65,6 +65,10 @@ class ActivityFeedbackResponseDialog extends StatelessWidget { feedback, textAlign: TextAlign.center, ), + Text( + L10n.of(context).feedbackRespDesc, + textAlign: TextAlign.center, + ), const SizedBox.shrink(), ], ), diff --git a/lib/pangea/activity_sessions/activity_session_start/activity_sessions_start_view.dart b/lib/pangea/activity_sessions/activity_session_start/activity_sessions_start_view.dart index 4c4674a5e..35defca6a 100644 --- a/lib/pangea/activity_sessions/activity_session_start/activity_sessions_start_view.dart +++ b/lib/pangea/activity_sessions/activity_session_start/activity_sessions_start_view.dart @@ -11,6 +11,7 @@ import 'package:fluffychat/pangea/activity_sessions/activity_session_start/activ 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/common/widgets/error_indicator.dart'; +import 'package:fluffychat/pangea/course_plans/course_activity_repo.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; import 'package:fluffychat/utils/stream_extension.dart'; import 'package:fluffychat/widgets/future_loading_dialog.dart'; @@ -91,6 +92,10 @@ class ActivitySessionStartView extends StatelessWidget { return; } + CourseActivityRepo.setSentFeedback( + controller.widget.activityId, + ); + await showDialog( context: context, builder: (context) { diff --git a/lib/pangea/course_plans/course_activity_repo.dart b/lib/pangea/course_plans/course_activity_repo.dart index 228c7d597..a4ca2e1b9 100644 --- a/lib/pangea/course_plans/course_activity_repo.dart +++ b/lib/pangea/course_plans/course_activity_repo.dart @@ -13,7 +13,48 @@ class CourseActivityRepo { static final Map>> _cache = {}; static final GetStorage _storage = GetStorage('course_activity_storage'); + static Map get sentFeedback { + final entry = _storage.read("sent_feedback"); + if (entry != null && entry is Map) { + try { + return Map.from( + entry.map((key, value) => MapEntry(key, DateTime.parse(value))), + ); + } catch (e) { + _storage.remove("sent_feedback"); + } + } + return {}; + } + + static Future setSentFeedback(String activityId) async { + final currentValue = sentFeedback; + currentValue[activityId] = DateTime.now(); + await _storage.write( + "sent_feedback", + currentValue.map((key, value) => MapEntry(key, value.toIso8601String())), + ); + } + + static Future _clearSentFeedback(String activityId) async { + final currentValue = sentFeedback; + currentValue.remove(activityId); + await _storage.write( + "sent_feedback", + currentValue.map((key, value) => MapEntry(key, value.toIso8601String())), + ); + } + static ActivityPlanModel? _getCached(String uuid) { + final sentActivityFeedback = sentFeedback[uuid]; + if (sentActivityFeedback != null && + DateTime.now().difference(sentActivityFeedback) > + const Duration(minutes: 15)) { + _storage.remove(uuid); + _clearSentFeedback(uuid); + return null; + } + final json = _storage.read>(uuid); if (json != null) { try { @@ -159,4 +200,8 @@ class CourseActivityRepo { }).whereType>(), ); } + + static Future clearCache() async { + await _storage.erase(); + } } diff --git a/lib/pangea/course_plans/course_location_media_repo.dart b/lib/pangea/course_plans/course_location_media_repo.dart index 19a1543bb..502e84d77 100644 --- a/lib/pangea/course_plans/course_location_media_repo.dart +++ b/lib/pangea/course_plans/course_location_media_repo.dart @@ -104,4 +104,8 @@ class CourseLocationMediaRepo { _cache.remove(topicId); } } + + static Future clearCache() async { + await _storage.erase(); + } } diff --git a/lib/pangea/course_plans/course_location_repo.dart b/lib/pangea/course_plans/course_location_repo.dart index 68353e76e..9497a1fcd 100644 --- a/lib/pangea/course_plans/course_location_repo.dart +++ b/lib/pangea/course_plans/course_location_repo.dart @@ -111,4 +111,8 @@ class CourseLocationRepo { _cache.remove(topicId); } } + + static Future clearCache() async { + await _storage.erase(); + } } diff --git a/lib/pangea/course_plans/course_media_repo.dart b/lib/pangea/course_plans/course_media_repo.dart index cef4f382a..64bc0631c 100644 --- a/lib/pangea/course_plans/course_media_repo.dart +++ b/lib/pangea/course_plans/course_media_repo.dart @@ -102,4 +102,8 @@ class CourseMediaRepo { _cache.remove(courseId); } } + + static Future clearCache() async { + await _storage.erase(); + } } diff --git a/lib/pangea/course_plans/course_plans_repo.dart b/lib/pangea/course_plans/course_plans_repo.dart index c90b42efb..f2bb44ef7 100644 --- a/lib/pangea/course_plans/course_plans_repo.dart +++ b/lib/pangea/course_plans/course_plans_repo.dart @@ -3,7 +3,12 @@ import 'dart:async'; import 'package:get_storage/get_storage.dart'; import 'package:fluffychat/pangea/common/config/environment.dart'; +import 'package:fluffychat/pangea/course_plans/course_activity_repo.dart'; +import 'package:fluffychat/pangea/course_plans/course_location_media_repo.dart'; +import 'package:fluffychat/pangea/course_plans/course_location_repo.dart'; +import 'package:fluffychat/pangea/course_plans/course_media_repo.dart'; import 'package:fluffychat/pangea/course_plans/course_plan_model.dart'; +import 'package:fluffychat/pangea/course_plans/course_topic_repo.dart'; import 'package:fluffychat/pangea/learning_settings/enums/language_level_type_enum.dart'; import 'package:fluffychat/pangea/learning_settings/models/language_model.dart'; import 'package:fluffychat/pangea/payload_client/models/course_plan/cms_course_plan.dart'; @@ -41,8 +46,27 @@ class CourseFilter { class CoursePlansRepo { static final Map> cache = {}; static final GetStorage _courseStorage = GetStorage("course_storage"); + static const Duration cacheDuration = Duration(days: 1); + + static DateTime? get lastUpdated { + final entry = _courseStorage.read("last_updated"); + if (entry != null && entry is String) { + try { + return DateTime.parse(entry); + } catch (e) { + _courseStorage.remove("last_updated"); + } + } + return null; + } static CoursePlanModel? _getCached(String id) { + if (lastUpdated != null && + DateTime.now().difference(lastUpdated!) > cacheDuration) { + clearCache(); + return null; + } + final json = _courseStorage.read(id); if (json != null) { try { @@ -55,6 +79,12 @@ class CoursePlansRepo { } static Future _setCached(CoursePlanModel coursePlan) async { + if (lastUpdated == null) { + await _courseStorage.write( + "last_updated", + DateTime.now().toIso8601String(), + ); + } await _courseStorage.write(coursePlan.uuid, coursePlan.toJson()); } @@ -206,4 +236,17 @@ class CoursePlansRepo { .whereType() .toList(); } + + static Future clearCache() async { + final List futures = [ + CourseActivityRepo.clearCache(), + CourseLocationMediaRepo.clearCache(), + CourseLocationRepo.clearCache(), + CourseMediaRepo.clearCache(), + CourseTopicRepo.clearCache(), + _courseStorage.erase(), + ]; + + await Future.wait(futures); + } } diff --git a/lib/pangea/course_plans/course_topic_repo.dart b/lib/pangea/course_plans/course_topic_repo.dart index e7c17a044..33f6aa92d 100644 --- a/lib/pangea/course_plans/course_topic_repo.dart +++ b/lib/pangea/course_plans/course_topic_repo.dart @@ -113,4 +113,8 @@ class CourseTopicRepo { _cache.remove(courseId); } } + + static Future clearCache() async { + await _storage.erase(); + } } diff --git a/lib/pangea/guard/p_vguard.dart b/lib/pangea/guard/p_vguard.dart index 9d1145439..28298ff95 100644 --- a/lib/pangea/guard/p_vguard.dart +++ b/lib/pangea/guard/p_vguard.dart @@ -1,11 +1,12 @@ import 'dart:async'; -import 'package:fluffychat/pangea/course_plans/course_plan_room_extension.dart'; -import 'package:fluffychat/widgets/matrix.dart'; import 'package:flutter/material.dart'; + import 'package:go_router/go_router.dart'; import 'package:matrix/matrix.dart'; +import 'package:fluffychat/pangea/course_plans/course_plan_room_extension.dart'; +import 'package:fluffychat/widgets/matrix.dart'; import '../common/controllers/pangea_controller.dart'; class PAuthGaurd {