diff --git a/lib/app/app.dart b/lib/app/app.dart index 2c6972c..ff9e3fb 100644 --- a/lib/app/app.dart +++ b/lib/app/app.dart @@ -50,6 +50,7 @@ import 'package:yimaru_app/ui/views/course_subcategory/course_subcategory_view.d import 'package:yimaru_app/ui/views/course/course_view.dart'; import 'package:yimaru_app/services/audio_player_service.dart'; import 'package:yimaru_app/services/voice_recorder_service.dart'; +import 'package:yimaru_app/ui/views/course_practice_question/course_practice_question_view.dart'; // @stacked-import @StackedApp( @@ -88,6 +89,7 @@ import 'package:yimaru_app/services/voice_recorder_service.dart'; MaterialRoute(page: DuolingoView), MaterialRoute(page: CourseSubcategoryView), MaterialRoute(page: CourseView), + MaterialRoute(page: CoursePracticeQuestionView), // @stacked-route ], dependencies: [ diff --git a/lib/app/app.router.dart b/lib/app/app.router.dart index 3d47d9f..9198b1b 100644 --- a/lib/app/app.router.dart +++ b/lib/app/app.router.dart @@ -5,14 +5,14 @@ // ************************************************************************** // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'package:flutter/material.dart' as _i36; +import 'package:flutter/material.dart' as _i37; import 'package:flutter/material.dart'; import 'package:stacked/stacked.dart' as _i1; -import 'package:stacked_services/stacked_services.dart' as _i41; -import 'package:yimaru_app/models/course.dart' as _i37; -import 'package:yimaru_app/models/course_category.dart' as _i39; -import 'package:yimaru_app/models/course_lesson.dart' as _i38; -import 'package:yimaru_app/models/course_subcategory.dart' as _i40; +import 'package:stacked_services/stacked_services.dart' as _i42; +import 'package:yimaru_app/models/course.dart' as _i38; +import 'package:yimaru_app/models/course_category.dart' as _i40; +import 'package:yimaru_app/models/course_lesson.dart' as _i39; +import 'package:yimaru_app/models/course_subcategory.dart' as _i41; import 'package:yimaru_app/ui/views/account_privacy/account_privacy_view.dart' as _i9; import 'package:yimaru_app/ui/views/assessment/assessment_view.dart' as _i22; @@ -29,6 +29,8 @@ import 'package:yimaru_app/ui/views/course_payment/course_payment_view.dart' as _i28; import 'package:yimaru_app/ui/views/course_practice/course_practice_view.dart' as _i27; +import 'package:yimaru_app/ui/views/course_practice_question/course_practice_question_view.dart' + as _i36; import 'package:yimaru_app/ui/views/course_subcategory/course_subcategory_view.dart' as _i34; import 'package:yimaru_app/ui/views/downloads/downloads_view.dart' as _i7; @@ -134,6 +136,8 @@ class Routes { static const courseView = '/course-view'; + static const coursePracticeQuestionView = '/course-practice-question-view'; + static const all = { homeView, onboardingView, @@ -169,6 +173,7 @@ class Routes { duolingoView, courseSubcategoryView, courseView, + coursePracticeQuestionView, }; } @@ -310,17 +315,21 @@ class StackedRouter extends _i1.RouterBase { Routes.courseView, page: _i35.CourseView, ), + _i1.RouteDef( + Routes.coursePracticeQuestionView, + page: _i36.CoursePracticeQuestionView, + ), ]; final _pagesMap = { _i2.HomeView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i2.HomeView(), settings: data, ); }, _i3.OnboardingView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i3.OnboardingView(), settings: data, ); @@ -329,116 +338,116 @@ class StackedRouter extends _i1.RouterBase { final args = data.getArgs( orElse: () => const StartupViewArguments(), ); - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => _i4.StartupView(key: args.key, label: args.label), settings: data, ); }, _i5.ProfileView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i5.ProfileView(), settings: data, ); }, _i6.ProfileDetailView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i6.ProfileDetailView(), settings: data, ); }, _i7.DownloadsView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i7.DownloadsView(), settings: data, ); }, _i8.ProgressView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i8.ProgressView(), settings: data, ); }, _i9.AccountPrivacyView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i9.AccountPrivacyView(), settings: data, ); }, _i10.SupportView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i10.SupportView(), settings: data, ); }, _i11.TelegramSupportView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i11.TelegramSupportView(), settings: data, ); }, _i12.CallSupportView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i12.CallSupportView(), settings: data, ); }, _i13.LanguageView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i13.LanguageView(), settings: data, ); }, _i14.PrivacyPolicyView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i14.PrivacyPolicyView(), settings: data, ); }, _i15.TermsAndConditionsView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i15.TermsAndConditionsView(), settings: data, ); }, _i16.RegisterView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i16.RegisterView(), settings: data, ); }, _i17.LoginView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i17.LoginView(), settings: data, ); }, _i18.LearnView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i18.LearnView(), settings: data, ); }, _i19.LearnLevelView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i19.LearnLevelView(), settings: data, ); }, _i20.LearnModuleView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i20.LearnModuleView(), settings: data, ); }, _i21.WelcomeView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i21.WelcomeView(), settings: data, ); }, _i22.AssessmentView: (data) { final args = data.getArgs(nullOk: false); - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => _i22.AssessmentView(key: args.key, data: args.data), settings: data, @@ -446,7 +455,7 @@ class StackedRouter extends _i1.RouterBase { }, _i23.LearnLessonView: (data) { final args = data.getArgs(nullOk: false); - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => _i23.LearnLessonView( key: args.key, title: args.title, @@ -458,14 +467,14 @@ class StackedRouter extends _i1.RouterBase { ); }, _i24.ForgetPasswordView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i24.ForgetPasswordView(), settings: data, ); }, _i25.LearnLessonDetailView: (data) { final args = data.getArgs(nullOk: false); - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => _i25.LearnLessonDetailView( key: args.key, title: args.title, @@ -476,7 +485,7 @@ class StackedRouter extends _i1.RouterBase { }, _i26.LearnPracticeView: (data) { final args = data.getArgs(nullOk: false); - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => _i26.LearnPracticeView( key: args.key, title: args.title, @@ -488,7 +497,7 @@ class StackedRouter extends _i1.RouterBase { }, _i27.CoursePracticeView: (data) { final args = data.getArgs(nullOk: false); - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => _i27.CoursePracticeView(key: args.key, id: args.id), settings: data, @@ -496,21 +505,21 @@ class StackedRouter extends _i1.RouterBase { }, _i28.CoursePaymentView: (data) { final args = data.getArgs(nullOk: false); - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => _i28.CoursePaymentView(key: args.key, course: args.course), settings: data, ); }, _i29.CourseCategoryView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i29.CourseCategoryView(), settings: data, ); }, _i30.FailureView: (data) { final args = data.getArgs(nullOk: false); - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => _i30.FailureView(key: args.key, label: args.label), settings: data, @@ -518,7 +527,7 @@ class StackedRouter extends _i1.RouterBase { }, _i31.CourseLessonView: (data) { final args = data.getArgs(nullOk: false); - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => _i31.CourseLessonView(key: args.key, course: args.course), settings: data, @@ -526,21 +535,21 @@ class StackedRouter extends _i1.RouterBase { }, _i32.CourseLessonDetailView: (data) { final args = data.getArgs(nullOk: false); - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => _i32.CourseLessonDetailView(key: args.key, lesson: args.lesson), settings: data, ); }, _i33.DuolingoView: (data) { - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => const _i33.DuolingoView(), settings: data, ); }, _i34.CourseSubcategoryView: (data) { final args = data.getArgs(nullOk: false); - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => _i34.CourseSubcategoryView(key: args.key, category: args.category), settings: data, @@ -548,12 +557,21 @@ class StackedRouter extends _i1.RouterBase { }, _i35.CourseView: (data) { final args = data.getArgs(nullOk: false); - return _i36.MaterialPageRoute( + return _i37.MaterialPageRoute( builder: (context) => _i35.CourseView(key: args.key, subcategory: args.subcategory), settings: data, ); }, + _i36.CoursePracticeQuestionView: (data) { + final args = + data.getArgs(nullOk: false); + return _i37.MaterialPageRoute( + builder: (context) => + _i36.CoursePracticeQuestionView(key: args.key, id: args.id), + settings: data, + ); + }, }; @override @@ -569,7 +587,7 @@ class StartupViewArguments { this.label = 'Loading', }); - final _i36.Key? key; + final _i37.Key? key; final String label; @@ -596,7 +614,7 @@ class AssessmentViewArguments { required this.data, }); - final _i36.Key? key; + final _i37.Key? key; final Map data; @@ -627,7 +645,7 @@ class LearnLessonViewArguments { required this.description, }); - final _i36.Key? key; + final _i37.Key? key; final String title; @@ -674,7 +692,7 @@ class LearnLessonDetailViewArguments { required this.description, }); - final _i36.Key? key; + final _i37.Key? key; final String title; @@ -714,7 +732,7 @@ class LearnPracticeViewArguments { required this.buttonLabel, }); - final _i36.Key? key; + final _i37.Key? key; final String title; @@ -755,7 +773,7 @@ class CoursePracticeViewArguments { required this.id, }); - final _i36.Key? key; + final _i37.Key? key; final int id; @@ -782,9 +800,9 @@ class CoursePaymentViewArguments { required this.course, }); - final _i36.Key? key; + final _i37.Key? key; - final _i37.Course course; + final _i38.Course course; @override String toString() { @@ -809,7 +827,7 @@ class FailureViewArguments { required this.label, }); - final _i36.Key? key; + final _i37.Key? key; final String label; @@ -836,9 +854,9 @@ class CourseLessonViewArguments { required this.course, }); - final _i36.Key? key; + final _i37.Key? key; - final _i37.Course course; + final _i38.Course course; @override String toString() { @@ -863,9 +881,9 @@ class CourseLessonDetailViewArguments { required this.lesson, }); - final _i36.Key? key; + final _i37.Key? key; - final _i38.CourseLesson lesson; + final _i39.CourseLesson lesson; @override String toString() { @@ -890,9 +908,9 @@ class CourseSubcategoryViewArguments { required this.category, }); - final _i36.Key? key; + final _i37.Key? key; - final _i39.CourseCategory category; + final _i40.CourseCategory category; @override String toString() { @@ -917,9 +935,9 @@ class CourseViewArguments { required this.subcategory, }); - final _i36.Key? key; + final _i37.Key? key; - final _i40.CourseSubcategory subcategory; + final _i41.CourseSubcategory subcategory; @override String toString() { @@ -938,7 +956,34 @@ class CourseViewArguments { } } -extension NavigatorStateExtension on _i41.NavigationService { +class CoursePracticeQuestionViewArguments { + const CoursePracticeQuestionViewArguments({ + this.key, + required this.id, + }); + + final _i37.Key? key; + + final int id; + + @override + String toString() { + return '{"key": "$key", "id": "$id"}'; + } + + @override + bool operator ==(covariant CoursePracticeQuestionViewArguments other) { + if (identical(this, other)) return true; + return other.key == key && other.id == id; + } + + @override + int get hashCode { + return key.hashCode ^ id.hashCode; + } +} + +extension NavigatorStateExtension on _i42.NavigationService { Future navigateToHomeView([ int? routerId, bool preventDuplicates = true, @@ -968,7 +1013,7 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future navigateToStartupView({ - _i36.Key? key, + _i37.Key? key, String label = 'Loading', int? routerId, bool preventDuplicates = true, @@ -1223,7 +1268,7 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future navigateToAssessmentView({ - _i36.Key? key, + _i37.Key? key, required Map data, int? routerId, bool preventDuplicates = true, @@ -1240,7 +1285,7 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future navigateToLearnLessonView({ - _i36.Key? key, + _i37.Key? key, required String title, required String topics, required String subtitle, @@ -1281,7 +1326,7 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future navigateToLearnLessonDetailView({ - _i36.Key? key, + _i37.Key? key, required String title, required List> practices, required String description, @@ -1304,7 +1349,7 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future navigateToLearnPracticeView({ - _i36.Key? key, + _i37.Key? key, required String title, required String subtitle, required List> practices, @@ -1329,7 +1374,7 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future navigateToCoursePracticeView({ - _i36.Key? key, + _i37.Key? key, required int id, int? routerId, bool preventDuplicates = true, @@ -1346,8 +1391,8 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future navigateToCoursePaymentView({ - _i36.Key? key, - required _i37.Course course, + _i37.Key? key, + required _i38.Course course, int? routerId, bool preventDuplicates = true, Map? parameters, @@ -1377,7 +1422,7 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future navigateToFailureView({ - _i36.Key? key, + _i37.Key? key, required String label, int? routerId, bool preventDuplicates = true, @@ -1394,8 +1439,8 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future navigateToCourseLessonView({ - _i36.Key? key, - required _i37.Course course, + _i37.Key? key, + required _i38.Course course, int? routerId, bool preventDuplicates = true, Map? parameters, @@ -1411,8 +1456,8 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future navigateToCourseLessonDetailView({ - _i36.Key? key, - required _i38.CourseLesson lesson, + _i37.Key? key, + required _i39.CourseLesson lesson, int? routerId, bool preventDuplicates = true, Map? parameters, @@ -1442,8 +1487,8 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future navigateToCourseSubcategoryView({ - _i36.Key? key, - required _i39.CourseCategory category, + _i37.Key? key, + required _i40.CourseCategory category, int? routerId, bool preventDuplicates = true, Map? parameters, @@ -1459,8 +1504,8 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future navigateToCourseView({ - _i36.Key? key, - required _i40.CourseSubcategory subcategory, + _i37.Key? key, + required _i41.CourseSubcategory subcategory, int? routerId, bool preventDuplicates = true, Map? parameters, @@ -1475,6 +1520,23 @@ extension NavigatorStateExtension on _i41.NavigationService { transition: transition); } + Future navigateToCoursePracticeQuestionView({ + _i37.Key? key, + required int id, + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + }) async { + return navigateTo(Routes.coursePracticeQuestionView, + arguments: CoursePracticeQuestionViewArguments(key: key, id: id), + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + Future replaceWithHomeView([ int? routerId, bool preventDuplicates = true, @@ -1504,7 +1566,7 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future replaceWithStartupView({ - _i36.Key? key, + _i37.Key? key, String label = 'Loading', int? routerId, bool preventDuplicates = true, @@ -1759,7 +1821,7 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future replaceWithAssessmentView({ - _i36.Key? key, + _i37.Key? key, required Map data, int? routerId, bool preventDuplicates = true, @@ -1776,7 +1838,7 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future replaceWithLearnLessonView({ - _i36.Key? key, + _i37.Key? key, required String title, required String topics, required String subtitle, @@ -1817,7 +1879,7 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future replaceWithLearnLessonDetailView({ - _i36.Key? key, + _i37.Key? key, required String title, required List> practices, required String description, @@ -1840,7 +1902,7 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future replaceWithLearnPracticeView({ - _i36.Key? key, + _i37.Key? key, required String title, required String subtitle, required List> practices, @@ -1865,7 +1927,7 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future replaceWithCoursePracticeView({ - _i36.Key? key, + _i37.Key? key, required int id, int? routerId, bool preventDuplicates = true, @@ -1882,8 +1944,8 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future replaceWithCoursePaymentView({ - _i36.Key? key, - required _i37.Course course, + _i37.Key? key, + required _i38.Course course, int? routerId, bool preventDuplicates = true, Map? parameters, @@ -1913,7 +1975,7 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future replaceWithFailureView({ - _i36.Key? key, + _i37.Key? key, required String label, int? routerId, bool preventDuplicates = true, @@ -1930,8 +1992,8 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future replaceWithCourseLessonView({ - _i36.Key? key, - required _i37.Course course, + _i37.Key? key, + required _i38.Course course, int? routerId, bool preventDuplicates = true, Map? parameters, @@ -1947,8 +2009,8 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future replaceWithCourseLessonDetailView({ - _i36.Key? key, - required _i38.CourseLesson lesson, + _i37.Key? key, + required _i39.CourseLesson lesson, int? routerId, bool preventDuplicates = true, Map? parameters, @@ -1978,8 +2040,8 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future replaceWithCourseSubcategoryView({ - _i36.Key? key, - required _i39.CourseCategory category, + _i37.Key? key, + required _i40.CourseCategory category, int? routerId, bool preventDuplicates = true, Map? parameters, @@ -1995,8 +2057,8 @@ extension NavigatorStateExtension on _i41.NavigationService { } Future replaceWithCourseView({ - _i36.Key? key, - required _i40.CourseSubcategory subcategory, + _i37.Key? key, + required _i41.CourseSubcategory subcategory, int? routerId, bool preventDuplicates = true, Map? parameters, @@ -2010,4 +2072,21 @@ extension NavigatorStateExtension on _i41.NavigationService { parameters: parameters, transition: transition); } + + Future replaceWithCoursePracticeQuestionView({ + _i37.Key? key, + required int id, + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + }) async { + return replaceWith(Routes.coursePracticeQuestionView, + arguments: CoursePracticeQuestionViewArguments(key: key, id: id), + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } } diff --git a/lib/models/course_lesson.dart b/lib/models/course_lesson.dart index b02703f..6c9116b 100644 --- a/lib/models/course_lesson.dart +++ b/lib/models/course_lesson.dart @@ -23,15 +23,15 @@ class CourseLesson { @JsonKey(name: 'video_url') String? videoUrl; + @JsonKey(name: 'vimeo_status') + String? vimeoStatus; + @JsonKey(name: 'instructor_id') int? instructorId; @JsonKey(name: 'sub_course_id') int? courseId; - @JsonKey(name: 'vimeo_status') - String? vimeoStatus; - @JsonKey(name: 'display_order') int? displayOrder; diff --git a/lib/models/option.dart b/lib/models/option.dart index 3930388..4786b34 100644 --- a/lib/models/option.dart +++ b/lib/models/option.dart @@ -5,12 +5,12 @@ part 'option.g.dart'; class Option { final int? id; - @JsonKey(name: 'option_text') - final String? optionText; - @JsonKey(name: 'is_correct') final bool? isCorrect; + @JsonKey(name: 'option_text') + final String? optionText; + const Option({this.id, this.optionText, this.isCorrect}); factory Option.fromJson(Map json) => _$OptionFromJson(json); diff --git a/lib/models/assessment.dart b/lib/models/question.dart similarity index 72% rename from lib/models/assessment.dart rename to lib/models/question.dart index 082ce80..3803fe2 100644 --- a/lib/models/assessment.dart +++ b/lib/models/question.dart @@ -1,9 +1,9 @@ import 'package:json_annotation/json_annotation.dart'; import 'package:yimaru_app/models/option.dart'; -part 'assessment.g.dart'; +part 'question.g.dart'; @JsonSerializable() -class Assessment { +class Question { final int? id; final int? points; @@ -21,7 +21,7 @@ class Assessment { @JsonKey(name: 'difficulty_level') final String? difficultyLevel; - const Assessment({ + const Question({ this.id, this.points, this.status, @@ -31,8 +31,8 @@ class Assessment { this.difficultyLevel, }); - factory Assessment.fromJson(Map json) => - _$AssessmentFromJson(json); + factory Question.fromJson(Map json) => + _$QuestionFromJson(json); - Map toJson() => _$AssessmentToJson(this); + Map toJson() => _$QuestionToJson(this); } diff --git a/lib/models/assessment.g.dart b/lib/models/question.g.dart similarity index 83% rename from lib/models/assessment.g.dart rename to lib/models/question.g.dart index a58d216..6e1a743 100644 --- a/lib/models/assessment.g.dart +++ b/lib/models/question.g.dart @@ -1,12 +1,12 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'assessment.dart'; +part of 'question.dart'; // ************************************************************************** // JsonSerializableGenerator // ************************************************************************** -Assessment _$AssessmentFromJson(Map json) => Assessment( +Question _$QuestionFromJson(Map json) => Question( id: (json['id'] as num?)?.toInt(), points: (json['points'] as num?)?.toInt(), status: json['status'] as String?, @@ -18,8 +18,7 @@ Assessment _$AssessmentFromJson(Map json) => Assessment( difficultyLevel: json['difficulty_level'] as String?, ); -Map _$AssessmentToJson(Assessment instance) => - { +Map _$QuestionToJson(Question instance) => { 'id': instance.id, 'points': instance.points, 'status': instance.status, diff --git a/lib/services/api_service.dart b/lib/services/api_service.dart index d92611b..2bc3727 100644 --- a/lib/services/api_service.dart +++ b/lib/services/api_service.dart @@ -1,5 +1,5 @@ import 'package:dio/dio.dart'; -import 'package:yimaru_app/models/assessment.dart'; +import 'package:yimaru_app/models/question.dart'; import 'package:yimaru_app/models/course_subcategory.dart'; import 'package:yimaru_app/models/course_category.dart'; import 'package:yimaru_app/models/course_lesson.dart'; @@ -18,7 +18,7 @@ class ApiService { // Dependency injection final _service = locator(); - // Register + // Register with email Future> registerWithEmail( Map data) async { try { @@ -46,7 +46,7 @@ class ApiService { } } - // Email login + // Login Future> login(Map data) async { try { Response response = await _service.dio.post( @@ -74,7 +74,7 @@ class ApiService { } } - // Google login + // Google auth Future> googleAuth(Map data) async { try { Response response = await _service.dio.post( @@ -211,7 +211,7 @@ class ApiService { } } - // Profile completed + // GEt profile completion status Future> getProfileStatus(UserModel? user) async { try { Response response = await _service.dio.get( @@ -238,7 +238,7 @@ class ApiService { } } - // Get profile + // Get profile data Future> getProfileData(int? userId) async { try { Response response = await _service.dio.get( @@ -345,10 +345,10 @@ class ApiService { } } - // Assessments - Future> getAssessments() async { + // Get assessments + Future> getAssessments() async { try { - List assessments = []; + List assessments = []; final Response response = await _service.dio.get('$kBaseUrl/$kAssessmentsUrl'); @@ -358,7 +358,7 @@ class ApiService { var decodedData = data['data'] as List; assessments = decodedData.map( (e) { - return Assessment.fromJson(e); + return Question.fromJson(e); }, ).toList(); return assessments; @@ -369,7 +369,7 @@ class ApiService { } } - // Course categories + // Get course categories Future> getCourseCategories() async { try { List categories = []; @@ -393,7 +393,7 @@ class ApiService { } } - // Course subcategory + // Get course subcategory Future> getCourseSubcategories(int id) async { try { List subcategories = []; @@ -417,7 +417,7 @@ class ApiService { } } - // Sub-courses + // Get courses Future> getCourses(int id) async { try { List courses = []; @@ -441,7 +441,7 @@ class ApiService { } } - // Course progress + // Get course progress Future> getCourseProgress(int id) async { try { List courseProgress = []; @@ -465,7 +465,7 @@ class ApiService { } } - // Course videos + // Get course lessons Future> getCourseLessons(int id) async { try { List courseLessons = []; @@ -513,12 +513,12 @@ class ApiService { } // Course practices - Future> getCoursePractices(Map data) async { + Future> getCoursePractices(int id) async { try { List coursePractices = []; - final Response response = await _service.dio - .get('$kBaseUrl/$kPracticeBaseUrl/$kCoursePractice', data: data); + final Response response = await _service.dio.get( + '$kBaseUrl/$kPracticeBaseUrl/$kCoursePractice?owner_type=SUB_COURSE&owner_id=$id'); if (response.statusCode == 200) { var data = response.data; @@ -536,7 +536,7 @@ class ApiService { } } - // Course practic questions + // Get course practic questions Future> getCoursePracticeQuestions(int id) async { try { List coursePracticeQuestions = []; @@ -559,4 +559,21 @@ class ApiService { return []; } } + + // Get course practice question + Future getCoursePracticeQuestion(int id) async { + try { + final Response response = + await _service.dio.get('$kBaseUrl/$kCoursePracticeQuestion/$id'); + + if (response.statusCode == 200) { + Question question = Question.fromJson(response.data['data']); + + return question; + } + return null; + } catch (e) { + return null; + } + } } diff --git a/lib/services/audio_player_service.dart b/lib/services/audio_player_service.dart index 7fbde1c..b290236 100644 --- a/lib/services/audio_player_service.dart +++ b/lib/services/audio_player_service.dart @@ -4,6 +4,7 @@ import 'package:stacked/stacked.dart'; import '../ui/common/helper_functions.dart'; class AudioPlayerService with ListenableServiceMixin { + // Player initialization final AudioPlayer _player = AudioPlayer(); AudioPlayer get player => _player; @@ -30,8 +31,6 @@ class AudioPlayerService with ListenableServiceMixin { } Future playLocal(String url) async { - - await _player.play(UrlSource(url)); } diff --git a/lib/services/authentication_service.dart b/lib/services/authentication_service.dart index d8e45c6..92f2868 100644 --- a/lib/services/authentication_service.dart +++ b/lib/services/authentication_service.dart @@ -67,25 +67,11 @@ class AuthenticationService with ListenableServiceMixin { profileCompleted: await _secureService.getBool('profileCompleted'), ); - /* UserModel( - email: _user?.email, - gender: _user?.gender, - region: _user?.region, - userId: _user?.userId, - country: _user?.country, - lastName: _user?.lastName, - birthday: _user?.birthday, - firstName: _user?.firstName, - occupation: _user?.occupation, - accessToken: _user?.accessToken, - refreshToken: _user?.refreshToken, - profilePicture: _user?.profilePicture, - userInfoLoaded: _user?.userInfoLoaded ?? false, - profileCompleted: await _secureService.getBool('profileCompleted')); - */ + notifyListeners(); } + // Save profile picture Future saveProfilePicture(String image) async { await _secureService.setString('profilePicture', image); _user = _user?.copyWith( @@ -93,26 +79,10 @@ class AuthenticationService with ListenableServiceMixin { profilePicture: await _secureService.getString('profilePicture'), ); - /*UserModel( - email: _user?.email, - gender: _user?.gender, - region: _user?.region, - userId: _user?.userId, - country: _user?.country, - lastName: _user?.lastName, - birthday: _user?.birthday, - firstName: _user?.firstName, - occupation: _user?.occupation, - accessToken: _user?.accessToken, - refreshToken: _user?.refreshToken, - profileCompleted: _user?.profileCompleted, - userInfoLoaded: _user?.userInfoLoaded ?? false, - profilePicture: await _secureService.getString('profilePicture'), - ); -*/ notifyListeners(); } + // Save user data Future saveUserData(UserModel data) async { await _secureService.setBool('userInfoLoaded', true); await _secureService.setBool( @@ -145,6 +115,7 @@ class AuthenticationService with ListenableServiceMixin { notifyListeners(); } + // Update user data Future updateUserData(Map data) async { await _secureService.setString('region', data['region']); await _secureService.setString('gender', data['gender']); @@ -164,31 +135,19 @@ class AuthenticationService with ListenableServiceMixin { occupation: await _secureService.getString('occupation'), ); - /*UserModel( - email: _user?.email, - userId: _user?.userId, - accessToken: _user?.accessToken, - refreshToken: _user?.refreshToken, - profilePicture: _user?.profilePicture, - profileCompleted: _user?.profileCompleted, - region: await _secureService.getString('region'), - gender: await _secureService.getString('gender'), - country: await _secureService.getString('country'), - lastName: await _secureService.getString('lastName'), - birthday: await _secureService.getString('birthday'), - firstName: await _secureService.getString('firstName'), - occupation: await _secureService.getString('occupation'), - );*/ notifyListeners(); } + // Check first time install Future isFirstTimeInstall() async => await _secureService.getBool('firstTimeInstall') ?? true; + // Set first time install Future setFirstTimeInstall(bool value) async { await _secureService.setBool('firstTimeInstall', value); } + // Get user data Future getUser() async { _user = UserModel( userId: await _secureService.getInt('userId'), @@ -209,6 +168,7 @@ class AuthenticationService with ListenableServiceMixin { return _user; } + // Logout Future logout() async { bool firstTimeInstall = await isFirstTimeInstall(); _user = null; diff --git a/lib/services/course_service.dart b/lib/services/course_service.dart index fbe45d2..d3474bb 100644 --- a/lib/services/course_service.dart +++ b/lib/services/course_service.dart @@ -5,8 +5,10 @@ import 'package:yimaru_app/services/api_service.dart'; import '../models/course_detail.dart'; class CourseService { + // Dependency injection final _apiService = locator(); + // Get course detail Future> getCoursesDetail(int id) async { final courses = await _apiService.getCourses(id); final progress = await _apiService.getCourseProgress(id); diff --git a/lib/services/smart_auth_service.dart b/lib/services/smart_auth_service.dart index 214020b..623ca18 100644 --- a/lib/services/smart_auth_service.dart +++ b/lib/services/smart_auth_service.dart @@ -2,11 +2,14 @@ import 'package:pinput/pinput.dart'; import 'package:smart_auth/smart_auth.dart'; class SmartAuthService implements SmsRetriever { + // Instance initialization final SmartAuth _smartAuth = SmartAuth.instance; + // Dispose listener @override Future dispose() => _smartAuth.removeUserConsentApiListener(); + // Get sms code @override Future getSmsCode() async { final res = await _smartAuth.getSmsWithUserConsentApi(); @@ -21,6 +24,7 @@ class SmartAuthService implements SmsRetriever { } } + // Listen multiple sms @override bool get listenForMultipleSms => true; } diff --git a/lib/services/voice_recorder_service.dart b/lib/services/voice_recorder_service.dart index 68664ee..56218a1 100644 --- a/lib/services/voice_recorder_service.dart +++ b/lib/services/voice_recorder_service.dart @@ -3,29 +3,32 @@ import 'package:waveform_recorder/waveform_recorder.dart'; import 'package:yimaru_app/ui/common/enmus.dart'; class VoiceRecorderService with ListenableServiceMixin { + // Recording states VoiceRecordingState _recordingState = VoiceRecordingState.pending; VoiceRecordingState get recordingState => _recordingState; + // Voice recorder controller final WaveformRecorderController _waveController = WaveformRecorderController(); WaveformRecorderController get waveController => _waveController; - + // Start voice recording Future startRecording() async { - await _waveController.startRecording(); _recordingState = VoiceRecordingState.recording; notifyListeners(); } + // Stop voice recording Future stopRecording() async { await _waveController.stopRecording(); _recordingState = VoiceRecordingState.pending; notifyListeners(); } + // Get recorded audio Future getRecordedAudio() async { final file = _waveController.file; print('RECORDED $file'); diff --git a/lib/ui/common/app_constants.dart b/lib/ui/common/app_constants.dart index 768cdf1..fa0a855 100644 --- a/lib/ui/common/app_constants.dart +++ b/lib/ui/common/app_constants.dart @@ -1,5 +1,4 @@ String kBaseUrl = 'https://api.yimaruacademy.com'; -//String baseUrl = 'https://api.yimaru.yaltopia.com'; String kCoursesUrl = 'courses'; @@ -41,6 +40,8 @@ String kProfileStatusUrl = 'is-profile-completed'; String kCourseBaseUrl = 'api/v1/course-management'; +String kCoursePracticeQuestion = 'api/v1/questions'; + String kLessonProgressUrl = 'api/v1/progress/videos'; String kGoogleAuthUrl = 'api/v1/auth/google/android'; diff --git a/lib/ui/common/app_strings.dart b/lib/ui/common/app_strings.dart index e8e8f31..1cde717 100644 --- a/lib/ui/common/app_strings.dart +++ b/lib/ui/common/app_strings.dart @@ -3,14 +3,16 @@ const String ksHomeBottomSheetTitle = 'Build Great Apps!'; const String ksSuggestion = "15 minutes a day can make you 3x more fluent in 3 month"; +const String ksCategorySubtitle = + 'Watch expert-led videos and reinforce your knowledge through guided practice activities.'; + const String ksHomeBottomSheetDescription = 'Stacked is built to help you build better apps. Give us a chance and we\'ll prove it to you. Check out stacked.filledstacks.com to learn more'; const String ksPrivacyPolicy = 'A brief, simple overview of Yimaru’s commitment to user privacy. Our goal is to be transparent about the data we collect and how we use it to enhance your learning experience.'; -const String ksCategorySubtitle = - 'Watch expert-led videos and reinforce your knowledge through guided practice activities.'; + const String ksTerms = """

