import 'package:stacked/stacked.dart'; import 'package:yimaru_app/models/course_progress.dart'; import 'package:yimaru_app/models/module_progress.dart'; import 'package:yimaru_app/models/refresh_object.dart'; import 'package:yimaru_app/ui/common/enmus.dart'; import '../app/app.locator.dart'; import '../models/access.dart'; import '../models/learn_course.dart'; import '../models/learn_lesson.dart'; import '../models/learn_module.dart'; import '../models/learn_program.dart'; import '../models/progress_summary.dart'; import 'api_service.dart'; class LearnService with ListenableServiceMixin { // Dependency injection final _apiService = locator(); // Initialization learnService() { listenToReactiveValues( [_programs, _courses, _lessons, _modules, _totalCount]); } // Completed count int _completedCount = 0; int get completedCount => _completedCount; // Total count int _totalCount = 0; int get totalCount => _totalCount; // Total progress int _totalProgress = 0; int get totalProgress => _totalProgress; // Learn program List _programs = []; List get programs => _programs; // Learn course List _courses = []; List get courses => _courses; // Learn module List _modules = []; List get modules => _modules; // Learn lesson List _lessons = []; List get lessons => _lessons; // Learn programs Future refreshObject(String url) async { Map data = {'reference': url}; Map response = await _apiService.refreshObject(data); if (response['status'] == ResponseStatus.success) { RefreshObject object = response['data'] as RefreshObject; return object.url ?? ''; } return null; } // Learn programs Future getLearnPrograms() async { _programs = await _apiService.getLearnPrograms(); _programs.sort((a, b) => (a.sortOrder ?? 0).compareTo(b.sortOrder ?? 0)); notifyListeners(); } // Learn modules Future getLearnCourses(int id) async { _courses = await _apiService.getLearnCourses(id); _courses.sort((a, b) => (a.sortOrder ?? 0).compareTo(b.sortOrder ?? 0)); notifyListeners(); } // Learn modules Future getLearnModules(int id) async { _modules = await _apiService.getLearnModules(id); _modules.sort((a, b) => (a.sortOrder ?? 0).compareTo(b.sortOrder ?? 0)); notifyListeners(); } // Learn lessons Future getLearnLessons(int id) async { _lessons = await _apiService.getLearnLessons(id); _lessons.sort((a, b) => (a.sortOrder ?? 0).compareTo(b.sortOrder ?? 0)); notifyListeners(); } // Learn progress Future getLearnProgress() async { final summaries = await _apiService.getProgressSummary(); /// PROGRAM ACCESS MAP final Map programAccessMap = {}; /// COURSE ACCESS MAP final Map courseAccessMap = {}; /// MODULE ACCESS MAP final Map moduleAccessMap = {}; /// LESSON ACCESS MAP final Map lessonAccessMap = {}; // Build maps for (final summary in summaries) { if (summary.id != null) { programAccessMap[summary.id!] = summary.access; } for (final course in summary.courses ?? []) { if (course.id != null) { courseAccessMap[course.id!] = course.access; } for (final module in course.modules ?? []) { if (module.id != null) { moduleAccessMap[module.id!] = module.access; } for (final lesson in module.lessons ?? []) { if (lesson.id != null) { lessonAccessMap[lesson.id!] = lesson.access; } } } } } /// UPDATE PROGRAMS _programs = _programs.map((program) { return program.copyWith( access: programAccessMap[program.id] ?? program.access, ); }).toList(); /// UPDATE COURSES _courses = _courses.map((course) { return course.copyWith( access: courseAccessMap[course.id] ?? course.access, ); }).toList(); /// UPDATE MODULES _modules = _modules.map((module) { return module.copyWith( access: moduleAccessMap[module.id] ?? module.access, ); }).toList(); /// UPDATE LESSONS _lessons = _lessons.map((lesson) { return lesson.copyWith( access: lessonAccessMap[lesson.id] ?? lesson.access, ); }).toList(); notifyListeners(); } LearnModule? getLearnModuleById(int id) { try { return _modules.firstWhere((e) => e.id == id); } catch (_) { return null; } } LearnCourse? getLearnCourseById(int id) { try { return _courses.firstWhere((e) => e.id == id); } catch (_) { return null; } } Future getProgressSummary() async { final summaries = await _apiService.getProgressSummary(); for (final ProgressSummary summary in summaries) { _totalCount = _totalCount + (summary.access?.totalCount ?? 0); _completedCount = _completedCount + (summary.access?.completedCount ?? 0); for (final CourseProgress course in summary.courses ?? []) { _totalCount = _totalCount + (course.access?.totalCount ?? 0); _completedCount = _completedCount + (course.access?.completedCount ?? 0); for (final ModuleProgress module in course.modules ?? []) { _totalCount = _totalCount + (module.access?.totalCount ?? 0); _completedCount = _completedCount + (module.access?.completedCount ?? 0); } } } _totalProgress = summaries.fold( 0, (sum, progress) => sum + (progress.access?.progressPercent ?? 0)); notifyListeners(); } }