Merge branch 'release/0.1.9'
-fix(onboarding): Change onboarding assessment implementation
This commit is contained in:
commit
6b4f87476e
|
|
@ -25,7 +25,6 @@ import 'package:yimaru_app/services/secure_storage_service.dart';
|
||||||
import 'package:yimaru_app/services/dio_service.dart';
|
import 'package:yimaru_app/services/dio_service.dart';
|
||||||
import 'package:yimaru_app/services/status_checker_service.dart';
|
import 'package:yimaru_app/services/status_checker_service.dart';
|
||||||
import 'package:yimaru_app/ui/views/welcome/welcome_view.dart';
|
import 'package:yimaru_app/ui/views/welcome/welcome_view.dart';
|
||||||
import 'package:yimaru_app/ui/views/assessment/assessment_view.dart';
|
|
||||||
import 'package:yimaru_app/ui/views/learn_lesson/learn_lesson_view.dart';
|
import 'package:yimaru_app/ui/views/learn_lesson/learn_lesson_view.dart';
|
||||||
import 'package:yimaru_app/services/permission_handler_service.dart';
|
import 'package:yimaru_app/services/permission_handler_service.dart';
|
||||||
import 'package:yimaru_app/services/image_picker_service.dart';
|
import 'package:yimaru_app/services/image_picker_service.dart';
|
||||||
|
|
@ -52,6 +51,7 @@ import 'package:yimaru_app/ui/views/course_practice_question/course_practice_que
|
||||||
import 'package:yimaru_app/services/in_app_update_service.dart';
|
import 'package:yimaru_app/services/in_app_update_service.dart';
|
||||||
import 'package:yimaru_app/ui/views/learn_program/learn_program_view.dart';
|
import 'package:yimaru_app/ui/views/learn_program/learn_program_view.dart';
|
||||||
import 'package:yimaru_app/ui/views/learn_course/learn_course_view.dart';
|
import 'package:yimaru_app/ui/views/learn_course/learn_course_view.dart';
|
||||||
|
import 'package:yimaru_app/ui/views/assessment/assessment_view.dart';
|
||||||
// @stacked-import
|
// @stacked-import
|
||||||
|
|
||||||
@StackedApp(
|
@StackedApp(
|
||||||
|
|
@ -74,7 +74,6 @@ import 'package:yimaru_app/ui/views/learn_course/learn_course_view.dart';
|
||||||
MaterialRoute(page: LoginView),
|
MaterialRoute(page: LoginView),
|
||||||
MaterialRoute(page: LearnModuleView),
|
MaterialRoute(page: LearnModuleView),
|
||||||
MaterialRoute(page: WelcomeView),
|
MaterialRoute(page: WelcomeView),
|
||||||
MaterialRoute(page: AssessmentView),
|
|
||||||
MaterialRoute(page: LearnLessonView),
|
MaterialRoute(page: LearnLessonView),
|
||||||
MaterialRoute(page: ForgetPasswordView),
|
MaterialRoute(page: ForgetPasswordView),
|
||||||
MaterialRoute(page: LearnLessonDetailView),
|
MaterialRoute(page: LearnLessonDetailView),
|
||||||
|
|
@ -91,6 +90,7 @@ import 'package:yimaru_app/ui/views/learn_course/learn_course_view.dart';
|
||||||
MaterialRoute(page: CoursePracticeQuestionView),
|
MaterialRoute(page: CoursePracticeQuestionView),
|
||||||
MaterialRoute(page: LearnProgramView),
|
MaterialRoute(page: LearnProgramView),
|
||||||
MaterialRoute(page: LearnCourseView),
|
MaterialRoute(page: LearnCourseView),
|
||||||
|
MaterialRoute(page: AssessmentView),
|
||||||
// @stacked-route
|
// @stacked-route
|
||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
|
|
|
||||||
|
|
@ -20,43 +20,43 @@ import 'package:yimaru_app/models/subcategory.dart' as _i45;
|
||||||
import 'package:yimaru_app/ui/common/enmus.dart' as _i41;
|
import 'package:yimaru_app/ui/common/enmus.dart' as _i41;
|
||||||
import 'package:yimaru_app/ui/views/account_privacy/account_privacy_view.dart'
|
import 'package:yimaru_app/ui/views/account_privacy/account_privacy_view.dart'
|
||||||
as _i9;
|
as _i9;
|
||||||
import 'package:yimaru_app/ui/views/assessment/assessment_view.dart' as _i20;
|
import 'package:yimaru_app/ui/views/assessment/assessment_view.dart' as _i36;
|
||||||
import 'package:yimaru_app/ui/views/call_support/call_support_view.dart'
|
import 'package:yimaru_app/ui/views/call_support/call_support_view.dart'
|
||||||
as _i12;
|
as _i12;
|
||||||
import 'package:yimaru_app/ui/views/course/course_view.dart' as _i33;
|
import 'package:yimaru_app/ui/views/course/course_view.dart' as _i32;
|
||||||
import 'package:yimaru_app/ui/views/course_category/course_category_view.dart'
|
import 'package:yimaru_app/ui/views/course_category/course_category_view.dart'
|
||||||
as _i27;
|
|
||||||
import 'package:yimaru_app/ui/views/course_lesson/course_lesson_view.dart'
|
|
||||||
as _i29;
|
|
||||||
import 'package:yimaru_app/ui/views/course_lesson_detail/course_lesson_detail_view.dart'
|
|
||||||
as _i30;
|
|
||||||
import 'package:yimaru_app/ui/views/course_payment/course_payment_view.dart'
|
|
||||||
as _i26;
|
as _i26;
|
||||||
import 'package:yimaru_app/ui/views/course_practice/course_practice_view.dart'
|
import 'package:yimaru_app/ui/views/course_lesson/course_lesson_view.dart'
|
||||||
|
as _i28;
|
||||||
|
import 'package:yimaru_app/ui/views/course_lesson_detail/course_lesson_detail_view.dart'
|
||||||
|
as _i29;
|
||||||
|
import 'package:yimaru_app/ui/views/course_payment/course_payment_view.dart'
|
||||||
as _i25;
|
as _i25;
|
||||||
|
import 'package:yimaru_app/ui/views/course_practice/course_practice_view.dart'
|
||||||
|
as _i24;
|
||||||
import 'package:yimaru_app/ui/views/course_practice_question/course_practice_question_view.dart'
|
import 'package:yimaru_app/ui/views/course_practice_question/course_practice_question_view.dart'
|
||||||
as _i34;
|
as _i33;
|
||||||
import 'package:yimaru_app/ui/views/course_subcategory/course_subcategory_view.dart'
|
import 'package:yimaru_app/ui/views/course_subcategory/course_subcategory_view.dart'
|
||||||
as _i32;
|
as _i31;
|
||||||
import 'package:yimaru_app/ui/views/downloads/downloads_view.dart' as _i7;
|
import 'package:yimaru_app/ui/views/downloads/downloads_view.dart' as _i7;
|
||||||
import 'package:yimaru_app/ui/views/duolingo/duolingo_view.dart' as _i31;
|
import 'package:yimaru_app/ui/views/duolingo/duolingo_view.dart' as _i30;
|
||||||
import 'package:yimaru_app/ui/views/failure/failure_view.dart' as _i28;
|
import 'package:yimaru_app/ui/views/failure/failure_view.dart' as _i27;
|
||||||
import 'package:yimaru_app/ui/views/forget_password/forget_password_view.dart'
|
import 'package:yimaru_app/ui/views/forget_password/forget_password_view.dart'
|
||||||
as _i22;
|
as _i21;
|
||||||
import 'package:yimaru_app/ui/views/home/home_view.dart' as _i2;
|
import 'package:yimaru_app/ui/views/home/home_view.dart' as _i2;
|
||||||
import 'package:yimaru_app/ui/views/language/language_view.dart' as _i13;
|
import 'package:yimaru_app/ui/views/language/language_view.dart' as _i13;
|
||||||
import 'package:yimaru_app/ui/views/learn_course/learn_course_view.dart'
|
import 'package:yimaru_app/ui/views/learn_course/learn_course_view.dart'
|
||||||
as _i36;
|
as _i35;
|
||||||
import 'package:yimaru_app/ui/views/learn_lesson/learn_lesson_view.dart'
|
import 'package:yimaru_app/ui/views/learn_lesson/learn_lesson_view.dart'
|
||||||
as _i21;
|
as _i20;
|
||||||
import 'package:yimaru_app/ui/views/learn_lesson_detail/learn_lesson_detail_view.dart'
|
import 'package:yimaru_app/ui/views/learn_lesson_detail/learn_lesson_detail_view.dart'
|
||||||
as _i23;
|
as _i22;
|
||||||
import 'package:yimaru_app/ui/views/learn_module/learn_module_view.dart'
|
import 'package:yimaru_app/ui/views/learn_module/learn_module_view.dart'
|
||||||
as _i18;
|
as _i18;
|
||||||
import 'package:yimaru_app/ui/views/learn_practice/learn_practice_view.dart'
|
import 'package:yimaru_app/ui/views/learn_practice/learn_practice_view.dart'
|
||||||
as _i24;
|
as _i23;
|
||||||
import 'package:yimaru_app/ui/views/learn_program/learn_program_view.dart'
|
import 'package:yimaru_app/ui/views/learn_program/learn_program_view.dart'
|
||||||
as _i35;
|
as _i34;
|
||||||
import 'package:yimaru_app/ui/views/login/login_view.dart' as _i17;
|
import 'package:yimaru_app/ui/views/login/login_view.dart' as _i17;
|
||||||
import 'package:yimaru_app/ui/views/onboarding/onboarding_view.dart' as _i3;
|
import 'package:yimaru_app/ui/views/onboarding/onboarding_view.dart' as _i3;
|
||||||
import 'package:yimaru_app/ui/views/privacy_policy/privacy_policy_view.dart'
|
import 'package:yimaru_app/ui/views/privacy_policy/privacy_policy_view.dart'
|
||||||
|
|
@ -111,8 +111,6 @@ class Routes {
|
||||||
|
|
||||||
static const welcomeView = '/welcome-view';
|
static const welcomeView = '/welcome-view';
|
||||||
|
|
||||||
static const assessmentView = '/assessment-view';
|
|
||||||
|
|
||||||
static const learnLessonView = '/learn-lesson-view';
|
static const learnLessonView = '/learn-lesson-view';
|
||||||
|
|
||||||
static const forgetPasswordView = '/forget-password-view';
|
static const forgetPasswordView = '/forget-password-view';
|
||||||
|
|
@ -145,6 +143,8 @@ class Routes {
|
||||||
|
|
||||||
static const learnCourseView = '/learn-course-view';
|
static const learnCourseView = '/learn-course-view';
|
||||||
|
|
||||||
|
static const assessmentView = '/assessment-view';
|
||||||
|
|
||||||
static const all = <String>{
|
static const all = <String>{
|
||||||
homeView,
|
homeView,
|
||||||
onboardingView,
|
onboardingView,
|
||||||
|
|
@ -164,7 +164,6 @@ class Routes {
|
||||||
loginView,
|
loginView,
|
||||||
learnModuleView,
|
learnModuleView,
|
||||||
welcomeView,
|
welcomeView,
|
||||||
assessmentView,
|
|
||||||
learnLessonView,
|
learnLessonView,
|
||||||
forgetPasswordView,
|
forgetPasswordView,
|
||||||
learnLessonDetailView,
|
learnLessonDetailView,
|
||||||
|
|
@ -181,6 +180,7 @@ class Routes {
|
||||||
coursePracticeQuestionView,
|
coursePracticeQuestionView,
|
||||||
learnProgramView,
|
learnProgramView,
|
||||||
learnCourseView,
|
learnCourseView,
|
||||||
|
assessmentView,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -258,73 +258,73 @@ class StackedRouter extends _i1.RouterBase {
|
||||||
Routes.welcomeView,
|
Routes.welcomeView,
|
||||||
page: _i19.WelcomeView,
|
page: _i19.WelcomeView,
|
||||||
),
|
),
|
||||||
_i1.RouteDef(
|
|
||||||
Routes.assessmentView,
|
|
||||||
page: _i20.AssessmentView,
|
|
||||||
),
|
|
||||||
_i1.RouteDef(
|
_i1.RouteDef(
|
||||||
Routes.learnLessonView,
|
Routes.learnLessonView,
|
||||||
page: _i21.LearnLessonView,
|
page: _i20.LearnLessonView,
|
||||||
),
|
),
|
||||||
_i1.RouteDef(
|
_i1.RouteDef(
|
||||||
Routes.forgetPasswordView,
|
Routes.forgetPasswordView,
|
||||||
page: _i22.ForgetPasswordView,
|
page: _i21.ForgetPasswordView,
|
||||||
),
|
),
|
||||||
_i1.RouteDef(
|
_i1.RouteDef(
|
||||||
Routes.learnLessonDetailView,
|
Routes.learnLessonDetailView,
|
||||||
page: _i23.LearnLessonDetailView,
|
page: _i22.LearnLessonDetailView,
|
||||||
),
|
),
|
||||||
_i1.RouteDef(
|
_i1.RouteDef(
|
||||||
Routes.learnPracticeView,
|
Routes.learnPracticeView,
|
||||||
page: _i24.LearnPracticeView,
|
page: _i23.LearnPracticeView,
|
||||||
),
|
),
|
||||||
_i1.RouteDef(
|
_i1.RouteDef(
|
||||||
Routes.coursePracticeView,
|
Routes.coursePracticeView,
|
||||||
page: _i25.CoursePracticeView,
|
page: _i24.CoursePracticeView,
|
||||||
),
|
),
|
||||||
_i1.RouteDef(
|
_i1.RouteDef(
|
||||||
Routes.coursePaymentView,
|
Routes.coursePaymentView,
|
||||||
page: _i26.CoursePaymentView,
|
page: _i25.CoursePaymentView,
|
||||||
),
|
),
|
||||||
_i1.RouteDef(
|
_i1.RouteDef(
|
||||||
Routes.courseCategoryView,
|
Routes.courseCategoryView,
|
||||||
page: _i27.CourseCategoryView,
|
page: _i26.CourseCategoryView,
|
||||||
),
|
),
|
||||||
_i1.RouteDef(
|
_i1.RouteDef(
|
||||||
Routes.failureView,
|
Routes.failureView,
|
||||||
page: _i28.FailureView,
|
page: _i27.FailureView,
|
||||||
),
|
),
|
||||||
_i1.RouteDef(
|
_i1.RouteDef(
|
||||||
Routes.courseLessonView,
|
Routes.courseLessonView,
|
||||||
page: _i29.CourseLessonView,
|
page: _i28.CourseLessonView,
|
||||||
),
|
),
|
||||||
_i1.RouteDef(
|
_i1.RouteDef(
|
||||||
Routes.courseLessonDetailView,
|
Routes.courseLessonDetailView,
|
||||||
page: _i30.CourseLessonDetailView,
|
page: _i29.CourseLessonDetailView,
|
||||||
),
|
),
|
||||||
_i1.RouteDef(
|
_i1.RouteDef(
|
||||||
Routes.duolingoView,
|
Routes.duolingoView,
|
||||||
page: _i31.DuolingoView,
|
page: _i30.DuolingoView,
|
||||||
),
|
),
|
||||||
_i1.RouteDef(
|
_i1.RouteDef(
|
||||||
Routes.courseSubcategoryView,
|
Routes.courseSubcategoryView,
|
||||||
page: _i32.CourseSubcategoryView,
|
page: _i31.CourseSubcategoryView,
|
||||||
),
|
),
|
||||||
_i1.RouteDef(
|
_i1.RouteDef(
|
||||||
Routes.courseView,
|
Routes.courseView,
|
||||||
page: _i33.CourseView,
|
page: _i32.CourseView,
|
||||||
),
|
),
|
||||||
_i1.RouteDef(
|
_i1.RouteDef(
|
||||||
Routes.coursePracticeQuestionView,
|
Routes.coursePracticeQuestionView,
|
||||||
page: _i34.CoursePracticeQuestionView,
|
page: _i33.CoursePracticeQuestionView,
|
||||||
),
|
),
|
||||||
_i1.RouteDef(
|
_i1.RouteDef(
|
||||||
Routes.learnProgramView,
|
Routes.learnProgramView,
|
||||||
page: _i35.LearnProgramView,
|
page: _i34.LearnProgramView,
|
||||||
),
|
),
|
||||||
_i1.RouteDef(
|
_i1.RouteDef(
|
||||||
Routes.learnCourseView,
|
Routes.learnCourseView,
|
||||||
page: _i36.LearnCourseView,
|
page: _i35.LearnCourseView,
|
||||||
|
),
|
||||||
|
_i1.RouteDef(
|
||||||
|
Routes.assessmentView,
|
||||||
|
page: _i36.AssessmentView,
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
@ -490,143 +490,143 @@ class StackedRouter extends _i1.RouterBase {
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i20.AssessmentView: (data) {
|
_i20.LearnLessonView: (data) {
|
||||||
final args = data.getArgs<AssessmentViewArguments>(nullOk: false);
|
|
||||||
return _i37.MaterialPageRoute<dynamic>(
|
|
||||||
builder: (context) =>
|
|
||||||
_i20.AssessmentView(key: args.key, data: args.data),
|
|
||||||
settings: data,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
_i21.LearnLessonView: (data) {
|
|
||||||
final args = data.getArgs<LearnLessonViewArguments>(nullOk: false);
|
final args = data.getArgs<LearnLessonViewArguments>(nullOk: false);
|
||||||
return _i37.MaterialPageRoute<dynamic>(
|
return _i37.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) =>
|
builder: (context) =>
|
||||||
_i21.LearnLessonView(key: args.key, module: args.module),
|
_i20.LearnLessonView(key: args.key, module: args.module),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i22.ForgetPasswordView: (data) {
|
_i21.ForgetPasswordView: (data) {
|
||||||
final args = data.getArgs<ForgetPasswordViewArguments>(
|
final args = data.getArgs<ForgetPasswordViewArguments>(
|
||||||
orElse: () => const ForgetPasswordViewArguments(),
|
orElse: () => const ForgetPasswordViewArguments(),
|
||||||
);
|
);
|
||||||
return _i37.MaterialPageRoute<dynamic>(
|
return _i37.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => _i22.ForgetPasswordView(key: args.key),
|
builder: (context) => _i21.ForgetPasswordView(key: args.key),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i23.LearnLessonDetailView: (data) {
|
_i22.LearnLessonDetailView: (data) {
|
||||||
final args = data.getArgs<LearnLessonDetailViewArguments>(nullOk: false);
|
final args = data.getArgs<LearnLessonDetailViewArguments>(nullOk: false);
|
||||||
return _i37.MaterialPageRoute<dynamic>(
|
return _i37.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) =>
|
builder: (context) =>
|
||||||
_i23.LearnLessonDetailView(key: args.key, lesson: args.lesson),
|
_i22.LearnLessonDetailView(key: args.key, lesson: args.lesson),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i24.LearnPracticeView: (data) {
|
_i23.LearnPracticeView: (data) {
|
||||||
final args = data.getArgs<LearnPracticeViewArguments>(nullOk: false);
|
final args = data.getArgs<LearnPracticeViewArguments>(nullOk: false);
|
||||||
return _i37.MaterialPageRoute<dynamic>(
|
return _i37.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => _i24.LearnPracticeView(
|
builder: (context) => _i23.LearnPracticeView(
|
||||||
key: args.key, id: args.id, practice: args.practice),
|
key: args.key, id: args.id, practice: args.practice),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i25.CoursePracticeView: (data) {
|
_i24.CoursePracticeView: (data) {
|
||||||
final args = data.getArgs<CoursePracticeViewArguments>(nullOk: false);
|
final args = data.getArgs<CoursePracticeViewArguments>(nullOk: false);
|
||||||
return _i37.MaterialPageRoute<dynamic>(
|
return _i37.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) =>
|
builder: (context) =>
|
||||||
_i25.CoursePracticeView(key: args.key, id: args.id),
|
_i24.CoursePracticeView(key: args.key, id: args.id),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i26.CoursePaymentView: (data) {
|
_i25.CoursePaymentView: (data) {
|
||||||
final args = data.getArgs<CoursePaymentViewArguments>(nullOk: false);
|
final args = data.getArgs<CoursePaymentViewArguments>(nullOk: false);
|
||||||
return _i37.MaterialPageRoute<dynamic>(
|
return _i37.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) =>
|
builder: (context) =>
|
||||||
_i26.CoursePaymentView(key: args.key, course: args.course),
|
_i25.CoursePaymentView(key: args.key, course: args.course),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i27.CourseCategoryView: (data) {
|
_i26.CourseCategoryView: (data) {
|
||||||
final args = data.getArgs<CourseCategoryViewArguments>(
|
final args = data.getArgs<CourseCategoryViewArguments>(
|
||||||
orElse: () => const CourseCategoryViewArguments(),
|
orElse: () => const CourseCategoryViewArguments(),
|
||||||
);
|
);
|
||||||
return _i37.MaterialPageRoute<dynamic>(
|
return _i37.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => _i27.CourseCategoryView(key: args.key),
|
builder: (context) => _i26.CourseCategoryView(key: args.key),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i28.FailureView: (data) {
|
_i27.FailureView: (data) {
|
||||||
final args = data.getArgs<FailureViewArguments>(nullOk: false);
|
final args = data.getArgs<FailureViewArguments>(nullOk: false);
|
||||||
return _i37.MaterialPageRoute<dynamic>(
|
return _i37.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) =>
|
builder: (context) => _i27.FailureView(
|
||||||
_i28.FailureView(key: args.key, label: args.label),
|
key: args.key, onTap: args.onTap, label: args.label),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i29.CourseLessonView: (data) {
|
_i28.CourseLessonView: (data) {
|
||||||
final args = data.getArgs<CourseLessonViewArguments>(nullOk: false);
|
final args = data.getArgs<CourseLessonViewArguments>(nullOk: false);
|
||||||
return _i37.MaterialPageRoute<dynamic>(
|
return _i37.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) =>
|
builder: (context) =>
|
||||||
_i29.CourseLessonView(key: args.key, course: args.course),
|
_i28.CourseLessonView(key: args.key, course: args.course),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i30.CourseLessonDetailView: (data) {
|
_i29.CourseLessonDetailView: (data) {
|
||||||
final args = data.getArgs<CourseLessonDetailViewArguments>(nullOk: false);
|
final args = data.getArgs<CourseLessonDetailViewArguments>(nullOk: false);
|
||||||
return _i37.MaterialPageRoute<dynamic>(
|
return _i37.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) =>
|
builder: (context) =>
|
||||||
_i30.CourseLessonDetailView(key: args.key, lesson: args.lesson),
|
_i29.CourseLessonDetailView(key: args.key, lesson: args.lesson),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i31.DuolingoView: (data) {
|
_i30.DuolingoView: (data) {
|
||||||
final args = data.getArgs<DuolingoViewArguments>(
|
final args = data.getArgs<DuolingoViewArguments>(
|
||||||
orElse: () => const DuolingoViewArguments(),
|
orElse: () => const DuolingoViewArguments(),
|
||||||
);
|
);
|
||||||
return _i37.MaterialPageRoute<dynamic>(
|
return _i37.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => _i31.DuolingoView(key: args.key),
|
builder: (context) => _i30.DuolingoView(key: args.key),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i32.CourseSubcategoryView: (data) {
|
_i31.CourseSubcategoryView: (data) {
|
||||||
final args = data.getArgs<CourseSubcategoryViewArguments>(nullOk: false);
|
final args = data.getArgs<CourseSubcategoryViewArguments>(nullOk: false);
|
||||||
return _i37.MaterialPageRoute<dynamic>(
|
return _i37.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) =>
|
builder: (context) =>
|
||||||
_i32.CourseSubcategoryView(key: args.key, category: args.category),
|
_i31.CourseSubcategoryView(key: args.key, category: args.category),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i33.CourseView: (data) {
|
_i32.CourseView: (data) {
|
||||||
final args = data.getArgs<CourseViewArguments>(nullOk: false);
|
final args = data.getArgs<CourseViewArguments>(nullOk: false);
|
||||||
return _i37.MaterialPageRoute<dynamic>(
|
return _i37.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) =>
|
builder: (context) =>
|
||||||
_i33.CourseView(key: args.key, subcategory: args.subcategory),
|
_i32.CourseView(key: args.key, subcategory: args.subcategory),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i34.CoursePracticeQuestionView: (data) {
|
_i33.CoursePracticeQuestionView: (data) {
|
||||||
final args =
|
final args =
|
||||||
data.getArgs<CoursePracticeQuestionViewArguments>(nullOk: false);
|
data.getArgs<CoursePracticeQuestionViewArguments>(nullOk: false);
|
||||||
return _i37.MaterialPageRoute<dynamic>(
|
return _i37.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) =>
|
builder: (context) =>
|
||||||
_i34.CoursePracticeQuestionView(key: args.key, id: args.id),
|
_i33.CoursePracticeQuestionView(key: args.key, id: args.id),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i35.LearnProgramView: (data) {
|
_i34.LearnProgramView: (data) {
|
||||||
final args = data.getArgs<LearnProgramViewArguments>(
|
final args = data.getArgs<LearnProgramViewArguments>(
|
||||||
orElse: () => const LearnProgramViewArguments(),
|
orElse: () => const LearnProgramViewArguments(),
|
||||||
);
|
);
|
||||||
return _i37.MaterialPageRoute<dynamic>(
|
return _i37.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => _i35.LearnProgramView(key: args.key),
|
builder: (context) => _i34.LearnProgramView(key: args.key),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i36.LearnCourseView: (data) {
|
_i35.LearnCourseView: (data) {
|
||||||
final args = data.getArgs<LearnCourseViewArguments>(nullOk: false);
|
final args = data.getArgs<LearnCourseViewArguments>(nullOk: false);
|
||||||
return _i37.MaterialPageRoute<dynamic>(
|
return _i37.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => _i36.LearnCourseView(key: args.key, id: args.id),
|
builder: (context) => _i35.LearnCourseView(key: args.key, id: args.id),
|
||||||
|
settings: data,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
_i36.AssessmentView: (data) {
|
||||||
|
final args = data.getArgs<AssessmentViewArguments>(nullOk: false);
|
||||||
|
return _i37.MaterialPageRoute<dynamic>(
|
||||||
|
builder: (context) =>
|
||||||
|
_i36.AssessmentView(key: args.key, data: args.data),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
@ -1045,33 +1045,6 @@ class WelcomeViewArguments {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AssessmentViewArguments {
|
|
||||||
const AssessmentViewArguments({
|
|
||||||
this.key,
|
|
||||||
required this.data,
|
|
||||||
});
|
|
||||||
|
|
||||||
final _i37.Key? key;
|
|
||||||
|
|
||||||
final Map<String, dynamic> data;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return '{"key": "$key", "data": "$data"}';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(covariant AssessmentViewArguments other) {
|
|
||||||
if (identical(this, other)) return true;
|
|
||||||
return other.key == key && other.data == data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode {
|
|
||||||
return key.hashCode ^ data.hashCode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class LearnLessonViewArguments {
|
class LearnLessonViewArguments {
|
||||||
const LearnLessonViewArguments({
|
const LearnLessonViewArguments({
|
||||||
this.key,
|
this.key,
|
||||||
|
|
@ -1257,27 +1230,30 @@ class CourseCategoryViewArguments {
|
||||||
class FailureViewArguments {
|
class FailureViewArguments {
|
||||||
const FailureViewArguments({
|
const FailureViewArguments({
|
||||||
this.key,
|
this.key,
|
||||||
|
required this.onTap,
|
||||||
required this.label,
|
required this.label,
|
||||||
});
|
});
|
||||||
|
|
||||||
final _i37.Key? key;
|
final _i37.Key? key;
|
||||||
|
|
||||||
|
final void Function() onTap;
|
||||||
|
|
||||||
final String label;
|
final String label;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return '{"key": "$key", "label": "$label"}';
|
return '{"key": "$key", "onTap": "$onTap", "label": "$label"}';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(covariant FailureViewArguments other) {
|
bool operator ==(covariant FailureViewArguments other) {
|
||||||
if (identical(this, other)) return true;
|
if (identical(this, other)) return true;
|
||||||
return other.key == key && other.label == label;
|
return other.key == key && other.onTap == onTap && other.label == label;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode {
|
int get hashCode {
|
||||||
return key.hashCode ^ label.hashCode;
|
return key.hashCode ^ onTap.hashCode ^ label.hashCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1487,6 +1463,33 @@ class LearnCourseViewArguments {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AssessmentViewArguments {
|
||||||
|
const AssessmentViewArguments({
|
||||||
|
this.key,
|
||||||
|
required this.data,
|
||||||
|
});
|
||||||
|
|
||||||
|
final _i37.Key? key;
|
||||||
|
|
||||||
|
final Map<String, dynamic> data;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return '{"key": "$key", "data": "$data"}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(covariant AssessmentViewArguments other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
return other.key == key && other.data == data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return key.hashCode ^ data.hashCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension NavigatorStateExtension on _i46.NavigationService {
|
extension NavigatorStateExtension on _i46.NavigationService {
|
||||||
Future<dynamic> navigateToHomeView({
|
Future<dynamic> navigateToHomeView({
|
||||||
_i37.Key? key,
|
_i37.Key? key,
|
||||||
|
|
@ -1778,23 +1781,6 @@ extension NavigatorStateExtension on _i46.NavigationService {
|
||||||
transition: transition);
|
transition: transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<dynamic> navigateToAssessmentView({
|
|
||||||
_i37.Key? key,
|
|
||||||
required Map<String, dynamic> data,
|
|
||||||
int? routerId,
|
|
||||||
bool preventDuplicates = true,
|
|
||||||
Map<String, String>? parameters,
|
|
||||||
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
|
|
||||||
transition,
|
|
||||||
}) async {
|
|
||||||
return navigateTo<dynamic>(Routes.assessmentView,
|
|
||||||
arguments: AssessmentViewArguments(key: key, data: data),
|
|
||||||
id: routerId,
|
|
||||||
preventDuplicates: preventDuplicates,
|
|
||||||
parameters: parameters,
|
|
||||||
transition: transition);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<dynamic> navigateToLearnLessonView({
|
Future<dynamic> navigateToLearnLessonView({
|
||||||
_i37.Key? key,
|
_i37.Key? key,
|
||||||
required _i39.LearnModule module,
|
required _i39.LearnModule module,
|
||||||
|
|
@ -1916,6 +1902,7 @@ extension NavigatorStateExtension on _i46.NavigationService {
|
||||||
|
|
||||||
Future<dynamic> navigateToFailureView({
|
Future<dynamic> navigateToFailureView({
|
||||||
_i37.Key? key,
|
_i37.Key? key,
|
||||||
|
required void Function() onTap,
|
||||||
required String label,
|
required String label,
|
||||||
int? routerId,
|
int? routerId,
|
||||||
bool preventDuplicates = true,
|
bool preventDuplicates = true,
|
||||||
|
|
@ -1924,7 +1911,7 @@ extension NavigatorStateExtension on _i46.NavigationService {
|
||||||
transition,
|
transition,
|
||||||
}) async {
|
}) async {
|
||||||
return navigateTo<dynamic>(Routes.failureView,
|
return navigateTo<dynamic>(Routes.failureView,
|
||||||
arguments: FailureViewArguments(key: key, label: label),
|
arguments: FailureViewArguments(key: key, onTap: onTap, label: label),
|
||||||
id: routerId,
|
id: routerId,
|
||||||
preventDuplicates: preventDuplicates,
|
preventDuplicates: preventDuplicates,
|
||||||
parameters: parameters,
|
parameters: parameters,
|
||||||
|
|
@ -2065,6 +2052,23 @@ extension NavigatorStateExtension on _i46.NavigationService {
|
||||||
transition: transition);
|
transition: transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<dynamic> navigateToAssessmentView({
|
||||||
|
_i37.Key? key,
|
||||||
|
required Map<String, dynamic> data,
|
||||||
|
int? routerId,
|
||||||
|
bool preventDuplicates = true,
|
||||||
|
Map<String, String>? parameters,
|
||||||
|
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
|
||||||
|
transition,
|
||||||
|
}) async {
|
||||||
|
return navigateTo<dynamic>(Routes.assessmentView,
|
||||||
|
arguments: AssessmentViewArguments(key: key, data: data),
|
||||||
|
id: routerId,
|
||||||
|
preventDuplicates: preventDuplicates,
|
||||||
|
parameters: parameters,
|
||||||
|
transition: transition);
|
||||||
|
}
|
||||||
|
|
||||||
Future<dynamic> replaceWithHomeView({
|
Future<dynamic> replaceWithHomeView({
|
||||||
_i37.Key? key,
|
_i37.Key? key,
|
||||||
int? routerId,
|
int? routerId,
|
||||||
|
|
@ -2355,23 +2359,6 @@ extension NavigatorStateExtension on _i46.NavigationService {
|
||||||
transition: transition);
|
transition: transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<dynamic> replaceWithAssessmentView({
|
|
||||||
_i37.Key? key,
|
|
||||||
required Map<String, dynamic> data,
|
|
||||||
int? routerId,
|
|
||||||
bool preventDuplicates = true,
|
|
||||||
Map<String, String>? parameters,
|
|
||||||
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
|
|
||||||
transition,
|
|
||||||
}) async {
|
|
||||||
return replaceWith<dynamic>(Routes.assessmentView,
|
|
||||||
arguments: AssessmentViewArguments(key: key, data: data),
|
|
||||||
id: routerId,
|
|
||||||
preventDuplicates: preventDuplicates,
|
|
||||||
parameters: parameters,
|
|
||||||
transition: transition);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<dynamic> replaceWithLearnLessonView({
|
Future<dynamic> replaceWithLearnLessonView({
|
||||||
_i37.Key? key,
|
_i37.Key? key,
|
||||||
required _i39.LearnModule module,
|
required _i39.LearnModule module,
|
||||||
|
|
@ -2493,6 +2480,7 @@ extension NavigatorStateExtension on _i46.NavigationService {
|
||||||
|
|
||||||
Future<dynamic> replaceWithFailureView({
|
Future<dynamic> replaceWithFailureView({
|
||||||
_i37.Key? key,
|
_i37.Key? key,
|
||||||
|
required void Function() onTap,
|
||||||
required String label,
|
required String label,
|
||||||
int? routerId,
|
int? routerId,
|
||||||
bool preventDuplicates = true,
|
bool preventDuplicates = true,
|
||||||
|
|
@ -2501,7 +2489,7 @@ extension NavigatorStateExtension on _i46.NavigationService {
|
||||||
transition,
|
transition,
|
||||||
}) async {
|
}) async {
|
||||||
return replaceWith<dynamic>(Routes.failureView,
|
return replaceWith<dynamic>(Routes.failureView,
|
||||||
arguments: FailureViewArguments(key: key, label: label),
|
arguments: FailureViewArguments(key: key, onTap: onTap, label: label),
|
||||||
id: routerId,
|
id: routerId,
|
||||||
preventDuplicates: preventDuplicates,
|
preventDuplicates: preventDuplicates,
|
||||||
parameters: parameters,
|
parameters: parameters,
|
||||||
|
|
@ -2641,4 +2629,21 @@ extension NavigatorStateExtension on _i46.NavigationService {
|
||||||
parameters: parameters,
|
parameters: parameters,
|
||||||
transition: transition);
|
transition: transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<dynamic> replaceWithAssessmentView({
|
||||||
|
_i37.Key? key,
|
||||||
|
required Map<String, dynamic> data,
|
||||||
|
int? routerId,
|
||||||
|
bool preventDuplicates = true,
|
||||||
|
Map<String, String>? parameters,
|
||||||
|
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
|
||||||
|
transition,
|
||||||
|
}) async {
|
||||||
|
return replaceWith<dynamic>(Routes.assessmentView,
|
||||||
|
arguments: AssessmentViewArguments(key: key, data: data),
|
||||||
|
id: routerId,
|
||||||
|
preventDuplicates: preventDuplicates,
|
||||||
|
parameters: parameters,
|
||||||
|
transition: transition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
37
lib/models/assessment.dart
Normal file
37
lib/models/assessment.dart
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
|
part 'assessment.g.dart';
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class Assessment {
|
||||||
|
final int? id;
|
||||||
|
|
||||||
|
final String? title;
|
||||||
|
|
||||||
|
final String? status;
|
||||||
|
|
||||||
|
final String? description;
|
||||||
|
|
||||||
|
@JsonKey(name: 'set_type')
|
||||||
|
final String? setType;
|
||||||
|
|
||||||
|
@JsonKey(name: 'passing_score')
|
||||||
|
final int? passingScore;
|
||||||
|
|
||||||
|
@JsonKey(name: 'shuffle_questions')
|
||||||
|
final bool? shuffleQuestions;
|
||||||
|
|
||||||
|
const Assessment(
|
||||||
|
{this.id,
|
||||||
|
this.title,
|
||||||
|
this.status,
|
||||||
|
this.setType,
|
||||||
|
this.description,
|
||||||
|
this.passingScore,
|
||||||
|
this.shuffleQuestions});
|
||||||
|
|
||||||
|
factory Assessment.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$AssessmentFromJson(json);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$AssessmentToJson(this);
|
||||||
|
}
|
||||||
28
lib/models/assessment.g.dart
Normal file
28
lib/models/assessment.g.dart
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'assessment.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
Assessment _$AssessmentFromJson(Map<String, dynamic> json) => Assessment(
|
||||||
|
id: (json['id'] as num?)?.toInt(),
|
||||||
|
title: json['title'] as String?,
|
||||||
|
status: json['status'] as String?,
|
||||||
|
setType: json['set_type'] as String?,
|
||||||
|
description: json['description'] as String?,
|
||||||
|
passingScore: (json['passing_score'] as num?)?.toInt(),
|
||||||
|
shuffleQuestions: json['shuffle_questions'] as bool?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$AssessmentToJson(Assessment instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'id': instance.id,
|
||||||
|
'title': instance.title,
|
||||||
|
'status': instance.status,
|
||||||
|
'description': instance.description,
|
||||||
|
'set_type': instance.setType,
|
||||||
|
'passing_score': instance.passingScore,
|
||||||
|
'shuffle_questions': instance.shuffleQuestions,
|
||||||
|
};
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:yimaru_app/models/option.dart';
|
import 'package:yimaru_app/models/option.dart';
|
||||||
part 'question.g.dart';
|
part 'assessment_question.g.dart';
|
||||||
|
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class Question {
|
class AssessmentQuestion {
|
||||||
final int? id;
|
final int? id;
|
||||||
|
|
||||||
final int? points;
|
final int? points;
|
||||||
|
|
@ -18,21 +18,17 @@ class Question {
|
||||||
@JsonKey(name: 'question_text')
|
@JsonKey(name: 'question_text')
|
||||||
final String? questionText;
|
final String? questionText;
|
||||||
|
|
||||||
@JsonKey(name: 'difficulty_level')
|
const AssessmentQuestion({
|
||||||
final String? difficultyLevel;
|
|
||||||
|
|
||||||
const Question({
|
|
||||||
this.id,
|
this.id,
|
||||||
this.points,
|
this.points,
|
||||||
this.status,
|
this.status,
|
||||||
this.options,
|
this.options,
|
||||||
this.questionText,
|
this.questionText,
|
||||||
this.questionType,
|
this.questionType,
|
||||||
this.difficultyLevel,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
factory Question.fromJson(Map<String, dynamic> json) =>
|
factory AssessmentQuestion.fromJson(Map<String, dynamic> json) =>
|
||||||
_$QuestionFromJson(json);
|
_$AssessmentQuestionFromJson(json);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => _$QuestionToJson(this);
|
Map<String, dynamic> toJson() => _$AssessmentQuestionToJson(this);
|
||||||
}
|
}
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
part of 'question.dart';
|
part of 'assessment_question.dart';
|
||||||
|
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
// JsonSerializableGenerator
|
// JsonSerializableGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
Question _$QuestionFromJson(Map<String, dynamic> json) => Question(
|
AssessmentQuestion _$AssessmentQuestionFromJson(Map<String, dynamic> json) =>
|
||||||
|
AssessmentQuestion(
|
||||||
id: (json['id'] as num?)?.toInt(),
|
id: (json['id'] as num?)?.toInt(),
|
||||||
points: (json['points'] as num?)?.toInt(),
|
points: (json['points'] as num?)?.toInt(),
|
||||||
status: json['status'] as String?,
|
status: json['status'] as String?,
|
||||||
|
|
@ -15,15 +16,14 @@ Question _$QuestionFromJson(Map<String, dynamic> json) => Question(
|
||||||
.toList(),
|
.toList(),
|
||||||
questionText: json['question_text'] as String?,
|
questionText: json['question_text'] as String?,
|
||||||
questionType: json['question_type'] as String?,
|
questionType: json['question_type'] as String?,
|
||||||
difficultyLevel: json['difficulty_level'] as String?,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$QuestionToJson(Question instance) => <String, dynamic>{
|
Map<String, dynamic> _$AssessmentQuestionToJson(AssessmentQuestion instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
'id': instance.id,
|
'id': instance.id,
|
||||||
'points': instance.points,
|
'points': instance.points,
|
||||||
'status': instance.status,
|
'status': instance.status,
|
||||||
'options': instance.options,
|
'options': instance.options,
|
||||||
'question_type': instance.questionType,
|
'question_type': instance.questionType,
|
||||||
'question_text': instance.questionText,
|
'question_text': instance.questionText,
|
||||||
'difficulty_level': instance.difficultyLevel,
|
|
||||||
};
|
};
|
||||||
|
|
@ -11,7 +11,10 @@ class Option {
|
||||||
@JsonKey(name: 'option_text')
|
@JsonKey(name: 'option_text')
|
||||||
final String? optionText;
|
final String? optionText;
|
||||||
|
|
||||||
const Option({this.id, this.optionText, this.isCorrect});
|
@JsonKey(name: 'option_order')
|
||||||
|
final int? optionOrder;
|
||||||
|
|
||||||
|
const Option({this.id, this.optionText, this.isCorrect, this.optionOrder});
|
||||||
|
|
||||||
factory Option.fromJson(Map<String, dynamic> json) => _$OptionFromJson(json);
|
factory Option.fromJson(Map<String, dynamic> json) => _$OptionFromJson(json);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,12 @@ Option _$OptionFromJson(Map<String, dynamic> json) => Option(
|
||||||
id: (json['id'] as num?)?.toInt(),
|
id: (json['id'] as num?)?.toInt(),
|
||||||
optionText: json['option_text'] as String?,
|
optionText: json['option_text'] as String?,
|
||||||
isCorrect: json['is_correct'] as bool?,
|
isCorrect: json['is_correct'] as bool?,
|
||||||
|
optionOrder: (json['option_order'] as num?)?.toInt(),
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$OptionToJson(Option instance) => <String, dynamic>{
|
Map<String, dynamic> _$OptionToJson(Option instance) => <String, dynamic>{
|
||||||
'id': instance.id,
|
'id': instance.id,
|
||||||
'is_correct': instance.isCorrect,
|
'is_correct': instance.isCorrect,
|
||||||
'option_text': instance.optionText,
|
'option_text': instance.optionText,
|
||||||
|
'option_order': instance.optionOrder,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import 'package:yimaru_app/models/learn_lesson.dart';
|
||||||
import 'package:yimaru_app/models/learn_practice.dart';
|
import 'package:yimaru_app/models/learn_practice.dart';
|
||||||
import 'package:yimaru_app/models/learn_program.dart';
|
import 'package:yimaru_app/models/learn_program.dart';
|
||||||
import 'package:yimaru_app/models/level.dart';
|
import 'package:yimaru_app/models/level.dart';
|
||||||
import 'package:yimaru_app/models/question.dart';
|
import 'package:yimaru_app/models/assessment_question.dart';
|
||||||
import 'package:yimaru_app/models/subcategory.dart';
|
import 'package:yimaru_app/models/subcategory.dart';
|
||||||
import 'package:yimaru_app/models/category.dart';
|
import 'package:yimaru_app/models/category.dart';
|
||||||
import 'package:yimaru_app/models/course_lesson.dart';
|
import 'package:yimaru_app/models/course_lesson.dart';
|
||||||
|
|
@ -20,6 +20,7 @@ import '../models/learn_module.dart';
|
||||||
import '../models/learn_question.dart';
|
import '../models/learn_question.dart';
|
||||||
import '../models/lesson.dart';
|
import '../models/lesson.dart';
|
||||||
import '../models/module.dart';
|
import '../models/module.dart';
|
||||||
|
import '../models/assessment.dart';
|
||||||
import '../models/submodule.dart';
|
import '../models/submodule.dart';
|
||||||
import '../ui/common/enmus.dart';
|
import '../ui/common/enmus.dart';
|
||||||
|
|
||||||
|
|
@ -354,23 +355,47 @@ class ApiService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get assessments
|
// Get assessment question sets
|
||||||
Future<List<Question>> getAssessments() async {
|
Future<List<Assessment>> getAssessments() async {
|
||||||
try {
|
try {
|
||||||
List<Question> assessments = [];
|
List<Assessment> assessments = [];
|
||||||
|
|
||||||
final Response response =
|
final Response response = await _service.dio.get(
|
||||||
await _service.dio.get('$kBaseUrl/$kAssessmentsUrl');
|
'$kBaseUrl/api/$kApiVersionUrl/$kQuestionSetsUrl?set_type=INITIAL_ASSESSMENT&limit=10&offset=0');
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
var data = response.data;
|
||||||
|
var decodedData = data['data']['question_sets'] as List;
|
||||||
|
assessments = decodedData.map(
|
||||||
|
(e) {
|
||||||
|
return Assessment.fromJson(e);
|
||||||
|
},
|
||||||
|
).toList();
|
||||||
|
return assessments;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
} catch (e) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get assessment questions
|
||||||
|
Future<List<AssessmentQuestion>> getAssessmentQuestions(int id) async {
|
||||||
|
try {
|
||||||
|
List<AssessmentQuestion> questions = [];
|
||||||
|
|
||||||
|
final Response response = await _service.dio.get(
|
||||||
|
'$kBaseUrl/api/$kApiVersionUrl/$kQuestionSetsUrl/$id/$kQuestionsUrl');
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
var data = response.data;
|
var data = response.data;
|
||||||
var decodedData = data['data'] as List;
|
var decodedData = data['data'] as List;
|
||||||
assessments = decodedData.map(
|
questions = decodedData.map(
|
||||||
(e) {
|
(e) {
|
||||||
return Question.fromJson(e);
|
return AssessmentQuestion.fromJson(e);
|
||||||
},
|
},
|
||||||
).toList();
|
).toList();
|
||||||
return assessments;
|
return questions;
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -741,9 +766,9 @@ class ApiService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get course practic questions
|
// Get course practic questions
|
||||||
Future<List<Question>> getCoursePracticeQuestions(int id) async {
|
Future<List<AssessmentQuestion>> getCoursePracticeQuestions(int id) async {
|
||||||
try {
|
try {
|
||||||
List<Question> coursePracticeQuestions = [];
|
List<AssessmentQuestion> coursePracticeQuestions = [];
|
||||||
|
|
||||||
final Response response = await _service.dio
|
final Response response = await _service.dio
|
||||||
.get('$kBaseUrl/$kPracticeBaseUrl/$id/$kCoursePracticeQuestions');
|
.get('$kBaseUrl/$kPracticeBaseUrl/$id/$kCoursePracticeQuestions');
|
||||||
|
|
@ -753,7 +778,7 @@ class ApiService {
|
||||||
var decodedData = data['data'] as List;
|
var decodedData = data['data'] as List;
|
||||||
coursePracticeQuestions = decodedData.map(
|
coursePracticeQuestions = decodedData.map(
|
||||||
(e) {
|
(e) {
|
||||||
return Question.fromJson(e);
|
return AssessmentQuestion.fromJson(e);
|
||||||
},
|
},
|
||||||
).toList();
|
).toList();
|
||||||
return coursePracticeQuestions;
|
return coursePracticeQuestions;
|
||||||
|
|
@ -765,13 +790,14 @@ class ApiService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get course practice question
|
// Get course practice question
|
||||||
Future<Question?> getCoursePracticeQuestion(int id) async {
|
Future<AssessmentQuestion?> getCoursePracticeQuestion(int id) async {
|
||||||
try {
|
try {
|
||||||
final Response response =
|
final Response response =
|
||||||
await _service.dio.get('$kBaseUrl/$kCoursePracticeQuestion/$id');
|
await _service.dio.get('$kBaseUrl/$kCoursePracticeQuestion/$id');
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
Question question = Question.fromJson(response.data['data']);
|
AssessmentQuestion question =
|
||||||
|
AssessmentQuestion.fromJson(response.data['data']);
|
||||||
|
|
||||||
return question;
|
return question;
|
||||||
}
|
}
|
||||||
|
|
@ -950,9 +976,9 @@ class ApiService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Questions
|
// Questions
|
||||||
Future<List<Question>> getQuestions(int id) async {
|
Future<List<AssessmentQuestion>> getQuestions(int id) async {
|
||||||
try {
|
try {
|
||||||
List<Question> questions = [];
|
List<AssessmentQuestion> questions = [];
|
||||||
|
|
||||||
final Response response = await _service.dio.get(
|
final Response response = await _service.dio.get(
|
||||||
'$kBaseUrl/api/$kApiVersionUrl/$kQuestionSetsUrl/$id/$kQuestionsUrl');
|
'$kBaseUrl/api/$kApiVersionUrl/$kQuestionSetsUrl/$id/$kQuestionsUrl');
|
||||||
|
|
@ -962,7 +988,7 @@ class ApiService {
|
||||||
var decodedData = data['data'] as List;
|
var decodedData = data['data'] as List;
|
||||||
questions = decodedData.map(
|
questions = decodedData.map(
|
||||||
(e) {
|
(e) {
|
||||||
return Question.fromJson(e);
|
return AssessmentQuestion.fromJson(e);
|
||||||
},
|
},
|
||||||
).toList();
|
).toList();
|
||||||
return questions;
|
return questions;
|
||||||
|
|
|
||||||
|
|
@ -173,5 +173,6 @@ class AuthenticationService with ListenableServiceMixin {
|
||||||
_user = null;
|
_user = null;
|
||||||
await _secureService.clear();
|
await _secureService.clear();
|
||||||
await setFirstTimeInstall(firstTimeInstall);
|
await setFirstTimeInstall(firstTimeInstall);
|
||||||
|
notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,8 @@ class DioService {
|
||||||
DioService() {
|
DioService() {
|
||||||
_dio.options
|
_dio.options
|
||||||
..baseUrl = kBaseUrl
|
..baseUrl = kBaseUrl
|
||||||
..connectTimeout = const Duration(seconds: 30)
|
..connectTimeout = const Duration(seconds: 5)
|
||||||
..receiveTimeout = const Duration(seconds: 30);
|
..receiveTimeout = const Duration(seconds: 15);
|
||||||
|
|
||||||
_dio.interceptors.add(
|
_dio.interceptors.add(
|
||||||
InterceptorsWrapper(
|
InterceptorsWrapper(
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ enum LearnPractices { course, module, lesson }
|
||||||
// Voice recording state
|
// Voice recording state
|
||||||
enum VoiceRecordingState { pending, recording }
|
enum VoiceRecordingState { pending, recording }
|
||||||
|
|
||||||
// Levels
|
// // Levels
|
||||||
enum ProficiencyLevels { a1, a2, b1, b2, none }
|
// enum ProficiencyLevels { a1, a2, b1, b2, none }
|
||||||
|
|
||||||
// Progress status
|
// Progress status
|
||||||
enum ProgressStatuses { pending, started, completed }
|
enum ProgressStatuses { pending, started, completed }
|
||||||
|
|
@ -29,10 +29,11 @@ enum DuolingoAssessments { speaking, reading, writing, listening }
|
||||||
enum StateObjects {
|
enum StateObjects {
|
||||||
none,
|
none,
|
||||||
courses,
|
courses,
|
||||||
startupView,
|
|
||||||
register,
|
register,
|
||||||
verifyOtp,
|
verifyOtp,
|
||||||
resendOtp,
|
resendOtp,
|
||||||
|
assessments,
|
||||||
|
startupView,
|
||||||
learnLessons,
|
learnLessons,
|
||||||
learnModules,
|
learnModules,
|
||||||
learnCourses,
|
learnCourses,
|
||||||
|
|
@ -56,6 +57,7 @@ enum StateObjects {
|
||||||
learnPracticeSample,
|
learnPracticeSample,
|
||||||
learnPracticeAnswer,
|
learnPracticeAnswer,
|
||||||
loginWithPhoneNumber,
|
loginWithPhoneNumber,
|
||||||
|
assessmentQuestions,
|
||||||
learnPracticeQuestion,
|
learnPracticeQuestion,
|
||||||
coursePracticeQuestion,
|
coursePracticeQuestion,
|
||||||
coursePracticeQuestions,
|
coursePracticeQuestions,
|
||||||
|
|
|
||||||
|
|
@ -312,6 +312,10 @@ TextStyle style14MG400 = const TextStyle(
|
||||||
TextStyle style14DG500 =
|
TextStyle style14DG500 =
|
||||||
const TextStyle(color: kcDarkGrey, fontWeight: FontWeight.w500);
|
const TextStyle(color: kcDarkGrey, fontWeight: FontWeight.w500);
|
||||||
|
|
||||||
|
TextStyle style18MG500 =
|
||||||
|
const TextStyle(fontSize: 18,color: kcMediumGrey, fontWeight: FontWeight.w500);
|
||||||
|
|
||||||
|
|
||||||
TextStyle style14DG400 = const TextStyle(
|
TextStyle style14DG400 = const TextStyle(
|
||||||
color: kcDarkGrey,
|
color: kcDarkGrey,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ class AccountPrivacyView extends StackedView<AccountPrivacyViewModel> {
|
||||||
|
|
||||||
Widget _buildAppbar(AccountPrivacyViewModel viewModel) => SmallAppBar(
|
Widget _buildAppbar(AccountPrivacyViewModel viewModel) => SmallAppBar(
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
onTap: viewModel.pop,
|
onPop: viewModel.pop,
|
||||||
title: 'Account Privacy',
|
title: 'Account Privacy',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:stacked/stacked.dart';
|
import 'package:stacked/stacked.dart';
|
||||||
|
import 'package:yimaru_app/ui/common/enmus.dart';
|
||||||
import 'package:yimaru_app/ui/views/assessment/screens/assessment_questions_screen.dart';
|
import 'package:yimaru_app/ui/views/assessment/screens/assessment_questions_screen.dart';
|
||||||
import 'package:yimaru_app/ui/views/assessment/screens/assessment_intro_screen.dart';
|
import 'package:yimaru_app/ui/views/assessment/screens/assessment_intro_screen.dart';
|
||||||
import 'package:yimaru_app/ui/views/assessment/screens/assessment_result_screen.dart';
|
import 'package:yimaru_app/ui/views/assessment/screens/assessment_result_screen.dart';
|
||||||
import 'package:yimaru_app/ui/views/assessment/screens/start_lesson_screen.dart';
|
import 'package:yimaru_app/ui/views/assessment/screens/start_lesson_screen.dart';
|
||||||
|
|
||||||
|
import '../../widgets/assessment_loading_screen.dart';
|
||||||
import 'assessment_viewmodel.dart';
|
import 'assessment_viewmodel.dart';
|
||||||
|
|
||||||
class AssessmentView extends StackedView<AssessmentViewModel> {
|
class AssessmentView extends StackedView<AssessmentViewModel> {
|
||||||
|
|
@ -39,16 +41,29 @@ class AssessmentView extends StackedView<AssessmentViewModel> {
|
||||||
|
|
||||||
Widget _buildAssessmentScreens(AssessmentViewModel viewModel) => IndexedStack(
|
Widget _buildAssessmentScreens(AssessmentViewModel viewModel) => IndexedStack(
|
||||||
index: viewModel.currentPage,
|
index: viewModel.currentPage,
|
||||||
children: _buildScreens(),
|
children: _buildScreens(viewModel),
|
||||||
);
|
);
|
||||||
|
|
||||||
List<Widget> _buildScreens() => [
|
List<Widget> _buildScreens(AssessmentViewModel viewModel) => [
|
||||||
_buildAssessmentIntro(),
|
_buildAssessmentIntroWrapper(viewModel),
|
||||||
_buildAssessment(),
|
_buildAssessment(),
|
||||||
_buildAssessmentResult(),
|
_buildAssessmentResult(),
|
||||||
_buildStartLesson(),
|
_buildStartLesson(),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
Widget _buildAssessmentIntroWrapper(AssessmentViewModel viewModel) =>
|
||||||
|
viewModel.busy(StateObjects.assessments) || viewModel.assessments.isEmpty
|
||||||
|
? _buildPageLoadingIndicator(viewModel)
|
||||||
|
: _buildAssessmentIntro();
|
||||||
|
|
||||||
|
Widget _buildPageLoadingIndicator(AssessmentViewModel viewModel) =>
|
||||||
|
AssessmentLoadingScreen(
|
||||||
|
isEmpty: viewModel.assessments.isEmpty,
|
||||||
|
onTap: () async => await viewModel.getAssessments(),
|
||||||
|
isLoading: viewModel.busy(StateObjects.assessments),
|
||||||
|
onPop: viewModel.assessments.isEmpty ? viewModel.pop : null,
|
||||||
|
);
|
||||||
|
|
||||||
Widget _buildAssessmentIntro() => const AssessmentIntroScreen();
|
Widget _buildAssessmentIntro() => const AssessmentIntroScreen();
|
||||||
|
|
||||||
Widget _buildAssessment() => const AssessmentQuestionsScreen();
|
Widget _buildAssessment() => const AssessmentQuestionsScreen();
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:stacked/stacked.dart';
|
import 'package:stacked/stacked.dart';
|
||||||
import 'package:stacked_services/stacked_services.dart';
|
import 'package:stacked_services/stacked_services.dart';
|
||||||
|
import 'package:yimaru_app/models/assessment_question.dart';
|
||||||
import 'package:yimaru_app/models/option.dart';
|
import 'package:yimaru_app/models/option.dart';
|
||||||
import 'package:yimaru_app/services/status_checker_service.dart';
|
import 'package:yimaru_app/services/status_checker_service.dart';
|
||||||
import 'package:yimaru_app/ui/common/enmus.dart';
|
import 'package:yimaru_app/ui/common/enmus.dart';
|
||||||
|
|
||||||
import '../../../app/app.locator.dart';
|
import '../../../app/app.locator.dart';
|
||||||
import '../../../app/app.router.dart';
|
import '../../../app/app.router.dart';
|
||||||
import '../../../models/question.dart';
|
import '../../../models/assessment.dart';
|
||||||
import '../../../services/api_service.dart';
|
import '../../../services/api_service.dart';
|
||||||
import '../../common/app_colors.dart';
|
import '../../common/app_colors.dart';
|
||||||
import '../../common/ui_helpers.dart';
|
import '../../common/ui_helpers.dart';
|
||||||
|
|
@ -33,82 +34,78 @@ class AssessmentViewModel extends BaseViewModel {
|
||||||
PageController get pageController => _pageController;
|
PageController get pageController => _pageController;
|
||||||
|
|
||||||
// Assessment
|
// Assessment
|
||||||
int _currentQuestion = 0;
|
|
||||||
|
|
||||||
int get currentQuestion => _currentQuestion;
|
List<Assessment> _assessments = [];
|
||||||
|
|
||||||
List<Question> _assessments = [];
|
List<Assessment> get assessments => _assessments;
|
||||||
|
|
||||||
List<Question> get assessments => _assessments;
|
Assessment? _currentAssessment;
|
||||||
|
|
||||||
ProficiencyLevels _proficiencyLevel = ProficiencyLevels.none;
|
Assessment? get currentAssessment => _currentAssessment;
|
||||||
|
|
||||||
ProficiencyLevels get proficiencyLevel => _proficiencyLevel;
|
int _currentQuestionIndex = 0;
|
||||||
|
|
||||||
|
int get currentQuestionIndex => _currentQuestionIndex;
|
||||||
|
|
||||||
|
int _currentAssessmentIndex = 0;
|
||||||
|
|
||||||
|
int get currentAssessmentIndex => _currentAssessmentIndex;
|
||||||
|
|
||||||
|
String? _proficiencyLevel;
|
||||||
|
|
||||||
|
String? get proficiencyLevel => _proficiencyLevel;
|
||||||
|
|
||||||
final Map<String, dynamic> _selectedAnswers = {};
|
final Map<String, dynamic> _selectedAnswers = {};
|
||||||
|
|
||||||
Map<String, dynamic> get selectedAnswers => _selectedAnswers;
|
Map<String, dynamic> get selectedAnswers => _selectedAnswers;
|
||||||
|
|
||||||
|
List<AssessmentQuestion> _assessmentQuestions = [];
|
||||||
|
|
||||||
|
List<AssessmentQuestion> get assessmentQuestions => _assessmentQuestions;
|
||||||
|
|
||||||
// User data
|
// User data
|
||||||
final Map<String, dynamic> _userData = {};
|
final Map<String, dynamic> _userData = {};
|
||||||
|
|
||||||
Map<String, dynamic> get userData => _userData;
|
Map<String, dynamic> get userData => _userData;
|
||||||
|
|
||||||
// Assessment
|
// Assessment
|
||||||
|
Future<void> setFirstAssessment()async{
|
||||||
|
_proficiencyLevel = null;
|
||||||
|
_selectedAnswers.clear();
|
||||||
|
_currentQuestionIndex = 0;
|
||||||
|
_pageController.jumpToPage(_currentQuestionIndex);
|
||||||
|
_currentAssessment = assessments[currentAssessmentIndex];
|
||||||
|
await getAssessmentQuestions(
|
||||||
|
_currentAssessment?.id ?? 0);
|
||||||
|
|
||||||
|
next();
|
||||||
|
}
|
||||||
Map<String, dynamic> evaluateAssessment() {
|
Map<String, dynamic> evaluateAssessment() {
|
||||||
if (_currentQuestion == 5) {
|
bool levelPassed = canPassLevel();
|
||||||
// A1
|
if (levelPassed) {
|
||||||
final correctCount = countCorrectAnswersUntil(5);
|
return {'passed': true, 'level': _currentAssessment?.description};
|
||||||
|
|
||||||
if (correctCount > 3) {
|
|
||||||
return {'continue': true, 'level': ProficiencyLevels.a1};
|
|
||||||
} else {
|
|
||||||
return {'continue': false, 'level': ProficiencyLevels.a1};
|
|
||||||
}
|
|
||||||
} else if (_currentQuestion == 10) {
|
|
||||||
// A2
|
|
||||||
|
|
||||||
final correctCount = countCorrectAnswersUntil(10);
|
|
||||||
|
|
||||||
if (correctCount > 3) {
|
|
||||||
return {'continue': true, 'level': ProficiencyLevels.a2};
|
|
||||||
} else {
|
|
||||||
return {'continue': false, 'level': ProficiencyLevels.a2};
|
|
||||||
}
|
|
||||||
} else if (_currentQuestion == 16) {
|
|
||||||
// B1
|
|
||||||
final correctCount = countCorrectAnswersUntil(16);
|
|
||||||
|
|
||||||
if (correctCount > 4) {
|
|
||||||
return {'continue': true, 'level': ProficiencyLevels.b1};
|
|
||||||
} else {
|
|
||||||
return {'continue': false, 'level': ProficiencyLevels.b1};
|
|
||||||
}
|
|
||||||
} else if (_currentQuestion == 22) {
|
|
||||||
final correctCount = countCorrectAnswersUntil(16);
|
|
||||||
|
|
||||||
if (correctCount > 4) {
|
|
||||||
return {'continue': false, 'level': ProficiencyLevels.b2};
|
|
||||||
} else {
|
|
||||||
return {'continue': false, 'level': ProficiencyLevels.b2};
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return {'continue': true, 'level': ProficiencyLevels.none};
|
return {'passed': false, 'level': _currentAssessment?.description};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int countCorrectAnswersUntil(int untilQuestion) {
|
bool canPassLevel() {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
for (int i = 1; i <= untilQuestion; i++) {
|
for (int i = 1; i <= _assessmentQuestions.length; i++) {
|
||||||
final answer = _selectedAnswers[i.toString()];
|
final answer = _selectedAnswers[i.toString()];
|
||||||
|
|
||||||
if (answer is Map<String, dynamic> && answer['correct'] == true) {
|
if (answer is Map<String, dynamic> && answer['correct'] == true) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
print('COUNT: $count');
|
||||||
|
print('ASSESSMENT: ${_currentAssessment?.passingScore}');
|
||||||
|
if (count >= (_currentAssessment?.passingScore ?? 0)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return count;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isSelectedAnswer({required int question, required String answer}) {
|
bool isSelectedAnswer({required int question, required String answer}) {
|
||||||
|
|
@ -125,7 +122,7 @@ class AssessmentViewModel extends BaseViewModel {
|
||||||
question.toString(): {
|
question.toString(): {
|
||||||
'correct': correct,
|
'correct': correct,
|
||||||
'option': option?.optionText,
|
'option': option?.optionText,
|
||||||
'answer': _assessments[question - 1]
|
'answer': _assessmentQuestions[question - 1]
|
||||||
.options
|
.options
|
||||||
?.firstWhere((e) => e.isCorrect ?? false)
|
?.firstWhere((e) => e.isCorrect ?? false)
|
||||||
.optionText
|
.optionText
|
||||||
|
|
@ -152,32 +149,41 @@ class AssessmentViewModel extends BaseViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Question navigation
|
// Question navigation
|
||||||
void nextQuestion() {
|
Future<void> nextQuestion() async {
|
||||||
_currentQuestion++;
|
_currentQuestionIndex++;
|
||||||
Map<String, dynamic> response = evaluateAssessment();
|
Map<String, dynamic> response = evaluateAssessment();
|
||||||
|
print('LEVEL: $response');
|
||||||
if (_currentQuestion == _assessments.length) {
|
print('LENGTH: ${_assessmentQuestions.length}');
|
||||||
_proficiencyLevel = response['level'];
|
print('INDEX: $_currentQuestionIndex');
|
||||||
next();
|
if (_currentQuestionIndex == _assessmentQuestions.length) {
|
||||||
} else {
|
_currentAssessmentIndex = _currentAssessmentIndex + 1;
|
||||||
if (response['level'] == ProficiencyLevels.none) {
|
if (_currentAssessmentIndex == _assessments.length) {
|
||||||
_pageController.jumpToPage(_currentQuestion);
|
_proficiencyLevel = response['level'];
|
||||||
|
next();
|
||||||
} else {
|
} else {
|
||||||
if (response['continue']) {
|
if (response['passed']) {
|
||||||
_pageController.jumpToPage(_currentQuestion);
|
_selectedAnswers.clear();
|
||||||
|
_currentQuestionIndex = 0;
|
||||||
|
_proficiencyLevel = response['level'];
|
||||||
|
_currentAssessment = assessments[currentAssessmentIndex];
|
||||||
|
await getAssessmentQuestions(
|
||||||
|
_currentAssessment?.id ?? 0);
|
||||||
|
_pageController.jumpToPage(_currentQuestionIndex);
|
||||||
} else {
|
} else {
|
||||||
_proficiencyLevel = response['level'];
|
_proficiencyLevel = response['level'];
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
_pageController.jumpToPage(_currentQuestionIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
rebuildUi();
|
rebuildUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
void previousQuestion() {
|
void previousQuestion() {
|
||||||
if (_currentQuestion != 0) {
|
if (_currentQuestionIndex != 0) {
|
||||||
_currentQuestion--;
|
_currentQuestionIndex--;
|
||||||
_pageController.previousPage(
|
_pageController.previousPage(
|
||||||
duration: const Duration(microseconds: 100), curve: Curves.linear);
|
duration: const Duration(microseconds: 100), curve: Curves.linear);
|
||||||
rebuildUi();
|
rebuildUi();
|
||||||
|
|
@ -193,7 +199,7 @@ class AssessmentViewModel extends BaseViewModel {
|
||||||
_currentPage = 0;
|
_currentPage = 0;
|
||||||
rebuildUi();
|
rebuildUi();
|
||||||
} else if (_currentPage == 3) {
|
} else if (_currentPage == 3) {
|
||||||
if (_proficiencyLevel != ProficiencyLevels.none) {
|
if (_proficiencyLevel != null) {
|
||||||
_currentPage--;
|
_currentPage--;
|
||||||
} else {
|
} else {
|
||||||
_currentPage = 0;
|
_currentPage = 0;
|
||||||
|
|
@ -240,12 +246,12 @@ class AssessmentViewModel extends BaseViewModel {
|
||||||
// Navigation
|
// Navigation
|
||||||
void pop() => _navigationService.back();
|
void pop() => _navigationService.back();
|
||||||
|
|
||||||
Future<void> replaceWithStartUp() async =>
|
|
||||||
await _navigationService.clearStackAndShow(Routes.startupView);
|
|
||||||
|
|
||||||
Future<void> navigateToLanguage() async =>
|
Future<void> navigateToLanguage() async =>
|
||||||
await _navigationService.navigateToLanguageView();
|
await _navigationService.navigateToLanguageView();
|
||||||
|
|
||||||
|
Future<void> replaceWittStartUp() async =>
|
||||||
|
await _navigationService.clearStackAndShow(Routes.startupView);
|
||||||
|
|
||||||
// Remote api call
|
// Remote api call
|
||||||
|
|
||||||
// Complete profile
|
// Complete profile
|
||||||
|
|
@ -259,7 +265,7 @@ class AssessmentViewModel extends BaseViewModel {
|
||||||
await _apiService.completeProfile(_userData);
|
await _apiService.completeProfile(_userData);
|
||||||
if (response['status'] == ResponseStatus.success) {
|
if (response['status'] == ResponseStatus.success) {
|
||||||
clearUserData();
|
clearUserData();
|
||||||
await replaceWithStartUp();
|
await replaceWittStartUp();
|
||||||
showSuccessToast(response['message']);
|
showSuccessToast(response['message']);
|
||||||
} else {
|
} else {
|
||||||
showErrorToast(response['message']);
|
showErrorToast(response['message']);
|
||||||
|
|
@ -268,11 +274,23 @@ class AssessmentViewModel extends BaseViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assessments
|
// Assessments
|
||||||
|
Future<void> getAssessments() async =>
|
||||||
|
await runBusyFuture(_getAssessments(),
|
||||||
|
busyObject: StateObjects.assessments);
|
||||||
|
|
||||||
Future<void> _getAssessments() async {
|
Future<void> _getAssessments() async {
|
||||||
if (await _statusChecker.checkConnection()) {
|
if (await _statusChecker.checkConnection()) {
|
||||||
_assessments = await _apiService.getAssessments();
|
_assessments = await _apiService.getAssessments();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> getAssessments() async => await runBusyFuture(_getAssessments());
|
Future<void> getAssessmentQuestions(int id) async =>
|
||||||
|
await runBusyFuture(_getAssessmentQuestions(id),
|
||||||
|
busyObject: StateObjects.assessmentQuestions);
|
||||||
|
|
||||||
|
Future<void> _getAssessmentQuestions(int id) async {
|
||||||
|
if (await _statusChecker.checkConnection()) {
|
||||||
|
_assessmentQuestions = await _apiService.getAssessmentQuestions(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ import '../assessment_viewmodel.dart';
|
||||||
class AssessmentIntroScreen extends ViewModelWidget<AssessmentViewModel> {
|
class AssessmentIntroScreen extends ViewModelWidget<AssessmentViewModel> {
|
||||||
const AssessmentIntroScreen({super.key});
|
const AssessmentIntroScreen({super.key});
|
||||||
|
|
||||||
|
Future<void> _next(AssessmentViewModel viewModel) async =>
|
||||||
|
viewModel.setFirstAssessment();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, AssessmentViewModel viewModel) =>
|
Widget build(BuildContext context, AssessmentViewModel viewModel) =>
|
||||||
_buildScaffoldWrapper(viewModel);
|
_buildScaffoldWrapper(viewModel);
|
||||||
|
|
@ -95,8 +98,8 @@ class AssessmentIntroScreen extends ViewModelWidget<AssessmentViewModel> {
|
||||||
text: 'Continue',
|
text: 'Continue',
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
foregroundColor: kcWhite,
|
foregroundColor: kcWhite,
|
||||||
onTap: () => viewModel.next(),
|
|
||||||
backgroundColor: kcPrimaryColor,
|
backgroundColor: kcPrimaryColor,
|
||||||
|
onTap: () async => await _next(viewModel),
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildSkipButtonWrapper(AssessmentViewModel viewModel) => Padding(
|
Widget _buildSkipButtonWrapper(AssessmentViewModel viewModel) => Padding(
|
||||||
|
|
|
||||||
|
|
@ -6,28 +6,15 @@ import 'package:yimaru_app/ui/widgets/custom_elevated_button.dart';
|
||||||
import 'package:yimaru_app/ui/widgets/custom_small_radio_button.dart';
|
import 'package:yimaru_app/ui/widgets/custom_small_radio_button.dart';
|
||||||
import 'package:yimaru_app/ui/widgets/large_app_bar.dart';
|
import 'package:yimaru_app/ui/widgets/large_app_bar.dart';
|
||||||
|
|
||||||
|
import '../../../widgets/assessment_loading_screen.dart';
|
||||||
import '../assessment_viewmodel.dart';
|
import '../assessment_viewmodel.dart';
|
||||||
import 'assessment_loading_screen.dart';
|
|
||||||
|
|
||||||
class AssessmentQuestionsScreen extends ViewModelWidget<AssessmentViewModel> {
|
class AssessmentQuestionsScreen extends ViewModelWidget<AssessmentViewModel> {
|
||||||
const AssessmentQuestionsScreen({super.key});
|
const AssessmentQuestionsScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, AssessmentViewModel viewModel) =>
|
Widget build(BuildContext context, AssessmentViewModel viewModel) =>
|
||||||
_buildAssessmentScreens(viewModel);
|
_buildAssessmentScreensWrapper(viewModel);
|
||||||
|
|
||||||
Widget _buildAssessmentScreens(AssessmentViewModel viewModel) =>
|
|
||||||
viewModel.isBusy || viewModel.assessments.isEmpty
|
|
||||||
? _buildPageLoadingIndicator(viewModel)
|
|
||||||
: _buildAssessmentScreensWrapper(viewModel);
|
|
||||||
|
|
||||||
Widget _buildPageLoadingIndicator(AssessmentViewModel viewModel) =>
|
|
||||||
AssessmentLoadingScreen(
|
|
||||||
isLoading: viewModel.isBusy,
|
|
||||||
isEmpty: viewModel.assessments.isEmpty,
|
|
||||||
onTap: () async => await viewModel.getAssessments(),
|
|
||||||
onPop: viewModel.assessments.isEmpty ? viewModel.pop : null,
|
|
||||||
);
|
|
||||||
|
|
||||||
Widget _buildAssessmentScreensWrapper(AssessmentViewModel viewModel) =>
|
Widget _buildAssessmentScreensWrapper(AssessmentViewModel viewModel) =>
|
||||||
PopScope(
|
PopScope(
|
||||||
|
|
@ -52,7 +39,7 @@ class AssessmentQuestionsScreen extends ViewModelWidget<AssessmentViewModel> {
|
||||||
onClose: viewModel.abort,
|
onClose: viewModel.abort,
|
||||||
showLanguageSelection: false,
|
showLanguageSelection: false,
|
||||||
onPop: viewModel.previousQuestion,
|
onPop: viewModel.previousQuestion,
|
||||||
showBackButton: viewModel.currentQuestion == 0 ? false : true,
|
showBackButton: viewModel.currentQuestionIndex == 0 ? false : true,
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildExpandedBody(AssessmentViewModel viewModel) =>
|
Widget _buildExpandedBody(AssessmentViewModel viewModel) =>
|
||||||
|
|
@ -65,7 +52,7 @@ class AssessmentQuestionsScreen extends ViewModelWidget<AssessmentViewModel> {
|
||||||
|
|
||||||
Widget _buildAssessment(AssessmentViewModel viewModel) => PageView.builder(
|
Widget _buildAssessment(AssessmentViewModel viewModel) => PageView.builder(
|
||||||
controller: viewModel.pageController,
|
controller: viewModel.pageController,
|
||||||
itemCount: viewModel.assessments.length,
|
itemCount: viewModel.assessmentQuestions.length,
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
itemBuilder: (cotext, index) =>
|
itemBuilder: (cotext, index) =>
|
||||||
_buildBodyScroller(index: index, viewModel: viewModel),
|
_buildBodyScroller(index: index, viewModel: viewModel),
|
||||||
|
|
@ -98,7 +85,7 @@ class AssessmentQuestionsScreen extends ViewModelWidget<AssessmentViewModel> {
|
||||||
Widget _buildTitle(
|
Widget _buildTitle(
|
||||||
{required int index, required AssessmentViewModel viewModel}) =>
|
{required int index, required AssessmentViewModel viewModel}) =>
|
||||||
Text(
|
Text(
|
||||||
'Q${index + 1}. ${viewModel.assessments[index].questionText} ',
|
'Q${index + 1}. ${viewModel.assessmentQuestions[index].questionText} ',
|
||||||
style: style16DG600,
|
style: style16DG600,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -107,15 +94,18 @@ class AssessmentQuestionsScreen extends ViewModelWidget<AssessmentViewModel> {
|
||||||
ListView.builder(
|
ListView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
itemCount: viewModel.assessments[index].options?.length,
|
itemCount: viewModel.assessmentQuestions[index].options?.length,
|
||||||
itemBuilder: (context, inner) => _buildAnswer(
|
itemBuilder: (context, inner) => _buildAnswer(
|
||||||
onTap: () => viewModel.setSelectedAnswer(
|
onTap: () => viewModel.setSelectedAnswer(
|
||||||
question: index + 1,
|
question: index + 1,
|
||||||
option: viewModel.assessments[index].options?[inner]),
|
option: viewModel.assessmentQuestions[index].options?[inner]),
|
||||||
title: viewModel.assessments[index].options?[inner].optionText ?? '',
|
title:
|
||||||
|
viewModel.assessmentQuestions[index].options?[inner].optionText ??
|
||||||
|
'',
|
||||||
selected: viewModel.isSelectedAnswer(
|
selected: viewModel.isSelectedAnswer(
|
||||||
question: index + 1,
|
question: index + 1,
|
||||||
answer: viewModel.assessments[index].options?[inner].optionText ??
|
answer: viewModel
|
||||||
|
.assessmentQuestions[index].options?[inner].optionText ??
|
||||||
''),
|
''),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -150,8 +140,8 @@ class AssessmentQuestionsScreen extends ViewModelWidget<AssessmentViewModel> {
|
||||||
onTap: viewModel.selectedAnswers.containsKey(question.toString())
|
onTap: viewModel.selectedAnswers.containsKey(question.toString())
|
||||||
? () => viewModel.nextQuestion()
|
? () => viewModel.nextQuestion()
|
||||||
: null,
|
: null,
|
||||||
text: viewModel.currentQuestion == viewModel.assessments.length - 1
|
text: viewModel.currentQuestionIndex == viewModel.assessmentQuestions.length - 1
|
||||||
? 'Finish'
|
? 'Finish Level'
|
||||||
: 'Continue',
|
: 'Continue',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ class AssessmentResultScreen extends ViewModelWidget<AssessmentViewModel> {
|
||||||
];
|
];
|
||||||
|
|
||||||
Widget _buildTitle(AssessmentViewModel viewModel) => Text(
|
Widget _buildTitle(AssessmentViewModel viewModel) => Text(
|
||||||
'You’re likely a ${viewModel.proficiencyLevel.name.toUpperCase()} speaker!',
|
'You’re likely a ${viewModel.proficiencyLevel?.toUpperCase()} speaker!',
|
||||||
style: style25DG600,
|
style: style25DG600,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
);
|
);
|
||||||
|
|
@ -87,12 +87,12 @@ class AssessmentResultScreen extends ViewModelWidget<AssessmentViewModel> {
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildIconWrapper(AssessmentViewModel viewModel) =>
|
Widget _buildIconWrapper(AssessmentViewModel viewModel) =>
|
||||||
viewModel.proficiencyLevel != ProficiencyLevels.none
|
viewModel.proficiencyLevel != null
|
||||||
? _buildIcon(viewModel)
|
? _buildIcon(viewModel)
|
||||||
: Container();
|
: Container();
|
||||||
|
|
||||||
Widget _buildIcon(AssessmentViewModel viewModel) => SvgPicture.asset(
|
Widget _buildIcon(AssessmentViewModel viewModel) => SvgPicture.asset(
|
||||||
'assets/icons/${viewModel.proficiencyLevel.name.substring(0, 1)}_${viewModel.proficiencyLevel.name.substring(1)}.svg');
|
'assets/icons/${viewModel.proficiencyLevel?.substring(0, 1).toLowerCase()}_${viewModel.proficiencyLevel?.substring(1).toLowerCase()}.svg');
|
||||||
|
|
||||||
Widget _buildSecondarySubtitle() => Text(
|
Widget _buildSecondarySubtitle() => Text(
|
||||||
'Let\'s start your practice',
|
'Let\'s start your practice',
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@ class StartLessonScreen extends ViewModelWidget<AssessmentViewModel> {
|
||||||
const StartLessonScreen({super.key});
|
const StartLessonScreen({super.key});
|
||||||
|
|
||||||
Future<void> _start(AssessmentViewModel viewModel) async {
|
Future<void> _start(AssessmentViewModel viewModel) async {
|
||||||
if (viewModel.proficiencyLevel != ProficiencyLevels.none) {
|
if (viewModel.proficiencyLevel != null) {
|
||||||
Map<String, dynamic> data = {
|
Map<String, dynamic> data = {
|
||||||
'knowledge_level': viewModel.proficiencyLevel.name.toUpperCase()
|
'knowledge_level': viewModel.proficiencyLevel?.toUpperCase()
|
||||||
};
|
};
|
||||||
|
|
||||||
viewModel.addUserData(data);
|
viewModel.addUserData(data);
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ class CallSupportView extends StackedView<CallSupportViewModel> {
|
||||||
|
|
||||||
Widget _buildAppbar(CallSupportViewModel viewModel) => SmallAppBar(
|
Widget _buildAppbar(CallSupportViewModel viewModel) => SmallAppBar(
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
onTap: viewModel.pop,
|
onPop: viewModel.pop,
|
||||||
title: 'Call Support',
|
title: 'Call Support',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ class CourseView extends StackedView<CourseViewModel> {
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildAppBar(CourseViewModel viewModel) => SmallAppBar(
|
Widget _buildAppBar(CourseViewModel viewModel) => SmallAppBar(
|
||||||
onTap: viewModel.pop,
|
onPop: viewModel.pop,
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ class CourseLessonView extends StackedView<CourseLessonViewModel> {
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildAppBar(CourseLessonViewModel viewModel) => SmallAppBar(
|
Widget _buildAppBar(CourseLessonViewModel viewModel) => SmallAppBar(
|
||||||
onTap: viewModel.pop,
|
onPop: viewModel.pop,
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
title: 'Course Detail',
|
title: 'Course Detail',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ class CourseLessonDetailView extends StackedView<CourseLessonDetailViewModel> {
|
||||||
child: _buildAppBar(viewModel));
|
child: _buildAppBar(viewModel));
|
||||||
|
|
||||||
Widget _buildAppBar(CourseLessonDetailViewModel viewModel) => SmallAppBar(
|
Widget _buildAppBar(CourseLessonDetailViewModel viewModel) => SmallAppBar(
|
||||||
onTap: viewModel.pop,
|
onPop: viewModel.pop,
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
title: lesson.title ?? '',
|
title: lesson.title ?? '',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ class CoursePaymentView extends StackedView<CoursePaymentViewModel> {
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildAppBar(CoursePaymentViewModel viewModel) => SmallAppBar(
|
Widget _buildAppBar(CoursePaymentViewModel viewModel) => SmallAppBar(
|
||||||
onTap: viewModel.pop,
|
onPop: viewModel.pop,
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ class CoursePracticeView extends StackedView<CoursePracticeViewModel> {
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildAppBar(CoursePracticeViewModel viewModel) => SmallAppBar(
|
Widget _buildAppBar(CoursePracticeViewModel viewModel) => SmallAppBar(
|
||||||
onTap: viewModel.pop,
|
onPop: viewModel.pop,
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import 'package:stacked_services/stacked_services.dart';
|
||||||
|
|
||||||
import '../../../app/app.locator.dart';
|
import '../../../app/app.locator.dart';
|
||||||
import '../../../models/option.dart';
|
import '../../../models/option.dart';
|
||||||
import '../../../models/question.dart';
|
import '../../../models/assessment_question.dart';
|
||||||
import '../../../services/api_service.dart';
|
import '../../../services/api_service.dart';
|
||||||
import '../../../services/status_checker_service.dart';
|
import '../../../services/status_checker_service.dart';
|
||||||
import '../../common/app_colors.dart';
|
import '../../common/app_colors.dart';
|
||||||
|
|
@ -38,13 +38,14 @@ class CoursePracticeQuestionViewModel extends FormViewModel {
|
||||||
|
|
||||||
bool get focusAnswer => _focusAnswer;
|
bool get focusAnswer => _focusAnswer;
|
||||||
|
|
||||||
Question? _currentQuestion;
|
AssessmentQuestion? _currentQuestion;
|
||||||
|
|
||||||
Question? get currentQuestion => _currentQuestion;
|
AssessmentQuestion? get currentQuestion => _currentQuestion;
|
||||||
|
|
||||||
List<Question> _coursePracticeQuestions = [];
|
List<AssessmentQuestion> _coursePracticeQuestions = [];
|
||||||
|
|
||||||
List<Question> get coursePracticeQuestions => _coursePracticeQuestions;
|
List<AssessmentQuestion> get coursePracticeQuestions =>
|
||||||
|
_coursePracticeQuestions;
|
||||||
|
|
||||||
int _currentQuestionIndex = 0;
|
int _currentQuestionIndex = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ class CourseSubcategoryView extends StackedView<CourseSubcategoryViewModel> {
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildAppBar(CourseSubcategoryViewModel viewModel) => SmallAppBar(
|
Widget _buildAppBar(CourseSubcategoryViewModel viewModel) => SmallAppBar(
|
||||||
onTap: viewModel.pop,
|
onPop: viewModel.pop,
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ class DownloadsView extends StackedView<DownloadsViewModel> {
|
||||||
];
|
];
|
||||||
|
|
||||||
Widget _buildAppbar(DownloadsViewModel viewModel) => SmallAppBar(
|
Widget _buildAppbar(DownloadsViewModel viewModel) => SmallAppBar(
|
||||||
onTap: viewModel.pop,
|
onPop: viewModel.pop,
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
title: 'Offline Downloads',
|
title: 'Offline Downloads',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,10 @@ import 'failure_viewmodel.dart';
|
||||||
|
|
||||||
class FailureView extends StackedView<FailureViewModel> {
|
class FailureView extends StackedView<FailureViewModel> {
|
||||||
final String label;
|
final String label;
|
||||||
|
final GestureTapCallback onTap;
|
||||||
|
|
||||||
const FailureView({Key? key, required this.label}) : super(key: key);
|
const FailureView({Key? key, required this.onTap, required this.label})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FailureViewModel viewModelBuilder(BuildContext context) => FailureViewModel();
|
FailureViewModel viewModelBuilder(BuildContext context) => FailureViewModel();
|
||||||
|
|
@ -48,19 +50,38 @@ class FailureView extends StackedView<FailureViewModel> {
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: _buildUpperColumnChildren(),
|
children: _buildColumnChildren(),
|
||||||
);
|
);
|
||||||
|
|
||||||
List<Widget> _buildUpperColumnChildren() =>
|
List<Widget> _buildColumnChildren() =>
|
||||||
[_buildIconWrapper(), _buildSafeWrapper()];
|
[_buildIconWrapper(), _buildSafeWrapper()];
|
||||||
|
|
||||||
Widget _buildSafeWrapper() => SafeArea(child: _buildLoadingTextContainer());
|
Widget _buildIconWrapper() => Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 100),
|
||||||
Widget _buildLoadingTextContainer() => Padding(
|
child: _buildIcon(),
|
||||||
padding: const EdgeInsets.only(bottom: 50),
|
|
||||||
child: _buildLoadingTextWrapper(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Widget _buildIcon() => SvgPicture.asset('assets/icons/logo.svg', height: 50);
|
||||||
|
|
||||||
|
Widget _buildSafeWrapper() => SafeArea(child: _buildBottomSectionWrapper());
|
||||||
|
|
||||||
|
Widget _buildBottomSectionWrapper() => Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 50),
|
||||||
|
child: _buildBottomSectionColumn(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget _buildBottomSectionColumn() => Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: _buildBottomSectionChildren(),
|
||||||
|
);
|
||||||
|
|
||||||
|
List<Widget> _buildBottomSectionChildren() => [
|
||||||
|
_buildLoadingTextWrapper(),
|
||||||
|
verticalSpaceSmall,
|
||||||
|
_buildRetryButtonWrapper()
|
||||||
|
];
|
||||||
|
|
||||||
Widget _buildLoadingTextWrapper() => Row(
|
Widget _buildLoadingTextWrapper() => Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
|
@ -85,10 +106,14 @@ class FailureView extends StackedView<FailureViewModel> {
|
||||||
Widget _buildIndicator() =>
|
Widget _buildIndicator() =>
|
||||||
const CustomCircularProgressIndicator(color: kcWhite);
|
const CustomCircularProgressIndicator(color: kcWhite);
|
||||||
|
|
||||||
Widget _buildIconWrapper() => Padding(
|
Widget _buildRetryButtonWrapper() => GestureDetector(
|
||||||
padding: const EdgeInsets.only(top: 100),
|
onTap: onTap,
|
||||||
child: _buildIcon(),
|
child: _buildRetryButton(),
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildIcon() => SvgPicture.asset('assets/icons/logo.svg', height: 50);
|
Widget _buildRetryButton() => Text(
|
||||||
|
'Retry',
|
||||||
|
style: style16W600.copyWith(
|
||||||
|
fontStyle: FontStyle.italic, decoration: TextDecoration.underline),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,21 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:stacked/stacked.dart';
|
import 'package:stacked/stacked.dart';
|
||||||
import 'package:yimaru_app/ui/common/app_colors.dart';
|
import 'package:yimaru_app/ui/common/app_colors.dart';
|
||||||
import 'package:yimaru_app/ui/common/enmus.dart';
|
|
||||||
import 'package:yimaru_app/ui/views/learn_program/learn_program_view.dart';
|
import 'package:yimaru_app/ui/views/learn_program/learn_program_view.dart';
|
||||||
import 'package:yimaru_app/ui/views/profile/profile_view.dart';
|
import 'package:yimaru_app/ui/views/profile/profile_view.dart';
|
||||||
import 'package:yimaru_app/ui/views/startup/startup_view.dart';
|
|
||||||
import 'package:yimaru_app/ui/widgets/coming_soon.dart';
|
import 'package:yimaru_app/ui/widgets/coming_soon.dart';
|
||||||
|
|
||||||
|
import '../../common/enmus.dart';
|
||||||
|
import '../../widgets/page_loading_indicator.dart';
|
||||||
import 'home_viewmodel.dart';
|
import 'home_viewmodel.dart';
|
||||||
|
|
||||||
class HomeView extends StackedView<HomeViewModel> {
|
class HomeView extends StackedView<HomeViewModel> {
|
||||||
const HomeView({Key? key}) : super(key: key);
|
const HomeView({Key? key}) : super(key: key);
|
||||||
|
@override
|
||||||
|
void onViewModelReady(HomeViewModel viewModel) async {
|
||||||
|
await viewModel.inAppUpdate();
|
||||||
|
super.onViewModelReady(viewModel);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
HomeViewModel viewModelBuilder(BuildContext context) => HomeViewModel();
|
HomeViewModel viewModelBuilder(BuildContext context) => HomeViewModel();
|
||||||
|
|
@ -20,8 +25,6 @@ class HomeView extends StackedView<HomeViewModel> {
|
||||||
BuildContext context, HomeViewModel viewModel, Widget? child) =>
|
BuildContext context, HomeViewModel viewModel, Widget? child) =>
|
||||||
_buildScaffold(viewModel);
|
_buildScaffold(viewModel);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Widget _buildScaffold(HomeViewModel viewModel) => Scaffold(
|
Widget _buildScaffold(HomeViewModel viewModel) => Scaffold(
|
||||||
body: getViewForIndex(viewModel.currentPage),
|
body: getViewForIndex(viewModel.currentPage),
|
||||||
bottomNavigationBar: _buildBottomNav(viewModel),
|
bottomNavigationBar: _buildBottomNav(viewModel),
|
||||||
|
|
@ -56,22 +59,22 @@ class HomeView extends StackedView<HomeViewModel> {
|
||||||
label: 'Profile',
|
label: 'Profile',
|
||||||
icon: _buildProfileIcon(),
|
icon: _buildProfileIcon(),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildLearnIcon() => const Icon(Icons.school);
|
Widget _buildLearnIcon() => const Icon(Icons.school);
|
||||||
|
|
||||||
Widget _buildCourseIcon() => const Icon(Icons.book);
|
Widget _buildCourseIcon() => const Icon(Icons.book);
|
||||||
|
|
||||||
Widget _buildProfileIcon() => const Icon(Icons.person);
|
Widget _buildProfileIcon() => const Icon(Icons.person);
|
||||||
|
|
||||||
Widget getViewForIndex(int index) {
|
Widget getViewForIndex(int index) {
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 0:
|
case 0:
|
||||||
return const LearnProgramView();
|
return const LearnProgramView();
|
||||||
case 1:
|
case 1:
|
||||||
return const ComingSoon();
|
return const ComingSoon();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return const ProfileView();
|
return const ProfileView();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,19 @@
|
||||||
import 'package:yimaru_app/app/app.bottomsheets.dart';
|
import 'package:yimaru_app/app/app.bottomsheets.dart';
|
||||||
import 'package:yimaru_app/app/app.locator.dart';
|
import 'package:yimaru_app/app/app.locator.dart';
|
||||||
import 'package:yimaru_app/app/app.router.dart';
|
|
||||||
import 'package:yimaru_app/models/user.dart';
|
import 'package:yimaru_app/models/user.dart';
|
||||||
import 'package:yimaru_app/services/status_checker_service.dart';
|
import 'package:yimaru_app/services/status_checker_service.dart';
|
||||||
import 'package:yimaru_app/ui/common/app_strings.dart';
|
import 'package:yimaru_app/ui/common/app_strings.dart';
|
||||||
import 'package:stacked/stacked.dart';
|
import 'package:stacked/stacked.dart';
|
||||||
import 'package:stacked_services/stacked_services.dart';
|
import 'package:stacked_services/stacked_services.dart';
|
||||||
|
|
||||||
import '../../../services/api_service.dart';
|
|
||||||
import '../../../services/authentication_service.dart';
|
import '../../../services/authentication_service.dart';
|
||||||
import '../../../services/image_downloader_service.dart';
|
import '../../../services/in_app_update_service.dart';
|
||||||
import '../../common/enmus.dart';
|
|
||||||
import '../../common/ui_helpers.dart';
|
|
||||||
|
|
||||||
class HomeViewModel extends ReactiveViewModel {
|
class HomeViewModel extends ReactiveViewModel {
|
||||||
|
// Dependency injection
|
||||||
|
final _statusChecker = locator<StatusCheckerService>();
|
||||||
final _bottomSheetService = locator<BottomSheetService>();
|
final _bottomSheetService = locator<BottomSheetService>();
|
||||||
|
final _inAppUpdateService = locator<InAppUpdateService>();
|
||||||
final _authenticationService = locator<AuthenticationService>();
|
final _authenticationService = locator<AuthenticationService>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -46,9 +44,12 @@ class HomeViewModel extends ReactiveViewModel {
|
||||||
rebuildUi();
|
rebuildUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remote api calls
|
||||||
|
|
||||||
|
// In-app update
|
||||||
|
Future<void> inAppUpdate() async {
|
||||||
|
if (await _statusChecker.checkConnection()) {
|
||||||
|
await _inAppUpdateService.checkForUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ class LanguageView extends StackedView<LanguageViewModel> {
|
||||||
|
|
||||||
Widget _buildAppbar(LanguageViewModel viewModel) => SmallAppBar(
|
Widget _buildAppbar(LanguageViewModel viewModel) => SmallAppBar(
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
onTap: viewModel.pop,
|
onPop: viewModel.pop,
|
||||||
title: 'Language Preference',
|
title: 'Language Preference',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ class LearnCourseView extends StackedView<LearnCourseViewModel> {
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildAppBar(LearnCourseViewModel viewModel) => SmallAppBar(
|
Widget _buildAppBar(LearnCourseViewModel viewModel) => SmallAppBar(
|
||||||
onTap: viewModel.pop,
|
onPop: viewModel.pop,
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ class LearnLessonView extends StackedView<LearnLessonViewModel> {
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildAppBar(LearnLessonViewModel viewModel) => SmallAppBar(
|
Widget _buildAppBar(LearnLessonViewModel viewModel) => SmallAppBar(
|
||||||
onTap: viewModel.pop,
|
onPop: viewModel.pop,
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ class LearnLessonDetailView extends StackedView<LearnLessonDetailViewModel> {
|
||||||
|
|
||||||
Future<void> _navigate(LearnLessonDetailViewModel viewModel) async {
|
Future<void> _navigate(LearnLessonDetailViewModel viewModel) async {
|
||||||
await viewModel.pause();
|
await viewModel.pause();
|
||||||
await viewModel.navigateToLearnPractice();
|
await viewModel.navigateToLearnPractice(lesson.id ?? 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -60,7 +60,7 @@ class LearnLessonDetailView extends StackedView<LearnLessonDetailViewModel> {
|
||||||
child: _buildAppBar(viewModel));
|
child: _buildAppBar(viewModel));
|
||||||
|
|
||||||
Widget _buildAppBar(LearnLessonDetailViewModel viewModel) => SmallAppBar(
|
Widget _buildAppBar(LearnLessonDetailViewModel viewModel) => SmallAppBar(
|
||||||
onTap: viewModel.pop,
|
onPop: viewModel.pop,
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import 'package:stacked_services/stacked_services.dart';
|
||||||
import 'package:yimaru_app/ui/common/enmus.dart';
|
import 'package:yimaru_app/ui/common/enmus.dart';
|
||||||
|
|
||||||
import '../../../app/app.locator.dart';
|
import '../../../app/app.locator.dart';
|
||||||
|
import '../../../app/app.router.dart';
|
||||||
import '../../../services/status_checker_service.dart';
|
import '../../../services/status_checker_service.dart';
|
||||||
|
|
||||||
class LearnLessonDetailViewModel extends BaseViewModel {
|
class LearnLessonDetailViewModel extends BaseViewModel {
|
||||||
|
|
@ -44,6 +45,6 @@ class LearnLessonDetailViewModel extends BaseViewModel {
|
||||||
// Navigation
|
// Navigation
|
||||||
void pop() => _navigationService.back();
|
void pop() => _navigationService.back();
|
||||||
|
|
||||||
Future<void> navigateToLearnPractice() async {}
|
Future<void> navigateToLearnPractice(int id) async => await _navigationService
|
||||||
// await _navigationService.navigateToLearnPracticeView();
|
.navigateToLearnPracticeView(id: id, practice: LearnPractices.lesson);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ class LearnModuleView extends StackedView<LearnModuleViewModel> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onViewModelReady(LearnModuleViewModel viewModel) async {
|
void onViewModelReady(LearnModuleViewModel viewModel) async {
|
||||||
await viewModel.getLearnModules(1);
|
await viewModel.getLearnModules(course.id ?? 0);
|
||||||
super.onViewModelReady(viewModel);
|
super.onViewModelReady(viewModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,7 +58,7 @@ class LearnModuleView extends StackedView<LearnModuleViewModel> {
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildAppBar(LearnModuleViewModel viewModel) => SmallAppBar(
|
Widget _buildAppBar(LearnModuleViewModel viewModel) => SmallAppBar(
|
||||||
onTap: viewModel.pop,
|
onPop: viewModel.pop,
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -116,10 +116,10 @@ class LearnModuleView extends StackedView<LearnModuleViewModel> {
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
itemBuilder: (context, index) => _buildTile(
|
itemBuilder: (context, index) => _buildTile(
|
||||||
module: viewModel.modules[index],
|
module: viewModel.modules[index],
|
||||||
onModuleTap: () async =>
|
|
||||||
await viewModel.navigateToLearnLesson(viewModel.modules[index]),
|
|
||||||
onPracticeTap: () async => await viewModel
|
onPracticeTap: () async => await viewModel
|
||||||
.navigateToLearnPractice(viewModel.modules[index].id ?? 0),
|
.navigateToLearnPractice(viewModel.modules[index].id ?? 0),
|
||||||
|
onModuleTap: () async =>
|
||||||
|
await viewModel.navigateToLearnLesson(viewModel.modules[index]),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:stacked/stacked.dart';
|
import 'package:stacked/stacked.dart';
|
||||||
import 'package:yimaru_app/ui/common/enmus.dart';
|
import 'package:yimaru_app/ui/common/enmus.dart';
|
||||||
import 'package:yimaru_app/ui/views/learn_practice/screens/finish_learn_practice_screen.dart';
|
import 'package:yimaru_app/ui/views/learn_practice/screens/finish_learn_practice_screen.dart';
|
||||||
|
import 'package:yimaru_app/ui/views/learn_practice/screens/learn_loading_screen.dart';
|
||||||
import 'package:yimaru_app/ui/views/learn_practice/screens/learn_practice_completion_screen.dart';
|
import 'package:yimaru_app/ui/views/learn_practice/screens/learn_practice_completion_screen.dart';
|
||||||
import 'package:yimaru_app/ui/views/learn_practice/screens/learn_practice_result_screen.dart';
|
import 'package:yimaru_app/ui/views/learn_practice/screens/learn_practice_result_screen.dart';
|
||||||
import 'package:yimaru_app/ui/views/learn_practice/screens/learn_practice_questions_screen.dart';
|
import 'package:yimaru_app/ui/views/learn_practice/screens/learn_practice_questions_screen.dart';
|
||||||
|
|
@ -78,7 +79,20 @@ class LearnPracticeView extends StackedView<LearnPracticeViewModel> {
|
||||||
Widget _buildBodyState(LearnPracticeViewModel viewModel) =>
|
Widget _buildBodyState(LearnPracticeViewModel viewModel) =>
|
||||||
viewModel.busy(StateObjects.learnPractices)
|
viewModel.busy(StateObjects.learnPractices)
|
||||||
? const PageLoadingIndicator()
|
? const PageLoadingIndicator()
|
||||||
: _buildBody(viewModel);
|
: viewModel.practices.isEmpty || viewModel.questions.isEmpty
|
||||||
|
? _buildPageLoadingIndicator(viewModel)
|
||||||
|
: _buildBody(viewModel);
|
||||||
|
|
||||||
|
Widget _buildPageLoadingIndicator(LearnPracticeViewModel viewModel) =>
|
||||||
|
LearnLoadingScreen(
|
||||||
|
isLoading: viewModel.busy(StateObjects.learnPractices),
|
||||||
|
onTap: () async =>
|
||||||
|
await viewModel.getLearnPractices(id: id, practice: practice),
|
||||||
|
onPop: viewModel.practices.isEmpty || viewModel.questions.isEmpty
|
||||||
|
? viewModel.pop
|
||||||
|
: null,
|
||||||
|
isEmpty: viewModel.practices.isEmpty || viewModel.questions.isEmpty,
|
||||||
|
);
|
||||||
|
|
||||||
Widget _buildBody(LearnPracticeViewModel viewModel) => IndexedStack(
|
Widget _buildBody(LearnPracticeViewModel viewModel) => IndexedStack(
|
||||||
index: viewModel.currentPage, children: _buildScreens(viewModel));
|
index: viewModel.currentPage, children: _buildScreens(viewModel));
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,10 @@ class LearnPracticeViewModel extends ReactiveViewModel {
|
||||||
await _audioPlayerService.playUrl(question.voicePrompt ?? '');
|
await _audioPlayerService.playUrl(question.voicePrompt ?? '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> replayVoicePrompt(LearnQuestion question) async {
|
||||||
|
await _audioPlayerService.playUrl(question.voicePrompt ?? '');
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> playResult(
|
Future<void> playResult(
|
||||||
{required Map<String, dynamic> answer, required Voice voice}) async {
|
{required Map<String, dynamic> answer, required Voice voice}) async {
|
||||||
setBusyObject(playing: voice, object: answer['busy_object']);
|
setBusyObject(playing: voice, object: answer['busy_object']);
|
||||||
|
|
@ -222,6 +226,7 @@ class LearnPracticeViewModel extends ReactiveViewModel {
|
||||||
_questionSetController.nextPage(
|
_questionSetController.nextPage(
|
||||||
duration: const Duration(milliseconds: 350),
|
duration: const Duration(milliseconds: 350),
|
||||||
curve: Curves.easeInOutCubic);
|
curve: Curves.easeInOutCubic);
|
||||||
|
await playVoicePrompt(_questions[index]);
|
||||||
} else {
|
} else {
|
||||||
goTo(3);
|
goTo(3);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ class FinishLearnPracticeScreen
|
||||||
|
|
||||||
Widget _buildAppBar(LearnPracticeViewModel viewModel) => SmallAppBar(
|
Widget _buildAppBar(LearnPracticeViewModel viewModel) => SmallAppBar(
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
onTap: viewModel.goBack,
|
onPop: viewModel.goBack,
|
||||||
title: 'Practice Speaking',
|
title: 'Practice Speaking',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,8 @@ class InteractLearnPracticeScreen
|
||||||
viewModel.stopRecording();
|
viewModel.stopRecording();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _start(LearnPracticeViewModel viewModel) =>
|
void _reply(LearnPracticeViewModel viewModel) =>
|
||||||
viewModel.playVoicePrompt(question);
|
viewModel.replayVoicePrompt(question);
|
||||||
|
|
||||||
Future<void> _stop(LearnPracticeViewModel viewModel) async =>
|
Future<void> _stop(LearnPracticeViewModel viewModel) async =>
|
||||||
await viewModel.nextQuestion(index: index, question: question);
|
await viewModel.nextQuestion(index: index, question: question);
|
||||||
|
|
@ -116,7 +116,7 @@ class InteractLearnPracticeScreen
|
||||||
required LearnPracticeViewModel viewModel}) =>
|
required LearnPracticeViewModel viewModel}) =>
|
||||||
SmallAppBar(
|
SmallAppBar(
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
onTap: () async =>
|
onPop: () async =>
|
||||||
await _showSheet(context: context, viewModel: viewModel),
|
await _showSheet(context: context, viewModel: viewModel),
|
||||||
title: 'Practice Speaking ($index/${viewModel.questions.length})');
|
title: 'Practice Speaking ($index/${viewModel.questions.length})');
|
||||||
|
|
||||||
|
|
@ -263,7 +263,7 @@ class InteractLearnPracticeScreen
|
||||||
: kcLightGrey,
|
: kcLightGrey,
|
||||||
onTap: viewModel.recordingState == VoiceRecordingState.pending &&
|
onTap: viewModel.recordingState == VoiceRecordingState.pending &&
|
||||||
viewModel.player.state != PlayerState.playing
|
viewModel.player.state != PlayerState.playing
|
||||||
? () => _start(viewModel)
|
? () => _reply(viewModel)
|
||||||
: null,
|
: null,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -272,15 +272,15 @@ class InteractLearnPracticeScreen
|
||||||
|
|
||||||
Widget _buildMicButton(LearnPracticeViewModel viewModel) => ElevatedButton(
|
Widget _buildMicButton(LearnPracticeViewModel viewModel) => ElevatedButton(
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
|
shadowColor: const WidgetStatePropertyAll(kcWhite),
|
||||||
|
shape: const WidgetStatePropertyAll(CircleBorder()),
|
||||||
|
padding: const WidgetStatePropertyAll(EdgeInsets.all(15)),
|
||||||
backgroundColor: WidgetStatePropertyAll(
|
backgroundColor: WidgetStatePropertyAll(
|
||||||
viewModel.player.state == PlayerState.playing ||
|
viewModel.player.state == PlayerState.playing ||
|
||||||
viewModel.busy(StateObjects.recordLearnPracticeAnswer)
|
viewModel.busy(StateObjects.recordLearnPracticeAnswer)
|
||||||
? kcVeryLightGrey
|
? kcVeryLightGrey
|
||||||
: kcPrimaryColor,
|
: kcPrimaryColor,
|
||||||
),
|
),
|
||||||
shadowColor: const WidgetStatePropertyAll(kcWhite),
|
|
||||||
shape: const WidgetStatePropertyAll(CircleBorder()),
|
|
||||||
padding: const WidgetStatePropertyAll(EdgeInsets.all(15)),
|
|
||||||
),
|
),
|
||||||
onPressed: () async => viewModel.player.state == PlayerState.playing ||
|
onPressed: () async => viewModel.player.state == PlayerState.playing ||
|
||||||
viewModel.busy(StateObjects.recordLearnPracticeAnswer)
|
viewModel.busy(StateObjects.recordLearnPracticeAnswer)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:yimaru_app/ui/widgets/no_data_indicator.dart';
|
||||||
|
import 'package:yimaru_app/ui/widgets/page_loading_indicator.dart';
|
||||||
|
import 'package:yimaru_app/ui/widgets/small_app_bar.dart';
|
||||||
|
|
||||||
|
import '../../../common/app_colors.dart';
|
||||||
|
import '../../../common/ui_helpers.dart';
|
||||||
|
import '../../../widgets/large_app_bar.dart';
|
||||||
|
import '../../../widgets/refresh_button.dart';
|
||||||
|
|
||||||
|
class LearnLoadingScreen extends StatelessWidget {
|
||||||
|
final bool isEmpty;
|
||||||
|
final bool isLoading;
|
||||||
|
final GestureTapCallback? onPop;
|
||||||
|
final GestureTapCallback? onTap;
|
||||||
|
|
||||||
|
const LearnLoadingScreen(
|
||||||
|
{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() => SafeArea(child: _buildStack());
|
||||||
|
|
||||||
|
Widget _buildStack() => Stack(
|
||||||
|
children: [
|
||||||
|
_buildColumn(),
|
||||||
|
if (isEmpty) _buildRefreshButtonWrapper(),
|
||||||
|
if (isLoading) _buildPageIndicator()
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget _buildColumn() => Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: _buildColumnChildren(),
|
||||||
|
);
|
||||||
|
|
||||||
|
List<Widget> _buildColumnChildren() =>
|
||||||
|
[verticalSpaceMedium, _buildAppBarWrapper(), _buildBody()];
|
||||||
|
|
||||||
|
Widget _buildAppBarWrapper() => Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 15),
|
||||||
|
child: _buildAppBar(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget _buildAppBar() => SmallAppBar(onPop: onPop, showBackButton: true);
|
||||||
|
|
||||||
|
Widget _buildBody() => Expanded(child: Container());
|
||||||
|
|
||||||
|
Widget _buildPageIndicator() => const PageLoadingIndicator();
|
||||||
|
|
||||||
|
Widget _buildRefreshButtonWrapper() => Align(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child:_buildRefreshButton());
|
||||||
|
|
||||||
|
Widget _buildRefreshButton()=> NoDataIndicator(title:'No practice available!' ,onTap: onTap,);
|
||||||
|
}
|
||||||
|
|
@ -72,7 +72,7 @@ class LearnPracticeIntroScreen extends ViewModelWidget<LearnPracticeViewModel> {
|
||||||
SmallAppBar(
|
SmallAppBar(
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
title: 'Practice Speaking',
|
title: 'Practice Speaking',
|
||||||
onTap: () async =>
|
onPop: () async =>
|
||||||
await _showSheet(context: context, viewModel: viewModel),
|
await _showSheet(context: context, viewModel: viewModel),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ class LearnPracticeQuestionsScreen
|
||||||
required LearnQuestion question,
|
required LearnQuestion question,
|
||||||
}) =>
|
}) =>
|
||||||
[
|
[
|
||||||
_buildStartLearnPracticeScreen(index: index, question: question),
|
if(index ==1) _buildStartLearnPracticeScreen(index: index, question: question),
|
||||||
_buildInteractLearnPracticeScreen(index: index, question: question)
|
_buildInteractLearnPracticeScreen(index: index, question: question)
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ class LearnPracticeResultScreen
|
||||||
SmallAppBar(
|
SmallAppBar(
|
||||||
title: 'Result',
|
title: 'Result',
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
onTap: () async =>
|
onPop: () async =>
|
||||||
await _showSheet(context: context, viewModel: viewModel),
|
await _showSheet(context: context, viewModel: viewModel),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ class StartLearnPracticeScreen extends ViewModelWidget<LearnPracticeViewModel> {
|
||||||
required LearnPracticeViewModel viewModel}) =>
|
required LearnPracticeViewModel viewModel}) =>
|
||||||
SmallAppBar(
|
SmallAppBar(
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
onTap: () async =>
|
onPop: () async =>
|
||||||
await _showSheet(context: context, viewModel: viewModel),
|
await _showSheet(context: context, viewModel: viewModel),
|
||||||
title: 'Practice Speaking ($index/${viewModel.questions.length})');
|
title: 'Practice Speaking ($index/${viewModel.questions.length})');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,6 @@ class LoginViewModel extends ReactiveViewModel
|
||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
|
|
||||||
|
|
||||||
Future<void> navigateToRegister() async =>
|
Future<void> navigateToRegister() async =>
|
||||||
await _navigationService.navigateToRegisterView();
|
await _navigationService.navigateToRegisterView();
|
||||||
|
|
||||||
|
|
@ -165,9 +164,6 @@ class LoginViewModel extends ReactiveViewModel
|
||||||
Future<void> replaceWithStartUp() async =>
|
Future<void> replaceWithStartUp() async =>
|
||||||
await _navigationService.clearStackAndShow(Routes.startupView);
|
await _navigationService.clearStackAndShow(Routes.startupView);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Remote api calls
|
// Remote api calls
|
||||||
|
|
||||||
// Login with email
|
// Login with email
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ class OnboardingView extends StackedView<OnboardingViewModel>
|
||||||
|
|
||||||
void _initClearData() {
|
void _initClearData() {
|
||||||
topicController.clear();
|
topicController.clear();
|
||||||
|
regionController.clear();
|
||||||
fullNameController.clear();
|
fullNameController.clear();
|
||||||
challengeController.clear();
|
challengeController.clear();
|
||||||
occupationController.clear();
|
occupationController.clear();
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,7 @@ class OnboardingViewModel extends ReactiveViewModel
|
||||||
|
|
||||||
final List<String> _topics = [
|
final List<String> _topics = [
|
||||||
'Food & Cooking',
|
'Food & Cooking',
|
||||||
' Hobbies, Sports, Music',
|
'Hobbies, Sports, Music',
|
||||||
'Tech, News, Business',
|
'Tech, News, Business',
|
||||||
'Travel, Places, Culture',
|
'Travel, Places, Culture',
|
||||||
'Other'
|
'Other'
|
||||||
|
|
@ -547,6 +547,7 @@ class OnboardingViewModel extends ReactiveViewModel
|
||||||
|
|
||||||
// Reset country region form screen
|
// Reset country region form screen
|
||||||
void resetCountryRegionFormScreen() {
|
void resetCountryRegionFormScreen() {
|
||||||
|
_focusRegion = false;
|
||||||
_selectedCountry = 'Ethiopia';
|
_selectedCountry = 'Ethiopia';
|
||||||
rebuildUi();
|
rebuildUi();
|
||||||
}
|
}
|
||||||
|
|
@ -613,6 +614,4 @@ class OnboardingViewModel extends ReactiveViewModel
|
||||||
|
|
||||||
Future<void> navigateToAssessment() async =>
|
Future<void> navigateToAssessment() async =>
|
||||||
await _navigationService.navigateToAssessmentView(data: _userData);
|
await _navigationService.navigateToAssessmentView(data: _userData);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ class PrivacyPolicyView extends StackedView<PrivacyPolicyViewModel> {
|
||||||
|
|
||||||
Widget _buildAppbar(PrivacyPolicyViewModel viewModel) => SmallAppBar(
|
Widget _buildAppbar(PrivacyPolicyViewModel viewModel) => SmallAppBar(
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
onTap: viewModel.pop,
|
onPop: viewModel.pop,
|
||||||
title: 'Privacy Policy',
|
title: 'Privacy Policy',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import 'package:stacked/stacked.dart';
|
||||||
import 'package:yimaru_app/ui/common/app_colors.dart';
|
import 'package:yimaru_app/ui/common/app_colors.dart';
|
||||||
import 'package:yimaru_app/ui/common/enmus.dart';
|
import 'package:yimaru_app/ui/common/enmus.dart';
|
||||||
import 'package:yimaru_app/ui/common/ui_helpers.dart';
|
import 'package:yimaru_app/ui/common/ui_helpers.dart';
|
||||||
|
import 'package:yimaru_app/ui/widgets/page_loading_indicator.dart';
|
||||||
import 'package:yimaru_app/ui/widgets/profile_card.dart';
|
import 'package:yimaru_app/ui/widgets/profile_card.dart';
|
||||||
import 'package:yimaru_app/ui/widgets/profile_image.dart';
|
import 'package:yimaru_app/ui/widgets/profile_image.dart';
|
||||||
import 'package:yimaru_app/ui/widgets/view_profile_button.dart';
|
import 'package:yimaru_app/ui/widgets/view_profile_button.dart';
|
||||||
|
|
@ -155,7 +156,7 @@ class ProfileView extends StackedView<ProfileViewModel> {
|
||||||
children: _buildSettingsChildren(viewModel));
|
children: _buildSettingsChildren(viewModel));
|
||||||
|
|
||||||
List<Widget> _buildSettingsChildren(ProfileViewModel viewModel) => [
|
List<Widget> _buildSettingsChildren(ProfileViewModel viewModel) => [
|
||||||
_buildDownloadsCard(viewModel),
|
// _buildDownloadsCard(viewModel),
|
||||||
_buildProgressCard(viewModel),
|
_buildProgressCard(viewModel),
|
||||||
_buildAccountCard(viewModel),
|
_buildAccountCard(viewModel),
|
||||||
_buildSupportCard(viewModel)
|
_buildSupportCard(viewModel)
|
||||||
|
|
@ -191,7 +192,7 @@ class ProfileView extends StackedView<ProfileViewModel> {
|
||||||
|
|
||||||
Widget _buildLogOutButton(ProfileViewModel viewModel) => CustomElevatedButton(
|
Widget _buildLogOutButton(ProfileViewModel viewModel) => CustomElevatedButton(
|
||||||
height: 55,
|
height: 55,
|
||||||
text: 'Log Out',
|
text: 'Logout',
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
foregroundColor: kcRed,
|
foregroundColor: kcRed,
|
||||||
backgroundColor: kcRed.withOpacity(0.25),
|
backgroundColor: kcRed.withOpacity(0.25),
|
||||||
|
|
|
||||||
|
|
@ -61,13 +61,6 @@ class ProfileViewModel extends ReactiveViewModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logout
|
|
||||||
Future<void> _logout() async {
|
|
||||||
await _googleAuthService.logout();
|
|
||||||
await _authenticationService.logout();
|
|
||||||
await _navigationService.replaceWithLoginView();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dialog
|
// Dialog
|
||||||
Future<bool?> showAbortDialog() async {
|
Future<bool?> showAbortDialog() async {
|
||||||
DialogResponse? response = await _dialogService.showDialog(
|
DialogResponse? response = await _dialogService.showDialog(
|
||||||
|
|
@ -82,13 +75,6 @@ class ProfileViewModel extends ReactiveViewModel {
|
||||||
return response?.confirmed;
|
return response?.confirmed;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> logout() async {
|
|
||||||
bool? response = await showAbortDialog();
|
|
||||||
if (response != null && response) {
|
|
||||||
await _logout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
void pop() => _navigationService.back();
|
void pop() => _navigationService.back();
|
||||||
|
|
||||||
|
|
@ -107,6 +93,9 @@ class ProfileViewModel extends ReactiveViewModel {
|
||||||
Future<void> navigateToSupport() async =>
|
Future<void> navigateToSupport() async =>
|
||||||
await _navigationService.navigateToSupportView();
|
await _navigationService.navigateToSupportView();
|
||||||
|
|
||||||
|
Future<void> navigateToLogin() async =>
|
||||||
|
await _navigationService.clearStackAndShow(Routes.loginView);
|
||||||
|
|
||||||
// Remote api call
|
// Remote api call
|
||||||
|
|
||||||
// Update profile
|
// Update profile
|
||||||
|
|
@ -115,10 +104,21 @@ class ProfileViewModel extends ReactiveViewModel {
|
||||||
|
|
||||||
Future<void> _updateProfilePicture(String image) async {
|
Future<void> _updateProfilePicture(String image) async {
|
||||||
if (await _statusChecker.checkConnection()) {
|
if (await _statusChecker.checkConnection()) {
|
||||||
Map<String, dynamic> data = {
|
Map<String, dynamic> data = {'profile_picture_url': image};
|
||||||
'profile_picture_url': image,
|
|
||||||
};
|
|
||||||
await _apiService.updateProfileImage(data: data, userId: _user?.userId);
|
await _apiService.updateProfileImage(data: data, userId: _user?.userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> logout() async {
|
||||||
|
bool? response = await showAbortDialog();
|
||||||
|
if (response != null && response) {
|
||||||
|
await _logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _logout() async {
|
||||||
|
await _googleAuthService.logout();
|
||||||
|
await _authenticationService.logout();
|
||||||
|
await navigateToLogin();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,13 +34,13 @@ class ProfileDetailView extends StackedView<ProfileDetailViewModel>
|
||||||
|
|
||||||
Future<void> _update(ProfileDetailViewModel viewModel) async {
|
Future<void> _update(ProfileDetailViewModel viewModel) async {
|
||||||
Map<String, dynamic> data = {
|
Map<String, dynamic> data = {
|
||||||
'region':regionController.text,
|
'region': regionController.text,
|
||||||
'gender': viewModel.selectedGender,
|
'gender': viewModel.selectedGender,
|
||||||
'last_name': lastNameController.text,
|
'last_name': lastNameController.text,
|
||||||
'country': viewModel.selectedCountry,
|
'country': viewModel.selectedCountry,
|
||||||
'first_name': firstNameController.text,
|
'first_name': firstNameController.text,
|
||||||
'occupation': occupationController.text,
|
'occupation': occupationController.text,
|
||||||
'birth_day': DateFormat('d MMM, yyyy').format(DateTime.now()),
|
'birth_day': DateFormat('yyyy-MM-dd').format(DateTime.now()),
|
||||||
};
|
};
|
||||||
|
|
||||||
viewModel.addUserData(data);
|
viewModel.addUserData(data);
|
||||||
|
|
@ -75,7 +75,6 @@ class ProfileDetailView extends StackedView<ProfileDetailViewModel>
|
||||||
viewModel.clearUserData();
|
viewModel.clearUserData();
|
||||||
viewModel.setGender(viewModel.user?.gender ?? '');
|
viewModel.setGender(viewModel.user?.gender ?? '');
|
||||||
viewModel.setSelectedCountry(viewModel.user?.country ?? 'Ethiopia');
|
viewModel.setSelectedCountry(viewModel.user?.country ?? 'Ethiopia');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -147,7 +146,7 @@ class ProfileDetailView extends StackedView<ProfileDetailViewModel>
|
||||||
];
|
];
|
||||||
|
|
||||||
Widget _buildAppbar(ProfileDetailViewModel viewModel) => SmallAppBar(
|
Widget _buildAppbar(ProfileDetailViewModel viewModel) => SmallAppBar(
|
||||||
onTap: viewModel.pop,
|
onPop: viewModel.pop,
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
title: 'Edit Profile',
|
title: 'Edit Profile',
|
||||||
);
|
);
|
||||||
|
|
@ -192,9 +191,8 @@ class ProfileDetailView extends StackedView<ProfileDetailViewModel>
|
||||||
verticalSpaceSmall,
|
verticalSpaceSmall,
|
||||||
_buildCountryDropdown(viewModel),
|
_buildCountryDropdown(viewModel),
|
||||||
verticalSpaceMedium,
|
verticalSpaceMedium,
|
||||||
_buildRegionFormFieldWrapper(viewModel),
|
_buildRegionFormFieldWrapper(viewModel),
|
||||||
verticalSpaceMedium,
|
verticalSpaceMedium,
|
||||||
|
|
||||||
_buildOccupationDropdownWrapper(viewModel),
|
_buildOccupationDropdownWrapper(viewModel),
|
||||||
verticalSpaceLarge,
|
verticalSpaceLarge,
|
||||||
_buildLowerColumn(viewModel)
|
_buildLowerColumn(viewModel)
|
||||||
|
|
@ -533,9 +531,10 @@ class ProfileDetailView extends StackedView<ProfileDetailViewModel>
|
||||||
);
|
);
|
||||||
|
|
||||||
List<Widget> _buildRegionFormFieldChildren(
|
List<Widget> _buildRegionFormFieldChildren(
|
||||||
ProfileDetailViewModel viewModel) =>
|
ProfileDetailViewModel viewModel) =>
|
||||||
[
|
[
|
||||||
_buildRegionFormFieldLabel(),verticalSpaceSmall,
|
_buildRegionFormFieldLabel(),
|
||||||
|
verticalSpaceSmall,
|
||||||
_buildRegionFormField(viewModel),
|
_buildRegionFormField(viewModel),
|
||||||
if (viewModel.hasRegionValidationMessage && viewModel.focusRegion)
|
if (viewModel.hasRegionValidationMessage && viewModel.focusRegion)
|
||||||
verticalSpaceTiny,
|
verticalSpaceTiny,
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,6 @@ class ProfileDetailViewModel extends ReactiveViewModel
|
||||||
|
|
||||||
String? get selectedGender => _selectedGender;
|
String? get selectedGender => _selectedGender;
|
||||||
|
|
||||||
|
|
||||||
// First name
|
// First name
|
||||||
bool _focusPhoneNumber = false;
|
bool _focusPhoneNumber = false;
|
||||||
|
|
||||||
|
|
@ -63,7 +62,6 @@ class ProfileDetailViewModel extends ReactiveViewModel
|
||||||
|
|
||||||
String get selectedCountry => _selectedCountry;
|
String get selectedCountry => _selectedCountry;
|
||||||
|
|
||||||
|
|
||||||
// Occupation
|
// Occupation
|
||||||
bool _focusOccupation = false;
|
bool _focusOccupation = false;
|
||||||
|
|
||||||
|
|
@ -97,7 +95,6 @@ class ProfileDetailViewModel extends ReactiveViewModel
|
||||||
rebuildUi();
|
rebuildUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Phone number
|
// Phone number
|
||||||
void setPhoneNumberFocus() {
|
void setPhoneNumberFocus() {
|
||||||
_focusPhoneNumber = true;
|
_focusPhoneNumber = true;
|
||||||
|
|
@ -113,167 +110,165 @@ class ProfileDetailViewModel extends ReactiveViewModel
|
||||||
// Country
|
// Country
|
||||||
// Country
|
// Country
|
||||||
List<String> getCountries() => [
|
List<String> getCountries() => [
|
||||||
"Afghanistan",
|
"Afghanistan",
|
||||||
"Albania",
|
"Albania",
|
||||||
"Algeria",
|
"Algeria",
|
||||||
"Andorra",
|
"Andorra",
|
||||||
"Angola",
|
"Angola",
|
||||||
"Argentina",
|
"Argentina",
|
||||||
"Armenia",
|
"Armenia",
|
||||||
"Australia",
|
"Australia",
|
||||||
"Austria",
|
"Austria",
|
||||||
"Azerbaijan",
|
"Azerbaijan",
|
||||||
"Bahrain",
|
"Bahrain",
|
||||||
"Bangladesh",
|
"Bangladesh",
|
||||||
"Belarus",
|
"Belarus",
|
||||||
"Belgium",
|
"Belgium",
|
||||||
"Belize",
|
"Belize",
|
||||||
"Benin",
|
"Benin",
|
||||||
"Bhutan",
|
"Bhutan",
|
||||||
"Bolivia",
|
"Bolivia",
|
||||||
"Bosnia and Herzegovina",
|
"Bosnia and Herzegovina",
|
||||||
"Botswana",
|
"Botswana",
|
||||||
"Brazil",
|
"Brazil",
|
||||||
"Brunei",
|
"Brunei",
|
||||||
"Bulgaria",
|
"Bulgaria",
|
||||||
"Burkina Faso",
|
"Burkina Faso",
|
||||||
"Burundi",
|
"Burundi",
|
||||||
"Cambodia",
|
"Cambodia",
|
||||||
"Cameroon",
|
"Cameroon",
|
||||||
"Canada",
|
"Canada",
|
||||||
"Chad",
|
"Chad",
|
||||||
"Chile",
|
"Chile",
|
||||||
"China",
|
"China",
|
||||||
"Colombia",
|
"Colombia",
|
||||||
"Comoros",
|
"Comoros",
|
||||||
"Congo",
|
"Congo",
|
||||||
"Costa Rica",
|
"Costa Rica",
|
||||||
"Croatia",
|
"Croatia",
|
||||||
"Cuba",
|
"Cuba",
|
||||||
"Cyprus",
|
"Cyprus",
|
||||||
"Czech Republic",
|
"Czech Republic",
|
||||||
"Denmark",
|
"Denmark",
|
||||||
"Djibouti",
|
"Djibouti",
|
||||||
"Dominican Republic",
|
"Dominican Republic",
|
||||||
"Ecuador",
|
"Ecuador",
|
||||||
"Egypt",
|
"Egypt",
|
||||||
"El Salvador",
|
"El Salvador",
|
||||||
"Eritrea",
|
"Eritrea",
|
||||||
"Estonia",
|
"Estonia",
|
||||||
"Eswatini",
|
"Eswatini",
|
||||||
"Ethiopia",
|
"Ethiopia",
|
||||||
"Finland",
|
"Finland",
|
||||||
"France",
|
"France",
|
||||||
"Gabon",
|
"Gabon",
|
||||||
"Gambia",
|
"Gambia",
|
||||||
"Georgia",
|
"Georgia",
|
||||||
"Germany",
|
"Germany",
|
||||||
"Ghana",
|
"Ghana",
|
||||||
"Greece",
|
"Greece",
|
||||||
"Guatemala",
|
"Guatemala",
|
||||||
"Guinea",
|
"Guinea",
|
||||||
"Haiti",
|
"Haiti",
|
||||||
"Honduras",
|
"Honduras",
|
||||||
"Hungary",
|
"Hungary",
|
||||||
"Iceland",
|
"Iceland",
|
||||||
"India",
|
"India",
|
||||||
"Indonesia",
|
"Indonesia",
|
||||||
"Iran",
|
"Iran",
|
||||||
"Iraq",
|
"Iraq",
|
||||||
"Ireland",
|
"Ireland",
|
||||||
"Israel",
|
"Israel",
|
||||||
"Italy",
|
"Italy",
|
||||||
"Jamaica",
|
"Jamaica",
|
||||||
"Japan",
|
"Japan",
|
||||||
"Jordan",
|
"Jordan",
|
||||||
"Kazakhstan",
|
"Kazakhstan",
|
||||||
"Kenya",
|
"Kenya",
|
||||||
"Kuwait",
|
"Kuwait",
|
||||||
"Kyrgyzstan",
|
"Kyrgyzstan",
|
||||||
"Laos",
|
"Laos",
|
||||||
"Latvia",
|
"Latvia",
|
||||||
"Lebanon",
|
"Lebanon",
|
||||||
"Liberia",
|
"Liberia",
|
||||||
"Libya",
|
"Libya",
|
||||||
"Lithuania",
|
"Lithuania",
|
||||||
"Luxembourg",
|
"Luxembourg",
|
||||||
"Madagascar",
|
"Madagascar",
|
||||||
"Malawi",
|
"Malawi",
|
||||||
"Malaysia",
|
"Malaysia",
|
||||||
"Maldives",
|
"Maldives",
|
||||||
"Mali",
|
"Mali",
|
||||||
"Malta",
|
"Malta",
|
||||||
"Mexico",
|
"Mexico",
|
||||||
"Moldova",
|
"Moldova",
|
||||||
"Monaco",
|
"Monaco",
|
||||||
"Mongolia",
|
"Mongolia",
|
||||||
"Morocco",
|
"Morocco",
|
||||||
"Mozambique",
|
"Mozambique",
|
||||||
"Myanmar",
|
"Myanmar",
|
||||||
"Namibia",
|
"Namibia",
|
||||||
"Nepal",
|
"Nepal",
|
||||||
"Netherlands",
|
"Netherlands",
|
||||||
"New Zealand",
|
"New Zealand",
|
||||||
"Nicaragua",
|
"Nicaragua",
|
||||||
"Niger",
|
"Niger",
|
||||||
"Nigeria",
|
"Nigeria",
|
||||||
"North Korea",
|
"North Korea",
|
||||||
"Norway",
|
"Norway",
|
||||||
"Oman",
|
"Oman",
|
||||||
"Pakistan",
|
"Pakistan",
|
||||||
"Panama",
|
"Panama",
|
||||||
"Paraguay",
|
"Paraguay",
|
||||||
"Peru",
|
"Peru",
|
||||||
"Philippines",
|
"Philippines",
|
||||||
"Poland",
|
"Poland",
|
||||||
"Portugal",
|
"Portugal",
|
||||||
"Qatar",
|
"Qatar",
|
||||||
"Romania",
|
"Romania",
|
||||||
"Russia",
|
"Russia",
|
||||||
"Rwanda",
|
"Rwanda",
|
||||||
"Saudi Arabia",
|
"Saudi Arabia",
|
||||||
"Senegal",
|
"Senegal",
|
||||||
"Serbia",
|
"Serbia",
|
||||||
"Singapore",
|
"Singapore",
|
||||||
"Slovakia",
|
"Slovakia",
|
||||||
"Slovenia",
|
"Slovenia",
|
||||||
"Somalia",
|
"Somalia",
|
||||||
"South Africa",
|
"South Africa",
|
||||||
"South Korea",
|
"South Korea",
|
||||||
"Spain",
|
"Spain",
|
||||||
"Sri Lanka",
|
"Sri Lanka",
|
||||||
"Sudan",
|
"Sudan",
|
||||||
"Sweden",
|
"Sweden",
|
||||||
"Switzerland",
|
"Switzerland",
|
||||||
"Syria",
|
"Syria",
|
||||||
"Taiwan",
|
"Taiwan",
|
||||||
"Tajikistan",
|
"Tajikistan",
|
||||||
"Tanzania",
|
"Tanzania",
|
||||||
"Thailand",
|
"Thailand",
|
||||||
"Tunisia",
|
"Tunisia",
|
||||||
"Turkey",
|
"Turkey",
|
||||||
"Uganda",
|
"Uganda",
|
||||||
"Ukraine",
|
"Ukraine",
|
||||||
"United Arab Emirates",
|
"United Arab Emirates",
|
||||||
"United Kingdom",
|
"United Kingdom",
|
||||||
"United States",
|
"United States",
|
||||||
"Uruguay",
|
"Uruguay",
|
||||||
"Uzbekistan",
|
"Uzbekistan",
|
||||||
"Venezuela",
|
"Venezuela",
|
||||||
"Vietnam",
|
"Vietnam",
|
||||||
"Yemen",
|
"Yemen",
|
||||||
"Zambia",
|
"Zambia",
|
||||||
"Zimbabwe"
|
"Zimbabwe"
|
||||||
];
|
];
|
||||||
|
|
||||||
void setSelectedCountry(String value) {
|
void setSelectedCountry(String value) {
|
||||||
_selectedCountry = value;
|
_selectedCountry = value;
|
||||||
|
|
||||||
|
|
||||||
rebuildUi();
|
rebuildUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Occupation
|
// Occupation
|
||||||
void setOccupationFocus() {
|
void setOccupationFocus() {
|
||||||
_focusOccupation = true;
|
_focusOccupation = true;
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ class ProgressView extends StackedView<ProgressViewModel> {
|
||||||
Widget _buildAppbar(ProgressViewModel viewModel) => SmallAppBar(
|
Widget _buildAppbar(ProgressViewModel viewModel) => SmallAppBar(
|
||||||
title: 'My Progress',
|
title: 'My Progress',
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
onTap: viewModel.pop,
|
onPop: viewModel.pop,
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildContentScrollViewWrapper(ProgressViewModel viewModel) =>
|
Widget _buildContentScrollViewWrapper(ProgressViewModel viewModel) =>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import 'package:yimaru_app/ui/common/ui_helpers.dart';
|
||||||
import '../../../app/app.locator.dart';
|
import '../../../app/app.locator.dart';
|
||||||
import '../../../models/user.dart';
|
import '../../../models/user.dart';
|
||||||
import '../../../services/google_auth_service.dart';
|
import '../../../services/google_auth_service.dart';
|
||||||
import '../../../services/smart_auth_service.dart';
|
|
||||||
import '../../../services/status_checker_service.dart';
|
import '../../../services/status_checker_service.dart';
|
||||||
|
|
||||||
class RegisterViewModel extends ReactiveViewModel
|
class RegisterViewModel extends ReactiveViewModel
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,8 @@ class StartupView extends StackedView<StartupViewModel> {
|
||||||
|
|
||||||
Widget _buildColumn() => Column(
|
Widget _buildColumn() => Column(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: _buildUpperColumnChildren(),
|
children: _buildUpperColumnChildren(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import 'package:stacked/stacked.dart';
|
import 'package:stacked/stacked.dart';
|
||||||
import 'package:stacked_services/stacked_services.dart';
|
import 'package:stacked_services/stacked_services.dart';
|
||||||
import 'package:yimaru_app/services/authentication_service.dart';
|
import 'package:yimaru_app/services/authentication_service.dart';
|
||||||
import 'package:yimaru_app/services/in_app_update_service.dart';
|
|
||||||
|
|
||||||
import '../../../app/app.locator.dart';
|
import '../../../app/app.locator.dart';
|
||||||
import '../../../app/app.router.dart';
|
import '../../../app/app.router.dart';
|
||||||
|
|
@ -10,14 +9,12 @@ import '../../../services/api_service.dart';
|
||||||
import '../../../services/image_downloader_service.dart';
|
import '../../../services/image_downloader_service.dart';
|
||||||
import '../../../services/status_checker_service.dart';
|
import '../../../services/status_checker_service.dart';
|
||||||
import '../../common/enmus.dart';
|
import '../../common/enmus.dart';
|
||||||
import '../../common/ui_helpers.dart';
|
|
||||||
|
|
||||||
class StartupViewModel extends ReactiveViewModel {
|
class StartupViewModel extends ReactiveViewModel {
|
||||||
// Dependency injection
|
// Dependency injection
|
||||||
final _apiService = locator<ApiService>();
|
final _apiService = locator<ApiService>();
|
||||||
final _statusChecker = locator<StatusCheckerService>();
|
final _statusChecker = locator<StatusCheckerService>();
|
||||||
final _navigationService = locator<NavigationService>();
|
final _navigationService = locator<NavigationService>();
|
||||||
final _inAppUpdateService = locator<InAppUpdateService>();
|
|
||||||
final _authenticationService = locator<AuthenticationService>();
|
final _authenticationService = locator<AuthenticationService>();
|
||||||
final _imageDownloaderService = locator<ImageDownloaderService>();
|
final _imageDownloaderService = locator<ImageDownloaderService>();
|
||||||
|
|
||||||
|
|
@ -30,15 +27,12 @@ class StartupViewModel extends ReactiveViewModel {
|
||||||
|
|
||||||
User? get user => _user;
|
User? get user => _user;
|
||||||
|
|
||||||
|
// Main startup and navigation logic
|
||||||
// Place anything here that needs to happen before we get into the application
|
|
||||||
Future runStartupLogic() async {
|
Future runStartupLogic() async {
|
||||||
final loggedIn = await _authenticationService.userLoggedIn();
|
final loggedIn = await _authenticationService.userLoggedIn();
|
||||||
|
|
||||||
final firstTimeInstall = await _authenticationService.isFirstTimeInstall();
|
final firstTimeInstall = await _authenticationService.isFirstTimeInstall();
|
||||||
|
|
||||||
await _inAppUpdate();
|
|
||||||
|
|
||||||
if (firstTimeInstall) {
|
if (firstTimeInstall) {
|
||||||
await _navigationService.replaceWithWelcomeView();
|
await _navigationService.replaceWithWelcomeView();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -52,63 +46,45 @@ class StartupViewModel extends ReactiveViewModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
Future<void> replaceWithFailure() async => await _navigationService
|
Future<void> replaceWithFailure() async => await _navigationService.replaceWithFailureView(
|
||||||
.replaceWithFailureView(label: 'Check you internet connection');
|
label: 'Check you internet connection',
|
||||||
|
onTap: () async => await _getProfileStatus());
|
||||||
|
|
||||||
Future<void> replaceWithOnboarding() async =>
|
Future<void> replaceWithOnboarding() async =>
|
||||||
await _navigationService.replaceWithOnboardingView();
|
await _navigationService.replaceWithOnboardingView();
|
||||||
|
|
||||||
|
|
||||||
Future<void> replaceWithHome() async =>
|
Future<void> replaceWithHome() async =>
|
||||||
await _navigationService.replaceWithHomeView();
|
await _navigationService.replaceWithHomeView();
|
||||||
|
|
||||||
// Remote api calls
|
// Remote api calls
|
||||||
|
|
||||||
// In-app update
|
|
||||||
Future<void> _inAppUpdate() async {
|
|
||||||
if (await _statusChecker.checkConnection()) {
|
|
||||||
await _inAppUpdateService.checkForUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get profile status
|
// Get profile status
|
||||||
Future<void> _getProfileStatus() async {
|
Future<void> _getProfileStatus() async {
|
||||||
|
final bool? profileCompleted = _user?.profileCompleted;
|
||||||
Map<String, dynamic> response = {};
|
Map<String, dynamic> response = {};
|
||||||
if (_user?.profileCompleted == null) {
|
if (profileCompleted == null) {
|
||||||
if (await _statusChecker.checkConnection()) {
|
if (await _statusChecker.checkConnection()) {
|
||||||
print('PATH: 1');
|
|
||||||
response = await _apiService.getProfileStatus(_user);
|
response = await _apiService.getProfileStatus(_user);
|
||||||
} else {
|
} else {
|
||||||
print('PATH: 2');
|
|
||||||
|
|
||||||
await Future.delayed(kDuration);
|
|
||||||
await replaceWithFailure();
|
await replaceWithFailure();
|
||||||
}
|
}
|
||||||
} else if (!(_user?.profileCompleted ?? false)) {
|
} else if (!profileCompleted) {
|
||||||
print('PATH: 3');
|
|
||||||
|
|
||||||
response = {'data': false, 'status': ResponseStatus.success};
|
response = {'data': false, 'status': ResponseStatus.success};
|
||||||
} else {
|
} else {
|
||||||
print('PATH: 4');
|
|
||||||
|
|
||||||
response = {'data': true, 'status': ResponseStatus.success};
|
response = {'data': true, 'status': ResponseStatus.success};
|
||||||
}
|
}
|
||||||
if (response['status'] == ResponseStatus.success && !response['data']) {
|
if (response['status'] == ResponseStatus.success && !response['data']) {
|
||||||
print('PATH: 5');
|
|
||||||
|
|
||||||
await replaceWithOnboarding();
|
await replaceWithOnboarding();
|
||||||
} else if (response['status'] == ResponseStatus.success &&
|
} else if (response['status'] == ResponseStatus.success &&
|
||||||
response['data']) {
|
response['data']) {
|
||||||
print('PATH: 6');
|
|
||||||
|
|
||||||
await saveProfileStatus(response['data']);
|
await saveProfileStatus(response['data']);
|
||||||
|
|
||||||
await _getProfileData();
|
await _getProfileData();
|
||||||
|
|
||||||
await replaceWithHome();
|
await replaceWithHome();
|
||||||
|
} else {
|
||||||
|
await replaceWithFailure();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,26 +94,24 @@ class StartupViewModel extends ReactiveViewModel {
|
||||||
|
|
||||||
// Get profile data
|
// Get profile data
|
||||||
Future<void> _getProfileData() async {
|
Future<void> _getProfileData() async {
|
||||||
if (!(_user?.userInfoLoaded ?? false)) {
|
bool? infoLoaded = _user?.userInfoLoaded ?? false;
|
||||||
|
bool? profileCompleted = _user?.profileCompleted ?? false;
|
||||||
|
|
||||||
|
if (!infoLoaded) {
|
||||||
Map<String, dynamic> response = {};
|
Map<String, dynamic> response = {};
|
||||||
|
|
||||||
if (_user?.profileCompleted != null &&
|
if (profileCompleted) {
|
||||||
(_user?.profileCompleted ?? false)) {
|
response = await _apiService.getProfileData(_user?.userId);
|
||||||
if (await _statusChecker.checkConnection()) {
|
|
||||||
response = await _apiService.getProfileData(_user?.userId);
|
|
||||||
|
|
||||||
if (response['status'] == ResponseStatus.success) {
|
if (response['status'] == ResponseStatus.success) {
|
||||||
User user = response['data'] as User;
|
User user = response['data'] as User;
|
||||||
|
|
||||||
await _authenticationService.saveUserData(user);
|
await _authenticationService.saveUserData(user);
|
||||||
|
|
||||||
String image =
|
String image =
|
||||||
await _imageDownloaderService.downloader(user.profilePicture);
|
await _imageDownloaderService.downloader(user.profilePicture);
|
||||||
|
|
||||||
await _authenticationService.saveProfilePicture(image);
|
await _authenticationService.saveProfilePicture(image);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
await replaceWithFailure();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ class SupportView extends StackedView<SupportViewModel> {
|
||||||
Widget _buildAppbar(SupportViewModel viewModel) => SmallAppBar(
|
Widget _buildAppbar(SupportViewModel viewModel) => SmallAppBar(
|
||||||
title: 'Need Help?',
|
title: 'Need Help?',
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
onTap: viewModel.pop,
|
onPop: viewModel.pop,
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildContentWrapper(SupportViewModel viewModel) =>
|
Widget _buildContentWrapper(SupportViewModel viewModel) =>
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ class TelegramSupportView extends StackedView<TelegramSupportViewModel> {
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildAppbar(TelegramSupportViewModel viewModel) => SmallAppBar(
|
Widget _buildAppbar(TelegramSupportViewModel viewModel) => SmallAppBar(
|
||||||
onTap: viewModel.pop,
|
onPop: viewModel.pop,
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
title: 'Telegram Support',
|
title: 'Telegram Support',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ class TermsAndConditionsView extends StackedView<TermsAndConditionsViewModel> {
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildAppbar(TermsAndConditionsViewModel viewModel) => SmallAppBar(
|
Widget _buildAppbar(TermsAndConditionsViewModel viewModel) => SmallAppBar(
|
||||||
onTap: viewModel.pop,
|
onPop: viewModel.pop,
|
||||||
showBackButton: true,
|
showBackButton: true,
|
||||||
title: 'Terms and Conditions',
|
title: 'Terms and Conditions',
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:yimaru_app/ui/widgets/page_loading_indicator.dart';
|
import 'package:yimaru_app/ui/widgets/page_loading_indicator.dart';
|
||||||
|
import 'package:yimaru_app/ui/widgets/refresh_button.dart';
|
||||||
|
|
||||||
import '../../../common/app_colors.dart';
|
import '../common/app_colors.dart';
|
||||||
import '../../../widgets/large_app_bar.dart';
|
import 'large_app_bar.dart';
|
||||||
import '../../../widgets/refresh_button.dart';
|
|
||||||
|
|
||||||
class AssessmentLoadingScreen extends StatelessWidget {
|
class AssessmentLoadingScreen extends StatelessWidget {
|
||||||
final bool isEmpty;
|
final bool isEmpty;
|
||||||
|
|
@ -55,7 +55,7 @@ class LearnLessonTile extends ViewModelWidget<LearnLessonViewModel> {
|
||||||
expandedCrossAxisAlignment: CrossAxisAlignment.start,
|
expandedCrossAxisAlignment: CrossAxisAlignment.start,
|
||||||
collapsedBackgroundColor: kcPrimaryColor.withOpacity(0.1),
|
collapsedBackgroundColor: kcPrimaryColor.withOpacity(0.1),
|
||||||
childrenPadding: const EdgeInsets.fromLTRB(15, 0, 15, 15),
|
childrenPadding: const EdgeInsets.fromLTRB(15, 0, 15, 15),
|
||||||
// enabled: status != ProgressStatuses.pending,
|
// enabled: (lesson.access?.isAccessible ?? false),
|
||||||
// backgroundColor: ProgressStatuses.pending == status
|
// backgroundColor: ProgressStatuses.pending == status
|
||||||
// ? kcPrimaryColor.withOpacity(0.1)
|
// ? kcPrimaryColor.withOpacity(0.1)
|
||||||
// : kcGreen.withOpacity(0.1),
|
// : kcGreen.withOpacity(0.1),
|
||||||
|
|
|
||||||
|
|
@ -56,9 +56,7 @@ class LearnModuleTile extends ViewModelWidget<LearnModuleViewModel> {
|
||||||
{required BuildContext context,
|
{required BuildContext context,
|
||||||
required LearnModuleViewModel viewModel}) =>
|
required LearnModuleViewModel viewModel}) =>
|
||||||
ExpansionTile(
|
ExpansionTile(
|
||||||
enabled: true,
|
|
||||||
textColor: kcDarkGrey,
|
textColor: kcDarkGrey,
|
||||||
showTrailingIcon: true,
|
|
||||||
initiallyExpanded: true,
|
initiallyExpanded: true,
|
||||||
subtitle: _buildContent(),
|
subtitle: _buildContent(),
|
||||||
title: _buildTitleWrapper(),
|
title: _buildTitleWrapper(),
|
||||||
|
|
@ -69,13 +67,12 @@ class LearnModuleTile extends ViewModelWidget<LearnModuleViewModel> {
|
||||||
shape: Border.all(color: kcTransparent),
|
shape: Border.all(color: kcTransparent),
|
||||||
expandedAlignment: Alignment.centerLeft,
|
expandedAlignment: Alignment.centerLeft,
|
||||||
collapsedBackgroundColor: kcBackgroundColor,
|
collapsedBackgroundColor: kcBackgroundColor,
|
||||||
|
enabled: (module.access?.isAccessible ?? false),
|
||||||
controlAffinity: ListTileControlAffinity.trailing,
|
controlAffinity: ListTileControlAffinity.trailing,
|
||||||
expandedCrossAxisAlignment: CrossAxisAlignment.start,
|
expandedCrossAxisAlignment: CrossAxisAlignment.start,
|
||||||
tilePadding: const EdgeInsets.symmetric(horizontal: 15),
|
tilePadding: const EdgeInsets.symmetric(horizontal: 15),
|
||||||
childrenPadding: const EdgeInsets.fromLTRB(70, 0, 15, 15),
|
childrenPadding: const EdgeInsets.fromLTRB(70, 0, 15, 15),
|
||||||
// enabled:(module.access?.isAccessible ?? false) ,
|
showTrailingIcon: (module.access?.isAccessible ?? false) ? true : false,
|
||||||
// showTrailingIcon: status != ProgressStatuses.pending ? true : false,
|
|
||||||
//initiallyExpanded: status == ProgressStatuses.started ? true : false,
|
|
||||||
children:
|
children:
|
||||||
_buildExpansionTileChildren(context: context, viewModel: viewModel),
|
_buildExpansionTileChildren(context: context, viewModel: viewModel),
|
||||||
);
|
);
|
||||||
|
|
@ -209,9 +206,9 @@ class LearnModuleTile extends ViewModelWidget<LearnModuleViewModel> {
|
||||||
onTap: viewModel.pop,
|
onTap: viewModel.pop,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Widget _buildContainerShaderState() => status == ProgressStatuses.pending
|
Widget _buildContainerShaderState() => !(module.access?.isAccessible ?? false)
|
||||||
// ? _buildContainerShaderWrapper()
|
? _buildContainerShaderWrapper()
|
||||||
// : Container();
|
: Container();
|
||||||
|
|
||||||
Widget _buildContainerShaderWrapper() => Positioned.fill(
|
Widget _buildContainerShaderWrapper() => Positioned.fill(
|
||||||
child: _buildContainerShader(),
|
child: _buildContainerShader(),
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import 'package:yimaru_app/ui/common/app_colors.dart';
|
||||||
import 'package:yimaru_app/ui/common/ui_helpers.dart';
|
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/views/learn_practice/learn_practice_viewmodel.dart';
|
||||||
|
|
||||||
|
|
||||||
class LearnPracticeTipSection extends ViewModelWidget<LearnPracticeViewModel> {
|
class LearnPracticeTipSection extends ViewModelWidget<LearnPracticeViewModel> {
|
||||||
const LearnPracticeTipSection({super.key});
|
const LearnPracticeTipSection({super.key});
|
||||||
|
|
||||||
|
|
|
||||||
45
lib/ui/widgets/no_data_indicator.dart
Normal file
45
lib/ui/widgets/no_data_indicator.dart
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:yimaru_app/ui/common/app_colors.dart';
|
||||||
|
|
||||||
|
import '../common/ui_helpers.dart';
|
||||||
|
|
||||||
|
class NoDataIndicator extends StatelessWidget {
|
||||||
|
final String title;
|
||||||
|
final GestureTapCallback? onTap;
|
||||||
|
|
||||||
|
const NoDataIndicator({super.key, this.onTap, required this.title});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => _buildColumn();
|
||||||
|
|
||||||
|
Widget _buildColumn() => Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: _buildColumnChildren(),
|
||||||
|
);
|
||||||
|
|
||||||
|
List<Widget> _buildColumnChildren() => [
|
||||||
|
_buildIconWrapper(),
|
||||||
|
verticalSpaceMedium,
|
||||||
|
_buildTitle(),
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
Widget _buildTitle() => Text(
|
||||||
|
title,
|
||||||
|
style: style16P600,
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget _buildIconWrapper() => GestureDetector(
|
||||||
|
onTap: onTap,
|
||||||
|
child: _buildIcon(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget _buildIcon() => const Icon(
|
||||||
|
Icons.replay,
|
||||||
|
size: 75,
|
||||||
|
color: kcPrimaryColor,
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -5,10 +5,10 @@ import 'package:yimaru_app/ui/widgets/custom_back_button.dart';
|
||||||
class SmallAppBar extends StatelessWidget {
|
class SmallAppBar extends StatelessWidget {
|
||||||
final String? title;
|
final String? title;
|
||||||
final bool showBackButton;
|
final bool showBackButton;
|
||||||
final GestureTapCallback? onTap;
|
final GestureTapCallback? onPop;
|
||||||
|
|
||||||
const SmallAppBar(
|
const SmallAppBar(
|
||||||
{super.key, this.onTap, this.title, required this.showBackButton});
|
{super.key, this.onPop, this.title, required this.showBackButton});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => _buildAppBar();
|
Widget build(BuildContext context) => _buildAppBar();
|
||||||
|
|
@ -28,7 +28,7 @@ class SmallAppBar extends StatelessWidget {
|
||||||
child: _buildBackButton(),
|
child: _buildBackButton(),
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildBackButton() => CustomBackButton(onTap: onTap);
|
Widget _buildBackButton() => CustomBackButton(onTap: onPop);
|
||||||
|
|
||||||
Widget _buildTitleWrapper() => Align(
|
Widget _buildTitleWrapper() => Align(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
name: yimaru_app
|
name: yimaru_app
|
||||||
version: 0.1.8+10
|
version: 0.1.9+11
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
description: A new Flutter project.
|
description: A new Flutter project.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,48 +8,49 @@ import 'dart:ui' as _i10;
|
||||||
|
|
||||||
import 'package:audioplayers/audioplayers.dart' as _i4;
|
import 'package:audioplayers/audioplayers.dart' as _i4;
|
||||||
import 'package:dio/dio.dart' as _i2;
|
import 'package:dio/dio.dart' as _i2;
|
||||||
import 'package:firebase_messaging/firebase_messaging.dart' as _i39;
|
import 'package:firebase_messaging/firebase_messaging.dart' as _i40;
|
||||||
import 'package:flutter/material.dart' as _i8;
|
import 'package:flutter/material.dart' as _i8;
|
||||||
import 'package:mockito/mockito.dart' as _i1;
|
import 'package:mockito/mockito.dart' as _i1;
|
||||||
import 'package:mockito/src/dummies.dart' as _i7;
|
import 'package:mockito/src/dummies.dart' as _i7;
|
||||||
import 'package:permission_handler/permission_handler.dart' as _i34;
|
import 'package:permission_handler/permission_handler.dart' as _i35;
|
||||||
import 'package:stacked_services/stacked_services.dart' as _i6;
|
import 'package:stacked_services/stacked_services.dart' as _i6;
|
||||||
import 'package:waveform_recorder/waveform_recorder.dart' as _i5;
|
import 'package:waveform_recorder/waveform_recorder.dart' as _i5;
|
||||||
import 'package:yimaru_app/models/category.dart' as _i21;
|
import 'package:yimaru_app/models/assessment.dart' as _i14;
|
||||||
import 'package:yimaru_app/models/course.dart' as _i26;
|
import 'package:yimaru_app/models/assessment_question.dart' as _i15;
|
||||||
import 'package:yimaru_app/models/course_detail.dart' as _i42;
|
import 'package:yimaru_app/models/category.dart' as _i22;
|
||||||
import 'package:yimaru_app/models/course_lesson.dart' as _i24;
|
import 'package:yimaru_app/models/course.dart' as _i27;
|
||||||
import 'package:yimaru_app/models/course_progress.dart' as _i23;
|
import 'package:yimaru_app/models/course_detail.dart' as _i43;
|
||||||
import 'package:yimaru_app/models/learn_course.dart' as _i16;
|
import 'package:yimaru_app/models/course_lesson.dart' as _i25;
|
||||||
import 'package:yimaru_app/models/learn_lesson.dart' as _i19;
|
import 'package:yimaru_app/models/course_progress.dart' as _i24;
|
||||||
import 'package:yimaru_app/models/learn_module.dart' as _i18;
|
import 'package:yimaru_app/models/learn_course.dart' as _i17;
|
||||||
import 'package:yimaru_app/models/learn_practice.dart' as _i17;
|
import 'package:yimaru_app/models/learn_lesson.dart' as _i20;
|
||||||
import 'package:yimaru_app/models/learn_program.dart' as _i15;
|
import 'package:yimaru_app/models/learn_module.dart' as _i19;
|
||||||
import 'package:yimaru_app/models/learn_question.dart' as _i20;
|
import 'package:yimaru_app/models/learn_practice.dart' as _i18;
|
||||||
import 'package:yimaru_app/models/lesson.dart' as _i30;
|
import 'package:yimaru_app/models/learn_program.dart' as _i16;
|
||||||
import 'package:yimaru_app/models/level.dart' as _i27;
|
import 'package:yimaru_app/models/learn_question.dart' as _i21;
|
||||||
import 'package:yimaru_app/models/module.dart' as _i28;
|
import 'package:yimaru_app/models/lesson.dart' as _i31;
|
||||||
import 'package:yimaru_app/models/practice.dart' as _i25;
|
import 'package:yimaru_app/models/level.dart' as _i28;
|
||||||
import 'package:yimaru_app/models/question.dart' as _i14;
|
import 'package:yimaru_app/models/module.dart' as _i29;
|
||||||
import 'package:yimaru_app/models/subcategory.dart' as _i22;
|
import 'package:yimaru_app/models/practice.dart' as _i26;
|
||||||
import 'package:yimaru_app/models/submodule.dart' as _i29;
|
import 'package:yimaru_app/models/subcategory.dart' as _i23;
|
||||||
|
import 'package:yimaru_app/models/submodule.dart' as _i30;
|
||||||
import 'package:yimaru_app/models/user.dart' as _i12;
|
import 'package:yimaru_app/models/user.dart' as _i12;
|
||||||
import 'package:yimaru_app/services/api_service.dart' as _i13;
|
import 'package:yimaru_app/services/api_service.dart' as _i13;
|
||||||
import 'package:yimaru_app/services/audio_player_service.dart' as _i43;
|
import 'package:yimaru_app/services/audio_player_service.dart' as _i44;
|
||||||
import 'package:yimaru_app/services/authentication_service.dart' as _i11;
|
import 'package:yimaru_app/services/authentication_service.dart' as _i11;
|
||||||
import 'package:yimaru_app/services/course_service.dart' as _i41;
|
import 'package:yimaru_app/services/course_service.dart' as _i42;
|
||||||
import 'package:yimaru_app/services/dio_service.dart' as _i31;
|
import 'package:yimaru_app/services/dio_service.dart' as _i32;
|
||||||
import 'package:yimaru_app/services/google_auth_service.dart' as _i36;
|
import 'package:yimaru_app/services/google_auth_service.dart' as _i37;
|
||||||
import 'package:yimaru_app/services/image_downloader_service.dart' as _i37;
|
import 'package:yimaru_app/services/image_downloader_service.dart' as _i38;
|
||||||
import 'package:yimaru_app/services/image_picker_service.dart' as _i35;
|
import 'package:yimaru_app/services/image_picker_service.dart' as _i36;
|
||||||
import 'package:yimaru_app/services/in_app_update_service.dart' as _i46;
|
import 'package:yimaru_app/services/in_app_update_service.dart' as _i47;
|
||||||
import 'package:yimaru_app/services/notification_service.dart' as _i38;
|
import 'package:yimaru_app/services/notification_service.dart' as _i39;
|
||||||
import 'package:yimaru_app/services/permission_handler_service.dart' as _i33;
|
import 'package:yimaru_app/services/permission_handler_service.dart' as _i34;
|
||||||
import 'package:yimaru_app/services/secure_storage_service.dart' as _i3;
|
import 'package:yimaru_app/services/secure_storage_service.dart' as _i3;
|
||||||
import 'package:yimaru_app/services/smart_auth_service.dart' as _i40;
|
import 'package:yimaru_app/services/smart_auth_service.dart' as _i41;
|
||||||
import 'package:yimaru_app/services/status_checker_service.dart' as _i32;
|
import 'package:yimaru_app/services/status_checker_service.dart' as _i33;
|
||||||
import 'package:yimaru_app/services/voice_recorder_service.dart' as _i44;
|
import 'package:yimaru_app/services/voice_recorder_service.dart' as _i45;
|
||||||
import 'package:yimaru_app/ui/common/enmus.dart' as _i45;
|
import 'package:yimaru_app/ui/common/enmus.dart' as _i46;
|
||||||
|
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint
|
||||||
// ignore_for_file: avoid_redundant_argument_values
|
// ignore_for_file: avoid_redundant_argument_values
|
||||||
|
|
@ -1125,168 +1126,183 @@ class MockApiService extends _i1.Mock implements _i13.ApiService {
|
||||||
) as _i9.Future<Map<String, dynamic>>);
|
) as _i9.Future<Map<String, dynamic>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i14.Question>> getAssessments() => (super.noSuchMethod(
|
_i9.Future<List<_i14.Assessment>> getAssessments() => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getAssessments,
|
#getAssessments,
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
returnValue: _i9.Future<List<_i14.Question>>.value(<_i14.Question>[]),
|
returnValue:
|
||||||
|
_i9.Future<List<_i14.Assessment>>.value(<_i14.Assessment>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i14.Question>>.value(<_i14.Question>[]),
|
_i9.Future<List<_i14.Assessment>>.value(<_i14.Assessment>[]),
|
||||||
) as _i9.Future<List<_i14.Question>>);
|
) as _i9.Future<List<_i14.Assessment>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i15.LearnProgram>> getLearnPrograms() => (super.noSuchMethod(
|
_i9.Future<List<_i15.AssessmentQuestion>> getAssessmentQuestions(int? id) =>
|
||||||
|
(super.noSuchMethod(
|
||||||
|
Invocation.method(
|
||||||
|
#getAssessmentQuestions,
|
||||||
|
[id],
|
||||||
|
),
|
||||||
|
returnValue: _i9.Future<List<_i15.AssessmentQuestion>>.value(
|
||||||
|
<_i15.AssessmentQuestion>[]),
|
||||||
|
returnValueForMissingStub:
|
||||||
|
_i9.Future<List<_i15.AssessmentQuestion>>.value(
|
||||||
|
<_i15.AssessmentQuestion>[]),
|
||||||
|
) as _i9.Future<List<_i15.AssessmentQuestion>>);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_i9.Future<List<_i16.LearnProgram>> getLearnPrograms() => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getLearnPrograms,
|
#getLearnPrograms,
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
returnValue:
|
returnValue:
|
||||||
_i9.Future<List<_i15.LearnProgram>>.value(<_i15.LearnProgram>[]),
|
_i9.Future<List<_i16.LearnProgram>>.value(<_i16.LearnProgram>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i15.LearnProgram>>.value(<_i15.LearnProgram>[]),
|
_i9.Future<List<_i16.LearnProgram>>.value(<_i16.LearnProgram>[]),
|
||||||
) as _i9.Future<List<_i15.LearnProgram>>);
|
) as _i9.Future<List<_i16.LearnProgram>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i16.LearnCourse>> getLearnCourse(int? id) =>
|
_i9.Future<List<_i17.LearnCourse>> getLearnCourse(int? id) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getLearnCourse,
|
#getLearnCourse,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue:
|
returnValue:
|
||||||
_i9.Future<List<_i16.LearnCourse>>.value(<_i16.LearnCourse>[]),
|
_i9.Future<List<_i17.LearnCourse>>.value(<_i17.LearnCourse>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i16.LearnCourse>>.value(<_i16.LearnCourse>[]),
|
_i9.Future<List<_i17.LearnCourse>>.value(<_i17.LearnCourse>[]),
|
||||||
) as _i9.Future<List<_i16.LearnCourse>>);
|
) as _i9.Future<List<_i17.LearnCourse>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i17.LearnPractice>> getLearnCoursePractices(int? id) =>
|
_i9.Future<List<_i18.LearnPractice>> getLearnCoursePractices(int? id) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getLearnCoursePractices,
|
#getLearnCoursePractices,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue:
|
returnValue:
|
||||||
_i9.Future<List<_i17.LearnPractice>>.value(<_i17.LearnPractice>[]),
|
_i9.Future<List<_i18.LearnPractice>>.value(<_i18.LearnPractice>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i17.LearnPractice>>.value(<_i17.LearnPractice>[]),
|
_i9.Future<List<_i18.LearnPractice>>.value(<_i18.LearnPractice>[]),
|
||||||
) as _i9.Future<List<_i17.LearnPractice>>);
|
) as _i9.Future<List<_i18.LearnPractice>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i18.LearnModule>> getLearnModules(int? id) =>
|
_i9.Future<List<_i19.LearnModule>> getLearnModules(int? id) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getLearnModules,
|
#getLearnModules,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue:
|
returnValue:
|
||||||
_i9.Future<List<_i18.LearnModule>>.value(<_i18.LearnModule>[]),
|
_i9.Future<List<_i19.LearnModule>>.value(<_i19.LearnModule>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i18.LearnModule>>.value(<_i18.LearnModule>[]),
|
_i9.Future<List<_i19.LearnModule>>.value(<_i19.LearnModule>[]),
|
||||||
) as _i9.Future<List<_i18.LearnModule>>);
|
) as _i9.Future<List<_i19.LearnModule>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i17.LearnPractice>> getLearnModulePractices(int? id) =>
|
_i9.Future<List<_i18.LearnPractice>> getLearnModulePractices(int? id) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getLearnModulePractices,
|
#getLearnModulePractices,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue:
|
returnValue:
|
||||||
_i9.Future<List<_i17.LearnPractice>>.value(<_i17.LearnPractice>[]),
|
_i9.Future<List<_i18.LearnPractice>>.value(<_i18.LearnPractice>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i17.LearnPractice>>.value(<_i17.LearnPractice>[]),
|
_i9.Future<List<_i18.LearnPractice>>.value(<_i18.LearnPractice>[]),
|
||||||
) as _i9.Future<List<_i17.LearnPractice>>);
|
) as _i9.Future<List<_i18.LearnPractice>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i19.LearnLesson>> getLearnLessons(int? id) =>
|
_i9.Future<List<_i20.LearnLesson>> getLearnLessons(int? id) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getLearnLessons,
|
#getLearnLessons,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue:
|
returnValue:
|
||||||
_i9.Future<List<_i19.LearnLesson>>.value(<_i19.LearnLesson>[]),
|
_i9.Future<List<_i20.LearnLesson>>.value(<_i20.LearnLesson>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i19.LearnLesson>>.value(<_i19.LearnLesson>[]),
|
_i9.Future<List<_i20.LearnLesson>>.value(<_i20.LearnLesson>[]),
|
||||||
) as _i9.Future<List<_i19.LearnLesson>>);
|
) as _i9.Future<List<_i20.LearnLesson>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i17.LearnPractice>> getLearnLessonPractices(int? id) =>
|
_i9.Future<List<_i18.LearnPractice>> getLearnLessonPractices(int? id) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getLearnLessonPractices,
|
#getLearnLessonPractices,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue:
|
returnValue:
|
||||||
_i9.Future<List<_i17.LearnPractice>>.value(<_i17.LearnPractice>[]),
|
_i9.Future<List<_i18.LearnPractice>>.value(<_i18.LearnPractice>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i17.LearnPractice>>.value(<_i17.LearnPractice>[]),
|
_i9.Future<List<_i18.LearnPractice>>.value(<_i18.LearnPractice>[]),
|
||||||
) as _i9.Future<List<_i17.LearnPractice>>);
|
) as _i9.Future<List<_i18.LearnPractice>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i20.LearnQuestion>> getLearnQuestions(int? id) =>
|
_i9.Future<List<_i21.LearnQuestion>> getLearnQuestions(int? id) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getLearnQuestions,
|
#getLearnQuestions,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue:
|
returnValue:
|
||||||
_i9.Future<List<_i20.LearnQuestion>>.value(<_i20.LearnQuestion>[]),
|
_i9.Future<List<_i21.LearnQuestion>>.value(<_i21.LearnQuestion>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i20.LearnQuestion>>.value(<_i20.LearnQuestion>[]),
|
_i9.Future<List<_i21.LearnQuestion>>.value(<_i21.LearnQuestion>[]),
|
||||||
) as _i9.Future<List<_i20.LearnQuestion>>);
|
) as _i9.Future<List<_i21.LearnQuestion>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i21.Category>> getCategories() => (super.noSuchMethod(
|
_i9.Future<List<_i22.Category>> getCategories() => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getCategories,
|
#getCategories,
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
returnValue: _i9.Future<List<_i21.Category>>.value(<_i21.Category>[]),
|
returnValue: _i9.Future<List<_i22.Category>>.value(<_i22.Category>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i21.Category>>.value(<_i21.Category>[]),
|
_i9.Future<List<_i22.Category>>.value(<_i22.Category>[]),
|
||||||
) as _i9.Future<List<_i21.Category>>);
|
) as _i9.Future<List<_i22.Category>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i22.Subcategory>> getSubcategories(int? id) =>
|
_i9.Future<List<_i23.Subcategory>> getSubcategories(int? id) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getSubcategories,
|
#getSubcategories,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue:
|
returnValue:
|
||||||
_i9.Future<List<_i22.Subcategory>>.value(<_i22.Subcategory>[]),
|
_i9.Future<List<_i23.Subcategory>>.value(<_i23.Subcategory>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i22.Subcategory>>.value(<_i22.Subcategory>[]),
|
_i9.Future<List<_i23.Subcategory>>.value(<_i23.Subcategory>[]),
|
||||||
) as _i9.Future<List<_i22.Subcategory>>);
|
) as _i9.Future<List<_i23.Subcategory>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i23.CourseProgress>> getCourseProgress(int? id) =>
|
_i9.Future<List<_i24.CourseProgress>> getCourseProgress(int? id) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getCourseProgress,
|
#getCourseProgress,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue: _i9.Future<List<_i23.CourseProgress>>.value(
|
returnValue: _i9.Future<List<_i24.CourseProgress>>.value(
|
||||||
<_i23.CourseProgress>[]),
|
<_i24.CourseProgress>[]),
|
||||||
returnValueForMissingStub: _i9.Future<List<_i23.CourseProgress>>.value(
|
returnValueForMissingStub: _i9.Future<List<_i24.CourseProgress>>.value(
|
||||||
<_i23.CourseProgress>[]),
|
<_i24.CourseProgress>[]),
|
||||||
) as _i9.Future<List<_i23.CourseProgress>>);
|
) as _i9.Future<List<_i24.CourseProgress>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i24.CourseLesson>> getCourseLessons(int? id) =>
|
_i9.Future<List<_i25.CourseLesson>> getCourseLessons(int? id) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getCourseLessons,
|
#getCourseLessons,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue:
|
returnValue:
|
||||||
_i9.Future<List<_i24.CourseLesson>>.value(<_i24.CourseLesson>[]),
|
_i9.Future<List<_i25.CourseLesson>>.value(<_i25.CourseLesson>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i24.CourseLesson>>.value(<_i24.CourseLesson>[]),
|
_i9.Future<List<_i25.CourseLesson>>.value(<_i25.CourseLesson>[]),
|
||||||
) as _i9.Future<List<_i24.CourseLesson>>);
|
) as _i9.Future<List<_i25.CourseLesson>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<Map<String, dynamic>> completeLesson(int? id) =>
|
_i9.Future<Map<String, dynamic>> completeLesson(int? id) =>
|
||||||
|
|
@ -1302,130 +1318,136 @@ class MockApiService extends _i1.Mock implements _i13.ApiService {
|
||||||
) as _i9.Future<Map<String, dynamic>>);
|
) as _i9.Future<Map<String, dynamic>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i25.Practice>> getCoursePractices(int? id) =>
|
_i9.Future<List<_i26.Practice>> getCoursePractices(int? id) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getCoursePractices,
|
#getCoursePractices,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue: _i9.Future<List<_i25.Practice>>.value(<_i25.Practice>[]),
|
returnValue: _i9.Future<List<_i26.Practice>>.value(<_i26.Practice>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i25.Practice>>.value(<_i25.Practice>[]),
|
_i9.Future<List<_i26.Practice>>.value(<_i26.Practice>[]),
|
||||||
) as _i9.Future<List<_i25.Practice>>);
|
) as _i9.Future<List<_i26.Practice>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i14.Question>> getCoursePracticeQuestions(int? id) =>
|
_i9.Future<List<_i15.AssessmentQuestion>> getCoursePracticeQuestions(
|
||||||
|
int? id) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getCoursePracticeQuestions,
|
#getCoursePracticeQuestions,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue: _i9.Future<List<_i14.Question>>.value(<_i14.Question>[]),
|
returnValue: _i9.Future<List<_i15.AssessmentQuestion>>.value(
|
||||||
|
<_i15.AssessmentQuestion>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i14.Question>>.value(<_i14.Question>[]),
|
_i9.Future<List<_i15.AssessmentQuestion>>.value(
|
||||||
) as _i9.Future<List<_i14.Question>>);
|
<_i15.AssessmentQuestion>[]),
|
||||||
|
) as _i9.Future<List<_i15.AssessmentQuestion>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<_i14.Question?> getCoursePracticeQuestion(int? id) =>
|
_i9.Future<_i15.AssessmentQuestion?> getCoursePracticeQuestion(int? id) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getCoursePracticeQuestion,
|
#getCoursePracticeQuestion,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue: _i9.Future<_i14.Question?>.value(),
|
returnValue: _i9.Future<_i15.AssessmentQuestion?>.value(),
|
||||||
returnValueForMissingStub: _i9.Future<_i14.Question?>.value(),
|
returnValueForMissingStub: _i9.Future<_i15.AssessmentQuestion?>.value(),
|
||||||
) as _i9.Future<_i14.Question?>);
|
) as _i9.Future<_i15.AssessmentQuestion?>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i22.Subcategory>> getLearnSubcategories() =>
|
_i9.Future<List<_i23.Subcategory>> getLearnSubcategories() =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getLearnSubcategories,
|
#getLearnSubcategories,
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
returnValue:
|
returnValue:
|
||||||
_i9.Future<List<_i22.Subcategory>>.value(<_i22.Subcategory>[]),
|
_i9.Future<List<_i23.Subcategory>>.value(<_i23.Subcategory>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i22.Subcategory>>.value(<_i22.Subcategory>[]),
|
_i9.Future<List<_i23.Subcategory>>.value(<_i23.Subcategory>[]),
|
||||||
) as _i9.Future<List<_i22.Subcategory>>);
|
) as _i9.Future<List<_i23.Subcategory>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i26.Course>> getCourses(int? id) => (super.noSuchMethod(
|
_i9.Future<List<_i27.Course>> getCourses(int? id) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getCourses,
|
#getCourses,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue: _i9.Future<List<_i26.Course>>.value(<_i26.Course>[]),
|
returnValue: _i9.Future<List<_i27.Course>>.value(<_i27.Course>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i26.Course>>.value(<_i26.Course>[]),
|
_i9.Future<List<_i27.Course>>.value(<_i27.Course>[]),
|
||||||
) as _i9.Future<List<_i26.Course>>);
|
) as _i9.Future<List<_i27.Course>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i27.Level>> getLevels(int? id) => (super.noSuchMethod(
|
_i9.Future<List<_i28.Level>> getLevels(int? id) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getLevels,
|
#getLevels,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue: _i9.Future<List<_i27.Level>>.value(<_i27.Level>[]),
|
returnValue: _i9.Future<List<_i28.Level>>.value(<_i28.Level>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i27.Level>>.value(<_i27.Level>[]),
|
_i9.Future<List<_i28.Level>>.value(<_i28.Level>[]),
|
||||||
) as _i9.Future<List<_i27.Level>>);
|
) as _i9.Future<List<_i28.Level>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i28.Module>> getModules(int? id) => (super.noSuchMethod(
|
_i9.Future<List<_i29.Module>> getModules(int? id) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getModules,
|
#getModules,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue: _i9.Future<List<_i28.Module>>.value(<_i28.Module>[]),
|
returnValue: _i9.Future<List<_i29.Module>>.value(<_i29.Module>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i28.Module>>.value(<_i28.Module>[]),
|
_i9.Future<List<_i29.Module>>.value(<_i29.Module>[]),
|
||||||
) as _i9.Future<List<_i28.Module>>);
|
) as _i9.Future<List<_i29.Module>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i29.Submodule>> getSubmodules(int? id) =>
|
_i9.Future<List<_i30.Submodule>> getSubmodules(int? id) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getSubmodules,
|
#getSubmodules,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue: _i9.Future<List<_i29.Submodule>>.value(<_i29.Submodule>[]),
|
returnValue: _i9.Future<List<_i30.Submodule>>.value(<_i30.Submodule>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i29.Submodule>>.value(<_i29.Submodule>[]),
|
_i9.Future<List<_i30.Submodule>>.value(<_i30.Submodule>[]),
|
||||||
) as _i9.Future<List<_i29.Submodule>>);
|
) as _i9.Future<List<_i30.Submodule>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i30.Lesson>> getLessons(int? id) => (super.noSuchMethod(
|
_i9.Future<List<_i31.Lesson>> getLessons(int? id) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getLessons,
|
#getLessons,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue: _i9.Future<List<_i30.Lesson>>.value(<_i30.Lesson>[]),
|
returnValue: _i9.Future<List<_i31.Lesson>>.value(<_i31.Lesson>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i30.Lesson>>.value(<_i30.Lesson>[]),
|
_i9.Future<List<_i31.Lesson>>.value(<_i31.Lesson>[]),
|
||||||
) as _i9.Future<List<_i30.Lesson>>);
|
) as _i9.Future<List<_i31.Lesson>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i25.Practice>> getPractices(int? id) => (super.noSuchMethod(
|
_i9.Future<List<_i26.Practice>> getPractices(int? id) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getPractices,
|
#getPractices,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue: _i9.Future<List<_i25.Practice>>.value(<_i25.Practice>[]),
|
returnValue: _i9.Future<List<_i26.Practice>>.value(<_i26.Practice>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i25.Practice>>.value(<_i25.Practice>[]),
|
_i9.Future<List<_i26.Practice>>.value(<_i26.Practice>[]),
|
||||||
) as _i9.Future<List<_i25.Practice>>);
|
) as _i9.Future<List<_i26.Practice>>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i14.Question>> getQuestions(int? id) => (super.noSuchMethod(
|
_i9.Future<List<_i15.AssessmentQuestion>> getQuestions(int? id) =>
|
||||||
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getQuestions,
|
#getQuestions,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue: _i9.Future<List<_i14.Question>>.value(<_i14.Question>[]),
|
returnValue: _i9.Future<List<_i15.AssessmentQuestion>>.value(
|
||||||
|
<_i15.AssessmentQuestion>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i14.Question>>.value(<_i14.Question>[]),
|
_i9.Future<List<_i15.AssessmentQuestion>>.value(
|
||||||
) as _i9.Future<List<_i14.Question>>);
|
<_i15.AssessmentQuestion>[]),
|
||||||
|
) as _i9.Future<List<_i15.AssessmentQuestion>>);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A class which mocks [SecureStorageService].
|
/// A class which mocks [SecureStorageService].
|
||||||
|
|
@ -1528,7 +1550,7 @@ class MockSecureStorageService extends _i1.Mock
|
||||||
/// A class which mocks [DioService].
|
/// A class which mocks [DioService].
|
||||||
///
|
///
|
||||||
/// See the documentation for Mockito's code generation for more information.
|
/// See the documentation for Mockito's code generation for more information.
|
||||||
class MockDioService extends _i1.Mock implements _i31.DioService {
|
class MockDioService extends _i1.Mock implements _i32.DioService {
|
||||||
@override
|
@override
|
||||||
_i2.Dio get dio => (super.noSuchMethod(
|
_i2.Dio get dio => (super.noSuchMethod(
|
||||||
Invocation.getter(#dio),
|
Invocation.getter(#dio),
|
||||||
|
|
@ -1547,7 +1569,7 @@ class MockDioService extends _i1.Mock implements _i31.DioService {
|
||||||
///
|
///
|
||||||
/// See the documentation for Mockito's code generation for more information.
|
/// See the documentation for Mockito's code generation for more information.
|
||||||
class MockStatusCheckerService extends _i1.Mock
|
class MockStatusCheckerService extends _i1.Mock
|
||||||
implements _i32.StatusCheckerService {
|
implements _i33.StatusCheckerService {
|
||||||
@override
|
@override
|
||||||
_i3.SecureStorageService get storage => (super.noSuchMethod(
|
_i3.SecureStorageService get storage => (super.noSuchMethod(
|
||||||
Invocation.getter(#storage),
|
Invocation.getter(#storage),
|
||||||
|
|
@ -1583,40 +1605,40 @@ class MockStatusCheckerService extends _i1.Mock
|
||||||
///
|
///
|
||||||
/// See the documentation for Mockito's code generation for more information.
|
/// See the documentation for Mockito's code generation for more information.
|
||||||
class MockPermissionHandlerService extends _i1.Mock
|
class MockPermissionHandlerService extends _i1.Mock
|
||||||
implements _i33.PermissionHandlerService {
|
implements _i34.PermissionHandlerService {
|
||||||
@override
|
@override
|
||||||
_i9.Future<_i34.PermissionStatus> requestPermission(
|
_i9.Future<_i35.PermissionStatus> requestPermission(
|
||||||
_i34.Permission? requestedPermission) =>
|
_i35.Permission? requestedPermission) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#requestPermission,
|
#requestPermission,
|
||||||
[requestedPermission],
|
[requestedPermission],
|
||||||
),
|
),
|
||||||
returnValue: _i9.Future<_i34.PermissionStatus>.value(
|
returnValue: _i9.Future<_i35.PermissionStatus>.value(
|
||||||
_i34.PermissionStatus.denied),
|
_i35.PermissionStatus.denied),
|
||||||
returnValueForMissingStub: _i9.Future<_i34.PermissionStatus>.value(
|
returnValueForMissingStub: _i9.Future<_i35.PermissionStatus>.value(
|
||||||
_i34.PermissionStatus.denied),
|
_i35.PermissionStatus.denied),
|
||||||
) as _i9.Future<_i34.PermissionStatus>);
|
) as _i9.Future<_i35.PermissionStatus>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<_i34.PermissionStatus> request(_i34.Permission? permission) =>
|
_i9.Future<_i35.PermissionStatus> request(_i35.Permission? permission) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#request,
|
#request,
|
||||||
[permission],
|
[permission],
|
||||||
),
|
),
|
||||||
returnValue: _i9.Future<_i34.PermissionStatus>.value(
|
returnValue: _i9.Future<_i35.PermissionStatus>.value(
|
||||||
_i34.PermissionStatus.denied),
|
_i35.PermissionStatus.denied),
|
||||||
returnValueForMissingStub: _i9.Future<_i34.PermissionStatus>.value(
|
returnValueForMissingStub: _i9.Future<_i35.PermissionStatus>.value(
|
||||||
_i34.PermissionStatus.denied),
|
_i35.PermissionStatus.denied),
|
||||||
) as _i9.Future<_i34.PermissionStatus>);
|
) as _i9.Future<_i35.PermissionStatus>);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A class which mocks [ImagePickerService].
|
/// A class which mocks [ImagePickerService].
|
||||||
///
|
///
|
||||||
/// See the documentation for Mockito's code generation for more information.
|
/// See the documentation for Mockito's code generation for more information.
|
||||||
class MockImagePickerService extends _i1.Mock
|
class MockImagePickerService extends _i1.Mock
|
||||||
implements _i35.ImagePickerService {
|
implements _i36.ImagePickerService {
|
||||||
@override
|
@override
|
||||||
_i9.Future<String?> gallery() => (super.noSuchMethod(
|
_i9.Future<String?> gallery() => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
|
|
@ -1641,7 +1663,7 @@ class MockImagePickerService extends _i1.Mock
|
||||||
/// A class which mocks [GoogleAuthService].
|
/// A class which mocks [GoogleAuthService].
|
||||||
///
|
///
|
||||||
/// See the documentation for Mockito's code generation for more information.
|
/// See the documentation for Mockito's code generation for more information.
|
||||||
class MockGoogleAuthService extends _i1.Mock implements _i36.GoogleAuthService {
|
class MockGoogleAuthService extends _i1.Mock implements _i37.GoogleAuthService {
|
||||||
@override
|
@override
|
||||||
int get listenersCount => (super.noSuchMethod(
|
int get listenersCount => (super.noSuchMethod(
|
||||||
Invocation.getter(#listenersCount),
|
Invocation.getter(#listenersCount),
|
||||||
|
|
@ -1711,7 +1733,7 @@ class MockGoogleAuthService extends _i1.Mock implements _i36.GoogleAuthService {
|
||||||
///
|
///
|
||||||
/// See the documentation for Mockito's code generation for more information.
|
/// See the documentation for Mockito's code generation for more information.
|
||||||
class MockImageDownloaderService extends _i1.Mock
|
class MockImageDownloaderService extends _i1.Mock
|
||||||
implements _i37.ImageDownloaderService {
|
implements _i38.ImageDownloaderService {
|
||||||
@override
|
@override
|
||||||
_i9.Future<String> downloader(String? networkImage) => (super.noSuchMethod(
|
_i9.Future<String> downloader(String? networkImage) => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
|
|
@ -1740,7 +1762,7 @@ class MockImageDownloaderService extends _i1.Mock
|
||||||
///
|
///
|
||||||
/// See the documentation for Mockito's code generation for more information.
|
/// See the documentation for Mockito's code generation for more information.
|
||||||
class MockNotificationService extends _i1.Mock
|
class MockNotificationService extends _i1.Mock
|
||||||
implements _i38.NotificationService {
|
implements _i39.NotificationService {
|
||||||
@override
|
@override
|
||||||
_i9.Future<void> initialize() => (super.noSuchMethod(
|
_i9.Future<void> initialize() => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
|
|
@ -1762,7 +1784,7 @@ class MockNotificationService extends _i1.Mock
|
||||||
) as _i9.Future<void>);
|
) as _i9.Future<void>);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i9.Future<void> showNotification(_i39.RemoteMessage? message) =>
|
_i9.Future<void> showNotification(_i40.RemoteMessage? message) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#showNotification,
|
#showNotification,
|
||||||
|
|
@ -1796,7 +1818,7 @@ class MockNotificationService extends _i1.Mock
|
||||||
/// A class which mocks [SmartAuthService].
|
/// A class which mocks [SmartAuthService].
|
||||||
///
|
///
|
||||||
/// See the documentation for Mockito's code generation for more information.
|
/// See the documentation for Mockito's code generation for more information.
|
||||||
class MockSmartAuthService extends _i1.Mock implements _i40.SmartAuthService {
|
class MockSmartAuthService extends _i1.Mock implements _i41.SmartAuthService {
|
||||||
@override
|
@override
|
||||||
bool get listenForMultipleSms => (super.noSuchMethod(
|
bool get listenForMultipleSms => (super.noSuchMethod(
|
||||||
Invocation.getter(#listenForMultipleSms),
|
Invocation.getter(#listenForMultipleSms),
|
||||||
|
|
@ -1828,26 +1850,26 @@ class MockSmartAuthService extends _i1.Mock implements _i40.SmartAuthService {
|
||||||
/// A class which mocks [CourseService].
|
/// A class which mocks [CourseService].
|
||||||
///
|
///
|
||||||
/// See the documentation for Mockito's code generation for more information.
|
/// See the documentation for Mockito's code generation for more information.
|
||||||
class MockCourseService extends _i1.Mock implements _i41.CourseService {
|
class MockCourseService extends _i1.Mock implements _i42.CourseService {
|
||||||
@override
|
@override
|
||||||
_i9.Future<List<_i42.CourseDetail>> getCoursesDetail(int? id) =>
|
_i9.Future<List<_i43.CourseDetail>> getCoursesDetail(int? id) =>
|
||||||
(super.noSuchMethod(
|
(super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
#getCoursesDetail,
|
#getCoursesDetail,
|
||||||
[id],
|
[id],
|
||||||
),
|
),
|
||||||
returnValue:
|
returnValue:
|
||||||
_i9.Future<List<_i42.CourseDetail>>.value(<_i42.CourseDetail>[]),
|
_i9.Future<List<_i43.CourseDetail>>.value(<_i43.CourseDetail>[]),
|
||||||
returnValueForMissingStub:
|
returnValueForMissingStub:
|
||||||
_i9.Future<List<_i42.CourseDetail>>.value(<_i42.CourseDetail>[]),
|
_i9.Future<List<_i43.CourseDetail>>.value(<_i43.CourseDetail>[]),
|
||||||
) as _i9.Future<List<_i42.CourseDetail>>);
|
) as _i9.Future<List<_i43.CourseDetail>>);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A class which mocks [AudioPlayerService].
|
/// A class which mocks [AudioPlayerService].
|
||||||
///
|
///
|
||||||
/// See the documentation for Mockito's code generation for more information.
|
/// See the documentation for Mockito's code generation for more information.
|
||||||
class MockAudioPlayerService extends _i1.Mock
|
class MockAudioPlayerService extends _i1.Mock
|
||||||
implements _i43.AudioPlayerService {
|
implements _i44.AudioPlayerService {
|
||||||
@override
|
@override
|
||||||
_i4.AudioPlayer get player => (super.noSuchMethod(
|
_i4.AudioPlayer get player => (super.noSuchMethod(
|
||||||
Invocation.getter(#player),
|
Invocation.getter(#player),
|
||||||
|
|
@ -1971,13 +1993,13 @@ class MockAudioPlayerService extends _i1.Mock
|
||||||
///
|
///
|
||||||
/// See the documentation for Mockito's code generation for more information.
|
/// See the documentation for Mockito's code generation for more information.
|
||||||
class MockVoiceRecorderService extends _i1.Mock
|
class MockVoiceRecorderService extends _i1.Mock
|
||||||
implements _i44.VoiceRecorderService {
|
implements _i45.VoiceRecorderService {
|
||||||
@override
|
@override
|
||||||
_i45.VoiceRecordingState get recordingState => (super.noSuchMethod(
|
_i46.VoiceRecordingState get recordingState => (super.noSuchMethod(
|
||||||
Invocation.getter(#recordingState),
|
Invocation.getter(#recordingState),
|
||||||
returnValue: _i45.VoiceRecordingState.pending,
|
returnValue: _i46.VoiceRecordingState.pending,
|
||||||
returnValueForMissingStub: _i45.VoiceRecordingState.pending,
|
returnValueForMissingStub: _i46.VoiceRecordingState.pending,
|
||||||
) as _i45.VoiceRecordingState);
|
) as _i46.VoiceRecordingState);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_i5.WaveformRecorderController get waveController => (super.noSuchMethod(
|
_i5.WaveformRecorderController get waveController => (super.noSuchMethod(
|
||||||
|
|
@ -2078,7 +2100,7 @@ class MockVoiceRecorderService extends _i1.Mock
|
||||||
///
|
///
|
||||||
/// See the documentation for Mockito's code generation for more information.
|
/// See the documentation for Mockito's code generation for more information.
|
||||||
class MockInAppUpdateService extends _i1.Mock
|
class MockInAppUpdateService extends _i1.Mock
|
||||||
implements _i46.InAppUpdateService {
|
implements _i47.InAppUpdateService {
|
||||||
@override
|
@override
|
||||||
_i9.Future<int> getBatteryLevel() => (super.noSuchMethod(
|
_i9.Future<int> getBatteryLevel() => (super.noSuchMethod(
|
||||||
Invocation.method(
|
Invocation.method(
|
||||||
|
|
|
||||||
11
test/viewmodels/assessment_question_viewmodel_test.dart
Normal file
11
test/viewmodels/assessment_question_viewmodel_test.dart
Normal file
|
|
@ -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('AssessmentQuestionViewModel Tests -', () {
|
||||||
|
setUp(() => registerServices());
|
||||||
|
tearDown(() => locator.reset());
|
||||||
|
});
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user