diff --git a/lib/ui/common/enmus.dart b/lib/ui/common/enmus.dart index 57f9cf4..ddf461d 100644 --- a/lib/ui/common/enmus.dart +++ b/lib/ui/common/enmus.dart @@ -1,9 +1,9 @@ -// Login method -enum LoginMethod { phone, email, google } - // Response status enum ResponseStatus { success, failure } +// Login method +enum LoginMethod { phone, email, google } + // Sign-up method enum SignUpMethod { phone, email, google } @@ -45,6 +45,7 @@ enum StateObjects { learnPracticeAnswer, loginWithPhoneNumber, learnPracticeQuestion, + coursePracticeQuestion, + coursePracticeQuestions, recordLearnPracticeAnswer, - } diff --git a/lib/ui/common/helper_functions.dart b/lib/ui/common/helper_functions.dart index 3cb9782..a58b7da 100644 --- a/lib/ui/common/helper_functions.dart +++ b/lib/ui/common/helper_functions.dart @@ -1,9 +1,8 @@ -// Split full name import 'dart:math'; import 'dart:ui'; import 'app_colors.dart'; - +// Split full name Map splitFullName(String fullName) { final parts = fullName.trim().split(RegExp(r'\s+')); @@ -22,6 +21,7 @@ Map splitFullName(String fullName) { }; } +// Get random color Color getColor() { final generator = Random(); int random = generator.nextInt(8); @@ -44,6 +44,7 @@ Color getColor() { } } +// Get playable url String? getPlayableUrl(String url) { try { // Case 1: /file/d/FILE_ID/view diff --git a/lib/ui/common/validators/form_validator.dart b/lib/ui/common/validators/form_validator.dart index f83a814..58148f1 100644 --- a/lib/ui/common/validators/form_validator.dart +++ b/lib/ui/common/validators/form_validator.dart @@ -14,7 +14,7 @@ class FormValidator { return null; } - // Form validator + // Full name validator static String? validateFullNameForm(String? value) { if (value == null) { return null; diff --git a/lib/ui/views/assessment/assessment_view.dart b/lib/ui/views/assessment/assessment_view.dart index 0a9d926..f07a4c9 100644 --- a/lib/ui/views/assessment/assessment_view.dart +++ b/lib/ui/views/assessment/assessment_view.dart @@ -45,12 +45,6 @@ class AssessmentView extends StackedView { List _buildScreens() => [ _buildAssessmentIntro(), _buildAssessment(), - /* - _buildAssessmentFailure(), - _buildRetakeAssessment(), - _buildResultAnalysis(), - _buildAssessmentCompletion(), - */ _buildAssessmentResult(), _buildStartLesson(), ]; diff --git a/lib/ui/views/assessment/assessment_viewmodel.dart b/lib/ui/views/assessment/assessment_viewmodel.dart index 79b988e..bfdbcb8 100644 --- a/lib/ui/views/assessment/assessment_viewmodel.dart +++ b/lib/ui/views/assessment/assessment_viewmodel.dart @@ -7,7 +7,7 @@ import 'package:yimaru_app/ui/common/enmus.dart'; import '../../../app/app.locator.dart'; import '../../../app/app.router.dart'; -import '../../../models/assessment.dart'; +import '../../../models/question.dart'; import '../../../services/api_service.dart'; import '../../common/app_colors.dart'; import '../../common/ui_helpers.dart'; @@ -24,14 +24,14 @@ class AssessmentViewModel extends BaseViewModel { int get currentPage => _currentPage; - final PageController _pageController = PageController(); - - PageController get pageController => _pageController; - int _previousPage = 0; int get previousPage => _previousPage; + final PageController _pageController = PageController(); + + PageController get pageController => _pageController; + // Assessment int _currentQuestion = 0; @@ -41,9 +41,9 @@ class AssessmentViewModel extends BaseViewModel { ProficiencyLevels get proficiencyLevel => _proficiencyLevel; - List _assessments = []; + List _assessments = []; - List get assessments => _assessments; + List get assessments => _assessments; final Map _selectedAnswers = {}; @@ -251,13 +251,6 @@ class AssessmentViewModel extends BaseViewModel { Future _getAssessments() async { if (await _statusChecker.checkConnection()) { _assessments = await _apiService.getAssessments(); - /* - for (int i = 0; i < 6; i++) { - final generator = Random(); - int random = generator.nextInt(15); - response.add(response[random]); - } - */ } } diff --git a/lib/ui/views/course/course_viewmodel.dart b/lib/ui/views/course/course_viewmodel.dart index cb268d2..44a27cf 100644 --- a/lib/ui/views/course/course_viewmodel.dart +++ b/lib/ui/views/course/course_viewmodel.dart @@ -44,7 +44,6 @@ class CourseViewModel extends BaseViewModel { _courseDetail = await _courseService.getCoursesDetail(id); _courseDetail.sort((a, b) => (a.course?.displayOrder ?? 0).compareTo(b.course?.displayOrder ?? 0)); - rebuildUi(); } } } diff --git a/lib/ui/views/course_category/course_category_viewmodel.dart b/lib/ui/views/course_category/course_category_viewmodel.dart index 6cc881e..8cfb712 100644 --- a/lib/ui/views/course_category/course_category_viewmodel.dart +++ b/lib/ui/views/course_category/course_category_viewmodel.dart @@ -50,7 +50,6 @@ class CourseCategoryViewModel extends ReactiveViewModel { if (await _statusChecker.checkConnection()) { _categories = await _apiService.getCourseCategories(); - rebuildUi(); } } } diff --git a/lib/ui/views/course_lesson/course_lesson_viewmodel.dart b/lib/ui/views/course_lesson/course_lesson_viewmodel.dart index 5858342..44c9c73 100644 --- a/lib/ui/views/course_lesson/course_lesson_viewmodel.dart +++ b/lib/ui/views/course_lesson/course_lesson_viewmodel.dart @@ -40,10 +40,6 @@ class CourseLessonViewModel extends BaseViewModel { Future _getCourseLessons(int courseId) async { if (await _statusChecker.checkConnection()) { _courseLessons = await _apiService.getCourseLessons(1); - - if (_courseLessons.isNotEmpty) { - rebuildUi(); - } } } } diff --git a/lib/ui/views/course_practice/course_practice_view.dart b/lib/ui/views/course_practice/course_practice_view.dart index f42545e..c8635d5 100644 --- a/lib/ui/views/course_practice/course_practice_view.dart +++ b/lib/ui/views/course_practice/course_practice_view.dart @@ -92,19 +92,25 @@ class CoursePracticeView extends StackedView { ); Widget _buildListView(CoursePracticeViewModel viewModel) => GridView.builder( - itemCount: 6, shrinkWrap: true, + itemCount: viewModel.coursePractices.length, physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) => - _buildCard(title: viewModel.coursePractices[index].title ?? ''), + itemBuilder: (context, index) => _buildCard( + title: viewModel.coursePractices[index].title ?? '', + onTap: () async => + await viewModel.navigateToCoursePracticeQuestion(viewModel.coursePractices[index].id ?? 0), + ), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, mainAxisSpacing: 15, crossAxisSpacing: 15, - childAspectRatio: 1.45, + childAspectRatio: 1.2, ), ); - Widget _buildCard({required String title}) => - CoursePracticeCard(title: title); + Widget _buildCard({ + required String title, + GestureTapCallback? onTap, + }) => + CoursePracticeCard(onTap: onTap, title: title); } diff --git a/lib/ui/views/course_practice/course_practice_viewmodel.dart b/lib/ui/views/course_practice/course_practice_viewmodel.dart index 66e3860..f7b1453 100644 --- a/lib/ui/views/course_practice/course_practice_viewmodel.dart +++ b/lib/ui/views/course_practice/course_practice_viewmodel.dart @@ -1,5 +1,6 @@ import 'package:stacked/stacked.dart'; import 'package:stacked_services/stacked_services.dart'; +import 'package:yimaru_app/app/app.router.dart'; import 'package:yimaru_app/models/practice.dart'; import '../../../app/app.locator.dart'; @@ -23,19 +24,19 @@ class CoursePracticeViewModel extends BaseViewModel { // Navigation void pop() => _navigationService.back(); + Future navigateToCoursePracticeQuestion(int id) async => + await _navigationService.navigateToCoursePracticeQuestionView(id: id); + // Remote api call - // Courses + // Course practices Future getCoursePractice(int id) async => await runBusyFuture(_getCoursePractice(id), busyObject: StateObjects.coursePractice); Future _getCoursePractice(int id) async { if (await _statusChecker.checkConnection()) { - Map data = {'owner_id': id, 'owner_type': 'SUB_COURSE'}; - _coursePractices = await _apiService.getCoursePractices(data); - - rebuildUi(); + _coursePractices = await _apiService.getCoursePractices(id); } } } diff --git a/lib/ui/views/course_practice_question/course_practice_question_view.dart b/lib/ui/views/course_practice_question/course_practice_question_view.dart new file mode 100644 index 0000000..0b6f9d3 --- /dev/null +++ b/lib/ui/views/course_practice_question/course_practice_question_view.dart @@ -0,0 +1,63 @@ +import 'package:flutter/material.dart'; +import 'package:stacked/stacked.dart'; +import 'package:stacked/stacked_annotations.dart'; +import 'package:yimaru_app/ui/views/course_practice_question/course_practice_question_view.form.dart'; +import 'package:yimaru_app/ui/views/course_practice_question/screens/practice_questions_screen.dart'; +import 'package:yimaru_app/ui/views/course_practice_question/screens/practice_result_screen.dart'; + +import '../../common/validators/form_validator.dart'; +import 'course_practice_question_viewmodel.dart'; + +@FormView(fields: [ + FormTextField(name: 'answer', validator: FormValidator.validateForm), +]) +class CoursePracticeQuestionView + extends StackedView + with $CoursePracticeQuestionView { + final int id; + + const CoursePracticeQuestionView({Key? key, required this.id}) + : super(key: key); + + @override + void onViewModelReady(CoursePracticeQuestionViewModel viewModel) async { + await viewModel.getCoursePracticeQuestions(id); + syncFormWithViewModel(viewModel); + super.onViewModelReady(viewModel); + } + + @override + CoursePracticeQuestionViewModel viewModelBuilder(BuildContext context) => + CoursePracticeQuestionViewModel(); + + @override + Widget builder( + BuildContext context, + CoursePracticeQuestionViewModel viewModel, + Widget? child, + ) => + _buildAssessmentScreensWrapper(viewModel); + + Widget _buildAssessmentScreensWrapper( + CoursePracticeQuestionViewModel viewModel) => + PopScope( + canPop: false, + onPopInvokedWithResult: (value, data) => viewModel.previousQuestion(), + child: _buildAssessmentScreens(viewModel)); + + Widget _buildAssessmentScreens(CoursePracticeQuestionViewModel viewModel) => + IndexedStack( + index: viewModel.currentPage, + children: _buildScreens(), + ); + + List _buildScreens() => [ + _buildPracticeQuestionScreen(), + _buildPracticeResultScreen(), + ]; + + Widget _buildPracticeQuestionScreen() => + PracticeQuestionsScreen(id: id, answerController: answerController); + + Widget _buildPracticeResultScreen() => const PracticeResultScreen(); +} diff --git a/lib/ui/views/course_practice_question/course_practice_question_view.form.dart b/lib/ui/views/course_practice_question/course_practice_question_view.form.dart new file mode 100644 index 0000000..c47bf09 --- /dev/null +++ b/lib/ui/views/course_practice_question/course_practice_question_view.form.dart @@ -0,0 +1,180 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// StackedFormGenerator +// ************************************************************************** + +// ignore_for_file: public_member_api_docs, constant_identifier_names, non_constant_identifier_names,unnecessary_this + +import 'package:flutter/material.dart'; +import 'package:stacked/stacked.dart'; +import 'package:yimaru_app/ui/common/validators/form_validator.dart'; + +const bool _autoTextFieldValidation = true; + +const String AnswerValueKey = 'answer'; + +final Map + _CoursePracticeQuestionViewTextEditingControllers = {}; + +final Map _CoursePracticeQuestionViewFocusNodes = {}; + +final Map + _CoursePracticeQuestionViewTextValidations = { + AnswerValueKey: FormValidator.validateForm, +}; + +mixin $CoursePracticeQuestionView { + TextEditingController get answerController => + _getFormTextEditingController(AnswerValueKey); + + FocusNode get answerFocusNode => _getFormFocusNode(AnswerValueKey); + + TextEditingController _getFormTextEditingController( + String key, { + String? initialValue, + }) { + if (_CoursePracticeQuestionViewTextEditingControllers.containsKey(key)) { + return _CoursePracticeQuestionViewTextEditingControllers[key]!; + } + + _CoursePracticeQuestionViewTextEditingControllers[key] = + TextEditingController(text: initialValue); + return _CoursePracticeQuestionViewTextEditingControllers[key]!; + } + + FocusNode _getFormFocusNode(String key) { + if (_CoursePracticeQuestionViewFocusNodes.containsKey(key)) { + return _CoursePracticeQuestionViewFocusNodes[key]!; + } + _CoursePracticeQuestionViewFocusNodes[key] = FocusNode(); + return _CoursePracticeQuestionViewFocusNodes[key]!; + } + + /// Registers a listener on every generated controller that calls [model.setData()] + /// with the latest textController values + void syncFormWithViewModel(FormStateHelper model) { + answerController.addListener(() => _updateFormData(model)); + + _updateFormData(model, forceValidate: _autoTextFieldValidation); + } + + /// Registers a listener on every generated controller that calls [model.setData()] + /// with the latest textController values + @Deprecated( + 'Use syncFormWithViewModel instead.' + 'This feature was deprecated after 3.1.0.', + ) + void listenToFormUpdated(FormViewModel model) { + answerController.addListener(() => _updateFormData(model)); + + _updateFormData(model, forceValidate: _autoTextFieldValidation); + } + + /// Updates the formData on the FormViewModel + void _updateFormData(FormStateHelper model, {bool forceValidate = false}) { + model.setData( + model.formValueMap + ..addAll({ + AnswerValueKey: answerController.text, + }), + ); + + if (_autoTextFieldValidation || forceValidate) { + updateValidationData(model); + } + } + + bool validateFormFields(FormViewModel model) { + _updateFormData(model, forceValidate: true); + return model.isFormValid; + } + + /// Calls dispose on all the generated controllers and focus nodes + void disposeForm() { + // The dispose function for a TextEditingController sets all listeners to null + + for (var controller + in _CoursePracticeQuestionViewTextEditingControllers.values) { + controller.dispose(); + } + for (var focusNode in _CoursePracticeQuestionViewFocusNodes.values) { + focusNode.dispose(); + } + + _CoursePracticeQuestionViewTextEditingControllers.clear(); + _CoursePracticeQuestionViewFocusNodes.clear(); + } +} + +extension ValueProperties on FormStateHelper { + bool get hasAnyValidationMessage => this + .fieldsValidationMessages + .values + .any((validation) => validation != null); + + bool get isFormValid { + if (!_autoTextFieldValidation) this.validateForm(); + + return !hasAnyValidationMessage; + } + + String? get answerValue => this.formValueMap[AnswerValueKey] as String?; + + set answerValue(String? value) { + this.setData( + this.formValueMap..addAll({AnswerValueKey: value}), + ); + + if (_CoursePracticeQuestionViewTextEditingControllers.containsKey( + AnswerValueKey)) { + _CoursePracticeQuestionViewTextEditingControllers[AnswerValueKey]?.text = + value ?? ''; + } + } + + bool get hasAnswer => + this.formValueMap.containsKey(AnswerValueKey) && + (answerValue?.isNotEmpty ?? false); + + bool get hasAnswerValidationMessage => + this.fieldsValidationMessages[AnswerValueKey]?.isNotEmpty ?? false; + + String? get answerValidationMessage => + this.fieldsValidationMessages[AnswerValueKey]; +} + +extension Methods on FormStateHelper { + setAnswerValidationMessage(String? validationMessage) => + this.fieldsValidationMessages[AnswerValueKey] = validationMessage; + + /// Clears text input fields on the Form + void clearForm() { + answerValue = ''; + } + + /// Validates text input fields on the Form + void validateForm() { + this.setValidationMessages({ + AnswerValueKey: getValidationMessage(AnswerValueKey), + }); + } +} + +/// Returns the validation message for the given key +String? getValidationMessage(String key) { + final validatorForKey = _CoursePracticeQuestionViewTextValidations[key]; + if (validatorForKey == null) return null; + + String? validationMessageForKey = validatorForKey( + _CoursePracticeQuestionViewTextEditingControllers[key]!.text, + ); + + return validationMessageForKey; +} + +/// Updates the fieldsValidationMessages on the FormViewModel +void updateValidationData(FormStateHelper model) => + model.setValidationMessages({ + AnswerValueKey: getValidationMessage(AnswerValueKey), + }); diff --git a/lib/ui/views/course_practice_question/course_practice_question_viewmodel.dart b/lib/ui/views/course_practice_question/course_practice_question_viewmodel.dart new file mode 100644 index 0000000..3238f42 --- /dev/null +++ b/lib/ui/views/course_practice_question/course_practice_question_viewmodel.dart @@ -0,0 +1,209 @@ +import 'package:flutter/cupertino.dart'; +import 'package:stacked/stacked.dart'; +import 'package:stacked_services/stacked_services.dart'; +import 'package:yimaru_app/models/practice_question.dart'; + +import '../../../app/app.locator.dart'; +import '../../../models/option.dart'; +import '../../../models/question.dart'; +import '../../../services/api_service.dart'; +import '../../../services/status_checker_service.dart'; +import '../../common/app_colors.dart'; +import '../../common/enmus.dart'; + +class CoursePracticeQuestionViewModel extends FormViewModel { + // Dependency injection + final _apiService = locator(); + + final _dialogService = locator(); + + final _statusChecker = locator(); + + final _navigationService = locator(); + + // In-app navigation + int _currentPage = 0; + + int get currentPage => _currentPage; + + int _previousPage = 0; + + int get previousPage => _previousPage; + + final PageController _pageController = PageController(); + + PageController get pageController => _pageController; + + // Course practice questions + bool _focusAnswer = false; + + bool get focusAnswer => _focusAnswer; + + Question? _currentQuestion; + + Question? get currentQuestion => _currentQuestion; + + List _coursePracticeQuestions = []; + + List get coursePracticeQuestions => + _coursePracticeQuestions; + + int _currentQuestionIndex = 0; + + int get currentQuestionIndex => _currentQuestionIndex; + + final Map _selectedAnswers = {}; + + Map get selectedAnswers => _selectedAnswers; + + // Question + + void setAnswerFocus() { + _focusAnswer = true; + rebuildUi(); + } + + void setSelectedAnswer({required int question, required Option? option}) { + bool correct = false; + if (option?.isCorrect ?? false) { + correct = true; + } + + final data = { + question.toString(): { + 'correct': correct, + 'option': option?.optionText, + 'answer': _currentQuestion?.options + ?.firstWhere((e) => e.isCorrect ?? false) + .optionText + } + }; + + _selectedAnswers.addAll(data); + + rebuildUi(); + } + + bool isSelectedAnswer({required int question, required String answer}) { + return _selectedAnswers[question.toString()]?['option'] == answer; + } + + // Dialog + Future showAbortDialog() async { + DialogResponse? response = await _dialogService.showDialog( + cancelTitle: 'No', + buttonTitle: 'Yes', + title: 'Abort Practice', + barrierDismissible: true, + cancelTitleColor: kcDarkGrey, + buttonTitleColor: kcPrimaryColor, + description: 'Are you sure to abort the practice ?', + ); + return response?.confirmed; + } + + Future abort() async { + bool? response = await showAbortDialog(); + if (response != null && response) { + next(page: 1); + } + } + + // Reset practice + void reset() { + _selectedAnswers.clear(); + rebuildUi(); + } + + // Question navigation + void previousQuestion() { + if (_currentQuestionIndex != 0) { + _currentQuestionIndex--; + _pageController.previousPage( + duration: const Duration(microseconds: 100), curve: Curves.linear); + rebuildUi(); + } + } + + // In-app navigation + void goTo(int page) { + _currentPage = page; + rebuildUi(); + } + + void next({int? page}) async { + if (page == null) { + if (_previousPage != 0) { + _currentPage = _previousPage; + } else { + _currentPage++; + } + } else { + _previousPage = _currentPage; + _currentPage = page; + } + rebuildUi(); + } + + void goBack() { + if (_currentPage == 0) { + pop(); + } else { + _currentPage = 0; + rebuildUi(); + } + } + + // Navigation + void pop() => _navigationService.back(); + + // Remote api call + + // Course practice questions + Future getCoursePracticeQuestions(int id) async => + await runBusyFuture(_getCoursePracticeQuestions(id), + busyObject: StateObjects.coursePracticeQuestions); + + Future _getCoursePracticeQuestions(int id) async { + if (await _statusChecker.checkConnection()) { + _coursePracticeQuestions = + await _apiService.getCoursePracticeQuestions(id); + if (_coursePracticeQuestions.isNotEmpty) { + _currentQuestion = await _apiService.getCoursePracticeQuestion( + coursePracticeQuestions.first.questionId ?? 0); + } + } + } + + // Course practice question + Future getCoursePracticeQuestion(int id) async => + await runBusyFuture(_getCoursePracticeQuestion(id), + busyObject: StateObjects.coursePractice); + + Future _getCoursePracticeQuestion(int id) async { + if (await _statusChecker.checkConnection()) { + _currentQuestion = await _apiService.getCoursePracticeQuestion(id); + } + } + + // Question navigation + Future nextQuestion(int id) async => + await runBusyFuture(_nextQuestion(id), + busyObject: StateObjects.coursePractice); + + Future _nextQuestion(int id)async{ + _currentQuestionIndex++; + + if (_currentQuestionIndex == _coursePracticeQuestions.length) { + next(); + } else { + if (await _statusChecker.checkConnection()) { + _currentQuestion = await _apiService.getCoursePracticeQuestion(id); + _pageController.jumpToPage(_currentQuestionIndex); + + } + } + } + + +} diff --git a/lib/ui/views/course_practice_question/screens/practice_questions_screen.dart b/lib/ui/views/course_practice_question/screens/practice_questions_screen.dart new file mode 100644 index 0000000..049b66a --- /dev/null +++ b/lib/ui/views/course_practice_question/screens/practice_questions_screen.dart @@ -0,0 +1,107 @@ +import 'package:flutter/material.dart'; +import 'package:stacked/stacked.dart'; +import 'package:yimaru_app/ui/common/app_colors.dart'; +import 'package:yimaru_app/ui/common/enmus.dart'; +import 'package:yimaru_app/ui/views/course_practice_question/course_practice_question_viewmodel.dart'; +import 'package:yimaru_app/ui/widgets/large_app_bar.dart'; +import 'package:yimaru_app/ui/widgets/selectable_course_practice_question.dart'; +import 'package:yimaru_app/ui/widgets/writing_course_practice_question.dart'; + +import 'question_loading_screen.dart'; + +class PracticeQuestionsScreen + extends ViewModelWidget { + final int id; + final TextEditingController answerController; + + const PracticeQuestionsScreen( + {super.key, required this.id, required this.answerController}); + + @override + Widget build( + BuildContext context, CoursePracticeQuestionViewModel viewModel) => + _buildAssessmentScreens(viewModel); + + Widget _buildAssessmentScreens(CoursePracticeQuestionViewModel viewModel) => + viewModel.busy(StateObjects.coursePracticeQuestions) || + viewModel.busy(StateObjects.coursePracticeQuestion) || + viewModel.coursePracticeQuestions.isEmpty || + viewModel.currentQuestion == null + ? _buildPageLoadingIndicator(viewModel) + : _buildScaffoldWrapper(viewModel); + + Widget _buildPageLoadingIndicator( + CoursePracticeQuestionViewModel viewModel) => + QuestionLoadingScreen( + onPop: viewModel.coursePracticeQuestions.isEmpty || + viewModel.currentQuestion == null + ? viewModel.pop + : null, + isEmpty: viewModel.coursePracticeQuestions.isEmpty || + viewModel.currentQuestion == null + ? true + : false, + isLoading: viewModel.busy(StateObjects.coursePracticeQuestions) || + viewModel.busy(StateObjects.coursePracticeQuestion), + onTap: () async => await viewModel.getCoursePracticeQuestions(id), + ); + + Widget _buildScaffoldWrapper(CoursePracticeQuestionViewModel viewModel) => + Scaffold( + backgroundColor: kcBackgroundColor, + body: _buildScaffold(viewModel), + ); + + Widget _buildScaffold(CoursePracticeQuestionViewModel viewModel) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: _buildScaffoldChildren(viewModel), + ); + + List _buildScaffoldChildren( + CoursePracticeQuestionViewModel viewModel) => + [_buildAppBar(viewModel), _buildExpandedBody(viewModel)]; + + Widget _buildAppBar(CoursePracticeQuestionViewModel viewModel) => LargeAppBar( + onClose: viewModel.abort, + showLanguageSelection: false, + onPop: viewModel.previousQuestion, + showBackButton: viewModel.currentQuestionIndex == 0 ? false : true, + ); + + Widget _buildExpandedBody(CoursePracticeQuestionViewModel viewModel) => + Expanded(child: _buildBodyWrapper(viewModel)); + + Widget _buildBodyWrapper(CoursePracticeQuestionViewModel viewModel) => + Padding( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: _buildQuestion(viewModel), + ); + + Widget _buildQuestion(CoursePracticeQuestionViewModel viewModel) => + PageView.builder( + controller: viewModel.pageController, + physics: const NeverScrollableScrollPhysics(), + itemCount: viewModel.coursePracticeQuestions.length, + itemBuilder: (cotext, index) => + _buildQuestionType(index: index, viewModel: viewModel), + ); + + Widget _buildQuestionType( + {required int index, + required CoursePracticeQuestionViewModel viewModel}) => + viewModel.currentQuestion?.questionType == 'SHORT_ANSWER' + ? _buildWritingCoursePracticeQuestion(index) + : _buildCoursePracticeQuestionWrapper(index); + + Widget _buildCoursePracticeQuestionWrapper(int index) => + SingleChildScrollView( + child: _buildSelectableCoursePracticeQuestion(index), + ); + + Widget _buildSelectableCoursePracticeQuestion(int index) => + SelectableCoursePracticeQuestion(index: index); + + Widget _buildWritingCoursePracticeQuestion(int index) => + WritingCoursePracticeQuestion( + index: index, answerController: answerController); +} diff --git a/lib/ui/views/course_practice_question/screens/practice_result_screen.dart b/lib/ui/views/course_practice_question/screens/practice_result_screen.dart new file mode 100644 index 0000000..ec1909a --- /dev/null +++ b/lib/ui/views/course_practice_question/screens/practice_result_screen.dart @@ -0,0 +1,142 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:stacked/stacked.dart'; +import 'package:yimaru_app/ui/views/course_practice_question/course_practice_question_viewmodel.dart'; + +import '../../../common/app_colors.dart'; +import '../../../common/ui_helpers.dart'; +import '../../../widgets/custom_elevated_button.dart'; +import '../../../widgets/large_app_bar.dart'; + +class PracticeResultScreen + extends ViewModelWidget { + const PracticeResultScreen({super.key}); + + void _retake(CoursePracticeQuestionViewModel viewModel) { + viewModel.reset(); + viewModel.goTo(0); + } + + @override + Widget build( + BuildContext context, CoursePracticeQuestionViewModel viewModel) => + _buildScaffoldWrapper(viewModel); + + Widget _buildScaffoldWrapper(CoursePracticeQuestionViewModel viewModel) => + Scaffold( + backgroundColor: kcBackgroundColor, + body: _buildScaffold(viewModel), + ); + + Widget _buildScaffold(CoursePracticeQuestionViewModel viewModel) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: _buildScaffoldChildren(viewModel), + ); + + List _buildScaffoldChildren( + CoursePracticeQuestionViewModel viewModel) => + [ + _buildAppBar(viewModel), + verticalSpaceMedium, + _buildExpandedBody(viewModel) + ]; + + Widget _buildExpandedBody(CoursePracticeQuestionViewModel viewModel) => + Expanded(child: _buildBodyWrapper(viewModel)); + + Widget _buildBodyWrapper(CoursePracticeQuestionViewModel viewModel) => + Padding( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: _buildBody(viewModel), + ); + + Widget _buildBody(CoursePracticeQuestionViewModel viewModel) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: _buildBodyChildren(viewModel), + ); + + List _buildBodyChildren(CoursePracticeQuestionViewModel viewModel) => + [_buildUpperColumn(viewModel), _buildLowerColumn(viewModel)]; + + Widget _buildUpperColumn(CoursePracticeQuestionViewModel viewModel) => Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: _buildUpperColumnChildren(viewModel), + ); + + List _buildUpperColumnChildren( + CoursePracticeQuestionViewModel viewModel) => + [ + verticalSpaceLarge, + _buildIcon(), + verticalSpaceMedium, + _buildTitle(), + verticalSpaceSmall, + _buildSubtitle(), + ]; + + Widget _buildAppBar(CoursePracticeQuestionViewModel viewModel) => LargeAppBar( + showBackButton: true, + showLanguageSelection: false, + onPop: () => viewModel.pop(), + ); + + Widget _buildIcon() => SvgPicture.asset( + 'assets/icons/complete.svg', + ); + + Widget _buildTitle() => Text( + 'Practice Completed', + style: style25DG600, + textAlign: TextAlign.center, + ); + + Widget _buildSubtitle() => Text( + 'You’ve finished this practice. Great work!', + style: style14MG400, + textAlign: TextAlign.center, + ); + + Widget _buildLowerColumn(CoursePracticeQuestionViewModel viewModel) => Column( + mainAxisSize: MainAxisSize.min, + children: _buildLowerColumnChildren(viewModel), + ); + + List _buildLowerColumnChildren( + CoursePracticeQuestionViewModel viewModel) => + [ + _buildContinueButton(viewModel), + verticalSpaceSmall, + _buildSkipButtonWrapper(viewModel) + ]; + + Widget _buildContinueButton(CoursePracticeQuestionViewModel viewModel) => + CustomElevatedButton( + height: 55, + safe: false, + borderRadius: 12, + text: 'Practice Again', + foregroundColor: kcWhite, + onTap: () => _retake(viewModel), + backgroundColor: kcPrimaryColor, + ); + + Widget _buildSkipButtonWrapper(CoursePracticeQuestionViewModel viewModel) => + Padding( + padding: const EdgeInsets.only(bottom: 50), + child: _buildSkipButton(viewModel), + ); + + Widget _buildSkipButton(CoursePracticeQuestionViewModel viewModel) => + CustomElevatedButton( + height: 55, + text: 'Continue', + borderRadius: 12, + onTap: viewModel.pop, + backgroundColor: kcWhite, + borderColor: kcPrimaryColor, + foregroundColor: kcPrimaryColor, + ); +} diff --git a/lib/ui/views/course_practice_question/screens/question_loading_screen.dart b/lib/ui/views/course_practice_question/screens/question_loading_screen.dart new file mode 100644 index 0000000..56ab395 --- /dev/null +++ b/lib/ui/views/course_practice_question/screens/question_loading_screen.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; +import 'package:yimaru_app/ui/widgets/page_loading_indicator.dart'; + +import '../../../common/app_colors.dart'; +import '../../../widgets/large_app_bar.dart'; +import '../../../widgets/refresh_button.dart'; + +class QuestionLoadingScreen extends StatelessWidget { + final bool isEmpty; + final bool isLoading; + final GestureTapCallback? onPop; + final GestureTapCallback? onTap; + const QuestionLoadingScreen( + {super.key, + this.onTap, + this.onPop, + required this.isEmpty, + required this.isLoading}); + + @override + Widget build(BuildContext context) => _buildScaffoldWrapper(); + + Widget _buildScaffoldWrapper() => Scaffold( + backgroundColor: kcBackgroundColor, + body: _buildScaffold(), + ); + + Widget _buildScaffold() => Stack( + children: [ + _buildColumn(), + if (isEmpty) _buildRefreshButton(), + if (isLoading) _buildPageIndicator() + ], + ); + + Widget _buildColumn() => Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: _buildColumnChildren(), + ); + + List _buildColumnChildren() => [_buildAppBar(), _buildBody()]; + + Widget _buildAppBar() => LargeAppBar( + onPop: onPop, + showBackButton: true, + showLanguageSelection: true, + ); + + Widget _buildBody() => Expanded(child: Container()); + + Widget _buildPageIndicator() => const PageLoadingIndicator(); + + Widget _buildRefreshButton() => RefreshButton(onTap: onTap); +} diff --git a/lib/ui/views/course_subcategory/course_subcategory_viewmodel.dart b/lib/ui/views/course_subcategory/course_subcategory_viewmodel.dart index 1b5f957..e84127d 100644 --- a/lib/ui/views/course_subcategory/course_subcategory_viewmodel.dart +++ b/lib/ui/views/course_subcategory/course_subcategory_viewmodel.dart @@ -41,7 +41,6 @@ class CourseSubcategoryViewModel extends BaseViewModel { if (await _statusChecker.checkConnection()) { _subcategories = await _apiService.getCourseSubcategories(id); - rebuildUi(); } } } diff --git a/lib/ui/views/learn_practice/learn_practice_viewmodel.dart b/lib/ui/views/learn_practice/learn_practice_viewmodel.dart index c4b7782..71625be 100644 --- a/lib/ui/views/learn_practice/learn_practice_viewmodel.dart +++ b/lib/ui/views/learn_practice/learn_practice_viewmodel.dart @@ -21,7 +21,6 @@ class LearnPracticeViewModel extends ReactiveViewModel { final _voiceRecorderService = locator(); - final _authenticationService = locator(); LearnPracticeViewModel() { @@ -30,7 +29,7 @@ class LearnPracticeViewModel extends ReactiveViewModel { @override List get listenableServices => - [_audioPlayerService, _voiceRecorderService,_authenticationService]; + [_audioPlayerService, _voiceRecorderService, _authenticationService]; // User UserModel? get _user => _authenticationService.user; @@ -68,7 +67,6 @@ class LearnPracticeViewModel extends ReactiveViewModel { VoiceRecordingState get recordingState => _recordingState; - // Busy object StateObjects _busyObject = StateObjects.none; @@ -84,19 +82,16 @@ class LearnPracticeViewModel extends ReactiveViewModel { Map get selectedPractice => _selectedPractice; - - // Practice void setPractice(Map practice) { _selectedPractice = practice; goTo(1); } - - // Play practice audio - Future playQuestionAudio() async => await runBusyFuture(_playQuestionAudio(), - busyObject: StateObjects.learnPracticeQuestion); + Future playQuestionAudio() async => + await runBusyFuture(_playQuestionAudio(), + busyObject: StateObjects.learnPracticeQuestion); Future _playQuestionAudio() async { goTo(3); @@ -115,57 +110,59 @@ class LearnPracticeViewModel extends ReactiveViewModel { print('POSITION: $_position'); rebuildUi(); }); - } // Set busy object - void setBusyObject(StateObjects object){ + void setBusyObject(StateObjects object) { _busyObject = object; notifyListeners(); } - // Sample audio - Future playSampleAudio() async => await runBusyFuture(_playSampleAudio(), - busyObject: StateObjects.learnPracticeSample); + Future playSampleAudio() async => + await runBusyFuture(_playSampleAudio(), + busyObject: StateObjects.learnPracticeSample); Future _playSampleAudio() async { setBusyObject(StateObjects.learnPracticeSample); await _audioPlayerService.playUrl(_selectedPractice['sample_answer']); } - Future pauseSampleAudio()async=> await runBusyFuture(_pauseSampleAudio(), - busyObject: StateObjects.learnPracticeSample); + + Future pauseSampleAudio() async => + await runBusyFuture(_pauseSampleAudio(), + busyObject: StateObjects.learnPracticeSample); Future _pauseSampleAudio() async { setBusyObject(StateObjects.learnPracticeSample); await _audioPlayerService.pause(); } - // Recorded audio - Future playRecordedAudio() async => await runBusyFuture(_playRecordedAudio(), - busyObject: StateObjects.learnPracticeAnswer); + Future playRecordedAudio() async => + await runBusyFuture(_playRecordedAudio(), + busyObject: StateObjects.learnPracticeAnswer); Future _playRecordedAudio() async { setBusyObject(StateObjects.learnPracticeAnswer); - await _audioPlayerService.playLocal(await _voiceRecorderService.getRecordedAudio() ?? ''); + await _audioPlayerService + .playLocal(await _voiceRecorderService.getRecordedAudio() ?? ''); } - Future pauseRecordedAudio()async=> await runBusyFuture(_pauseRecordedAudio(), - busyObject: StateObjects.learnPracticeAnswer); - + Future pauseRecordedAudio() async => + await runBusyFuture(_pauseRecordedAudio(), + busyObject: StateObjects.learnPracticeAnswer); Future _pauseRecordedAudio() async { setBusyObject(StateObjects.learnPracticeAnswer); await _audioPlayerService.pause(); } - // Voice recorder - Future startRecording() async => await runBusyFuture(_startRecording(),busyObject: StateObjects.recordLearnPracticeAnswer ); - - Future _startRecording() async => await _voiceRecorderService.startRecording(); + Future startRecording() async => await runBusyFuture(_startRecording(), + busyObject: StateObjects.recordLearnPracticeAnswer); + Future _startRecording() async => + await _voiceRecorderService.startRecording(); Future stopRecording() async => await _voiceRecorderService.stopRecording(); diff --git a/lib/ui/views/learn_practice/screens/start_learn_practice_screen.dart b/lib/ui/views/learn_practice/screens/start_learn_practice_screen.dart index 2afee30..4521b10 100644 --- a/lib/ui/views/learn_practice/screens/start_learn_practice_screen.dart +++ b/lib/ui/views/learn_practice/screens/start_learn_practice_screen.dart @@ -60,7 +60,6 @@ class StartLearnPracticeScreen extends ViewModelWidget { child: _buildStartButtonContainer(viewModel), ); - Widget _buildStartButtonContainer(LearnPracticeViewModel viewModel) => GestureDetector( onTap: () => _start(viewModel), @@ -160,22 +159,21 @@ class StartLearnPracticeScreen extends ViewModelWidget { Expanded(child: _buildMicButton(viewModel)); Widget _buildMicButton(LearnPracticeViewModel viewModel) => ElevatedButton( - onPressed: null, - style: const ButtonStyle( - shape: WidgetStatePropertyAll(CircleBorder()), - padding: WidgetStatePropertyAll(EdgeInsets.all(15)), - shadowColor: WidgetStatePropertyAll(kcPrimaryColor), - backgroundColor: WidgetStatePropertyAll(kcVeryLightGrey), - ), - child: _buildMicIcon(), - ); - + onPressed: null, + style: const ButtonStyle( + shape: WidgetStatePropertyAll(CircleBorder()), + padding: WidgetStatePropertyAll(EdgeInsets.all(15)), + shadowColor: WidgetStatePropertyAll(kcPrimaryColor), + backgroundColor: WidgetStatePropertyAll(kcVeryLightGrey), + ), + child: _buildMicIcon(), + ); Widget _buildMicIcon() => const Icon( - Icons.mic, - size: 35, - color: kcWhite, - ); + Icons.mic, + size: 35, + color: kcWhite, + ); Widget _buildEmptySpace() => Expanded(child: Container()); } diff --git a/lib/ui/widgets/course_practice_card.dart b/lib/ui/widgets/course_practice_card.dart index af3dba7..576909a 100644 --- a/lib/ui/widgets/course_practice_card.dart +++ b/lib/ui/widgets/course_practice_card.dart @@ -6,14 +6,15 @@ import 'custom_elevated_button.dart'; class CoursePracticeCard extends StatelessWidget { final String title; + final GestureTapCallback? onTap; - const CoursePracticeCard({super.key, required this.title}); + const CoursePracticeCard({super.key, this.onTap, required this.title}); @override Widget build(BuildContext context) => _buildContainer(); Widget _buildContainer() => Container( - height: 200, + // height: 250, decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), color: kcPrimaryColor.withValues(alpha: 0.25), @@ -27,14 +28,19 @@ class CoursePracticeCard extends StatelessWidget { List _buildColumnChildren() => [ verticalSpaceTiny, - _buildTitle(), + _buildTitleWrapper(), + verticalSpaceSmall, + _buildStartButtonWrapper(), verticalSpaceSmall, - _buildStartButtonWrapper() ]; + Widget _buildTitleWrapper() => Expanded(child: _buildTitle()); + Widget _buildTitle() => Text( title, + maxLines: 2, style: style18DG700, + overflow: TextOverflow.fade, ); Widget _buildStartButtonWrapper() => SizedBox( @@ -42,11 +48,12 @@ class CoursePracticeCard extends StatelessWidget { child: _buildStartButton(), ); - Widget _buildStartButton() => const CustomElevatedButton( + Widget _buildStartButton() => CustomElevatedButton( height: 50, width: 200, + onTap: onTap, borderRadius: 8, - text: 'Start Test', + text: 'Start Practice', foregroundColor: kcWhite, backgroundColor: kcPrimaryColor, ); diff --git a/lib/ui/widgets/learn_practice_result_card.dart b/lib/ui/widgets/learn_practice_result_card.dart index 93f7368..0def5bd 100644 --- a/lib/ui/widgets/learn_practice_result_card.dart +++ b/lib/ui/widgets/learn_practice_result_card.dart @@ -5,57 +5,57 @@ import 'package:yimaru_app/ui/common/ui_helpers.dart'; import 'package:yimaru_app/ui/views/learn_practice/learn_practice_viewmodel.dart'; import 'package:yimaru_app/ui/widgets/learn_practice_answer_card.dart'; - class LearnPracticeResultCard extends ViewModelWidget { final Map data; - const LearnPracticeResultCard( - {super.key, required this.data}); + const LearnPracticeResultCard({super.key, required this.data}); @override - Widget build(BuildContext context,LearnPracticeViewModel viewModel) => _buildColumnWrapper(); + Widget build(BuildContext context, LearnPracticeViewModel viewModel) => + _buildColumnWrapper(); Widget _buildColumnWrapper() => SizedBox( - height: 100, - width: double.maxFinite, - child: _buildColumn(), - ); + height: 100, + width: double.maxFinite, + child: _buildColumn(), + ); Widget _buildColumn() => Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: _buildColumnChildren(), - ); + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: _buildColumnChildren(), + ); List _buildColumnChildren() => [_buildQuestion(), verticalSpaceSmall, _buildRow()]; Widget _buildQuestion() => Text( - data['question_text'], - style: style14DG400, - ); + data['question_text'], + style: style14DG400, + ); Widget _buildRow() => Row( - children: _buildRowChildren(), - ); + children: _buildRowChildren(), + ); List _buildRowChildren() => [ - _buildSampleResponseWrapper(), - horizontalSpaceSmall, - _buildActualResponseWrapper() - ]; + _buildSampleResponseWrapper(), + horizontalSpaceSmall, + _buildActualResponseWrapper() + ]; Widget _buildSampleResponseWrapper() => Expanded(child: _buildSampleResponse()); - Widget _buildSampleResponse() => - const LearnPracticeAnswerCard(title: 'Sample Answer' ,object: StateObjects.learnPracticeSample,); + Widget _buildSampleResponse() => const LearnPracticeAnswerCard( + title: 'Sample Answer', + object: StateObjects.learnPracticeSample, + ); Widget _buildActualResponseWrapper() => Expanded(child: _buildActualResponse()); - Widget _buildActualResponse() => - const LearnPracticeAnswerCard(title: 'Your Answer',object: StateObjects.learnPracticeAnswer,); - - - + Widget _buildActualResponse() => const LearnPracticeAnswerCard( + title: 'Your Answer', + object: StateObjects.learnPracticeAnswer, + ); } diff --git a/lib/ui/widgets/practice_result_card.dart b/lib/ui/widgets/practice_result_card.dart index a1f7cd0..1bafcbe 100644 --- a/lib/ui/widgets/practice_result_card.dart +++ b/lib/ui/widgets/practice_result_card.dart @@ -6,11 +6,11 @@ import 'package:yimaru_app/ui/widgets/custom_response_card.dart'; class PracticeResultCard extends ViewModelWidget { final Map data; - const PracticeResultCard( - {super.key, required this.data}); + const PracticeResultCard({super.key, required this.data}); @override - Widget build(BuildContext context,LearnPracticeViewModel viewModel) => _buildColumnWrapper(); + Widget build(BuildContext context, LearnPracticeViewModel viewModel) => + _buildColumnWrapper(); Widget _buildColumnWrapper() => SizedBox( height: 100, @@ -46,11 +46,11 @@ class PracticeResultCard extends ViewModelWidget { Expanded(child: _buildSampleResponse()); Widget _buildSampleResponse() => - const CustomResponseCard(title: 'Sample Answer', subtitle: '0:54'); + const CustomResponseCard(title: 'Sample Answer', subtitle: '0:54'); Widget _buildActualResponseWrapper() => Expanded(child: _buildActualResponse()); Widget _buildActualResponse() => - const CustomResponseCard(title: 'Sample Answer', subtitle: '0:54'); + const CustomResponseCard(title: 'Sample Answer', subtitle: '0:54'); } diff --git a/lib/ui/widgets/selectable_course_practice_question.dart b/lib/ui/widgets/selectable_course_practice_question.dart new file mode 100644 index 0000000..0a2dded --- /dev/null +++ b/lib/ui/widgets/selectable_course_practice_question.dart @@ -0,0 +1,113 @@ +import 'package:flutter/material.dart'; +import 'package:stacked/stacked.dart'; +import 'package:yimaru_app/ui/common/enmus.dart'; +import 'package:yimaru_app/ui/widgets/custom_circular_progress_indicator.dart'; + +import '../common/app_colors.dart'; +import '../common/ui_helpers.dart'; +import '../views/course_practice_question/course_practice_question_viewmodel.dart'; +import 'custom_elevated_button.dart'; +import 'custom_small_radio_button.dart'; + +class SelectableCoursePracticeQuestion + extends ViewModelWidget { + final int index; + + const SelectableCoursePracticeQuestion({super.key, required this.index}); + + @override + Widget build( + BuildContext context, CoursePracticeQuestionViewModel viewModel) => + _buildBodyScroller(viewModel); + + Widget _buildBodyScroller(CoursePracticeQuestionViewModel viewModel) => + SingleChildScrollView( + child: _buildBody(viewModel), + ); + + Widget _buildBody(CoursePracticeQuestionViewModel viewModel) => Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: _buildBodyChildren(viewModel), + ); + + List _buildBodyChildren(CoursePracticeQuestionViewModel viewModel) => + [ + verticalSpaceMedium, + _buildTitle(viewModel), + verticalSpaceMedium, + _buildAnswers(viewModel), + _buildContinueButtonWrapper(viewModel) + ]; + + Widget _buildTitle(CoursePracticeQuestionViewModel viewModel) => Text( + 'Q${index + 1}. ${viewModel.currentQuestion?.questionText} ', + style: style16DG600, + ); + + Widget _buildAnswers(CoursePracticeQuestionViewModel viewModel) => + ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: viewModel.currentQuestion?.options?.length, + itemBuilder: (context, inner) => _buildAnswer( + title: viewModel.currentQuestion?.options?[inner].optionText ?? '', + selected: viewModel.isSelectedAnswer( + question: index + 1, + answer: + viewModel.currentQuestion?.options?[inner].optionText ?? ''), + onTap: () => viewModel.setSelectedAnswer( + question: index + 1, + option: viewModel.currentQuestion?.options?[inner]), + ), + ); + + Widget _buildAnswer( + {required String title, + required bool selected, + required GestureTapCallback onTap}) => + CustomSmallRadioButton( + title: title, + onTap: onTap, + selected: selected, + ); + + Widget _buildContinueButtonWrapper( + CoursePracticeQuestionViewModel viewModel) => + Padding( + padding: const EdgeInsets.only(bottom: 50), + child: _buildContinueButtonState(viewModel), + ); + + Widget _buildContinueButtonState(CoursePracticeQuestionViewModel viewModel) => + viewModel.busy(StateObjects.coursePracticeQuestion) + ? _buildProgressIndicator() + : _buildContinueButton(viewModel); + + Widget _buildProgressIndicator()=>const CustomCircularProgressIndicator(color: kcPrimaryColor); + + Widget _buildContinueButton(CoursePracticeQuestionViewModel viewModel) => + CustomElevatedButton( + height: 55, + borderRadius: 12, + foregroundColor: kcWhite, + text: viewModel.currentQuestionIndex == + viewModel.coursePracticeQuestions.length - 1 + ? 'Finish' + : 'Continue', + backgroundColor: + viewModel.selectedAnswers.containsKey((index + 1).toString()) + ? kcPrimaryColor + : kcPrimaryColor.withOpacity(0.1), + onTap: viewModel.selectedAnswers.containsKey((index + 1).toString()) + ? ()async =>await viewModel.nextQuestion(viewModel + .coursePracticeQuestions[ + index + 1 < viewModel.coursePracticeQuestions.length + ? index + 1 + : index] + .questionId ?? + 0) + : null, + + ); +} diff --git a/lib/ui/widgets/writing_course_practice_question.dart b/lib/ui/widgets/writing_course_practice_question.dart new file mode 100644 index 0000000..ffcbba0 --- /dev/null +++ b/lib/ui/widgets/writing_course_practice_question.dart @@ -0,0 +1,123 @@ +import 'package:flutter/material.dart'; +import 'package:stacked/stacked.dart'; + +import '../common/app_colors.dart'; +import '../common/enmus.dart'; +import '../common/ui_helpers.dart'; +import '../views/course_practice_question/course_practice_question_view.form.dart'; +import '../views/course_practice_question/course_practice_question_viewmodel.dart'; +import 'custom_circular_progress_indicator.dart'; +import 'custom_elevated_button.dart'; + +class WritingCoursePracticeQuestion + extends ViewModelWidget { + final int index; + final TextEditingController answerController; + + const WritingCoursePracticeQuestion( + {super.key, required this.index, required this.answerController}); + + @override + Widget build( + BuildContext context, CoursePracticeQuestionViewModel viewModel) => + _buildBody(viewModel); + + Widget _buildBody(CoursePracticeQuestionViewModel viewModel) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: _buildBodyChildren(viewModel), + ); + + List _buildBodyChildren(CoursePracticeQuestionViewModel viewModel) => + [_buildColumnScroller(viewModel), _buildContinueButtonWrapper(viewModel)]; + + Widget _buildColumnScroller(CoursePracticeQuestionViewModel viewModel) => + SingleChildScrollView( + child: _buildUpperColumn(viewModel), + ); + + Widget _buildUpperColumn(CoursePracticeQuestionViewModel viewModel) => Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: _buildUpperColumnChildren(viewModel), + ); + + List _buildUpperColumnChildren( + CoursePracticeQuestionViewModel viewModel) => + [ + verticalSpaceMedium, + _buildTitle(viewModel), + verticalSpaceLarge, + _buildQuestionFormField(viewModel), + if (viewModel.hasAnswerValidationMessage && viewModel.focusAnswer) + verticalSpaceTiny, + if (viewModel.hasAnswerValidationMessage && viewModel.focusAnswer) + _buildQuestionValidatorWrapper(viewModel), + ]; + + Widget _buildTitle(CoursePracticeQuestionViewModel viewModel) => Text( + 'Q${index + 1}. ${viewModel.coursePracticeQuestions[index].questionText} ', + style: style16DG600, + ); + + Widget _buildQuestionFormField(CoursePracticeQuestionViewModel viewModel) => + TextFormField( + maxLines: 3, + controller: answerController, + onTap: viewModel.setAnswerFocus, + decoration: inputDecoration( + hint: 'Enter Your Answer', + focus: viewModel.focusAnswer, + filled: answerController.text.isNotEmpty), + ); + + Widget _buildQuestionValidatorWrapper( + CoursePracticeQuestionViewModel viewModel) => + viewModel.hasAnswerValidationMessage + ? _buildQuestionValidator(viewModel) + : Container(); + + Widget _buildQuestionValidator(CoursePracticeQuestionViewModel viewModel) => + Text( + viewModel.answerValidationMessage!, + style: const TextStyle( + fontSize: 12, + color: Colors.red, + fontWeight: FontWeight.w700, + ), + ); + + Widget _buildContinueButtonWrapper( + CoursePracticeQuestionViewModel viewModel) => + Padding( + padding: const EdgeInsets.only(bottom: 50), + child: _buildContinueButtonState(viewModel), + ); + + Widget _buildContinueButtonState(CoursePracticeQuestionViewModel viewModel) => + viewModel.busy(StateObjects.coursePracticeQuestion) + ? _buildProgressIndicator() + : _buildContinueButton(viewModel); + + Widget _buildProgressIndicator()=>const CustomCircularProgressIndicator(color: kcPrimaryColor); + + Widget _buildContinueButton(CoursePracticeQuestionViewModel viewModel) => + CustomElevatedButton( + height: 55, + borderRadius: 12, + foregroundColor: kcWhite, + backgroundColor: answerController.text.isNotEmpty + ? kcPrimaryColor + : kcPrimaryColor.withOpacity(0.1), + onTap: answerController.text.isNotEmpty + ? ()async =>await viewModel.nextQuestion( + index + 1 < viewModel.coursePracticeQuestions.length + ? index + 1 + : index) + : null, + text: viewModel.currentQuestionIndex == + viewModel.coursePracticeQuestions.length - 1 + ? 'Finish' + : 'Continue', + ); +} diff --git a/pubspec.yaml b/pubspec.yaml index c849ba9..3cc40d1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: yimaru_app description: A new Flutter project. publish_to: 'none' -version: 0.1.0 +version: 0.1.1 environment: sdk: '>=3.0.3 <4.0.0' diff --git a/test/helpers/test_helpers.mocks.dart b/test/helpers/test_helpers.mocks.dart index fe7192d..ccea6c5 100644 --- a/test/helpers/test_helpers.mocks.dart +++ b/test/helpers/test_helpers.mocks.dart @@ -3,41 +3,43 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i8; -import 'dart:ui' as _i9; +import 'dart:async' as _i9; +import 'dart:ui' as _i10; import 'package:audioplayers/audioplayers.dart' as _i4; import 'package:dio/dio.dart' as _i2; -import 'package:firebase_messaging/firebase_messaging.dart' as _i29; -import 'package:flutter/material.dart' as _i7; +import 'package:firebase_messaging/firebase_messaging.dart' as _i30; +import 'package:flutter/material.dart' as _i8; import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i6; -import 'package:permission_handler/permission_handler.dart' as _i24; -import 'package:stacked_services/stacked_services.dart' as _i5; -import 'package:yimaru_app/models/assessment.dart' as _i13; -import 'package:yimaru_app/models/course.dart' as _i16; -import 'package:yimaru_app/models/course_category.dart' as _i14; -import 'package:yimaru_app/models/course_detail.dart' as _i32; -import 'package:yimaru_app/models/course_lesson.dart' as _i18; -import 'package:yimaru_app/models/course_progress.dart' as _i17; -import 'package:yimaru_app/models/course_subcategory.dart' as _i15; -import 'package:yimaru_app/models/practice.dart' as _i19; -import 'package:yimaru_app/models/practice_question.dart' as _i20; -import 'package:yimaru_app/models/user_model.dart' as _i11; -import 'package:yimaru_app/services/api_service.dart' as _i12; -import 'package:yimaru_app/services/audio_player_service.dart' as _i33; -import 'package:yimaru_app/services/authentication_service.dart' as _i10; -import 'package:yimaru_app/services/course_service.dart' as _i31; -import 'package:yimaru_app/services/dio_service.dart' as _i21; -import 'package:yimaru_app/services/google_auth_service.dart' as _i26; -import 'package:yimaru_app/services/image_downloader_service.dart' as _i27; -import 'package:yimaru_app/services/image_picker_service.dart' as _i25; -import 'package:yimaru_app/services/notification_service.dart' as _i28; -import 'package:yimaru_app/services/permission_handler_service.dart' as _i23; +import 'package:mockito/src/dummies.dart' as _i7; +import 'package:permission_handler/permission_handler.dart' as _i25; +import 'package:stacked_services/stacked_services.dart' as _i6; +import 'package:waveform_recorder/waveform_recorder.dart' as _i5; +import 'package:yimaru_app/models/course.dart' as _i17; +import 'package:yimaru_app/models/course_category.dart' as _i15; +import 'package:yimaru_app/models/course_detail.dart' as _i33; +import 'package:yimaru_app/models/course_lesson.dart' as _i19; +import 'package:yimaru_app/models/course_progress.dart' as _i18; +import 'package:yimaru_app/models/course_subcategory.dart' as _i16; +import 'package:yimaru_app/models/practice.dart' as _i20; +import 'package:yimaru_app/models/practice_question.dart' as _i21; +import 'package:yimaru_app/models/question.dart' as _i14; +import 'package:yimaru_app/models/user_model.dart' as _i12; +import 'package:yimaru_app/services/api_service.dart' as _i13; +import 'package:yimaru_app/services/audio_player_service.dart' as _i34; +import 'package:yimaru_app/services/authentication_service.dart' as _i11; +import 'package:yimaru_app/services/course_service.dart' as _i32; +import 'package:yimaru_app/services/dio_service.dart' as _i22; +import 'package:yimaru_app/services/google_auth_service.dart' as _i27; +import 'package:yimaru_app/services/image_downloader_service.dart' as _i28; +import 'package:yimaru_app/services/image_picker_service.dart' as _i26; +import 'package:yimaru_app/services/notification_service.dart' as _i29; +import 'package:yimaru_app/services/permission_handler_service.dart' as _i24; import 'package:yimaru_app/services/secure_storage_service.dart' as _i3; -import 'package:yimaru_app/services/smart_auth_service.dart' as _i30; -import 'package:yimaru_app/services/status_checker_service.dart' as _i22; -import 'package:yimaru_app/services/voice_recorder_service.dart' as _i34; +import 'package:yimaru_app/services/smart_auth_service.dart' as _i31; +import 'package:yimaru_app/services/status_checker_service.dart' as _i23; +import 'package:yimaru_app/services/voice_recorder_service.dart' as _i35; +import 'package:yimaru_app/ui/common/enmus.dart' as _i36; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -83,18 +85,29 @@ class _FakeAudioPlayer_2 extends _i1.SmartFake implements _i4.AudioPlayer { ); } +class _FakeWaveformRecorderController_3 extends _i1.SmartFake + implements _i5.WaveformRecorderController { + _FakeWaveformRecorderController_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + /// A class which mocks [NavigationService]. /// /// See the documentation for Mockito's code generation for more information. -class MockNavigationService extends _i1.Mock implements _i5.NavigationService { +class MockNavigationService extends _i1.Mock implements _i6.NavigationService { @override String get previousRoute => (super.noSuchMethod( Invocation.getter(#previousRoute), - returnValue: _i6.dummyValue( + returnValue: _i7.dummyValue( this, Invocation.getter(#previousRoute), ), - returnValueForMissingStub: _i6.dummyValue( + returnValueForMissingStub: _i7.dummyValue( this, Invocation.getter(#previousRoute), ), @@ -103,25 +116,25 @@ class MockNavigationService extends _i1.Mock implements _i5.NavigationService { @override String get currentRoute => (super.noSuchMethod( Invocation.getter(#currentRoute), - returnValue: _i6.dummyValue( + returnValue: _i7.dummyValue( this, Invocation.getter(#currentRoute), ), - returnValueForMissingStub: _i6.dummyValue( + returnValueForMissingStub: _i7.dummyValue( this, Invocation.getter(#currentRoute), ), ) as String); @override - _i7.GlobalKey<_i7.NavigatorState>? nestedNavigationKey(int? index) => + _i8.GlobalKey<_i8.NavigatorState>? nestedNavigationKey(int? index) => (super.noSuchMethod( Invocation.method( #nestedNavigationKey, [index], ), returnValueForMissingStub: null, - ) as _i7.GlobalKey<_i7.NavigatorState>?); + ) as _i8.GlobalKey<_i8.NavigatorState>?); @override void config({ @@ -130,7 +143,7 @@ class MockNavigationService extends _i1.Mock implements _i5.NavigationService { bool? defaultOpaqueRoute, Duration? defaultDurationTransition, bool? defaultGlobalState, - _i5.Transition? defaultTransitionStyle, + _i6.Transition? defaultTransitionStyle, String? defaultTransition, }) => super.noSuchMethod( @@ -151,18 +164,18 @@ class MockNavigationService extends _i1.Mock implements _i5.NavigationService { ); @override - _i8.Future? navigateWithTransition( - _i7.Widget? page, { + _i9.Future? navigateWithTransition( + _i8.Widget? page, { bool? opaque, String? transition = r'', Duration? duration, bool? popGesture, int? id, - _i7.Curve? curve, + _i8.Curve? curve, bool? fullscreenDialog = false, bool? preventDuplicates = true, - _i5.Transition? transitionClass, - _i5.Transition? transitionStyle, + _i6.Transition? transitionClass, + _i6.Transition? transitionStyle, String? routeName, }) => (super.noSuchMethod( @@ -184,21 +197,21 @@ class MockNavigationService extends _i1.Mock implements _i5.NavigationService { }, ), returnValueForMissingStub: null, - ) as _i8.Future?); + ) as _i9.Future?); @override - _i8.Future? replaceWithTransition( - _i7.Widget? page, { + _i9.Future? replaceWithTransition( + _i8.Widget? page, { bool? opaque, String? transition = r'', Duration? duration, bool? popGesture, int? id, - _i7.Curve? curve, + _i8.Curve? curve, bool? fullscreenDialog = false, bool? preventDuplicates = true, - _i5.Transition? transitionClass, - _i5.Transition? transitionStyle, + _i6.Transition? transitionClass, + _i6.Transition? transitionStyle, String? routeName, }) => (super.noSuchMethod( @@ -220,7 +233,7 @@ class MockNavigationService extends _i1.Mock implements _i5.NavigationService { }, ), returnValueForMissingStub: null, - ) as _i8.Future?); + ) as _i9.Future?); @override bool back({ @@ -242,7 +255,7 @@ class MockNavigationService extends _i1.Mock implements _i5.NavigationService { @override void popUntil( - _i7.RoutePredicate? predicate, { + _i8.RoutePredicate? predicate, { int? id, }) => super.noSuchMethod( @@ -264,13 +277,13 @@ class MockNavigationService extends _i1.Mock implements _i5.NavigationService { ); @override - _i8.Future? navigateTo( + _i9.Future? navigateTo( String? routeName, { dynamic arguments, int? id, bool? preventDuplicates = true, Map? parameters, - _i7.RouteTransitionsBuilder? transition, + _i8.RouteTransitionsBuilder? transition, }) => (super.noSuchMethod( Invocation.method( @@ -285,21 +298,21 @@ class MockNavigationService extends _i1.Mock implements _i5.NavigationService { }, ), returnValueForMissingStub: null, - ) as _i8.Future?); + ) as _i9.Future?); @override - _i8.Future? navigateToView( - _i7.Widget? view, { + _i9.Future? navigateToView( + _i8.Widget? view, { dynamic arguments, int? id, bool? opaque, - _i7.Curve? curve, + _i8.Curve? curve, Duration? duration, bool? fullscreenDialog = false, bool? popGesture, bool? preventDuplicates = true, - _i5.Transition? transition, - _i5.Transition? transitionStyle, + _i6.Transition? transition, + _i6.Transition? transitionStyle, }) => (super.noSuchMethod( Invocation.method( @@ -319,16 +332,16 @@ class MockNavigationService extends _i1.Mock implements _i5.NavigationService { }, ), returnValueForMissingStub: null, - ) as _i8.Future?); + ) as _i9.Future?); @override - _i8.Future? replaceWith( + _i9.Future? replaceWith( String? routeName, { dynamic arguments, int? id, bool? preventDuplicates = true, Map? parameters, - _i7.RouteTransitionsBuilder? transition, + _i8.RouteTransitionsBuilder? transition, }) => (super.noSuchMethod( Invocation.method( @@ -343,10 +356,10 @@ class MockNavigationService extends _i1.Mock implements _i5.NavigationService { }, ), returnValueForMissingStub: null, - ) as _i8.Future?); + ) as _i9.Future?); @override - _i8.Future? clearStackAndShow( + _i9.Future? clearStackAndShow( String? routeName, { dynamic arguments, int? id, @@ -363,11 +376,11 @@ class MockNavigationService extends _i1.Mock implements _i5.NavigationService { }, ), returnValueForMissingStub: null, - ) as _i8.Future?); + ) as _i9.Future?); @override - _i8.Future? clearStackAndShowView( - _i7.Widget? view, { + _i9.Future? clearStackAndShowView( + _i8.Widget? view, { dynamic arguments, int? id, }) => @@ -381,10 +394,10 @@ class MockNavigationService extends _i1.Mock implements _i5.NavigationService { }, ), returnValueForMissingStub: null, - ) as _i8.Future?); + ) as _i9.Future?); @override - _i8.Future? clearTillFirstAndShow( + _i9.Future? clearTillFirstAndShow( String? routeName, { dynamic arguments, int? id, @@ -403,11 +416,11 @@ class MockNavigationService extends _i1.Mock implements _i5.NavigationService { }, ), returnValueForMissingStub: null, - ) as _i8.Future?); + ) as _i9.Future?); @override - _i8.Future? clearTillFirstAndShowView( - _i7.Widget? view, { + _i9.Future? clearTillFirstAndShowView( + _i8.Widget? view, { dynamic arguments, int? id, }) => @@ -421,12 +434,12 @@ class MockNavigationService extends _i1.Mock implements _i5.NavigationService { }, ), returnValueForMissingStub: null, - ) as _i8.Future?); + ) as _i9.Future?); @override - _i8.Future? pushNamedAndRemoveUntil( + _i9.Future? pushNamedAndRemoveUntil( String? routeName, { - _i7.RoutePredicate? predicate, + _i8.RoutePredicate? predicate, dynamic arguments, int? id, }) => @@ -441,16 +454,16 @@ class MockNavigationService extends _i1.Mock implements _i5.NavigationService { }, ), returnValueForMissingStub: null, - ) as _i8.Future?); + ) as _i9.Future?); } /// A class which mocks [BottomSheetService]. /// /// See the documentation for Mockito's code generation for more information. class MockBottomSheetService extends _i1.Mock - implements _i5.BottomSheetService { + implements _i6.BottomSheetService { @override - void setCustomSheetBuilders(Map? builders) => + void setCustomSheetBuilders(Map? builders) => super.noSuchMethod( Invocation.method( #setCustomSheetBuilders, @@ -460,7 +473,7 @@ class MockBottomSheetService extends _i1.Mock ); @override - _i8.Future<_i5.SheetResponse?> showBottomSheet({ + _i9.Future<_i6.SheetResponse?> showBottomSheet({ required String? title, String? description, String? confirmButtonTitle = r'Ok', @@ -493,13 +506,13 @@ class MockBottomSheetService extends _i1.Mock #elevation: elevation, }, ), - returnValue: _i8.Future<_i5.SheetResponse?>.value(), + returnValue: _i9.Future<_i6.SheetResponse?>.value(), returnValueForMissingStub: - _i8.Future<_i5.SheetResponse?>.value(), - ) as _i8.Future<_i5.SheetResponse?>); + _i9.Future<_i6.SheetResponse?>.value(), + ) as _i9.Future<_i6.SheetResponse?>); @override - _i8.Future<_i5.SheetResponse?> showCustomSheet({ + _i9.Future<_i6.SheetResponse?> showCustomSheet({ dynamic variant, String? title, String? description, @@ -512,7 +525,7 @@ class MockBottomSheetService extends _i1.Mock bool? showIconInAdditionalButton = false, String? additionalButtonTitle, bool? takesInput = false, - _i9.Color? barrierColor = const _i9.Color(2315255808), + _i10.Color? barrierColor = const _i10.Color(2315255808), double? elevation = 1.0, bool? barrierDismissible = true, bool? isScrollControlled = false, @@ -556,12 +569,12 @@ class MockBottomSheetService extends _i1.Mock #useRootNavigator: useRootNavigator, }, ), - returnValue: _i8.Future<_i5.SheetResponse?>.value(), - returnValueForMissingStub: _i8.Future<_i5.SheetResponse?>.value(), - ) as _i8.Future<_i5.SheetResponse?>); + returnValue: _i9.Future<_i6.SheetResponse?>.value(), + returnValueForMissingStub: _i9.Future<_i6.SheetResponse?>.value(), + ) as _i9.Future<_i6.SheetResponse?>); @override - void completeSheet(_i5.SheetResponse? response) => + void completeSheet(_i6.SheetResponse? response) => super.noSuchMethod( Invocation.method( #completeSheet, @@ -574,10 +587,10 @@ class MockBottomSheetService extends _i1.Mock /// A class which mocks [DialogService]. /// /// See the documentation for Mockito's code generation for more information. -class MockDialogService extends _i1.Mock implements _i5.DialogService { +class MockDialogService extends _i1.Mock implements _i6.DialogService { @override void registerCustomDialogBuilders( - Map? builders) => + Map? builders) => super.noSuchMethod( Invocation.method( #registerCustomDialogBuilders, @@ -589,10 +602,10 @@ class MockDialogService extends _i1.Mock implements _i5.DialogService { @override void registerCustomDialogBuilder({ required dynamic variant, - required _i7.Widget Function( - _i7.BuildContext, - _i5.DialogRequest, - dynamic Function(_i5.DialogResponse), + required _i8.Widget Function( + _i8.BuildContext, + _i6.DialogRequest, + dynamic Function(_i6.DialogResponse), )? builder, }) => super.noSuchMethod( @@ -608,17 +621,17 @@ class MockDialogService extends _i1.Mock implements _i5.DialogService { ); @override - _i8.Future<_i5.DialogResponse?> showDialog({ + _i9.Future<_i6.DialogResponse?> showDialog({ String? title, String? description, String? cancelTitle, - _i9.Color? cancelTitleColor, + _i10.Color? cancelTitleColor, String? buttonTitle = r'Ok', - _i9.Color? buttonTitleColor, + _i10.Color? buttonTitleColor, bool? barrierDismissible = false, - _i7.RouteSettings? routeSettings, - _i7.GlobalKey<_i7.NavigatorState>? navigatorKey, - _i5.DialogPlatform? dialogPlatform, + _i8.RouteSettings? routeSettings, + _i8.GlobalKey<_i8.NavigatorState>? navigatorKey, + _i6.DialogPlatform? dialogPlatform, }) => (super.noSuchMethod( Invocation.method( @@ -637,13 +650,13 @@ class MockDialogService extends _i1.Mock implements _i5.DialogService { #dialogPlatform: dialogPlatform, }, ), - returnValue: _i8.Future<_i5.DialogResponse?>.value(), + returnValue: _i9.Future<_i6.DialogResponse?>.value(), returnValueForMissingStub: - _i8.Future<_i5.DialogResponse?>.value(), - ) as _i8.Future<_i5.DialogResponse?>); + _i9.Future<_i6.DialogResponse?>.value(), + ) as _i9.Future<_i6.DialogResponse?>); @override - _i8.Future<_i5.DialogResponse?> showCustomDialog({ + _i9.Future<_i6.DialogResponse?> showCustomDialog({ dynamic variant, String? title, String? description, @@ -656,13 +669,13 @@ class MockDialogService extends _i1.Mock implements _i5.DialogService { bool? showIconInAdditionalButton = false, String? additionalButtonTitle, bool? takesInput = false, - _i9.Color? barrierColor = const _i9.Color(2315255808), + _i10.Color? barrierColor = const _i10.Color(2315255808), bool? barrierDismissible = false, String? barrierLabel = r'', bool? useSafeArea = true, - _i7.RouteSettings? routeSettings, - _i7.GlobalKey<_i7.NavigatorState>? navigatorKey, - _i7.RouteTransitionsBuilder? transitionBuilder, + _i8.RouteSettings? routeSettings, + _i8.GlobalKey<_i8.NavigatorState>? navigatorKey, + _i8.RouteTransitionsBuilder? transitionBuilder, dynamic customData, R? data, }) => @@ -694,21 +707,21 @@ class MockDialogService extends _i1.Mock implements _i5.DialogService { #data: data, }, ), - returnValue: _i8.Future<_i5.DialogResponse?>.value(), - returnValueForMissingStub: _i8.Future<_i5.DialogResponse?>.value(), - ) as _i8.Future<_i5.DialogResponse?>); + returnValue: _i9.Future<_i6.DialogResponse?>.value(), + returnValueForMissingStub: _i9.Future<_i6.DialogResponse?>.value(), + ) as _i9.Future<_i6.DialogResponse?>); @override - _i8.Future<_i5.DialogResponse?> showConfirmationDialog({ + _i9.Future<_i6.DialogResponse?> showConfirmationDialog({ String? title, String? description, String? cancelTitle = r'Cancel', - _i9.Color? cancelTitleColor, + _i10.Color? cancelTitleColor, String? confirmationTitle = r'Ok', - _i9.Color? confirmationTitleColor, + _i10.Color? confirmationTitleColor, bool? barrierDismissible = false, - _i7.RouteSettings? routeSettings, - _i5.DialogPlatform? dialogPlatform, + _i8.RouteSettings? routeSettings, + _i6.DialogPlatform? dialogPlatform, }) => (super.noSuchMethod( Invocation.method( @@ -726,13 +739,13 @@ class MockDialogService extends _i1.Mock implements _i5.DialogService { #dialogPlatform: dialogPlatform, }, ), - returnValue: _i8.Future<_i5.DialogResponse?>.value(), + returnValue: _i9.Future<_i6.DialogResponse?>.value(), returnValueForMissingStub: - _i8.Future<_i5.DialogResponse?>.value(), - ) as _i8.Future<_i5.DialogResponse?>); + _i9.Future<_i6.DialogResponse?>.value(), + ) as _i9.Future<_i6.DialogResponse?>); @override - void completeDialog(_i5.DialogResponse? response) => + void completeDialog(_i6.DialogResponse? response) => super.noSuchMethod( Invocation.method( #completeDialog, @@ -746,7 +759,7 @@ class MockDialogService extends _i1.Mock implements _i5.DialogService { /// /// See the documentation for Mockito's code generation for more information. class MockAuthenticationService extends _i1.Mock - implements _i10.AuthenticationService { + implements _i11.AuthenticationService { @override int get listenersCount => (super.noSuchMethod( Invocation.getter(#listenersCount), @@ -755,47 +768,47 @@ class MockAuthenticationService extends _i1.Mock ) as int); @override - _i8.Future userLoggedIn() => (super.noSuchMethod( + _i9.Future userLoggedIn() => (super.noSuchMethod( Invocation.method( #userLoggedIn, [], ), - returnValue: _i8.Future.value(false), - returnValueForMissingStub: _i8.Future.value(false), - ) as _i8.Future); + returnValue: _i9.Future.value(false), + returnValueForMissingStub: _i9.Future.value(false), + ) as _i9.Future); @override - _i8.Future getAccessToken() => (super.noSuchMethod( + _i9.Future getAccessToken() => (super.noSuchMethod( Invocation.method( #getAccessToken, [], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future getRefreshToken() => (super.noSuchMethod( + _i9.Future getRefreshToken() => (super.noSuchMethod( Invocation.method( #getRefreshToken, [], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future getUserId() => (super.noSuchMethod( + _i9.Future getUserId() => (super.noSuchMethod( Invocation.method( #getUserId, [], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future saveTokens({ + _i9.Future saveTokens({ required String? access, required String? refresh, }) => @@ -808,101 +821,101 @@ class MockAuthenticationService extends _i1.Mock #refresh: refresh, }, ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future saveUserCredential(Map? data) => + _i9.Future saveUserCredential(Map? data) => (super.noSuchMethod( Invocation.method( #saveUserCredential, [data], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future saveProfileStatus(bool? value) => (super.noSuchMethod( + _i9.Future saveProfileStatus(bool? value) => (super.noSuchMethod( Invocation.method( #saveProfileStatus, [value], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future saveProfilePicture(String? image) => (super.noSuchMethod( + _i9.Future saveProfilePicture(String? image) => (super.noSuchMethod( Invocation.method( #saveProfilePicture, [image], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future saveUserData(_i11.UserModel? data) => (super.noSuchMethod( + _i9.Future saveUserData(_i12.UserModel? data) => (super.noSuchMethod( Invocation.method( #saveUserData, [data], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future updateUserData(Map? data) => + _i9.Future updateUserData(Map? data) => (super.noSuchMethod( Invocation.method( #updateUserData, [data], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future isFirstTimeInstall() => (super.noSuchMethod( + _i9.Future isFirstTimeInstall() => (super.noSuchMethod( Invocation.method( #isFirstTimeInstall, [], ), - returnValue: _i8.Future.value(false), - returnValueForMissingStub: _i8.Future.value(false), - ) as _i8.Future); + returnValue: _i9.Future.value(false), + returnValueForMissingStub: _i9.Future.value(false), + ) as _i9.Future); @override - _i8.Future setFirstTimeInstall(bool? value) => (super.noSuchMethod( + _i9.Future setFirstTimeInstall(bool? value) => (super.noSuchMethod( Invocation.method( #setFirstTimeInstall, [value], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future<_i11.UserModel?> getUser() => (super.noSuchMethod( + _i9.Future<_i12.UserModel?> getUser() => (super.noSuchMethod( Invocation.method( #getUser, [], ), - returnValue: _i8.Future<_i11.UserModel?>.value(), - returnValueForMissingStub: _i8.Future<_i11.UserModel?>.value(), - ) as _i8.Future<_i11.UserModel?>); + returnValue: _i9.Future<_i12.UserModel?>.value(), + returnValueForMissingStub: _i9.Future<_i12.UserModel?>.value(), + ) as _i9.Future<_i12.UserModel?>); @override - _i8.Future logout() => (super.noSuchMethod( + _i9.Future logout() => (super.noSuchMethod( Invocation.method( #logout, [], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override void listenToReactiveValues(List? reactiveValues) => @@ -945,9 +958,9 @@ class MockAuthenticationService extends _i1.Mock /// A class which mocks [ApiService]. /// /// See the documentation for Mockito's code generation for more information. -class MockApiService extends _i1.Mock implements _i12.ApiService { +class MockApiService extends _i1.Mock implements _i13.ApiService { @override - _i8.Future> registerWithEmail( + _i9.Future> registerWithEmail( Map? data) => (super.noSuchMethod( Invocation.method( @@ -955,65 +968,65 @@ class MockApiService extends _i1.Mock implements _i12.ApiService { [data], ), returnValue: - _i8.Future>.value({}), + _i9.Future>.value({}), returnValueForMissingStub: - _i8.Future>.value({}), - ) as _i8.Future>); + _i9.Future>.value({}), + ) as _i9.Future>); @override - _i8.Future> login(Map? data) => + _i9.Future> login(Map? data) => (super.noSuchMethod( Invocation.method( #login, [data], ), returnValue: - _i8.Future>.value({}), + _i9.Future>.value({}), returnValueForMissingStub: - _i8.Future>.value({}), - ) as _i8.Future>); + _i9.Future>.value({}), + ) as _i9.Future>); @override - _i8.Future> googleAuth(Map? data) => + _i9.Future> googleAuth(Map? data) => (super.noSuchMethod( Invocation.method( #googleAuth, [data], ), returnValue: - _i8.Future>.value({}), + _i9.Future>.value({}), returnValueForMissingStub: - _i8.Future>.value({}), - ) as _i8.Future>); + _i9.Future>.value({}), + ) as _i9.Future>); @override - _i8.Future> verifyOtp(Map? data) => + _i9.Future> verifyOtp(Map? data) => (super.noSuchMethod( Invocation.method( #verifyOtp, [data], ), returnValue: - _i8.Future>.value({}), + _i9.Future>.value({}), returnValueForMissingStub: - _i8.Future>.value({}), - ) as _i8.Future>); + _i9.Future>.value({}), + ) as _i9.Future>); @override - _i8.Future> resendOtp(Map? data) => + _i9.Future> resendOtp(Map? data) => (super.noSuchMethod( Invocation.method( #resendOtp, [data], ), returnValue: - _i8.Future>.value({}), + _i9.Future>.value({}), returnValueForMissingStub: - _i8.Future>.value({}), - ) as _i8.Future>); + _i9.Future>.value({}), + ) as _i9.Future>); @override - _i8.Future> requestResetCode( + _i9.Future> requestResetCode( Map? data) => (super.noSuchMethod( Invocation.method( @@ -1021,52 +1034,52 @@ class MockApiService extends _i1.Mock implements _i12.ApiService { [data], ), returnValue: - _i8.Future>.value({}), + _i9.Future>.value({}), returnValueForMissingStub: - _i8.Future>.value({}), - ) as _i8.Future>); + _i9.Future>.value({}), + ) as _i9.Future>); @override - _i8.Future> resetPassword(Map? data) => + _i9.Future> resetPassword(Map? data) => (super.noSuchMethod( Invocation.method( #resetPassword, [data], ), returnValue: - _i8.Future>.value({}), + _i9.Future>.value({}), returnValueForMissingStub: - _i8.Future>.value({}), - ) as _i8.Future>); + _i9.Future>.value({}), + ) as _i9.Future>); @override - _i8.Future> getProfileStatus(_i11.UserModel? user) => + _i9.Future> getProfileStatus(_i12.UserModel? user) => (super.noSuchMethod( Invocation.method( #getProfileStatus, [user], ), returnValue: - _i8.Future>.value({}), + _i9.Future>.value({}), returnValueForMissingStub: - _i8.Future>.value({}), - ) as _i8.Future>); + _i9.Future>.value({}), + ) as _i9.Future>); @override - _i8.Future> getProfileData(int? userId) => + _i9.Future> getProfileData(int? userId) => (super.noSuchMethod( Invocation.method( #getProfileData, [userId], ), returnValue: - _i8.Future>.value({}), + _i9.Future>.value({}), returnValueForMissingStub: - _i8.Future>.value({}), - ) as _i8.Future>); + _i9.Future>.value({}), + ) as _i9.Future>); @override - _i8.Future> completeProfile( + _i9.Future> completeProfile( Map? data) => (super.noSuchMethod( Invocation.method( @@ -1074,13 +1087,13 @@ class MockApiService extends _i1.Mock implements _i12.ApiService { [data], ), returnValue: - _i8.Future>.value({}), + _i9.Future>.value({}), returnValueForMissingStub: - _i8.Future>.value({}), - ) as _i8.Future>); + _i9.Future>.value({}), + ) as _i9.Future>); @override - _i8.Future> updateProfileImage({ + _i9.Future> updateProfileImage({ required int? userId, required Map? data, }) => @@ -1094,126 +1107,124 @@ class MockApiService extends _i1.Mock implements _i12.ApiService { }, ), returnValue: - _i8.Future>.value({}), + _i9.Future>.value({}), returnValueForMissingStub: - _i8.Future>.value({}), - ) as _i8.Future>); + _i9.Future>.value({}), + ) as _i9.Future>); @override - _i8.Future> getAssessments() => (super.noSuchMethod( + _i9.Future> getAssessments() => (super.noSuchMethod( Invocation.method( #getAssessments, [], ), - returnValue: - _i8.Future>.value(<_i13.Assessment>[]), + returnValue: _i9.Future>.value(<_i14.Question>[]), returnValueForMissingStub: - _i8.Future>.value(<_i13.Assessment>[]), - ) as _i8.Future>); + _i9.Future>.value(<_i14.Question>[]), + ) as _i9.Future>); @override - _i8.Future> getCourseCategories() => + _i9.Future> getCourseCategories() => (super.noSuchMethod( Invocation.method( #getCourseCategories, [], ), - returnValue: _i8.Future>.value( - <_i14.CourseCategory>[]), - returnValueForMissingStub: _i8.Future>.value( - <_i14.CourseCategory>[]), - ) as _i8.Future>); + returnValue: _i9.Future>.value( + <_i15.CourseCategory>[]), + returnValueForMissingStub: _i9.Future>.value( + <_i15.CourseCategory>[]), + ) as _i9.Future>); @override - _i8.Future> getCourseSubcategories(int? id) => + _i9.Future> getCourseSubcategories(int? id) => (super.noSuchMethod( Invocation.method( #getCourseSubcategories, [id], ), - returnValue: _i8.Future>.value( - <_i15.CourseSubcategory>[]), + returnValue: _i9.Future>.value( + <_i16.CourseSubcategory>[]), returnValueForMissingStub: - _i8.Future>.value( - <_i15.CourseSubcategory>[]), - ) as _i8.Future>); + _i9.Future>.value( + <_i16.CourseSubcategory>[]), + ) as _i9.Future>); @override - _i8.Future> getCourses(int? id) => (super.noSuchMethod( + _i9.Future> getCourses(int? id) => (super.noSuchMethod( Invocation.method( #getCourses, [id], ), - returnValue: _i8.Future>.value(<_i16.Course>[]), + returnValue: _i9.Future>.value(<_i17.Course>[]), returnValueForMissingStub: - _i8.Future>.value(<_i16.Course>[]), - ) as _i8.Future>); + _i9.Future>.value(<_i17.Course>[]), + ) as _i9.Future>); @override - _i8.Future> getCourseProgress(int? id) => + _i9.Future> getCourseProgress(int? id) => (super.noSuchMethod( Invocation.method( #getCourseProgress, [id], ), - returnValue: _i8.Future>.value( - <_i17.CourseProgress>[]), - returnValueForMissingStub: _i8.Future>.value( - <_i17.CourseProgress>[]), - ) as _i8.Future>); + returnValue: _i9.Future>.value( + <_i18.CourseProgress>[]), + returnValueForMissingStub: _i9.Future>.value( + <_i18.CourseProgress>[]), + ) as _i9.Future>); @override - _i8.Future> getCourseLessons(int? id) => + _i9.Future> getCourseLessons(int? id) => (super.noSuchMethod( Invocation.method( #getCourseLessons, [id], ), returnValue: - _i8.Future>.value(<_i18.CourseLesson>[]), + _i9.Future>.value(<_i19.CourseLesson>[]), returnValueForMissingStub: - _i8.Future>.value(<_i18.CourseLesson>[]), - ) as _i8.Future>); + _i9.Future>.value(<_i19.CourseLesson>[]), + ) as _i9.Future>); @override - _i8.Future> completeLesson(int? id) => + _i9.Future> completeLesson(int? id) => (super.noSuchMethod( Invocation.method( #completeLesson, [id], ), returnValue: - _i8.Future>.value({}), + _i9.Future>.value({}), returnValueForMissingStub: - _i8.Future>.value({}), - ) as _i8.Future>); + _i9.Future>.value({}), + ) as _i9.Future>); @override - _i8.Future> getCoursePractices( - Map? data) => + _i9.Future> getCoursePractices(int? id) => (super.noSuchMethod( Invocation.method( #getCoursePractices, - [data], + [id], ), - returnValue: _i8.Future>.value(<_i19.Practice>[]), + returnValue: _i9.Future>.value(<_i20.Practice>[]), returnValueForMissingStub: - _i8.Future>.value(<_i19.Practice>[]), - ) as _i8.Future>); + _i9.Future>.value(<_i20.Practice>[]), + ) as _i9.Future>); @override - _i8.Future> getCoursePracticeQuestions(int? id) => + _i9.Future> getCoursePracticeQuestions(int? id) => (super.noSuchMethod( Invocation.method( #getCoursePracticeQuestions, [id], ), - returnValue: _i8.Future>.value( - <_i20.PracticeQuestion>[]), + returnValue: _i9.Future>.value( + <_i21.PracticeQuestion>[]), returnValueForMissingStub: - _i8.Future>.value( - <_i20.PracticeQuestion>[]), - ) as _i8.Future>); + _i9.Future>.value( + <_i21.PracticeQuestion>[]), + ) as _i9.Future>); } /// A class which mocks [SecureStorageService]. @@ -1222,47 +1233,47 @@ class MockApiService extends _i1.Mock implements _i12.ApiService { class MockSecureStorageService extends _i1.Mock implements _i3.SecureStorageService { @override - _i8.Future clear() => (super.noSuchMethod( + _i9.Future clear() => (super.noSuchMethod( Invocation.method( #clear, [], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future getBool(String? key) => (super.noSuchMethod( + _i9.Future getBool(String? key) => (super.noSuchMethod( Invocation.method( #getBool, [key], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future getString(String? key) => (super.noSuchMethod( + _i9.Future getString(String? key) => (super.noSuchMethod( Invocation.method( #getString, [key], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future getInt(String? key) => (super.noSuchMethod( + _i9.Future getInt(String? key) => (super.noSuchMethod( Invocation.method( #getInt, [key], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future setString( + _i9.Future setString( String? key, String? value, ) => @@ -1274,12 +1285,12 @@ class MockSecureStorageService extends _i1.Mock value, ], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future setInt( + _i9.Future setInt( String? key, int? value, ) => @@ -1291,12 +1302,12 @@ class MockSecureStorageService extends _i1.Mock value, ], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future setBool( + _i9.Future setBool( String? key, bool? value, ) => @@ -1308,15 +1319,15 @@ class MockSecureStorageService extends _i1.Mock value, ], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); } /// A class which mocks [DioService]. /// /// See the documentation for Mockito's code generation for more information. -class MockDioService extends _i1.Mock implements _i21.DioService { +class MockDioService extends _i1.Mock implements _i22.DioService { @override _i2.Dio get dio => (super.noSuchMethod( Invocation.getter(#dio), @@ -1335,7 +1346,7 @@ class MockDioService extends _i1.Mock implements _i21.DioService { /// /// See the documentation for Mockito's code generation for more information. class MockStatusCheckerService extends _i1.Mock - implements _i22.StatusCheckerService { + implements _i23.StatusCheckerService { @override _i3.SecureStorageService get storage => (super.noSuchMethod( Invocation.getter(#storage), @@ -1357,109 +1368,109 @@ class MockStatusCheckerService extends _i1.Mock ) as bool); @override - _i8.Future getBatteryLevel() => (super.noSuchMethod( + _i9.Future getBatteryLevel() => (super.noSuchMethod( Invocation.method( #getBatteryLevel, [], ), - returnValue: _i8.Future.value(0), - returnValueForMissingStub: _i8.Future.value(0), - ) as _i8.Future); + returnValue: _i9.Future.value(0), + returnValueForMissingStub: _i9.Future.value(0), + ) as _i9.Future); @override - _i8.Future checkConnection() => (super.noSuchMethod( + _i9.Future checkConnection() => (super.noSuchMethod( Invocation.method( #checkConnection, [], ), - returnValue: _i8.Future.value(false), - returnValueForMissingStub: _i8.Future.value(false), - ) as _i8.Future); + returnValue: _i9.Future.value(false), + returnValueForMissingStub: _i9.Future.value(false), + ) as _i9.Future); @override - _i8.Future getAvailableStorage() => (super.noSuchMethod( + _i9.Future getAvailableStorage() => (super.noSuchMethod( Invocation.method( #getAvailableStorage, [], ), - returnValue: _i8.Future.value(0), - returnValueForMissingStub: _i8.Future.value(0), - ) as _i8.Future); + returnValue: _i9.Future.value(0), + returnValueForMissingStub: _i9.Future.value(0), + ) as _i9.Future); @override - _i8.Future checkAndUpdate() => (super.noSuchMethod( + _i9.Future checkAndUpdate() => (super.noSuchMethod( Invocation.method( #checkAndUpdate, [], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); } /// A class which mocks [PermissionHandlerService]. /// /// See the documentation for Mockito's code generation for more information. class MockPermissionHandlerService extends _i1.Mock - implements _i23.PermissionHandlerService { + implements _i24.PermissionHandlerService { @override - _i8.Future<_i24.PermissionStatus> requestPermission( - _i24.Permission? requestedPermission) => + _i9.Future<_i25.PermissionStatus> requestPermission( + _i25.Permission? requestedPermission) => (super.noSuchMethod( Invocation.method( #requestPermission, [requestedPermission], ), - returnValue: _i8.Future<_i24.PermissionStatus>.value( - _i24.PermissionStatus.denied), - returnValueForMissingStub: _i8.Future<_i24.PermissionStatus>.value( - _i24.PermissionStatus.denied), - ) as _i8.Future<_i24.PermissionStatus>); + returnValue: _i9.Future<_i25.PermissionStatus>.value( + _i25.PermissionStatus.denied), + returnValueForMissingStub: _i9.Future<_i25.PermissionStatus>.value( + _i25.PermissionStatus.denied), + ) as _i9.Future<_i25.PermissionStatus>); @override - _i8.Future<_i24.PermissionStatus> request(_i24.Permission? permission) => + _i9.Future<_i25.PermissionStatus> request(_i25.Permission? permission) => (super.noSuchMethod( Invocation.method( #request, [permission], ), - returnValue: _i8.Future<_i24.PermissionStatus>.value( - _i24.PermissionStatus.denied), - returnValueForMissingStub: _i8.Future<_i24.PermissionStatus>.value( - _i24.PermissionStatus.denied), - ) as _i8.Future<_i24.PermissionStatus>); + returnValue: _i9.Future<_i25.PermissionStatus>.value( + _i25.PermissionStatus.denied), + returnValueForMissingStub: _i9.Future<_i25.PermissionStatus>.value( + _i25.PermissionStatus.denied), + ) as _i9.Future<_i25.PermissionStatus>); } /// A class which mocks [ImagePickerService]. /// /// See the documentation for Mockito's code generation for more information. class MockImagePickerService extends _i1.Mock - implements _i25.ImagePickerService { + implements _i26.ImagePickerService { @override - _i8.Future gallery() => (super.noSuchMethod( + _i9.Future gallery() => (super.noSuchMethod( Invocation.method( #gallery, [], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future camera() => (super.noSuchMethod( + _i9.Future camera() => (super.noSuchMethod( Invocation.method( #camera, [], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); } /// A class which mocks [GoogleAuthService]. /// /// See the documentation for Mockito's code generation for more information. -class MockGoogleAuthService extends _i1.Mock implements _i26.GoogleAuthService { +class MockGoogleAuthService extends _i1.Mock implements _i27.GoogleAuthService { @override int get listenersCount => (super.noSuchMethod( Invocation.getter(#listenersCount), @@ -1468,24 +1479,24 @@ class MockGoogleAuthService extends _i1.Mock implements _i26.GoogleAuthService { ) as int); @override - _i8.Future logout() => (super.noSuchMethod( + _i9.Future logout() => (super.noSuchMethod( Invocation.method( #logout, [], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future googleAuth() => (super.noSuchMethod( + _i9.Future googleAuth() => (super.noSuchMethod( Invocation.method( #googleAuth, [], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override void listenToReactiveValues(List? reactiveValues) => @@ -1529,14 +1540,14 @@ class MockGoogleAuthService extends _i1.Mock implements _i26.GoogleAuthService { /// /// See the documentation for Mockito's code generation for more information. class MockImageDownloaderService extends _i1.Mock - implements _i27.ImageDownloaderService { + implements _i28.ImageDownloaderService { @override - _i8.Future downloader(String? networkImage) => (super.noSuchMethod( + _i9.Future downloader(String? networkImage) => (super.noSuchMethod( Invocation.method( #downloader, [networkImage], ), - returnValue: _i8.Future.value(_i6.dummyValue( + returnValue: _i9.Future.value(_i7.dummyValue( this, Invocation.method( #downloader, @@ -1544,77 +1555,77 @@ class MockImageDownloaderService extends _i1.Mock ), )), returnValueForMissingStub: - _i8.Future.value(_i6.dummyValue( + _i9.Future.value(_i7.dummyValue( this, Invocation.method( #downloader, [networkImage], ), )), - ) as _i8.Future); + ) as _i9.Future); } /// A class which mocks [NotificationService]. /// /// See the documentation for Mockito's code generation for more information. class MockNotificationService extends _i1.Mock - implements _i28.NotificationService { + implements _i29.NotificationService { @override - _i8.Future initialize() => (super.noSuchMethod( + _i9.Future initialize() => (super.noSuchMethod( Invocation.method( #initialize, [], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future setupFlutterNotifications() => (super.noSuchMethod( + _i9.Future setupFlutterNotifications() => (super.noSuchMethod( Invocation.method( #setupFlutterNotifications, [], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future showNotification(_i29.RemoteMessage? message) => + _i9.Future showNotification(_i30.RemoteMessage? message) => (super.noSuchMethod( Invocation.method( #showNotification, [message], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future subscribeToTopic(String? topic) => (super.noSuchMethod( + _i9.Future subscribeToTopic(String? topic) => (super.noSuchMethod( Invocation.method( #subscribeToTopic, [topic], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future updateFCMToken() => (super.noSuchMethod( + _i9.Future updateFCMToken() => (super.noSuchMethod( Invocation.method( #updateFCMToken, [], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); } /// A class which mocks [SmartAuthService]. /// /// See the documentation for Mockito's code generation for more information. -class MockSmartAuthService extends _i1.Mock implements _i30.SmartAuthService { +class MockSmartAuthService extends _i1.Mock implements _i31.SmartAuthService { @override bool get listenForMultipleSms => (super.noSuchMethod( Invocation.getter(#listenForMultipleSms), @@ -1623,49 +1634,49 @@ class MockSmartAuthService extends _i1.Mock implements _i30.SmartAuthService { ) as bool); @override - _i8.Future dispose() => (super.noSuchMethod( + _i9.Future dispose() => (super.noSuchMethod( Invocation.method( #dispose, [], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future getSmsCode() => (super.noSuchMethod( + _i9.Future getSmsCode() => (super.noSuchMethod( Invocation.method( #getSmsCode, [], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); } /// A class which mocks [CourseService]. /// /// See the documentation for Mockito's code generation for more information. -class MockCourseService extends _i1.Mock implements _i31.CourseService { +class MockCourseService extends _i1.Mock implements _i32.CourseService { @override - _i8.Future> getCoursesDetail(int? id) => + _i9.Future> getCoursesDetail(int? id) => (super.noSuchMethod( Invocation.method( #getCoursesDetail, [id], ), returnValue: - _i8.Future>.value(<_i32.CourseDetail>[]), + _i9.Future>.value(<_i33.CourseDetail>[]), returnValueForMissingStub: - _i8.Future>.value(<_i32.CourseDetail>[]), - ) as _i8.Future>); + _i9.Future>.value(<_i33.CourseDetail>[]), + ) as _i9.Future>); } /// A class which mocks [AudioPlayerService]. /// /// See the documentation for Mockito's code generation for more information. class MockAudioPlayerService extends _i1.Mock - implements _i33.AudioPlayerService { + implements _i34.AudioPlayerService { @override _i4.AudioPlayer get player => (super.noSuchMethod( Invocation.getter(#player), @@ -1680,25 +1691,25 @@ class MockAudioPlayerService extends _i1.Mock ) as _i4.AudioPlayer); @override - _i8.Stream get positionStream => (super.noSuchMethod( + _i9.Stream get positionStream => (super.noSuchMethod( Invocation.getter(#positionStream), - returnValue: _i8.Stream.empty(), - returnValueForMissingStub: _i8.Stream.empty(), - ) as _i8.Stream); + returnValue: _i9.Stream.empty(), + returnValueForMissingStub: _i9.Stream.empty(), + ) as _i9.Stream); @override - _i8.Stream get durationStream => (super.noSuchMethod( + _i9.Stream get durationStream => (super.noSuchMethod( Invocation.getter(#durationStream), - returnValue: _i8.Stream.empty(), - returnValueForMissingStub: _i8.Stream.empty(), - ) as _i8.Stream); + returnValue: _i9.Stream.empty(), + returnValueForMissingStub: _i9.Stream.empty(), + ) as _i9.Stream); @override - _i8.Stream<_i4.PlayerState> get stateStream => (super.noSuchMethod( + _i9.Stream<_i4.PlayerState> get stateStream => (super.noSuchMethod( Invocation.getter(#stateStream), - returnValue: _i8.Stream<_i4.PlayerState>.empty(), - returnValueForMissingStub: _i8.Stream<_i4.PlayerState>.empty(), - ) as _i8.Stream<_i4.PlayerState>); + returnValue: _i9.Stream<_i4.PlayerState>.empty(), + returnValueForMissingStub: _i9.Stream<_i4.PlayerState>.empty(), + ) as _i9.Stream<_i4.PlayerState>); @override int get listenersCount => (super.noSuchMethod( @@ -1708,34 +1719,44 @@ class MockAudioPlayerService extends _i1.Mock ) as int); @override - _i8.Future playUrl(String? url) => (super.noSuchMethod( + _i9.Future playUrl(String? url) => (super.noSuchMethod( Invocation.method( - #play, + #playUrl, [url], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future pause() => (super.noSuchMethod( + _i9.Future playLocal(String? url) => (super.noSuchMethod( + Invocation.method( + #playLocal, + [url], + ), + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); + + @override + _i9.Future pause() => (super.noSuchMethod( Invocation.method( #pause, [], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override - _i8.Future seek(Duration? position) => (super.noSuchMethod( + _i9.Future seek(Duration? position) => (super.noSuchMethod( Invocation.method( #seek, [position], ), - returnValue: _i8.Future.value(), - returnValueForMissingStub: _i8.Future.value(), - ) as _i8.Future); + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); @override void listenToReactiveValues(List? reactiveValues) => @@ -1779,4 +1800,98 @@ class MockAudioPlayerService extends _i1.Mock /// /// See the documentation for Mockito's code generation for more information. class MockVoiceRecorderService extends _i1.Mock - implements _i34.VoiceRecorderService {} + implements _i35.VoiceRecorderService { + @override + _i36.VoiceRecordingState get recordingState => (super.noSuchMethod( + Invocation.getter(#recordingState), + returnValue: _i36.VoiceRecordingState.pending, + returnValueForMissingStub: _i36.VoiceRecordingState.pending, + ) as _i36.VoiceRecordingState); + + @override + _i5.WaveformRecorderController get waveController => (super.noSuchMethod( + Invocation.getter(#waveController), + returnValue: _FakeWaveformRecorderController_3( + this, + Invocation.getter(#waveController), + ), + returnValueForMissingStub: _FakeWaveformRecorderController_3( + this, + Invocation.getter(#waveController), + ), + ) as _i5.WaveformRecorderController); + + @override + int get listenersCount => (super.noSuchMethod( + Invocation.getter(#listenersCount), + returnValue: 0, + returnValueForMissingStub: 0, + ) as int); + + @override + _i9.Future startRecording() => (super.noSuchMethod( + Invocation.method( + #startRecording, + [], + ), + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); + + @override + _i9.Future stopRecording() => (super.noSuchMethod( + Invocation.method( + #stopRecording, + [], + ), + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); + + @override + _i9.Future getRecordedAudio() => (super.noSuchMethod( + Invocation.method( + #getRecordedAudio, + [], + ), + returnValue: _i9.Future.value(), + returnValueForMissingStub: _i9.Future.value(), + ) as _i9.Future); + + @override + void listenToReactiveValues(List? reactiveValues) => + super.noSuchMethod( + Invocation.method( + #listenToReactiveValues, + [reactiveValues], + ), + returnValueForMissingStub: null, + ); + + @override + void addListener(void Function()? listener) => super.noSuchMethod( + Invocation.method( + #addListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + void removeListener(void Function()? listener) => super.noSuchMethod( + Invocation.method( + #removeListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + void notifyListeners() => super.noSuchMethod( + Invocation.method( + #notifyListeners, + [], + ), + returnValueForMissingStub: null, + ); +} diff --git a/test/viewmodels/course_practice_question_viewmodel_test.dart b/test/viewmodels/course_practice_question_viewmodel_test.dart new file mode 100644 index 0000000..8400e76 --- /dev/null +++ b/test/viewmodels/course_practice_question_viewmodel_test.dart @@ -0,0 +1,11 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:yimaru_app/app/app.locator.dart'; + +import '../helpers/test_helpers.dart'; + +void main() { + group('CoursePracticeQuestionViewModel Tests -', () { + setUp(() => registerServices()); + tearDown(() => locator.reset()); + }); +}