feat(auth): Add refresh token functionality
This commit is contained in:
parent
56fc60e2fa
commit
befbfb4727
|
|
@ -29,6 +29,7 @@ import 'package:yimaru_app/services/dio_service.dart';
|
||||||
import 'package:yimaru_app/services/status_checker_service.dart';
|
import 'package:yimaru_app/services/status_checker_service.dart';
|
||||||
import 'package:yimaru_app/ui/views/welcome/welcome_view.dart';
|
import 'package:yimaru_app/ui/views/welcome/welcome_view.dart';
|
||||||
import 'package:yimaru_app/ui/views/assessment/assessment_view.dart';
|
import 'package:yimaru_app/ui/views/assessment/assessment_view.dart';
|
||||||
|
import 'package:yimaru_app/ui/views/learn_lesson/learn_lesson_view.dart';
|
||||||
// @stacked-import
|
// @stacked-import
|
||||||
|
|
||||||
@StackedApp(
|
@StackedApp(
|
||||||
|
|
@ -55,6 +56,7 @@ import 'package:yimaru_app/ui/views/assessment/assessment_view.dart';
|
||||||
MaterialRoute(page: LearnModuleView),
|
MaterialRoute(page: LearnModuleView),
|
||||||
MaterialRoute(page: WelcomeView),
|
MaterialRoute(page: WelcomeView),
|
||||||
MaterialRoute(page: AssessmentView),
|
MaterialRoute(page: AssessmentView),
|
||||||
|
MaterialRoute(page: LearnLessonView),
|
||||||
// @stacked-route
|
// @stacked-route
|
||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||||
import 'package:flutter/material.dart' as _i24;
|
import 'package:flutter/material.dart' as _i25;
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:stacked/stacked.dart' as _i1;
|
import 'package:stacked/stacked.dart' as _i1;
|
||||||
import 'package:stacked_services/stacked_services.dart' as _i25;
|
import 'package:stacked_services/stacked_services.dart' as _i26;
|
||||||
import 'package:yimaru_app/ui/views/account_privacy/account_privacy_view.dart'
|
import 'package:yimaru_app/ui/views/account_privacy/account_privacy_view.dart'
|
||||||
as _i10;
|
as _i10;
|
||||||
import 'package:yimaru_app/ui/views/assessment/assessment_view.dart' as _i23;
|
import 'package:yimaru_app/ui/views/assessment/assessment_view.dart' as _i23;
|
||||||
|
|
@ -18,6 +18,8 @@ import 'package:yimaru_app/ui/views/downloads/downloads_view.dart' as _i7;
|
||||||
import 'package:yimaru_app/ui/views/home/home_view.dart' as _i2;
|
import 'package:yimaru_app/ui/views/home/home_view.dart' as _i2;
|
||||||
import 'package:yimaru_app/ui/views/language/language_view.dart' as _i14;
|
import 'package:yimaru_app/ui/views/language/language_view.dart' as _i14;
|
||||||
import 'package:yimaru_app/ui/views/learn/learn_view.dart' as _i19;
|
import 'package:yimaru_app/ui/views/learn/learn_view.dart' as _i19;
|
||||||
|
import 'package:yimaru_app/ui/views/learn_lesson/learn_lesson_view.dart'
|
||||||
|
as _i24;
|
||||||
import 'package:yimaru_app/ui/views/learn_level/learn_level_view.dart' as _i20;
|
import 'package:yimaru_app/ui/views/learn_level/learn_level_view.dart' as _i20;
|
||||||
import 'package:yimaru_app/ui/views/learn_module/learn_module_view.dart'
|
import 'package:yimaru_app/ui/views/learn_module/learn_module_view.dart'
|
||||||
as _i21;
|
as _i21;
|
||||||
|
|
@ -85,6 +87,8 @@ class Routes {
|
||||||
|
|
||||||
static const assessmentView = '/assessment-view';
|
static const assessmentView = '/assessment-view';
|
||||||
|
|
||||||
|
static const learnLessonView = '/learn-lesson-view';
|
||||||
|
|
||||||
static const all = <String>{
|
static const all = <String>{
|
||||||
homeView,
|
homeView,
|
||||||
onboardingView,
|
onboardingView,
|
||||||
|
|
@ -108,6 +112,7 @@ class Routes {
|
||||||
learnModuleView,
|
learnModuleView,
|
||||||
welcomeView,
|
welcomeView,
|
||||||
assessmentView,
|
assessmentView,
|
||||||
|
learnLessonView,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -201,17 +206,21 @@ class StackedRouter extends _i1.RouterBase {
|
||||||
Routes.assessmentView,
|
Routes.assessmentView,
|
||||||
page: _i23.AssessmentView,
|
page: _i23.AssessmentView,
|
||||||
),
|
),
|
||||||
|
_i1.RouteDef(
|
||||||
|
Routes.learnLessonView,
|
||||||
|
page: _i24.LearnLessonView,
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
final _pagesMap = <Type, _i1.StackedRouteFactory>{
|
final _pagesMap = <Type, _i1.StackedRouteFactory>{
|
||||||
_i2.HomeView: (data) {
|
_i2.HomeView: (data) {
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => const _i2.HomeView(),
|
builder: (context) => const _i2.HomeView(),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i3.OnboardingView: (data) {
|
_i3.OnboardingView: (data) {
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => const _i3.OnboardingView(),
|
builder: (context) => const _i3.OnboardingView(),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
|
|
@ -220,127 +229,133 @@ class StackedRouter extends _i1.RouterBase {
|
||||||
final args = data.getArgs<StartupViewArguments>(
|
final args = data.getArgs<StartupViewArguments>(
|
||||||
orElse: () => const StartupViewArguments(),
|
orElse: () => const StartupViewArguments(),
|
||||||
);
|
);
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => _i4.StartupView(key: args.key, label: args.label),
|
builder: (context) => _i4.StartupView(key: args.key, label: args.label),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i5.ProfileView: (data) {
|
_i5.ProfileView: (data) {
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => const _i5.ProfileView(),
|
builder: (context) => const _i5.ProfileView(),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i6.ProfileDetailView: (data) {
|
_i6.ProfileDetailView: (data) {
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => const _i6.ProfileDetailView(),
|
builder: (context) => const _i6.ProfileDetailView(),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i7.DownloadsView: (data) {
|
_i7.DownloadsView: (data) {
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => const _i7.DownloadsView(),
|
builder: (context) => const _i7.DownloadsView(),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i8.ProgressView: (data) {
|
_i8.ProgressView: (data) {
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => const _i8.ProgressView(),
|
builder: (context) => const _i8.ProgressView(),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i9.OngoingProgressView: (data) {
|
_i9.OngoingProgressView: (data) {
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => const _i9.OngoingProgressView(),
|
builder: (context) => const _i9.OngoingProgressView(),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i10.AccountPrivacyView: (data) {
|
_i10.AccountPrivacyView: (data) {
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => const _i10.AccountPrivacyView(),
|
builder: (context) => const _i10.AccountPrivacyView(),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i11.SupportView: (data) {
|
_i11.SupportView: (data) {
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => const _i11.SupportView(),
|
builder: (context) => const _i11.SupportView(),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i12.TelegramSupportView: (data) {
|
_i12.TelegramSupportView: (data) {
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => const _i12.TelegramSupportView(),
|
builder: (context) => const _i12.TelegramSupportView(),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i13.CallSupportView: (data) {
|
_i13.CallSupportView: (data) {
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => const _i13.CallSupportView(),
|
builder: (context) => const _i13.CallSupportView(),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i14.LanguageView: (data) {
|
_i14.LanguageView: (data) {
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => const _i14.LanguageView(),
|
builder: (context) => const _i14.LanguageView(),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i15.PrivacyPolicyView: (data) {
|
_i15.PrivacyPolicyView: (data) {
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => const _i15.PrivacyPolicyView(),
|
builder: (context) => const _i15.PrivacyPolicyView(),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i16.TermsAndConditionsView: (data) {
|
_i16.TermsAndConditionsView: (data) {
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => const _i16.TermsAndConditionsView(),
|
builder: (context) => const _i16.TermsAndConditionsView(),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i17.RegisterView: (data) {
|
_i17.RegisterView: (data) {
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => const _i17.RegisterView(),
|
builder: (context) => const _i17.RegisterView(),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i18.LoginView: (data) {
|
_i18.LoginView: (data) {
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => const _i18.LoginView(),
|
builder: (context) => const _i18.LoginView(),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i19.LearnView: (data) {
|
_i19.LearnView: (data) {
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => const _i19.LearnView(),
|
builder: (context) => const _i19.LearnView(),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i20.LearnLevelView: (data) {
|
_i20.LearnLevelView: (data) {
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => const _i20.LearnLevelView(),
|
builder: (context) => const _i20.LearnLevelView(),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i21.LearnModuleView: (data) {
|
_i21.LearnModuleView: (data) {
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => const _i21.LearnModuleView(),
|
builder: (context) => const _i21.LearnModuleView(),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i22.WelcomeView: (data) {
|
_i22.WelcomeView: (data) {
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) => const _i22.WelcomeView(),
|
builder: (context) => const _i22.WelcomeView(),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_i23.AssessmentView: (data) {
|
_i23.AssessmentView: (data) {
|
||||||
final args = data.getArgs<AssessmentViewArguments>(nullOk: false);
|
final args = data.getArgs<AssessmentViewArguments>(nullOk: false);
|
||||||
return _i24.MaterialPageRoute<dynamic>(
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
builder: (context) =>
|
builder: (context) =>
|
||||||
_i23.AssessmentView(key: args.key, data: args.data),
|
_i23.AssessmentView(key: args.key, data: args.data),
|
||||||
settings: data,
|
settings: data,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
_i24.LearnLessonView: (data) {
|
||||||
|
return _i25.MaterialPageRoute<dynamic>(
|
||||||
|
builder: (context) => const _i24.LearnLessonView(),
|
||||||
|
settings: data,
|
||||||
|
);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -356,7 +371,7 @@ class StartupViewArguments {
|
||||||
this.label = 'Loading',
|
this.label = 'Loading',
|
||||||
});
|
});
|
||||||
|
|
||||||
final _i24.Key? key;
|
final _i25.Key? key;
|
||||||
|
|
||||||
final String label;
|
final String label;
|
||||||
|
|
||||||
|
|
@ -383,7 +398,7 @@ class AssessmentViewArguments {
|
||||||
required this.data,
|
required this.data,
|
||||||
});
|
});
|
||||||
|
|
||||||
final _i24.Key? key;
|
final _i25.Key? key;
|
||||||
|
|
||||||
final Map<String, dynamic> data;
|
final Map<String, dynamic> data;
|
||||||
|
|
||||||
|
|
@ -404,7 +419,7 @@ class AssessmentViewArguments {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension NavigatorStateExtension on _i25.NavigationService {
|
extension NavigatorStateExtension on _i26.NavigationService {
|
||||||
Future<dynamic> navigateToHomeView([
|
Future<dynamic> navigateToHomeView([
|
||||||
int? routerId,
|
int? routerId,
|
||||||
bool preventDuplicates = true,
|
bool preventDuplicates = true,
|
||||||
|
|
@ -434,7 +449,7 @@ extension NavigatorStateExtension on _i25.NavigationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<dynamic> navigateToStartupView({
|
Future<dynamic> navigateToStartupView({
|
||||||
_i24.Key? key,
|
_i25.Key? key,
|
||||||
String label = 'Loading',
|
String label = 'Loading',
|
||||||
int? routerId,
|
int? routerId,
|
||||||
bool preventDuplicates = true,
|
bool preventDuplicates = true,
|
||||||
|
|
@ -703,7 +718,7 @@ extension NavigatorStateExtension on _i25.NavigationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<dynamic> navigateToAssessmentView({
|
Future<dynamic> navigateToAssessmentView({
|
||||||
_i24.Key? key,
|
_i25.Key? key,
|
||||||
required Map<String, dynamic> data,
|
required Map<String, dynamic> data,
|
||||||
int? routerId,
|
int? routerId,
|
||||||
bool preventDuplicates = true,
|
bool preventDuplicates = true,
|
||||||
|
|
@ -719,6 +734,20 @@ extension NavigatorStateExtension on _i25.NavigationService {
|
||||||
transition: transition);
|
transition: transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<dynamic> navigateToLearnLessonView([
|
||||||
|
int? routerId,
|
||||||
|
bool preventDuplicates = true,
|
||||||
|
Map<String, String>? parameters,
|
||||||
|
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
|
||||||
|
transition,
|
||||||
|
]) async {
|
||||||
|
return navigateTo<dynamic>(Routes.learnLessonView,
|
||||||
|
id: routerId,
|
||||||
|
preventDuplicates: preventDuplicates,
|
||||||
|
parameters: parameters,
|
||||||
|
transition: transition);
|
||||||
|
}
|
||||||
|
|
||||||
Future<dynamic> replaceWithHomeView([
|
Future<dynamic> replaceWithHomeView([
|
||||||
int? routerId,
|
int? routerId,
|
||||||
bool preventDuplicates = true,
|
bool preventDuplicates = true,
|
||||||
|
|
@ -748,7 +777,7 @@ extension NavigatorStateExtension on _i25.NavigationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<dynamic> replaceWithStartupView({
|
Future<dynamic> replaceWithStartupView({
|
||||||
_i24.Key? key,
|
_i25.Key? key,
|
||||||
String label = 'Loading',
|
String label = 'Loading',
|
||||||
int? routerId,
|
int? routerId,
|
||||||
bool preventDuplicates = true,
|
bool preventDuplicates = true,
|
||||||
|
|
@ -1017,7 +1046,7 @@ extension NavigatorStateExtension on _i25.NavigationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<dynamic> replaceWithAssessmentView({
|
Future<dynamic> replaceWithAssessmentView({
|
||||||
_i24.Key? key,
|
_i25.Key? key,
|
||||||
required Map<String, dynamic> data,
|
required Map<String, dynamic> data,
|
||||||
int? routerId,
|
int? routerId,
|
||||||
bool preventDuplicates = true,
|
bool preventDuplicates = true,
|
||||||
|
|
@ -1032,4 +1061,18 @@ extension NavigatorStateExtension on _i25.NavigationService {
|
||||||
parameters: parameters,
|
parameters: parameters,
|
||||||
transition: transition);
|
transition: transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<dynamic> replaceWithLearnLessonView([
|
||||||
|
int? routerId,
|
||||||
|
bool preventDuplicates = true,
|
||||||
|
Map<String, String>? parameters,
|
||||||
|
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
|
||||||
|
transition,
|
||||||
|
]) async {
|
||||||
|
return replaceWith<dynamic>(Routes.learnLessonView,
|
||||||
|
id: routerId,
|
||||||
|
preventDuplicates: preventDuplicates,
|
||||||
|
parameters: parameters,
|
||||||
|
transition: transition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -130,13 +130,13 @@ class DioService {
|
||||||
if (user.refreshToken == null) return false;
|
if (user.refreshToken == null) return false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Map<String,dynamic> data = {
|
Map<String, dynamic> data = {
|
||||||
'role': 'STUDENT',
|
'role': 'STUDENT',
|
||||||
'user_id': user.userId,
|
'user_id': user.userId,
|
||||||
'access_token': user.accessToken,
|
'access_token': user.accessToken,
|
||||||
'refresh_token': user.refreshToken
|
'refresh_token': user.refreshToken
|
||||||
};
|
};
|
||||||
print(data);
|
print(data);
|
||||||
final response = await _refreshDio.post(
|
final response = await _refreshDio.post(
|
||||||
'$baseUrl/$kRefreshTokenUrl',
|
'$baseUrl/$kRefreshTokenUrl',
|
||||||
data: data,
|
data: data,
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ class LearnLessonViewModel extends BaseViewModel {
|
||||||
'status': ProgressStatuses.completed,
|
'status': ProgressStatuses.completed,
|
||||||
'thumbnail': 'assets/images/image_1.png',
|
'thumbnail': 'assets/images/image_1.png',
|
||||||
'title': '1.2 Talking About Your Surroundings',
|
'title': '1.2 Talking About Your Surroundings',
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'status': ProgressStatuses.pending,
|
'status': ProgressStatuses.pending,
|
||||||
|
|
@ -30,7 +29,6 @@ class LearnLessonViewModel extends BaseViewModel {
|
||||||
|
|
||||||
List<Map<String, dynamic>> get lessons => _lessons;
|
List<Map<String, dynamic>> get lessons => _lessons;
|
||||||
|
|
||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
void pop() => _navigationService.back();
|
void pop() => _navigationService.back();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:stacked/stacked.dart';
|
import 'package:stacked/stacked.dart';
|
||||||
import 'package:stacked_services/stacked_services.dart';
|
import 'package:stacked_services/stacked_services.dart';
|
||||||
|
import 'package:yimaru_app/app/app.router.dart';
|
||||||
|
|
||||||
import '../../../app/app.locator.dart';
|
import '../../../app/app.locator.dart';
|
||||||
import '../../common/enmus.dart';
|
import '../../common/enmus.dart';
|
||||||
|
|
@ -35,4 +36,6 @@ class LearnModuleViewModel extends BaseViewModel {
|
||||||
List<Map<String, dynamic>> get modules => _modules;
|
List<Map<String, dynamic>> get modules => _modules;
|
||||||
|
|
||||||
void pop() => _navigationService.back();
|
void pop() => _navigationService.back();
|
||||||
|
|
||||||
|
Future<void> navigateToLearnLesson() async=> await _navigationService.navigateToLearnLessonView();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,8 +83,8 @@ class OnboardingViewModel extends FormViewModel {
|
||||||
|
|
||||||
String get selectedRegion => _selectedRegion;
|
String get selectedRegion => _selectedRegion;
|
||||||
|
|
||||||
Future<List<String>> getRegions(String country) async =>
|
Future<List<String>> getRegions(String country) async => [
|
||||||
[ 'Afar',
|
'Afar',
|
||||||
'SNNPR',
|
'SNNPR',
|
||||||
'Amhara',
|
'Amhara',
|
||||||
'Harari',
|
'Harari',
|
||||||
|
|
@ -98,7 +98,6 @@ class OnboardingViewModel extends FormViewModel {
|
||||||
'Central Ethiopia',
|
'Central Ethiopia',
|
||||||
'Benishangul-Gumuz',
|
'Benishangul-Gumuz',
|
||||||
'South West Ethiopia',
|
'South West Ethiopia',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
// Learning goal
|
// Learning goal
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import 'package:iconsax/iconsax.dart';
|
||||||
import 'package:stacked/stacked.dart';
|
import 'package:stacked/stacked.dart';
|
||||||
import 'package:yimaru_app/ui/views/learn_module/learn_module_viewmodel.dart';
|
import 'package:yimaru_app/ui/views/learn_module/learn_module_viewmodel.dart';
|
||||||
import 'package:yimaru_app/ui/widgets/custom_linear_progress_indicator.dart';
|
import 'package:yimaru_app/ui/widgets/custom_linear_progress_indicator.dart';
|
||||||
|
import 'package:yimaru_app/ui/widgets/finish_practice_sheet.dart';
|
||||||
|
|
||||||
import '../common/app_colors.dart';
|
import '../common/app_colors.dart';
|
||||||
import '../common/enmus.dart';
|
import '../common/enmus.dart';
|
||||||
|
|
@ -35,27 +36,45 @@ class LearnModuleTile extends ViewModelWidget<LearnModuleViewModel> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _showSheet(
|
||||||
|
{required BuildContext context,
|
||||||
|
required LearnModuleViewModel viewModel}) async =>
|
||||||
|
await showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
backgroundColor: kcTransparent,
|
||||||
|
builder: (_) => _buildSheet(viewModel),
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, LearnModuleViewModel viewModel) =>
|
Widget build(BuildContext context, LearnModuleViewModel viewModel) =>
|
||||||
_buildExpansionTileCard(viewModel);
|
_buildExpansionTileCard(context: context, viewModel: viewModel);
|
||||||
|
|
||||||
Widget _buildExpansionTileCard(LearnModuleViewModel viewModel) => Container(
|
Widget _buildExpansionTileCard(
|
||||||
|
{required BuildContext context,
|
||||||
|
required LearnModuleViewModel viewModel}) =>
|
||||||
|
Container(
|
||||||
margin: const EdgeInsets.only(bottom: 15),
|
margin: const EdgeInsets.only(bottom: 15),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius: BorderRadius.circular(5),
|
||||||
border: Border.all(color: kcVeryLightGrey),
|
border: Border.all(color: kcVeryLightGrey),
|
||||||
),
|
),
|
||||||
child: _buildTileStack(viewModel),
|
child: _buildTileStack(context: context, viewModel: viewModel),
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildTileStack(LearnModuleViewModel viewModel) => Stack(
|
Widget _buildTileStack(
|
||||||
|
{required BuildContext context,
|
||||||
|
required LearnModuleViewModel viewModel}) =>
|
||||||
|
Stack(
|
||||||
children: [
|
children: [
|
||||||
_buildExpansionTile(viewModel),
|
_buildExpansionTile(context: context, viewModel: viewModel),
|
||||||
_buildContainerShaderWrapper()
|
_buildContainerShaderState()
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildExpansionTile(LearnModuleViewModel viewModel) => ExpansionTile(
|
Widget _buildExpansionTile(
|
||||||
|
{required BuildContext context,
|
||||||
|
required LearnModuleViewModel viewModel}) =>
|
||||||
|
ExpansionTile(
|
||||||
textColor: kcDarkGrey,
|
textColor: kcDarkGrey,
|
||||||
title: _buildTitle(),
|
title: _buildTitle(),
|
||||||
subtitle: _buildContent(),
|
subtitle: _buildContent(),
|
||||||
|
|
@ -73,7 +92,8 @@ class LearnModuleTile extends ViewModelWidget<LearnModuleViewModel> {
|
||||||
childrenPadding: const EdgeInsets.fromLTRB(70, 15, 15, 15),
|
childrenPadding: const EdgeInsets.fromLTRB(70, 15, 15, 15),
|
||||||
showTrailingIcon: status != ProgressStatuses.pending ? true : false,
|
showTrailingIcon: status != ProgressStatuses.pending ? true : false,
|
||||||
initiallyExpanded: status == ProgressStatuses.started ? true : false,
|
initiallyExpanded: status == ProgressStatuses.started ? true : false,
|
||||||
children: _buildExpansionTileChildren(viewModel),
|
children:
|
||||||
|
_buildExpansionTileChildren(context: context, viewModel: viewModel),
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildIconWrapper() => CircleAvatar(
|
Widget _buildIconWrapper() => CircleAvatar(
|
||||||
|
|
@ -102,21 +122,28 @@ class LearnModuleTile extends ViewModelWidget<LearnModuleViewModel> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
List<Widget> _buildExpansionTileChildren(LearnModuleViewModel viewModel) =>
|
List<Widget> _buildExpansionTileChildren(
|
||||||
[_buildExpansionTileItem(viewModel)];
|
{required BuildContext context,
|
||||||
|
required LearnModuleViewModel viewModel}) =>
|
||||||
|
[_buildExpansionTileItem(context: context, viewModel: viewModel)];
|
||||||
|
|
||||||
Widget _buildExpansionTileItem(LearnModuleViewModel viewModel) => Column(
|
Widget _buildExpansionTileItem(
|
||||||
|
{required BuildContext context,
|
||||||
|
required LearnModuleViewModel viewModel}) =>
|
||||||
|
Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: _buildExpansionTileItemChildren(viewModel),
|
children: _buildExpansionTileItemChildren(
|
||||||
|
context: context, viewModel: viewModel),
|
||||||
);
|
);
|
||||||
|
|
||||||
List<Widget> _buildExpansionTileItemChildren(
|
List<Widget> _buildExpansionTileItemChildren(
|
||||||
LearnModuleViewModel viewModel) =>
|
{required BuildContext context,
|
||||||
|
required LearnModuleViewModel viewModel}) =>
|
||||||
[
|
[
|
||||||
_buildProgressRow(),
|
_buildProgressRow(),
|
||||||
verticalSpaceSmall,
|
verticalSpaceSmall,
|
||||||
_buildActionButtonWrapper(viewModel)
|
_buildActionButtonWrapper(context: context, viewModel: viewModel)
|
||||||
];
|
];
|
||||||
|
|
||||||
Widget _buildProgressRow() => Row(
|
Widget _buildProgressRow() => Row(
|
||||||
|
|
@ -141,16 +168,22 @@ class LearnModuleTile extends ViewModelWidget<LearnModuleViewModel> {
|
||||||
style: TextStyle(color: kcDarkGrey),
|
style: TextStyle(color: kcDarkGrey),
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildActionButtonWrapper(LearnModuleViewModel viewModel) => SizedBox(
|
Widget _buildActionButtonWrapper(
|
||||||
|
{required BuildContext context,
|
||||||
|
required LearnModuleViewModel viewModel}) =>
|
||||||
|
SizedBox(
|
||||||
height: 40,
|
height: 40,
|
||||||
child: _buildActionButtons(viewModel),
|
child: _buildActionButtons(context: context, viewModel: viewModel),
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildActionButtons(LearnModuleViewModel viewModel) => Row(
|
Widget _buildActionButtons(
|
||||||
|
{required BuildContext context,
|
||||||
|
required LearnModuleViewModel viewModel}) =>
|
||||||
|
Row(
|
||||||
children: [
|
children: [
|
||||||
_buildLessonButtonWrapper(viewModel),
|
_buildLessonButtonWrapper(viewModel),
|
||||||
horizontalSpaceSmall,
|
horizontalSpaceSmall,
|
||||||
_buildPracticeButtonWrapper(viewModel)
|
_buildPracticeButtonWrapper(context: context, viewModel: viewModel)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -159,39 +192,52 @@ class LearnModuleTile extends ViewModelWidget<LearnModuleViewModel> {
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildLessonButton(LearnModuleViewModel viewModel) =>
|
Widget _buildLessonButton(LearnModuleViewModel viewModel) =>
|
||||||
const CustomElevatedButton(
|
CustomElevatedButton(
|
||||||
height: 15,
|
height: 15,
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
text: 'View Lessons',
|
text: 'View Lessons',
|
||||||
foregroundColor: kcWhite,
|
foregroundColor: kcWhite,
|
||||||
backgroundColor: kcPrimaryColor,
|
backgroundColor: kcPrimaryColor,
|
||||||
//onTap: () async => await viewModel.navigateToLearnModule(),
|
onTap: () async => await viewModel.navigateToLearnLesson(),
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildPracticeButtonWrapper(LearnModuleViewModel viewModel) =>
|
Widget _buildPracticeButtonWrapper(
|
||||||
|
{required BuildContext context,
|
||||||
|
required LearnModuleViewModel viewModel}) =>
|
||||||
Expanded(
|
Expanded(
|
||||||
child: _buildPracticeButton(viewModel),
|
child: _buildPracticeButton(context: context, viewModel: viewModel),
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildPracticeButton(LearnModuleViewModel viewModel) =>
|
Widget _buildPracticeButton(
|
||||||
const CustomElevatedButton(
|
{required BuildContext context,
|
||||||
|
required LearnModuleViewModel viewModel}) =>
|
||||||
|
CustomElevatedButton(
|
||||||
height: 15,
|
height: 15,
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
text: 'View Practices',
|
text: 'View Practices',
|
||||||
backgroundColor: kcWhite,
|
backgroundColor: kcWhite,
|
||||||
borderColor: kcPrimaryColor,
|
borderColor: kcPrimaryColor,
|
||||||
foregroundColor: kcPrimaryColor,
|
foregroundColor: kcPrimaryColor,
|
||||||
// onTap: () async => await viewModel.navigateToLearnLevel(),
|
onTap: () async =>
|
||||||
|
await _showSheet(context: context, viewModel: viewModel),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Widget _buildSheet(LearnModuleViewModel viewModel) => FinishPracticeSheet(
|
||||||
|
onTap: viewModel.pop,
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget _buildContainerShaderState() => status == ProgressStatuses.pending
|
||||||
|
? _buildContainerShaderWrapper()
|
||||||
|
: Container();
|
||||||
|
|
||||||
Widget _buildContainerShaderWrapper() => Positioned.fill(
|
Widget _buildContainerShaderWrapper() => Positioned.fill(
|
||||||
child: _buildContainerShader(),
|
child: _buildContainerShader(),
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildContainerShader() => Container(
|
Widget _buildContainerShader() => Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
|
color: kcWhite.withOpacity(0.5),
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius: BorderRadius.circular(5),
|
||||||
border: Border.all(color: kcWhite.withOpacity(0.75)),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,6 @@ import '../common/app_colors.dart';
|
||||||
import '../common/ui_helpers.dart';
|
import '../common/ui_helpers.dart';
|
||||||
import 'custom_linear_progress_indicator.dart';
|
import 'custom_linear_progress_indicator.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ModuleProgress extends StatelessWidget {
|
class ModuleProgress extends StatelessWidget {
|
||||||
const ModuleProgress({super.key});
|
const ModuleProgress({super.key});
|
||||||
|
|
||||||
|
|
@ -52,6 +50,4 @@ class ModuleProgress extends StatelessWidget {
|
||||||
activeColor: kcPrimaryColor,
|
activeColor: kcPrimaryColor,
|
||||||
backgroundColor: kcVeryLightGrey,
|
backgroundColor: kcVeryLightGrey,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ class MotivationCard extends StatelessWidget {
|
||||||
|
|
||||||
Widget _buildIcon() => Image.asset('assets/images/deer.png');
|
Widget _buildIcon() => Image.asset('assets/images/deer.png');
|
||||||
|
|
||||||
|
|
||||||
Widget _buildText() => Expanded(
|
Widget _buildText() => Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
'Let’s keep going — you’re more than halfway there!',
|
'Let’s keep going — you’re more than halfway there!',
|
||||||
|
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
import 'package:mockito/mockito.dart';
|
|
||||||
import 'package:yimaru_app/app/app.bottomsheets.dart';
|
|
||||||
import 'package:yimaru_app/app/app.locator.dart';
|
|
||||||
import 'package:yimaru_app/ui/common/app_strings.dart';
|
|
||||||
import 'package:yimaru_app/ui/views/home/home_viewmodel.dart';
|
|
||||||
|
|
||||||
import '../helpers/test_helpers.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
HomeViewModel getModel() => HomeViewModel();
|
|
||||||
|
|
||||||
group('HomeViewmodelTest -', () {
|
|
||||||
setUp(() => registerServices());
|
|
||||||
tearDown(() => locator.reset());
|
|
||||||
|
|
||||||
group('incrementCounter -', () {
|
|
||||||
test('When called once should return Counter is: 1', () {
|
|
||||||
final model = getModel();
|
|
||||||
model.incrementCounter();
|
|
||||||
expect(model.counterLabel, 'Counter is: 1');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
group('showBottomSheet -', () {
|
|
||||||
test(
|
|
||||||
'When called, should show custom bottom sheet using notice variant',
|
|
||||||
() {
|
|
||||||
final bottomSheetService = getAndRegisterBottomSheetService();
|
|
||||||
|
|
||||||
final model = getModel();
|
|
||||||
model.showBottomSheet();
|
|
||||||
verify(
|
|
||||||
bottomSheetService.showCustomSheet(
|
|
||||||
variant: BottomSheetType.notice,
|
|
||||||
title: ksHomeBottomSheetTitle,
|
|
||||||
description: ksHomeBottomSheetDescription,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user