diff --git a/lib/models/learn_question.dart b/lib/models/learn_question.dart index 3b8c0dc..f90ffed 100644 --- a/lib/models/learn_question.dart +++ b/lib/models/learn_question.dart @@ -1,5 +1,4 @@ import 'package:json_annotation/json_annotation.dart'; -import 'package:yimaru_app/models/option.dart'; part 'learn_question.g.dart'; diff --git a/lib/services/voice_recorder_service.dart b/lib/services/voice_recorder_service.dart index c0a7444..d4f97a6 100644 --- a/lib/services/voice_recorder_service.dart +++ b/lib/services/voice_recorder_service.dart @@ -14,7 +14,7 @@ class VoiceRecorderService with ListenableServiceMixin { WaveformRecorderController get waveController => _waveController; - bool _isRecording = false; + final bool _isRecording = false; bool get isRecording => _isRecording; diff --git a/lib/ui/common/enmus.dart b/lib/ui/common/enmus.dart index b9c3241..a6c93ef 100644 --- a/lib/ui/common/enmus.dart +++ b/lib/ui/common/enmus.dart @@ -29,7 +29,7 @@ enum DuolingoAssessments { speaking, reading, writing, listening } enum StateObjects { none, courses, - homeView, + startupView, register, verifyOtp, resendOtp, diff --git a/lib/ui/views/assessment/assessment_viewmodel.dart b/lib/ui/views/assessment/assessment_viewmodel.dart index 3c08b2c..2610005 100644 --- a/lib/ui/views/assessment/assessment_viewmodel.dart +++ b/lib/ui/views/assessment/assessment_viewmodel.dart @@ -240,8 +240,8 @@ class AssessmentViewModel extends BaseViewModel { // Navigation void pop() => _navigationService.back(); - Future replaceWithHome() async => - await _navigationService.clearStackAndShow(Routes.homeView); + Future replaceWithStartUp() async => + await _navigationService.clearStackAndShow(Routes.startupView); Future navigateToLanguage() async => await _navigationService.navigateToLanguageView(); @@ -259,7 +259,7 @@ class AssessmentViewModel extends BaseViewModel { await _apiService.completeProfile(_userData); if (response['status'] == ResponseStatus.success) { clearUserData(); - await replaceWithHome(); + await replaceWithStartUp(); showSuccessToast(response['message']); } else { showErrorToast(response['message']); diff --git a/lib/ui/views/home/home_view.dart b/lib/ui/views/home/home_view.dart index f7343f8..18c141a 100644 --- a/lib/ui/views/home/home_view.dart +++ b/lib/ui/views/home/home_view.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:stacked/stacked.dart'; import 'package:yimaru_app/ui/common/app_colors.dart'; import 'package:yimaru_app/ui/common/enmus.dart'; -import 'package:yimaru_app/ui/views/course_category/course_category_view.dart'; import 'package:yimaru_app/ui/views/learn_program/learn_program_view.dart'; import 'package:yimaru_app/ui/views/profile/profile_view.dart'; import 'package:yimaru_app/ui/views/startup/startup_view.dart'; @@ -16,27 +15,12 @@ class HomeView extends StackedView { @override HomeViewModel viewModelBuilder(BuildContext context) => HomeViewModel(); - @override - void onViewModelReady(HomeViewModel viewModel) async { - // Removable - await _init(viewModel); - super.onViewModelReady(viewModel); - } - - Future _init(HomeViewModel viewModel) async => - await viewModel.initialize(); - @override Widget builder( BuildContext context, HomeViewModel viewModel, Widget? child) => - _buildScaffoldWrapper(viewModel); + _buildScaffold(viewModel); - Widget _buildScaffoldWrapper(HomeViewModel viewModel) => - viewModel.busy(StateObjects.homeView) - ? _buildStartUpView() - : _buildScaffold(viewModel); - Widget _buildStartUpView() => const StartupView(label: 'Checking user info'); Widget _buildScaffold(HomeViewModel viewModel) => Scaffold( body: getViewForIndex(viewModel.currentPage), diff --git a/lib/ui/views/home/home_viewmodel.dart b/lib/ui/views/home/home_viewmodel.dart index 29f04ed..01b9c34 100644 --- a/lib/ui/views/home/home_viewmodel.dart +++ b/lib/ui/views/home/home_viewmodel.dart @@ -14,12 +14,9 @@ import '../../common/enmus.dart'; import '../../common/ui_helpers.dart'; class HomeViewModel extends ReactiveViewModel { - final _apiService = locator(); - final _statusChecker = locator(); - final _navigationService = locator(); + final _bottomSheetService = locator(); final _authenticationService = locator(); - final _imageDownloaderService = locator(); @override List get listenableServices => @@ -49,75 +46,9 @@ class HomeViewModel extends ReactiveViewModel { rebuildUi(); } - // Save profile status - Future saveProfileStatus(bool value) async => - await _authenticationService.saveProfileStatus(value); - // Navigation - Future replaceWithFailure() async => await _navigationService - .replaceWithFailureView(label: 'Check you internet connection'); - Future replaceWithOnboarding() async => - await _navigationService.replaceWithOnboardingView(); - // Remote api calls - // Initialize user data - Future initialize() async => - await runBusyFuture(_initialize(), busyObject: StateObjects.homeView); - Future _initialize() async { - await _getProfileStatus(); - await _getProfileData(); - } - - // Get profile data - Future _getProfileData() async { - if (!(_user?.userInfoLoaded ?? false)) { - Map response = {}; - - if (_user?.profileCompleted != null && - (_user?.profileCompleted ?? false)) { - if (await _statusChecker.checkConnection()) { - response = await _apiService.getProfileData(_user?.userId); - - if (response['status'] == ResponseStatus.success) { - User user = response['data'] as User; - - await _authenticationService.saveUserData(user); - - String image = - await _imageDownloaderService.downloader(user.profilePicture); - - await _authenticationService.saveProfilePicture(image); - } - } else { - await replaceWithFailure(); - } - } - } - } - - // Get profile status - Future _getProfileStatus() async { - Map response = {}; - if (_user?.profileCompleted == null) { - if (await _statusChecker.checkConnection()) { - response = await _apiService.getProfileStatus(_user); - } else { - await Future.delayed(kDuration); - await replaceWithFailure(); - } - } else if (!(_user?.profileCompleted ?? false)) { - response = {'data': false, 'status': ResponseStatus.success}; - } else { - response = {'data': true, 'status': ResponseStatus.success}; - } - if (response['status'] == ResponseStatus.success && !response['data']) { - await replaceWithOnboarding(); - } else if (response['status'] == ResponseStatus.success && - response['data']) { - await saveProfileStatus(response['data']); - } - } } diff --git a/lib/ui/views/learn_lesson_detail/learn_lesson_detail_viewmodel.dart b/lib/ui/views/learn_lesson_detail/learn_lesson_detail_viewmodel.dart index bb7e5e2..11979bc 100644 --- a/lib/ui/views/learn_lesson_detail/learn_lesson_detail_viewmodel.dart +++ b/lib/ui/views/learn_lesson_detail/learn_lesson_detail_viewmodel.dart @@ -1,7 +1,6 @@ import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:stacked/stacked.dart'; import 'package:stacked_services/stacked_services.dart'; -import 'package:yimaru_app/app/app.router.dart'; import 'package:yimaru_app/ui/common/enmus.dart'; import '../../../app/app.locator.dart'; diff --git a/lib/ui/views/learn_practice/learn_practice_view.dart b/lib/ui/views/learn_practice/learn_practice_view.dart index 32edfa0..564b884 100644 --- a/lib/ui/views/learn_practice/learn_practice_view.dart +++ b/lib/ui/views/learn_practice/learn_practice_view.dart @@ -5,9 +5,7 @@ import 'package:yimaru_app/ui/views/learn_practice/screens/finish_learn_practice 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'; -import 'package:yimaru_app/ui/views/learn_practice/screens/interact_learn_practice_screen.dart'; import 'package:yimaru_app/ui/views/learn_practice/screens/learn_practice_intro_screen.dart'; -import 'package:yimaru_app/ui/views/learn_practice/screens/start_learn_practice_screen.dart'; import 'package:yimaru_app/ui/widgets/page_loading_indicator.dart'; import '../../common/app_colors.dart'; diff --git a/lib/ui/views/learn_practice/learn_practice_viewmodel.dart b/lib/ui/views/learn_practice/learn_practice_viewmodel.dart index 46d8304..f955ab3 100644 --- a/lib/ui/views/learn_practice/learn_practice_viewmodel.dart +++ b/lib/ui/views/learn_practice/learn_practice_viewmodel.dart @@ -11,7 +11,6 @@ import 'package:yimaru_app/ui/common/enmus.dart'; import '../../../app/app.locator.dart'; import '../../../models/learn_question.dart'; -import '../../../models/question.dart'; import '../../../services/api_service.dart'; import '../../../services/audio_player_service.dart'; import '../../../services/status_checker_service.dart'; @@ -96,7 +95,7 @@ class LearnPracticeViewModel extends ReactiveViewModel { List get questions => _questions; // Practice answers - List> _answers = []; + final List> _answers = []; List> get answers => _answers; diff --git a/lib/ui/views/learn_practice/screens/learn_practice_intro_screen.dart b/lib/ui/views/learn_practice/screens/learn_practice_intro_screen.dart index f831db8..731bf6c 100644 --- a/lib/ui/views/learn_practice/screens/learn_practice_intro_screen.dart +++ b/lib/ui/views/learn_practice/screens/learn_practice_intro_screen.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:stacked/stacked.dart'; -import 'package:yimaru_app/models/learn_practice.dart'; import 'package:yimaru_app/ui/views/learn_practice/learn_practice_viewmodel.dart'; import '../../../common/app_colors.dart'; diff --git a/lib/ui/views/learn_practice/screens/learn_practice_questions_screen.dart b/lib/ui/views/learn_practice/screens/learn_practice_questions_screen.dart index 52b798a..1dff69e 100644 --- a/lib/ui/views/learn_practice/screens/learn_practice_questions_screen.dart +++ b/lib/ui/views/learn_practice/screens/learn_practice_questions_screen.dart @@ -1,14 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:flutter_carousel_widget/flutter_carousel_widget.dart'; import 'package:stacked/stacked.dart'; import 'package:yimaru_app/models/learn_question.dart'; -import 'package:yimaru_app/models/practice.dart'; import 'package:yimaru_app/ui/views/learn_practice/screens/start_learn_practice_screen.dart'; -import 'package:yimaru_app/ui/widgets/learn_practice_card.dart'; -import '../../../common/app_colors.dart'; -import '../../../common/ui_helpers.dart'; -import '../../../widgets/small_app_bar.dart'; import '../learn_practice_viewmodel.dart'; import 'interact_learn_practice_screen.dart'; diff --git a/lib/ui/views/login/login_viewmodel.dart b/lib/ui/views/login/login_viewmodel.dart index 19f841d..1fb0beb 100644 --- a/lib/ui/views/login/login_viewmodel.dart +++ b/lib/ui/views/login/login_viewmodel.dart @@ -154,8 +154,7 @@ class LoginViewModel extends ReactiveViewModel } // Navigation - Future replaceWithHome() async => - await _navigationService.clearStackAndShow(Routes.homeView); + Future navigateToRegister() async => await _navigationService.navigateToRegisterView(); @@ -163,6 +162,12 @@ class LoginViewModel extends ReactiveViewModel Future navigateToForgetPassword() async => await _navigationService.navigateToForgetPasswordView(); + Future replaceWithStartUp() async => + await _navigationService.clearStackAndShow(Routes.startupView); + + + + // Remote api calls // Login with email @@ -182,7 +187,7 @@ class LoginViewModel extends ReactiveViewModel await _authenticationService.saveUserCredential(data); clearUserData(); - await replaceWithHome(); + await replaceWithStartUp(); showSuccessToast(response['message']); } else { showErrorToast(response['message']); @@ -210,7 +215,7 @@ class LoginViewModel extends ReactiveViewModel }; await _authenticationService.saveUserCredential(data); clearUserData(); - await replaceWithHome(); + await replaceWithStartUp(); showSuccessToast(response['message']); } else { showErrorToast(response['message']); @@ -251,7 +256,7 @@ class LoginViewModel extends ReactiveViewModel }; await _authenticationService.saveUserCredential(data); - await replaceWithHome(); + await replaceWithStartUp(); showSuccessToast(response['message']); } else { showErrorToast(response['message']); diff --git a/lib/ui/views/onboarding/onboarding_view.dart b/lib/ui/views/onboarding/onboarding_view.dart index 142576b..a799e32 100644 --- a/lib/ui/views/onboarding/onboarding_view.dart +++ b/lib/ui/views/onboarding/onboarding_view.dart @@ -32,7 +32,6 @@ class OnboardingView extends StackedView void _initUserData(OnboardingViewModel viewModel) { fullNameController.text = viewModel.googleUser?.displayName ?? ''; - print('Full-NAME: ${fullNameController.text}'); } void _initClearData() { diff --git a/lib/ui/views/onboarding/onboarding_viewmodel.dart b/lib/ui/views/onboarding/onboarding_viewmodel.dart index c7bc537..d5b8b45 100644 --- a/lib/ui/views/onboarding/onboarding_viewmodel.dart +++ b/lib/ui/views/onboarding/onboarding_viewmodel.dart @@ -614,6 +614,5 @@ class OnboardingViewModel extends ReactiveViewModel Future navigateToAssessment() async => await _navigationService.navigateToAssessmentView(data: _userData); - Future replaceWithHome() async => - await _navigationService.clearStackAndShow(Routes.homeView); + } diff --git a/lib/ui/views/register/register_viewmodel.dart b/lib/ui/views/register/register_viewmodel.dart index 1eaa57f..67bca97 100644 --- a/lib/ui/views/register/register_viewmodel.dart +++ b/lib/ui/views/register/register_viewmodel.dart @@ -19,8 +19,6 @@ class RegisterViewModel extends ReactiveViewModel implements FormViewModel { final _apiService = locator(); - final _smartAuthService = locator(); - final _statusChecker = locator(); final _navigationService = locator(); @@ -297,8 +295,8 @@ class RegisterViewModel extends ReactiveViewModel Future replaceToLogin() async => await _navigationService.replaceWithLoginView(); - Future replaceWithHome() async => - await _navigationService.clearStackAndShow(Routes.homeView); + Future replaceWithStartUp() async => + await _navigationService.clearStackAndShow(Routes.startupView); // Remote api calls @@ -344,7 +342,7 @@ class RegisterViewModel extends ReactiveViewModel }; await _authenticationService.saveUserCredential(data); clearUserData(); - await replaceWithHome(); + await replaceWithStartUp(); showSuccessToast(response['message']); } else { showErrorToast(response['message']); @@ -367,7 +365,7 @@ class RegisterViewModel extends ReactiveViewModel }; await _authenticationService.saveUserCredential(data); - await replaceWithHome(); + await replaceWithStartUp(); showSuccessToast(response['message']); } else { showErrorToast(response['message']); diff --git a/lib/ui/views/startup/startup_view.dart b/lib/ui/views/startup/startup_view.dart index c2853b4..9c28170 100644 --- a/lib/ui/views/startup/startup_view.dart +++ b/lib/ui/views/startup/startup_view.dart @@ -6,6 +6,7 @@ import 'package:yimaru_app/ui/common/ui_helpers.dart'; import 'package:yimaru_app/ui/widgets/custom_circular_progress_indicator.dart'; import '../../common/app_colors.dart'; +import '../../common/enmus.dart'; import 'startup_viewmodel.dart'; class StartupView extends StackedView { @@ -18,13 +19,20 @@ class StartupView extends StackedView { StartupViewModel viewModel, Widget? child, ) => - _buildScaffoldWrapper(); + _buildScaffoldWrapper(viewModel); - Widget _buildScaffoldWrapper() => Scaffold( + Widget _buildScaffoldWrapper(StartupViewModel viewModel) => Scaffold( backgroundColor: kcBackgroundColor, - body: _buildScaffold(), + body: _buildScaffoldState(viewModel), ); + Widget _buildScaffoldState(StartupViewModel viewModel) => + viewModel.busy(StateObjects.startupView) + ? _buildStartUpView() + : _buildScaffold(); + + Widget _buildStartUpView() => const StartupView(label: 'Checking user info'); + Widget _buildScaffold() => Stack( children: _buildScaffoldChildren(), ); diff --git a/lib/ui/views/startup/startup_viewmodel.dart b/lib/ui/views/startup/startup_viewmodel.dart index 2bde2b5..49e27bd 100644 --- a/lib/ui/views/startup/startup_viewmodel.dart +++ b/lib/ui/views/startup/startup_viewmodel.dart @@ -5,14 +5,31 @@ import 'package:yimaru_app/services/in_app_update_service.dart'; import '../../../app/app.locator.dart'; import '../../../app/app.router.dart'; +import '../../../models/user.dart'; +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 BaseViewModel { +class StartupViewModel extends ReactiveViewModel { // Dependency injection + final _apiService = locator(); final _statusChecker = locator(); final _navigationService = locator(); final _inAppUpdateService = locator(); final _authenticationService = locator(); + final _imageDownloaderService = locator(); + + @override + List get listenableServices => + [_authenticationService]; + + // Current user + User? get _user => _authenticationService.user; + + User? get user => _user; + // Place anything here that needs to happen before we get into the application Future runStartupLogic() async { @@ -27,7 +44,7 @@ class StartupViewModel extends BaseViewModel { } else { if (loggedIn) { await _authenticationService.getUser(); - await _navigationService.replaceWithHomeView(); + await _getProfileStatus(); } else { // Removable await _navigationService.replaceWithLoginView(); @@ -35,9 +52,94 @@ class StartupViewModel extends BaseViewModel { } } + + + // Navigation + Future replaceWithFailure() async => await _navigationService + .replaceWithFailureView(label: 'Check you internet connection'); + + Future replaceWithOnboarding() async => + await _navigationService.replaceWithOnboardingView(); + + + Future replaceWithHome() async => + await _navigationService.replaceWithHomeView(); + + // Remote api calls + + // In-app update Future _inAppUpdate() async { if (await _statusChecker.checkConnection()) { await _inAppUpdateService.checkForUpdate(); } } + + // Get profile status + Future _getProfileStatus() async { + Map response = {}; + if (_user?.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'); + + 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(); + } + } + + // Save profile status + Future saveProfileStatus(bool value) async => + await _authenticationService.saveProfileStatus(value); + + // Get profile data + Future _getProfileData() async { + if (!(_user?.userInfoLoaded ?? false)) { + Map response = {}; + + if (_user?.profileCompleted != null && + (_user?.profileCompleted ?? false)) { + if (await _statusChecker.checkConnection()) { + response = await _apiService.getProfileData(_user?.userId); + + if (response['status'] == ResponseStatus.success) { + User user = response['data'] as User; + + await _authenticationService.saveUserData(user); + + String image = + await _imageDownloaderService.downloader(user.profilePicture); + + await _authenticationService.saveProfilePicture(image); + } + } else { + await replaceWithFailure(); + } + } + } + } } diff --git a/lib/ui/widgets/cancel_learn_practice_sheet.dart b/lib/ui/widgets/cancel_learn_practice_sheet.dart index ba9a328..f06e899 100644 --- a/lib/ui/widgets/cancel_learn_practice_sheet.dart +++ b/lib/ui/widgets/cancel_learn_practice_sheet.dart @@ -1,6 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:yimaru_app/ui/views/learn_practice/learn_practice_viewmodel.dart'; import 'package:yimaru_app/ui/widgets/speaking_partner_image.dart'; import '../common/app_colors.dart'; diff --git a/lib/ui/widgets/learn_practice_card.dart b/lib/ui/widgets/learn_practice_card.dart index aa39805..bd7c5c6 100644 --- a/lib/ui/widgets/learn_practice_card.dart +++ b/lib/ui/widgets/learn_practice_card.dart @@ -51,7 +51,7 @@ class LearnPracticeCard extends ViewModelWidget { ); Widget _buildStartButton(LearnPracticeViewModel viewModel) => - CustomElevatedButton( + const CustomElevatedButton( height: 50, width: 200, borderRadius: 8, diff --git a/lib/ui/widgets/learn_practice_tip_section.dart b/lib/ui/widgets/learn_practice_tip_section.dart index 49efe70..e76fb7e 100644 --- a/lib/ui/widgets/learn_practice_tip_section.dart +++ b/lib/ui/widgets/learn_practice_tip_section.dart @@ -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'; -import '../../models/learn_practice.dart'; class LearnPracticeTipSection extends ViewModelWidget { const LearnPracticeTipSection({super.key}); diff --git a/pubspec.yaml b/pubspec.yaml index b3c9d0b..36e209d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,9 +1,8 @@ name: yimaru_app -version: 0.1.5+7 +version: 0.1.6+8 publish_to: 'none' description: A new Flutter project. - environment: sdk: '>=3.0.3 <4.0.0'