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