Compare commits

..

No commits in common. "723fa384978a119c56a331c6225d89fad72f305d" and "2b2d44904481519bf40bd6c3a51083505316debd" have entirely different histories.

27 changed files with 716 additions and 900 deletions

View File

@ -187,14 +187,6 @@
"finish_all_practice_module": "የሞጁሉን ልምምድ ለመውሰድ የትምህርት ልምምዶችን ያጠናቅቁ", "finish_all_practice_module": "የሞጁሉን ልምምድ ለመውሰድ የትምህርት ልምምዶችን ያጠናቅቁ",
"finish_all_practice_course": "የኮርሱን ልምምድ ለመውሰድ የሞጁል ልምምዶችን ያጠናቅቁ", "finish_all_practice_course": "የኮርሱን ልምምድ ለመውሰድ የሞጁል ልምምዶችን ያጠናቅቁ",
"finish_all_practice_previouse_module": "ይህን ልምምድ ለመውሰድ የቀድሞውን የሞጁል ልምምድ ያጠናቅቁ", "finish_all_practice_previouse_module": "ይህን ልምምድ ለመውሰድ የቀድሞውን የሞጁል ልምምድ ያጠናቅቁ",
"finish_all_practice_previouse_course": "ይህን ለመውሰድ የቀድሞውን የኮርስ ልምምድ ያጠናቅቁ", "finish_all_practice_previouse_course": "ይህን ለመውሰድ የቀድሞውን የኮርስ ልምምድ ያጠናቅቁ"
"track_journey": "የትምህርት ጉዞዎን ይከታተሉ እና በጊዜ ሂደት ያሳዩትን እድገት ይመልከቱ።",
"learn_english": "እንግሊዝኛ ይማሩ",
"keep_momentum":"በጣም ጥሩ ስራ! በዚሁ ብርታት ይቀጥሉ።",
"completed_practices": "የተጠናቀቁ ልምምዶች",
"total_practices": "ጠቅላላ ልምምዶች",
"progress_percentage": "የእድገት መቶኛ"
} }

View File

@ -1,197 +1,192 @@
{
"loading": "Loading", {"loading": "Loading",
"welcome_back": "Welcome back", "welcome_back": "Welcome back",
"checking_user_info": "Checking user info", "checking_user_info": "Checking user info",
"dont_have_account": "Don't have an account?", "dont_have_account": "Don't have an account?",
"email": "Email", "email": "Email",
"password": "Password", "password": "Password",
"forgot_password": "Forgot password?", "forgot_password": "Forgot password?",
"cont": "Continue", "cont": "Continue",
"register": "Register", "register": "Register",
"login_with_google": "Login with Google", "login_with_google": "Login with Google",
"or": "Or", "or": "Or",
"login_with_phone": "Login with phone number", "login_with_phone": "Login with phone number",
"create_account": "Create an account", "create_account": "Create an account",
"already_have_account": "Already have an account?", "already_have_account": "Already have an account?",
"login": "Login", "login": "Login",
"register_with_google": "Register with Google", "register_with_google": "Register with Google",
"register_with_phone": "Register with phone number", "register_with_phone": "Register with phone number",
"enter_phone_number": "Enter your phone number. We will send you a confirmation code there.", "enter_phone_number": "Enter your phone number. We will send you a confirmation code there.",
"login_with_email": "Login with email", "login_with_email": "Login with email",
"create_password": "Create password", "create_password": "Create password",
"confirm_password": "Confirm password", "confirm_password": "Confirm password",
"eight_character_minimum": "8 characters minimum", "eight_character_minimum": "8 characters minimum",
"password_match": "password match", "password_match": "password match",
"sign_up_agreement": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy", "sign_up_agreement": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy",
"terms_of_services": "Terms of Service", "terms_of_services": "Terms of Service",
"and": "and", "and": "and",
"privacy_policy": "Privacy Policy", "privacy_policy": "Privacy Policy",
"register_with_email": "Register with email", "register_with_email": "Register with email",
"verification_code": "Verification Code", "verification_code": "Verification Code",
"resend_code": "Resend Code", "resend_code": "Resend Code",
"code_sent_to_phone": "Code sent to your number", "code_sent_to_phone": "Code sent to your number",
"code_sent_to_email": "Code sent to your email", "code_sent_to_email": "Code sent to your email",
"resend_code_in": "Resend code in", "resend_code_in": "Resend code in",
"reset_password": "Reset Password", "reset_password": "Reset Password",
"enter_email_reset_code": "Enter your email. We will send you a reset code.", "enter_email_reset_code": "Enter your email. We will send you a reset code.",
"please_wait": "Please wait", "please_wait": "Please wait",
"reset_code_sent": "Reset code sent successfully", "reset_code_sent": "Reset code sent successfully",
"reset_code": "Reset code", "reset_code": "Reset code",
"new_password": "New password", "new_password": "New password",
"logged_in_successfully": "Logged in successfully", "logged_in_successfully": "Logged in successfully",
"continue_learning": "Continue Learning", "continue_learning": "Continue Learning",
"start_learning": "Start Learning", "start_learning": "Start Learning",
"completed": "Completed", "completed": "Completed",
"view_course": "View course", "view_course": "View course",
"take_practice": "Take practice", "take_practice": "Take practice",
"your_current_level": "Your current level", "your_current_level": "Your current level",
"overall_progress": "Overall progress", "overall_progress": "Overall progress",
"great_work": "Keep up the great work! You're doing amazing", "great_work": "Keep up the great work! You're doing amazing",
"view_module": "View module", "view_module": "View module",
"progress": "Progress", "progress": "Progress",
"keep_going": "Let's keep going - you're more than half there", "keep_going": "Let's keep going - you're more than half there",
"lessons_in_module": "Lessons in this module", "lessons_in_module": "Lessons in this module",
"practice": "Practice", "practice": "Practice",
"start": "Start", "start": "Start",
"in_progress": "In Progress", "in_progress": "In Progress",
"hello": "Hello", "hello": "Hello",
"ready_to_learn": "Ready to keep learning English today", "ready_to_learn": "Ready to keep learning English today",
"learn": "Learn", "learn": "Learn",
"course": "Course", "course": "Course",
"profile": "Profile", "profile": "Profile",
"speaking_partner": "Speaking partner", "speaking_partner": "Speaking partner",
"practice_what_you_learned": "Let's practice what you just learnt", "practice_what_you_learned": "Let's practice what you just learnt",
"practice_questions": "I will ask you a few questions and you can respond", "practice_questions": "I will ask you a few questions and you can respond",
"start_practice": "Start practice", "start_practice": "Start practice",
"almost_there": "You're almost there", "almost_there": "You're almost there",
"finish_session": "Finish the session to see your progress", "finish_session": "Finish the session to see your progress",
"continue_practice": "Continue practice", "continue_practice": "Continue practice",
"end_session": "End session", "end_session": "End session",
"tap_start_to_listen": "Tap the start button to listen", "tap_start_to_listen": "Tap the start button to listen",
"practice_speaking": "Practice speaking", "practice_speaking": "Practice speaking",
"tap_microphone": "Tap the microphone to speak", "tap_microphone": "Tap the microphone to speak",
"reply": "Reply", "reply": "Reply",
"cancel": "Cancel", "cancel": "Cancel",
"you_are_speaking": "You're speaking", "you_are_speaking": "You're speaking",
"practice_completed": "Practice completed!", "practice_completed": "Practice completed!",
"great_improvement": "You sound more confident this time, great improvement", "great_improvement": "You sound more confident this time, great improvement",
"practice_again": "Practice again", "practice_again": "Practice again",
"conversation_review": "Conversation review", "conversation_review": "Conversation review",
"result": "Result", "result": "Result",
"quick_tip": "Quick tip", "quick_tip": "Quick tip",
"retry": "Retry", "retry": "Retry",
"completed_a1": "Yay, you've completed A1", "completed_a1": "Yay, you've completed A1",
"analyzing_speaking": "We're now analyzing your speaking skill", "analyzing_speaking": "We're now analyzing your speaking skill",
"view_profile": "View profile", "view_profile": "View profile",
"hi": "Hi", "hi": "Hi",
"edit_profile": "Edit profile", "edit_profile": "Edit profile",
"first_name": "First name", "first_name": "First name",
"last_name": "Last name", "last_name": "Last name",
"gender": "Gender", "gender": "Gender",
"male": "Male", "male": "Male",
"female": "Female", "female": "Female",
"phone_number": "Phone number", "phone_number": "Phone number",
"country": "Country", "country": "Country",
"region": "Region", "region": "Region",
"select_region": "Select region", "select_region": "Select region",
"enter_your_city": "Enter your city", "enter_your_city": "Enter your city",
"occupation": "Occupation", "occupation": "Occupation",
"select_occupation": "Select occupation", "select_occupation": "Select occupation",
"save_changes": "Save changes", "save_changes": "Save changes",
"my_progress": "My progress", "my_progress": "My progress",
"track_your_achievement": "Track your achievements and learning streak", "track_your_achievement": "Track your achievements and learning streak",
"account_and_privacy": "Account & Privacy", "account_and_privacy": "Account & Privacy",
"manage_settings": "Manage settings and app preference", "manage_settings": "Manage settings and app preference",
"support": "Support", "support": "Support",
"get_help": "Get help through phone or Telegram", "get_help": "Get help through phone or Telegram",
"logout": "Logout", "logout": "Logout",
"app_settings": "App settings", "app_settings": "App settings",
"legal_and_information": "Legal & Information", "legal_and_information": "Legal & Information",
"change_language": "Change language", "change_language": "Change language",
"terms_and_conditions": "Terms & Conditions", "terms_and_conditions":"Terms & Conditions",
"delete_account": "Delete account", "delete_account": "Delete account",
"language_preference": "Language preference", "language_preference": "Language preference",
"choose_your_language": "Choose your language", "choose_your_language": "Choose your language",
"switch_language_anytime": "You can switch languages anytime", "switch_language_anytime": "You can switch languages anytime",
"need_help": "Need help?", "need_help": "Need help?",
"call_support": "Call support", "call_support": "Call support",
"talk_with_support": "Talk with our support team directly", "talk_with_support": "Talk with our support team directly",
"telegram_support": "Telegram support", "telegram_support": "Telegram support",
"chat_via_telegram": "Chat instantly via Telegram", "chat_via_telegram" :"Chat instantly via Telegram",
"call_our_support": "Call our support team between 9 AM - 6 PM", "call_our_support": "Call our support team between 9 AM - 6 PM",
"tap_to_call": "Tap to call", "tap_to_call": "Tap to call",
"join_telegram": "Join Yimaru Academy on Telegram", "join_telegram": "Join Yimaru Academy on Telegram",
"connect_with_support_team": "Connect with our support team instantly on Telegram for quick assistance and community updates", "connect_with_support_team": "Connect with our support team instantly on Telegram for quick assistance and community updates",
"open_in_telegram": "Open in Telegram", "open_in_telegram": "Open in Telegram",
"search_for": "Search for", "search_for": "Search for",
"current_level": "Current Level", "current_level": "Current Level",
"keep_up_the_great_work": "Keep up the great work! You're doing amazing.", "keep_up_the_great_work": "Keep up the great work! You're doing amazing.",
"no_practice_available": "No practice available!", "no_practice_available": "No practice available!",
"begin_module_practice": "Begin Module Practice", "begin_module_practice": "Begin Module Practice",
"lets_practice_lesson": "Lets Practice", "lets_practice_lesson": "Lets Practice",
"lets_quickly_review": "Lets quickly review what youve learned in this module!", "lets_quickly_review": "Lets quickly review what youve learned in this module!",
"lets_practice_module": "Let's practice what you just learnt!", "lets_practice_module": "Let's practice what you just learnt!",
"ask_you_few_actions": "Ill ask you a few questions, and you can respond naturally.", "ask_you_few_actions": "Ill ask you a few questions, and you can respond naturally.",
"begin_level_practice": "Begin Level Practice", "begin_level_practice": "Begin Level Practice",
"lets_practice_course": "Lets Practice Course", "lets_practice_course": "Lets Practice Course",
"lets_quick_review": "Lets quickly review what youve learned in this level!", "lets_quick_review": "Lets quickly review what youve learned in this level!",
"speaking": "is speaking...", "speaking": "is speaking...",
"you_have_finished_practice": "You have finished your practice", "you_have_finished_practice": "You have finished your practice",
"view_results": "View My Results", "view_results": "View My Results",
"sample_answer": "Sample Answer", "sample_answer": "Sample Answer",
"your_answer": "Your Answer", "your_answer": "Your Answer",
"sound_confident": "You sound more confident this time - great improvement!", "sound_confident": "You sound more confident this time - great improvement!",
"you_have_completed": "Yay, youve completed", "you_have_completed": "Yay, youve completed",
"yes": "Yes", "yes": "Yes",
"no": "No", "no": "No",
"want_to_quit": "Are you sure you want to quit?", "want_to_quit": "Are you sure you want to quit?",
"required_field": "The field is required", "required_field": "The field is required",
"enter_full_name": "Enter your full name", "enter_full_name": "Enter your full name",
"invalid_email": "Invalid email format", "invalid_email": "Invalid email format",
"phone_must_start_with": "Phone number must start with 251", "phone_must_start_with": "Phone number must start with 251",
"phone_must_be": "Phone number must be 12 digits", "phone_must_be": "Phone number must be 12 digits",
"what_should_we_call_you": "What should we call you?", "what_should_we_call_you": "What should we call you?",
"name_for_personalization": "Well use your name to personalize your learning journey.", "name_for_personalization": "Well use your name to personalize your learning journey.",
"choose_your_gender": "Choose your gender?", "choose_your_gender": "Choose your gender?",
"gender_for_personalization": "Well personalize your learning experience based on your gender.", "gender_for_personalization": "Well personalize your learning experience based on your gender.",
"age_range": "Which age range are you in?", "age_range": "Which age range are you in?",
"age_for_personalization": "Well personalize your learning experience based on your age.", "age_for_personalization": "Well personalize your learning experience based on your age.",
"educational_background": "Whats your current educational level?", "educational_background": "Whats your current educational level?",
"education_for_personalization": "This helps us tailor your lessons to your experience.", "education_for_personalization": "This helps us tailor your lessons to your experience.",
"your_occupation": "Whats your occupation?", "your_occupation": "Whats your occupation?",
"occupation_for_personalization": "Well personalize your learning experience based on your occupation.", "occupation_for_personalization": "Well personalize your learning experience based on your occupation.",
"location": "Where are you from?", "location": "Where are you from?",
"select_country_region": "Select your country and region from the dropdown", "select_country_region": "Select your country and region from the dropdown",
"select_country": "Select country", "select_country": "Select country",
"learning_goal": "Choose your learning goal.", "learning_goal": "Choose your learning goal.",
"language_goal": "Whats your main goal for improving your English?", "language_goal": "Whats your main goal for improving your English?",
"your_goal": "Your goal helps us tailor your learning journey.", "your_goal": "Your goal helps us tailor your learning journey.",
"write_your_goal": "Write your goal…", "write_your_goal": "Write your goal…",
"challenge_you_face": "What challenge do you face most with English?", "challenge_you_face": "What challenge do you face most with English?",
"evey_one_has_strugle": "Everyone has struggles, lets start fixing yours", "evey_one_has_strugle": "Everyone has struggles, lets start fixing yours",
"write_your_challenge": "Write your challenge…", "write_your_challenge": "Write your challenge…",
"topic_interest": "Which topics interest you most?", "topic_interest": "Which topics interest you most?",
"favourite_topic": "Your favorite topics help us create fun, relatable lessons.", "favourite_topic": "Your favorite topics help us create fun, relatable lessons.",
"your_interest": "Write your interest…", "your_interest": "Write your interest…",
"want_quick_assessment": "Want a quick assessment to know your English level?", "want_quick_assessment": "Want a quick assessment to know your English level?",
"answer_quick_questions": "Answer a few quick questions to help us understand your English proficiency.", "answer_quick_questions": "Answer a few quick questions to help us understand your English proficiency.",
"skip": "Skip", "skip": "Skip",
"finish_level": "Finish Level", "finish_level": "Finish Level",
"likely_speaker": "Youre likely speaker of", "likely_speaker": "Youre likely speaker of",
"great_job": "Great Job! Heres your next step to keep improving.", "great_job": "Great Job! Heres your next step to keep improving.",
"lets_start_practice": "Let's start your practice", "lets_start_practice": "Let's start your practice",
"welcome_abroad": "Welcome aboard", "welcome_abroad": "Welcome aboard",
"ready_to_explore": "Youre ready to explore your personalized lessons.", "ready_to_explore": "Youre ready to explore your personalized lessons.",
"finish": "Finish", "finish": "Finish",
"finish_all_practice_lesson": "Finish the previous lesson practice to take this practice", "finish_all_practice_lesson": "Finish the previous lesson practice to take this practice",
"finish_all_practice_module": "Finish the lesson practices to take the Module Practice", "finish_all_practice_module": "Finish the lesson practices to take the Module Practice",
"finish_all_practice_course": "Finish the Module practices to take the Course practice", "finish_all_practice_course": "Finish the Module practices to take the Course practice",
"finish_all_practice_previouse_module": "Finish the previous Module practice to take this practice", "finish_all_practice_previouse_module": "Finish the previous Module practice to take this practice",
"finish_all_practice_previouse_course": "Finish the previous course practice to take this", "finish_all_practice_previouse_course": "Finish the previous course practice to take this"
"track_journey": "Track your learning journey and see your growth over time.",
"learn_english": "Learn English", }
"keep_momentum":"Great job! Keep the momentum.",
"completed_practices": "Completed Practices",
"total_practices": "Total Practices",
"progress_percentage": "Progress Percentage"
}

View File

@ -2,18 +2,13 @@ import 'package:stacked/stacked.dart';
import 'package:yimaru_app/app/app.locator.dart'; import 'package:yimaru_app/app/app.locator.dart';
import 'package:yimaru_app/models/user.dart'; import 'package:yimaru_app/models/user.dart';
import 'package:yimaru_app/services/secure_storage_service.dart'; import 'package:yimaru_app/services/secure_storage_service.dart';
import 'package:yimaru_app/ui/common/enmus.dart';
import 'google_auth_service.dart';
import 'localization_service.dart'; import 'localization_service.dart';
class AuthenticationService with ListenableServiceMixin { class AuthenticationService with ListenableServiceMixin {
// Dependency injection // Dependency injection
final _secureService = locator<SecureStorageService>(); final _secureService = locator<SecureStorageService>();
final _googleAuthService = locator<GoogleAuthService>();
final _localizationService = locator<LocalizationService>(); final _localizationService = locator<LocalizationService>();
// User data // User data
@ -23,15 +18,9 @@ class AuthenticationService with ListenableServiceMixin {
// Initialization // Initialization
AuthenticationService() { AuthenticationService() {
listenToReactiveValues([_user,_state, _localizationService]); listenToReactiveValues([_user, _localizationService]);
} }
// Logout state
StateObjects _state = StateObjects.none;
StateObjects get state => _state;
// Check user logged in // Check user logged in
Future<bool> userLoggedIn() async { Future<bool> userLoggedIn() async {
if (await _secureService.getString('userId') != null) { if (await _secureService.getString('userId') != null) {
@ -190,20 +179,13 @@ class AuthenticationService with ListenableServiceMixin {
// Logout // Logout
Future<void> logout() async { Future<void> logout() async {
_state = StateObjects.logout;
notifyListeners();
bool firstTimeInstall = await isFirstTimeInstall(); bool firstTimeInstall = await isFirstTimeInstall();
String language = await _localizationService.selectedLanguage['code']; String language = await _localizationService.selectedLanguage['code'];
_user = null; _user = null;
await _secureService.clear(); await _secureService.clear();
await _googleAuthService.logout();
await setFirstTimeInstall(firstTimeInstall); await setFirstTimeInstall(firstTimeInstall);
await _secureService.setString('language', language); await _secureService.setString('language', language);
_state = StateObjects.none;
notifyListeners(); notifyListeners();
} }
} }

View File

@ -19,6 +19,7 @@ class GoogleAuthService with ListenableServiceMixin {
Future<void> logout() async { Future<void> logout() async {
await _signIn.signOut(); await _signIn.signOut();
_googleUser = null; _googleUser = null;
notifyListeners();
} }
// Google authentication // Google authentication
@ -29,7 +30,10 @@ class GoogleAuthService with ListenableServiceMixin {
_googleUser ??= _googleUser ??=
await _signIn.authenticate(scopeHint: ['email', 'profile']); await _signIn.authenticate(scopeHint: ['email', 'profile']);
print('GOOGLE AUTH');
print(_googleUser?.email);
print(_googleUser?.displayName);
print(_googleUser?.authentication.idToken);
}); });
notifyListeners(); notifyListeners();
} catch (e) { } catch (e) {

View File

@ -5,53 +5,39 @@ import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import '../app/app.locator.dart'; import '../app/app.locator.dart';
import '../models/refresh_object.dart'; import '../ui/common/app_constants.dart';
import '../ui/common/enmus.dart';
import 'api_service.dart';
import 'dio_service.dart'; import 'dio_service.dart';
class ImageDownloaderService { class ImageDownloaderService {
// Dependency injection // Dependency injection
final _service = locator<DioService>(); final _service = locator<DioService>();
final _apiService = locator<ApiService>();
final Dio _dio = Dio();
// Image downloader // Image downloader
Future<String?> downloader(String? networkImage) async { Future<String> downloader(String? networkImage) async {
try { late File image;
File? image;
String? profileImage = networkImage; late String profileImage;
final Directory appDir = await getApplicationDocumentsDirectory(); final Directory appDir = await getApplicationDocumentsDirectory();
Map<String, dynamic> data = {'reference': profileImage}; if (networkImage != null) {
Map<String, dynamic> response = await _apiService.refreshObject(data); profileImage = networkImage.contains('https://lh3.googleusercontent.com')
? networkImage
if (response['status'] == ResponseStatus.success) { : '$kBaseUrl$networkImage';
RefreshObject object = response['data'] as RefreshObject;
profileImage = object.url;
}
if (profileImage != null) {
final Response profileImageResponse = await _dio.get<List<int>>(
profileImage,
options: Options(
responseType: ResponseType.bytes,
),
);
final localImagePath = join(appDir.path, 'profile.jpg');
image = File(localImagePath);
image.writeAsBytes(profileImageResponse.data);
return image.path;
}
return null;
} catch (e) {
return null;
} }
final Response profileImageResponse = await _service.dio.get(
profileImage,
options: Options(
followRedirects: false,
responseType: ResponseType.bytes,
),
);
final imageName = basename(networkImage ?? '');
final localImagePath = join(appDir.path, imageName);
image = File(localImagePath);
image.writeAsBytes(profileImageResponse.data);
return image.path;
} }
} }

View File

@ -1,6 +1,4 @@
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
import 'package:yimaru_app/models/course_progress.dart';
import 'package:yimaru_app/models/module_progress.dart';
import 'package:yimaru_app/models/refresh_object.dart'; import 'package:yimaru_app/models/refresh_object.dart';
import 'package:yimaru_app/ui/common/enmus.dart'; import 'package:yimaru_app/ui/common/enmus.dart';
@ -19,25 +17,9 @@ class LearnService with ListenableServiceMixin {
// Initialization // Initialization
learnService() { learnService() {
listenToReactiveValues( listenToReactiveValues([_programs, _courses, _lessons, _modules]);
[_programs, _courses, _lessons, _modules, _totalCount]);
} }
// Completed count
int _completedCount = 0;
int get completedCount => _completedCount;
// Total count
int _totalCount = 0;
int get totalCount => _totalCount;
// Total progress
int _totalProgress = 0;
int get totalProgress => _totalProgress;
// Learn program // Learn program
List<LearnProgram> _programs = []; List<LearnProgram> _programs = [];
@ -58,7 +40,10 @@ class LearnService with ListenableServiceMixin {
List<LearnLesson> get lessons => _lessons; List<LearnLesson> get lessons => _lessons;
// Learn progress
final List<ProgressSummary> _summaries = [];
List<ProgressSummary> get summaries => _summaries;
// Learn programs // Learn programs
Future<String?> refreshObject(String url) async { Future<String?> refreshObject(String url) async {
@ -102,7 +87,7 @@ class LearnService with ListenableServiceMixin {
} }
// Learn progress // Learn progress
Future<void> getLearnProgress() async { Future<void> getLearnProgressSummary() async {
final summaries = await _apiService.getProgressSummary(); final summaries = await _apiService.getProgressSummary();
/// PROGRAM ACCESS MAP /// PROGRAM ACCESS MAP
@ -163,6 +148,10 @@ class LearnService with ListenableServiceMixin {
); );
}).toList(); }).toList();
print(
'MY SUMMARIES - COMPLETED COUNT: ${_modules.first.access?.completedCount}');
print('PROGRESS PERCENT: ${_modules.first.access?.progressPercent}');
/// UPDATE LESSONS /// UPDATE LESSONS
_lessons = _lessons.map((lesson) { _lessons = _lessons.map((lesson) {
return lesson.copyWith( return lesson.copyWith(
@ -188,30 +177,4 @@ class LearnService with ListenableServiceMixin {
return null; return null;
} }
} }
Future<void> getProgressSummary() async {
final summaries = await _apiService.getProgressSummary();
for (final ProgressSummary summary in summaries) {
_totalCount = _totalCount + (summary.access?.totalCount ?? 0);
_completedCount = _completedCount + (summary.access?.completedCount ?? 0);
for (final CourseProgress course in summary.courses ?? []) {
_totalCount = _totalCount + (course.access?.totalCount ?? 0);
_completedCount =
_completedCount + (course.access?.completedCount ?? 0);
for (final ModuleProgress module in course.modules ?? []) {
_totalCount = _totalCount + (module.access?.totalCount ?? 0);
_completedCount =
_completedCount + (module.access?.completedCount ?? 0);
}
}
}
_totalProgress = summaries.fold(
0, (sum, progress) => sum + (progress.access?.progressPercent ?? 0));
notifyListeners();
}
} }

View File

@ -122,7 +122,7 @@ String kTelegramSupport = '@yimaruacademy2026';
String kTelegramSupportLink = 'https://t.me/yimaruacademy2026'; String kTelegramSupportLink = 'https://t.me/yimaruacademy2026';
String kErrorUrl = 'https://api.yimaruacademy.com/payment/error'; String kErrorUrl = 'https://yimaru.net/api/v1/payments/chapa/error';
String kSuccessUrl = String kSuccessUrl =
'https://api.yimaruacademy.com/payment/success'; 'https://api.yimaruacademy.com/api/v1/payments/chapa/success';

View File

@ -31,7 +31,6 @@ enum PracticeReason { course, module, lesson, previousModule, previousCourse }
// State object // State object
enum StateObjects { enum StateObjects {
none, none,
logout,
courses, courses,
register, register,
verifyOtp, verifyOtp,
@ -56,7 +55,6 @@ enum StateObjects {
loginWithGoogle, loginWithGoogle,
loadLessonVideo, loadLessonVideo,
loadCourseVideo, loadCourseVideo,
progressSummary,
requestResetCode, requestResetCode,
profileCompletion, profileCompletion,
learnSubscription, learnSubscription,

View File

@ -6,7 +6,7 @@ import 'dart:ui';
import 'package:easy_localization/easy_localization.dart' show AssetLoader; import 'package:easy_localization/easy_localization.dart' show AssetLoader;
class CodegenLoader extends AssetLoader{ class CodegenLoader extends AssetLoader {
const CodegenLoader(); const CodegenLoader();
@override @override
@ -14,399 +14,416 @@ class CodegenLoader extends AssetLoader{
return Future.value(mapLocales[locale.toString()]); return Future.value(mapLocales[locale.toString()]);
} }
static const Map<String,dynamic> _am = { static const Map<String, dynamic> _am = {
"loading": "በመጫን ላይ", "loading": "በመጫን ላይ",
"welcome_back": "እንኳን በደህና ተመለሱ", "welcome_back": "እንኳን በደህና ተመለሱ",
"checking_user_info": "የተጠቃሚ መረጃን በማረጋገጥ ላይ", "checking_user_info": "የተጠቃሚ መረጃን በማረጋገጥ ላይ",
"dont_have_account": "መለያ የለዎትም?", "dont_have_account": "መለያ የለዎትም?",
"email": "ኢሜይል", "email": "ኢሜይል",
"password": "የይለፍ ቃል", "password": "የይለፍ ቃል",
"forgot_password": "የይለፍ ቃል ረሱ?", "forgot_password": "የይለፍ ቃል ረሱ?",
"cont": "ቀጥል", "cont": "ቀጥል",
"register": "ይመዝገቡ", "register": "ይመዝገቡ",
"login_with_google": "በጉግል ይግቡ", "login_with_google": "በጉግል ይግቡ",
"or": "ወይም", "or": "ወይም",
"login_with_phone": "በስልክ ቁጥር ይግቡ", "login_with_phone": "በስልክ ቁጥር ይግቡ",
"create_account": "አዲስ መለያ ይፍጠሩ", "create_account": "አዲስ መለያ ይፍጠሩ",
"already_have_account": "መለያ አለዎት?", "already_have_account": "መለያ አለዎት?",
"login": " ይግቡ ", "login": " ይግቡ ",
"register_with_google": "በጉግል ይመዝገቡ", "register_with_google": "በጉግል ይመዝገቡ",
"register_with_phone": "በስልክ ቁጥር ይመዝገቡ", "register_with_phone": "በስልክ ቁጥር ይመዝገቡ",
"enter_phone_number": "የስልክ ቁጥርዎን ያስገቡ። የማረጋገጫ ኮድ እንልክልዎታለን።", "enter_phone_number": "የስልክ ቁጥርዎን ያስገቡ። የማረጋገጫ ኮድ እንልክልዎታለን።",
"login_with_email": "በኢሜይል ይግቡ", "login_with_email": "በኢሜይል ይግቡ",
"create_password": "የይለፍ ቃል ይፍጠሩ", "create_password": "የይለፍ ቃል ይፍጠሩ",
"confirm_password": "የይለፍ ቃል ያረጋግጡ", "confirm_password": "የይለፍ ቃል ያረጋግጡ",
"eight_character_minimum": "ቢያንስ 8 ፊደላት", "eight_character_minimum": "ቢያንስ 8 ፊደላት",
"password_match": "የይለፍ ቃሉ ተመሳስሏል", "password_match": "የይለፍ ቃሉ ተመሳስሏል",
"sign_up_agreement": "‘ይመዝገቡ’ የሚለውን ሲጫኑ በ‘አገልግሎት ውሎች’ እና ‘በግላዊነት ፖሊሲ’ ይስማማሉ።", "sign_up_agreement":
"terms_of_services": "የአገልግሎት ውሎች", "‘ይመዝገቡ’ የሚለውን ሲጫኑ በ‘አገልግሎት ውሎች’ እና ‘በግላዊነት ፖሊሲ’ ይስማማሉ።",
"and": "እና", "terms_of_services": "የአገልግሎት ውሎች",
"privacy_policy": "የግላዊነት ፖሊሲ", "and": "እና",
"register_with_email": "በኢሜል ይመዝገቡ", "privacy_policy": "የግላዊነት ፖሊሲ",
"verification_code": "የማረጋገጫ ኮድ", "register_with_email": "በኢሜል ይመዝገቡ",
"resend_code": "ኮዱን እንደገና ላክ", "verification_code": "የማረጋገጫ ኮድ",
"code_sent_to_phone": "ኮዱ ወደ ስልክ ቁጥርዎ ተልኳል", "resend_code": "ኮዱን እንደገና ላክ",
"code_sent_to_email": "ኮዱ ወደ ኢሜል ተልኳል", "code_sent_to_phone": "ኮዱ ወደ ስልክ ቁጥርዎ ተልኳል",
"resend_code_in": "ኮዱን እንደገና ለመላክ የቀረው ጊዜ", "code_sent_to_email": "ኮዱ ወደ ኢሜል ተልኳል",
"reset_password": " የይለፍ ቃልን ይቀይሩ", "resend_code_in": "ኮዱን እንደገና ለመላክ የቀረው ጊዜ",
"enter_email_reset_code": "ኢሜይልዎን ያስገቡ። የይለፍ ቃል መለወጫ ኮድ እንልክልዎታለን።", "reset_password": " የይለፍ ቃልን ይቀይሩ",
"please_wait": "እባክዎ ይጠብቁ", "enter_email_reset_code": "ኢሜይልዎን ያስገቡ። የይለፍ ቃል መለወጫ ኮድ እንልክልዎታለን።",
"reset_code_sent": "የመቀየሪያ ኮድ በተሳካ ሁኔታ ተልኳል", "please_wait": "እባክዎ ይጠብቁ",
"reset_code": " የመቀየሪያ ኮድ ", "reset_code_sent": "የመቀየሪያ ኮድ በተሳካ ሁኔታ ተልኳል",
"new_password": "አዲስ የይለፍ ቃል", "reset_code": " የመቀየሪያ ኮድ ",
"logged_in_successfully": "በተሳካ ሁኔታ ገብተዋል", "new_password": "አዲስ የይለፍ ቃል",
"view_course": " ኮርሱን ይመልከቱ", "logged_in_successfully": "በተሳካ ሁኔታ ገብተዋል",
"continue_learning": "መማርን ይቀጥሉ", "view_course": " ኮርሱን ይመልከቱ",
"start_learning": "ትምህርትን ይጀምሩ", "continue_learning": "መማርን ይቀጥሉ",
"completed": "ተጠናቋል", "start_learning": "ትምህርትን ይጀምሩ",
"take_practice": "ልምምድ ያድርጉ", "completed": "ተጠናቋል",
"your_current_level": "የአሁኑ ደረጃዎ", "take_practice": "ልምምድ ያድርጉ",
"overall_progress": "አጠቃላይ እድገት", "your_current_level": "የአሁኑ ደረጃዎ",
"great_work": "በርቱ! በጣም ጥሩ እየሰሩ ነው", "overall_progress": "አጠቃላይ እድገት",
"view_module": "ሞጁሉን ይመልከቱ", "great_work": "በርቱ! በጣም ጥሩ እየሰሩ ነው",
"progress": "እድገት", "view_module": "ሞጁሉን ይመልከቱ",
"keep_going": "ይቀጥሉ - ከግማሽ በላይ ጨርሰዋል ", "progress": "እድገት",
"lessons_in_module": "በዚህ ሞጁል ውስጥ ያሉ ትምህርቶች ", "keep_going": "ይቀጥሉ - ከግማሽ በላይ ጨርሰዋል ",
"practice": "ልምምድ", "lessons_in_module": "በዚህ ሞጁል ውስጥ ያሉ ትምህርቶች ",
"start": "ጀምር", "practice": "ልምምድ",
"in_progress": "በሂደት ላይ", "start": "ጀምር",
"hello": "ሰላም", "in_progress": "በሂደት ላይ",
"ready_to_learn": " ዛሬ እንግሊዝኛ ለመማር ተዘጋጅተዋል? ", "hello": "ሰላም",
"learn": "ይማሩ ", "ready_to_learn": " ዛሬ እንግሊዝኛ ለመማር ተዘጋጅተዋል? ",
"course": "ኮርስ", "learn": "ይማሩ ",
"profile": " ፕሮፋይል ", "course": "ኮርስ",
"speaking_partner": "የንግግር ጓደኛ", "profile": " ፕሮፋይል ",
"practice_what_you_learned": "አሁን የተማሩትን እንለማመድ", "speaking_partner": "የንግግር ጓደኛ",
"practice_questions": "ጥቂት ጥያቄዎችን እጠይቃለሁ እና መልስ መስጠት ይችላሉ", "practice_what_you_learned": "አሁን የተማሩትን እንለማመድ",
"start_practice": "ልምምድ ጀምር", "practice_questions": "ጥቂት ጥያቄዎችን እጠይቃለሁ እና መልስ መስጠት ይችላሉ",
"almost_there": "ሊጨርሱ ተቃርበዋል", "start_practice": "ልምምድ ጀምር",
"finish_session": "እድገትዎን ለማየት ክፍለ ጊዜውን ያጠናቅቁ", "almost_there": "ሊጨርሱ ተቃርበዋል",
"continue_practice": "ልምምዱን ይቀጥሉ", "finish_session": "እድገትዎን ለማየት ክፍለ ጊዜውን ያጠናቅቁ",
"end_session": "ክፍለ ጊዜውን ያብቁ ", "continue_practice": "ልምምዱን ይቀጥሉ",
"tap_start_to_listen": "ለማዳመጥ የጀምር ቁልፉን ይጫኑ", "end_session": "ክፍለ ጊዜውን ያብቁ ",
"practice_speaking": "ንግግርን ይለማመዱ", "tap_start_to_listen": "ለማዳመጥ የጀምር ቁልፉን ይጫኑ",
"tap_microphone": "ለመናገር ማይክሮፎኑን ይጫኑ", "practice_speaking": "ንግግርን ይለማመዱ",
"reply": "እንደገና አዳምጥ", "tap_microphone": "ለመናገር ማይክሮፎኑን ይጫኑ",
"cancel": "ይቅር", "reply": "እንደገና አዳምጥ",
"you_are_speaking": "እየተናገሩ ነው", "cancel": "ይቅር",
"practice_completed": "ልምምዱ ተጠናቅቋል", "you_are_speaking": "እየተናገሩ ነው",
"great_improvement": "በዚህኛው በራስ መተማመንዎ ጨምሯል፤ ትልቅ መሻሻል ነው", "practice_completed": "ልምምዱ ተጠናቅቋል",
"practice_again": "እንደገና ይለማመዱ", "great_improvement": "በዚህኛው በራስ መተማመንዎ ጨምሯል፤ ትልቅ መሻሻል ነው",
"conversation_review": "የንግግር ግምገማ", "practice_again": "እንደገና ይለማመዱ",
"result": "ውጤት", "conversation_review": "የንግግር ግምገማ",
"quick_tip": "ጠቃሚ ምክር", "result": "ውጤት",
"retry": "እንደገና ይሞክሩ", "quick_tip": "ጠቃሚ ምክር",
"completed_a1": "እንኳን ደስ አለዎት! A1 ደረጃን አጠናቅቀዋል", "retry": "እንደገና ይሞክሩ",
"analyzing_speaking": "የንግግር ችሎታዎን እየገመገምን ነው", "completed_a1": "እንኳን ደስ አለዎት! A1 ደረጃን አጠናቅቀዋል",
"view_profile": "ፕሮፋይሎን ይመልከቱ ", "analyzing_speaking": "የንግግር ችሎታዎን እየገመገምን ነው",
"hi": "ሰላም", "view_profile": "ፕሮፋይሎን ይመልከቱ ",
"edit_profile": "መገለጫ ያስተካክሉ", "hi": "ሰላም",
"first_name": "የመጀመሪያ ስም", "edit_profile": "መገለጫ ያስተካክሉ",
"last_name": "የአባት ስም", "first_name": "የመጀመሪያ ስም",
"gender": "ፆታ", "last_name": "የአባት ስም",
"male": "ወንድ", "gender": "ፆታ",
"female": "ሴት", "male": "ወንድ",
"phone_number": "የስልክ ቁጥር", "female": "ሴት",
"country": "ሀገር", "phone_number": "የስልክ ቁጥር",
"region": "ክልል", "country": "ሀገር",
"select_region": "ክልል ይምረጡ", "region": "ክልል",
"enter_your_city": "ከተማዎን ያስገቡ", "select_region": "ክልል ይምረጡ",
"occupation": "የስራ መስክ", "enter_your_city": "ከተማዎን ያስገቡ",
"select_occupation": "ሙያዎን ይምረጡ", "occupation": "የስራ መስክ",
"save_changes": "ለውጦችን ያስቀምጡ", "select_occupation": "ሙያዎን ይምረጡ",
"my_progress": "የእኔ እድገት", "save_changes": "ለውጦችን ያስቀምጡ",
"track_your_achievement": "ስኬቶችዎን እና ተከታታይ የትምህርት ጉዞዎን ይከታተሉ", "my_progress": "የእኔ እድገት",
"account_and_privacy": "መለያ እና ግላዊነት", "track_your_achievement": "ስኬቶችዎን እና ተከታታይ የትምህርት ጉዞዎን ይከታተሉ",
"manage_settings": "ቅንብሮችን እና የመተግበሪያ ምርጫዎችን ያስተዳድሩ", "account_and_privacy": "መለያ እና ግላዊነት",
"support": "ድጋፍ", "manage_settings": "ቅንብሮችን እና የመተግበሪያ ምርጫዎችን ያስተዳድሩ",
"get_help": "በስልክ ወይም በቴሌግራም እገዛ ያግኙ", "support": "ድጋፍ",
"logout": "ውጣ", "get_help": "በስልክ ወይም በቴሌግራም እገዛ ያግኙ",
"app_settings": "የመተግበሪያ ቅንብሮች", "logout": "ውጣ",
"legal_and_information": "ሕጋዊ እና መረጃ", "app_settings": "የመተግበሪያ ቅንብሮች",
"change_language": "ቋንቋ ቀይር", "legal_and_information": "ሕጋዊ እና መረጃ",
"terms_and_conditions": "ውሎች እና ሁኔታዎች", "change_language": "ቋንቋ ቀይር",
"delete_account": "መለያ ሰርዝ", "terms_and_conditions": "ውሎች እና ሁኔታዎች",
"language_preference": "የቋንቋ ምርጫ", "delete_account": "መለያ ሰርዝ",
"choose_your_language": "ለውጦችን አስቀምጥ", "language_preference": "የቋንቋ ምርጫ",
"switch_language_anytime": "ቋንቋዎችን በማንኛውም ጊዜ መቀየር ይችላሉ", "choose_your_language": "ለውጦችን አስቀምጥ",
"need_help": "እገዛ ይፈልጋሉ?", "switch_language_anytime": "ቋንቋዎችን በማንኛውም ጊዜ መቀየር ይችላሉ",
"call_support": "የስልክ ድጋፍ", "need_help": "እገዛ ይፈልጋሉ?",
"talk_with_support": "በቀጥታ ከድጋፍ ቡድናችን ጋር ይነጋገሩ", "call_support": "የስልክ ድጋፍ",
"telegram_support": "የቴሌግራም ድጋፍ", "talk_with_support": "በቀጥታ ከድጋፍ ቡድናችን ጋር ይነጋገሩ",
"chat_via_telegram": "በቴሌግራም በፍጥነት ይወያዩ", "telegram_support": "የቴሌግራም ድጋፍ",
"call_our_support": "ከ3 ጠዋት እስከ 12 ማታ ድረስ የድጋፍ ቡድናችንን ይደውሉ", "chat_via_telegram": "በቴሌግራም በፍጥነት ይወያዩ",
"tap_to_call": "ለመደወል ይንኩ", "call_our_support": "ከ3 ጠዋት እስከ 12 ማታ ድረስ የድጋፍ ቡድናችንን ይደውሉ",
"join_telegram": "በቴሌግራም የይማሩ አካዳሚን ይቀላቀሉ", "tap_to_call": "ለመደወል ይንኩ",
"connect_with_support_team": "ለፈጣን እርዳታ እና የማህበረሰብ ዝማኔዎች፣ በቴሌግራም ከድጋፍ ቡድናችን ጋር ወዲያውኑ ይገናኙ።", "join_telegram": "በቴሌግራም የይማሩ አካዳሚን ይቀላቀሉ",
"open_in_telegram": "በቴሌግራም ይክፈቱ", "connect_with_support_team":
"search_for": "ፈልጉት", "ለፈጣን እርዳታ እና የማህበረሰብ ዝማኔዎች፣ በቴሌግራም ከድጋፍ ቡድናችን ጋር ወዲያውኑ ይገናኙ።",
"current_level": "የአሁኑ ደረጃ", "open_in_telegram": "በቴሌግራም ይክፈቱ",
"keep_up_the_great_work": "በጣም ጥሩ እየሰራህ ነው! ቀጥልበት፣ አስደናቂ ነህ።", "search_for": "ፈልጉት",
"no_practice_available": "ምንም ልምምድ አልተገኘም!", "current_level": "የአሁኑ ደረጃ",
"begin_module_practice": "የሞጁሉን ልምምድ ጀምር", "keep_up_the_great_work": "በጣም ጥሩ እየሰራህ ነው! ቀጥልበት፣ አስደናቂ ነህ።",
"lets_practice_lesson": "እንለማመድ", "no_practice_available": "ምንም ልምምድ አልተገኘም!",
"lets_quickly_review": "በዚህ ሞጁል ውስጥ የተማርከውን በፍጥነት እንከልስ!", "begin_module_practice": "የሞጁሉን ልምምድ ጀምር",
"lets_practice_module": "አሁን የተማርከውን እንለማመድ!", "lets_practice_lesson": "እንለማመድ",
"ask_you_few_actions": "ጥቂት ጥያቄዎችን እጠይቅሃለሁ፣ አንተም በተፈጥሮ መልስ ልትሰጥ ትችላለህ።", "lets_quickly_review": "በዚህ ሞጁል ውስጥ የተማርከውን በፍጥነት እንከልስ!",
"begin_level_practice": "የደረጃ ልምምድን ጀምር", "lets_practice_module": "አሁን የተማርከውን እንለማመድ!",
"lets_practice_course": "የኮርሱን ልምምድ እንለማመድ", "ask_you_few_actions": "ጥቂት ጥያቄዎችን እጠይቅሃለሁ፣ አንተም በተፈጥሮ መልስ ልትሰጥ ትችላለህ።",
"lets_quick_review": "በዚህ ደረጃ የተማርከውን በፍጥነት እንከልስ!", "begin_level_practice": "የደረጃ ልምምድን ጀምር",
"speaking": "እየተናገረ ነው", "lets_practice_course": "የኮርሱን ልምምድ እንለማመድ",
"you_have_finished_practice": "ልምምድህን አጠናቀቅህ", "lets_quick_review": "በዚህ ደረጃ የተማርከውን በፍጥነት እንከልስ!",
"view_results": "ውጤቶቼን እይ", "speaking": "እየተናገረ ነው",
"sample_answer": "ናሙና መልስ", "you_have_finished_practice": "ልምምድህን አጠናቀቅህ",
"your_answer": "መልስህ", "view_results": "ውጤቶቼን እይ",
"sound_confident": "በዚህ ጊዜ የበለጠ እምነት ያለህ ይመስላል — በጣም ጥሩ መሻሻል ነው!", "sample_answer": "ናሙና መልስ",
"you_have_completed": "አያይ! አጠናቀቅህ", "your_answer": "መልስህ",
"yes": "አዎ", "sound_confident": "በዚህ ጊዜ የበለጠ እምነት ያለህ ይመስላል — በጣም ጥሩ መሻሻል ነው!",
"no": "አይ", "you_have_completed": "አያይ! አጠናቀቅህ",
"want_to_quit": "ለመውጣት እርግጠኛ ነህ?", "yes": "አዎ",
"required_field": "ይህ መስክ ያስፈልጋል", "no": "አይ",
"enter_full_name": "ሙሉ ስምህን አስገባ", "want_to_quit": "ለመውጣት እርግጠኛ ነህ?",
"invalid_email": "የማይሰራ የኢሜይል ቅርጸት", "required_field": "ይህ መስክ ያስፈልጋል",
"phone_must_start_with": "የስልክ ቁጥር በ251 መጀመር አለበት", "enter_full_name": "ሙሉ ስምህን አስገባ",
"phone_must_be": "የስልክ ቁጥር 12 አሃዞች መሆን አለበት", "invalid_email": "የማይሰራ የኢሜይል ቅርጸት",
"what_should_we_call_you": "ምን ብለን እንጠራህ?", "phone_must_start_with": "የስልክ ቁጥር በ251 መጀመር አለበት",
"name_for_personalization": "በመማር ጉዞህ ውስጥ ለግል ለማድረግ ስምህን እንጠቀማለን።", "phone_must_be": "የስልክ ቁጥር 12 አሃዞች መሆን አለበት",
"choose_your_gender": "ጾታህን ምረጥ", "what_should_we_call_you": "ምን ብለን እንጠራህ?",
"gender_for_personalization": "በጾታህ መሰረት የመማር ተሞክሮህን እናበጅለታለን።", "name_for_personalization": "በመማር ጉዞህ ውስጥ ለግል ለማድረግ ስምህን እንጠቀማለን።",
"age_range": "በየትኛው የእድሜ ክልል ውስጥ ነህ?", "choose_your_gender": "ጾታህን ምረጥ",
"age_for_personalization": "በእድሜህ መሰረት የመማር ተሞክሮህን እናበጅለታለን።", "gender_for_personalization": "በጾታህ መሰረት የመማር ተሞክሮህን እናበጅለታለን።",
"educational_background": "አሁን ያለህ የትምህርት ደረጃ ምንድን ነው?", "age_range": "በየትኛው የእድሜ ክልል ውስጥ ነህ?",
"education_for_personalization": "ይህ ትምህርቶችን ከልምድህ ጋር እንዲስማሙ ለማድረግ ይረዳናል።", "age_for_personalization": "በእድሜህ መሰረት የመማር ተሞክሮህን እናበጅለታለን።",
"your_occupation": "ስራህ ምንድን ነው?", "educational_background": "አሁን ያለህ የትምህርት ደረጃ ምንድን ነው?",
"occupation_for_personalization": "በስራህ መሰረት የመማር ተሞክሮህን እናበጅለታለን።", "education_for_personalization": "ይህ ትምህርቶችን ከልምድህ ጋር እንዲስማሙ ለማድረግ ይረዳናል።",
"location": "ከየት ነህ?", "your_occupation": "ስራህ ምንድን ነው?",
"select_country_region": "አገርህን እና ክልልህን ከተቆልቋይ ዝርዝሩ ምረጥ", "occupation_for_personalization": "በስራህ መሰረት የመማር ተሞክሮህን እናበጅለታለን።",
"select_country": "አገር ምረጥ", "location": "ከየት ነህ?",
"learning_goal": "የመማር ዓላማህን ምረጥ", "select_country_region": "አገርህን እና ክልልህን ከተቆልቋይ ዝርዝሩ ምረጥ",
"language_goal": "እንግሊዝኛህን ለማሻሻል ዋና ዓላማህ ምንድን ነው?", "select_country": "አገር ምረጥ",
"your_goal": "ዓላማህ የመማር ጉዞህን እንዲስማማ ለማድረግ ይረዳናል።", "learning_goal": "የመማር ዓላማህን ምረጥ",
"write_your_goal": "ዓላማህን ጻፍ…", "language_goal": "እንግሊዝኛህን ለማሻሻል ዋና ዓላማህ ምንድን ነው?",
"challenge_you_face": "What challenge do you face most with English?", "your_goal": "ዓላማህ የመማር ጉዞህን እንዲስማማ ለማድረግ ይረዳናል።",
"evey_one_has_strugle": "ሁሉም ሰው ችግሮች አሉት፣ የአንተን እንጀምር እንፍታ", "write_your_goal": "ዓላማህን ጻፍ…",
"write_your_challenge": "ችግርህን ጻፍ…", "challenge_you_face": "What challenge do you face most with English?",
"topic_interest": "በጣም የሚስቡህ ርዕሶች የትኞቹ ናቸው?", "evey_one_has_strugle": "ሁሉም ሰው ችግሮች አሉት፣ የአንተን እንጀምር እንፍታ",
"favourite_topic": "የምትወዳቸው ርዕሶች አስደሳች እና ከሕይወትህ ጋር የተዛመዱ ትምህርቶችን ለመፍጠር ይረዱናል።", "write_your_challenge": "ችግርህን ጻፍ…",
"your_interest": "ፍላጎትህን ጻፍ…", "topic_interest": "በጣም የሚስቡህ ርዕሶች የትኞቹ ናቸው?",
"want_quick_assessment": "የእንግሊዝኛ ደረጃህን ለማወቅ ፈጣን ግምገማ ትፈልጋለህ?", "favourite_topic":
"answer_quick_questions": "የእንግሊዝኛ ችሎታህን ለመረዳት ጥቂት ፈጣን ጥያቄዎችን መልስ።", "የምትወዳቸው ርዕሶች አስደሳች እና ከሕይወትህ ጋር የተዛመዱ ትምህርቶችን ለመፍጠር ይረዱናል።",
"skip": "ዝለል", "your_interest": "ፍላጎትህን ጻፍ…",
"finish_level": "ደረጃውን አጠናቅቅ", "want_quick_assessment": "የእንግሊዝኛ ደረጃህን ለማወቅ ፈጣን ግምገማ ትፈልጋለህ?",
"likely_speaker": "አንተ ምናልባት ተናጋሪ ነህ", "answer_quick_questions": "የእንግሊዝኛ ችሎታህን ለመረዳት ጥቂት ፈጣን ጥያቄዎችን መልስ።",
"great_job": "በጣም ጥሩ ስራ! ለመሻሻል ቀጣዩ ደረጃህ ይኸው ነው።", "skip": "ዝለል",
"lets_start_practice": "ልምምድህን እንጀምር", "finish_level": "ደረጃውን አጠናቅቅ",
"welcome_abroad": "እንኳን ደህና መጣህ", "likely_speaker": "አንተ ምናልባት ተናጋሪ ነህ",
"ready_to_explore": "የግል ትምህርቶችህን ለማሰስ ዝግጁ ነህ።", "great_job": "በጣም ጥሩ ስራ! ለመሻሻል ቀጣዩ ደረጃህ ይኸው ነው።",
"finish": "አጠናቅቅ", "lets_start_practice": "ልምምድህን እንጀምር",
"finish_all_practice_lesson": "ይህን ልምምድ ለመውሰድ የቀድሞውን የትምህርት ልምምድ ያጠናቅቁ", "welcome_abroad": "እንኳን ደህና መጣህ",
"finish_all_practice_module": "የሞጁሉን ልምምድ ለመውሰድ የትምህርት ልምምዶችን ያጠናቅቁ", "ready_to_explore": "የግል ትምህርቶችህን ለማሰስ ዝግጁ ነህ።",
"finish_all_practice_course": "የኮርሱን ልምምድ ለመውሰድ የሞጁል ልምምዶችን ያጠናቅቁ", "finish": "አጠናቅቅ",
"finish_all_practice_previouse_module": "ይህን ልምምድ ለመውሰድ የቀድሞውን የሞጁል ልምምድ ያጠናቅቁ", "finish_all_practice_lesson": "ይህን ልምምድ ለመውሰድ የቀድሞውን የትምህርት ልምምድ ያጠናቅቁ",
"finish_all_practice_previouse_course": "ይህን ለመውሰድ የቀድሞውን የኮርስ ልምምድ ያጠናቅቁ", "finish_all_practice_module": "የሞጁሉን ልምምድ ለመውሰድ የትምህርት ልምምዶችን ያጠናቅቁ",
"track_journey": "የትምህርት ጉዞዎን ይከታተሉ እና በጊዜ ሂደት ያሳዩትን እድገት ይመልከቱ።", "finish_all_practice_course": "የኮርሱን ልምምድ ለመውሰድ የሞጁል ልምምዶችን ያጠናቅቁ",
"learn_english": "እንግሊዝኛ ይማሩ", "finish_all_practice_previouse_module":
"keep_momentum": "በጣም ጥሩ ስራ! በዚሁ ብርታት ይቀጥሉ።", "ይህን ልምምድ ለመውሰድ የቀድሞውን የሞጁል ልምምድ ያጠናቅቁ",
"completed_practices": "የተጠናቀቁ ልምምዶች", "finish_all_practice_previouse_course": "ይህን ለመውሰድ የቀድሞውን የኮርስ ልምምድ ያጠናቅቁ"
"total_practices": "ጠቅላላ ልምምዶች", };
"progress_percentage": "የእድገት መቶኛ" static const Map<String, dynamic> _en = {
}; "loading": "Loading",
static const Map<String,dynamic> _en = { "welcome_back": "Welcome back",
"loading": "Loading", "checking_user_info": "Checking user info",
"welcome_back": "Welcome back", "dont_have_account": "Don't have an account?",
"checking_user_info": "Checking user info", "email": "Email",
"dont_have_account": "Don't have an account?", "password": "Password",
"email": "Email", "forgot_password": "Forgot password?",
"password": "Password", "cont": "Continue",
"forgot_password": "Forgot password?", "register": "Register",
"cont": "Continue", "login_with_google": "Login with Google",
"register": "Register", "or": "Or",
"login_with_google": "Login with Google", "login_with_phone": "Login with phone number",
"or": "Or", "create_account": "Create an account",
"login_with_phone": "Login with phone number", "already_have_account": "Already have an account?",
"create_account": "Create an account", "login": "Login",
"already_have_account": "Already have an account?", "register_with_google": "Register with Google",
"login": "Login", "register_with_phone": "Register with phone number",
"register_with_google": "Register with Google", "enter_phone_number":
"register_with_phone": "Register with phone number", "Enter your phone number. We will send you a confirmation code there.",
"enter_phone_number": "Enter your phone number. We will send you a confirmation code there.", "login_with_email": "Login with email",
"login_with_email": "Login with email", "create_password": "Create password",
"create_password": "Create password", "confirm_password": "Confirm password",
"confirm_password": "Confirm password", "eight_character_minimum": "8 characters minimum",
"eight_character_minimum": "8 characters minimum", "password_match": "password match",
"password_match": "password match", "sign_up_agreement":
"sign_up_agreement": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy", "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy",
"terms_of_services": "Terms of Service", "terms_of_services": "Terms of Service",
"and": "and", "and": "and",
"privacy_policy": "Privacy Policy", "privacy_policy": "Privacy Policy",
"register_with_email": "Register with email", "register_with_email": "Register with email",
"verification_code": "Verification Code", "verification_code": "Verification Code",
"resend_code": "Resend Code", "resend_code": "Resend Code",
"code_sent_to_phone": "Code sent to your number", "code_sent_to_phone": "Code sent to your number",
"code_sent_to_email": "Code sent to your email", "code_sent_to_email": "Code sent to your email",
"resend_code_in": "Resend code in", "resend_code_in": "Resend code in",
"reset_password": "Reset Password", "reset_password": "Reset Password",
"enter_email_reset_code": "Enter your email. We will send you a reset code.", "enter_email_reset_code":
"please_wait": "Please wait", "Enter your email. We will send you a reset code.",
"reset_code_sent": "Reset code sent successfully", "please_wait": "Please wait",
"reset_code": "Reset code", "reset_code_sent": "Reset code sent successfully",
"new_password": "New password", "reset_code": "Reset code",
"logged_in_successfully": "Logged in successfully", "new_password": "New password",
"continue_learning": "Continue Learning", "logged_in_successfully": "Logged in successfully",
"start_learning": "Start Learning", "continue_learning": "Continue Learning",
"completed": "Completed", "start_learning": "Start Learning",
"view_course": "View course", "completed": "Completed",
"take_practice": "Take practice", "view_course": "View course",
"your_current_level": "Your current level", "take_practice": "Take practice",
"overall_progress": "Overall progress", "your_current_level": "Your current level",
"great_work": "Keep up the great work! You're doing amazing", "overall_progress": "Overall progress",
"view_module": "View module", "great_work": "Keep up the great work! You're doing amazing",
"progress": "Progress", "view_module": "View module",
"keep_going": "Let's keep going - you're more than half there", "progress": "Progress",
"lessons_in_module": "Lessons in this module", "keep_going": "Let's keep going - you're more than half there",
"practice": "Practice", "lessons_in_module": "Lessons in this module",
"start": "Start", "practice": "Practice",
"in_progress": "In Progress", "start": "Start",
"hello": "Hello", "in_progress": "In Progress",
"ready_to_learn": "Ready to keep learning English today", "hello": "Hello",
"learn": "Learn", "ready_to_learn": "Ready to keep learning English today",
"course": "Course", "learn": "Learn",
"profile": "Profile", "course": "Course",
"speaking_partner": "Speaking partner", "profile": "Profile",
"practice_what_you_learned": "Let's practice what you just learnt", "speaking_partner": "Speaking partner",
"practice_questions": "I will ask you a few questions and you can respond", "practice_what_you_learned": "Let's practice what you just learnt",
"start_practice": "Start practice", "practice_questions": "I will ask you a few questions and you can respond",
"almost_there": "You're almost there", "start_practice": "Start practice",
"finish_session": "Finish the session to see your progress", "almost_there": "You're almost there",
"continue_practice": "Continue practice", "finish_session": "Finish the session to see your progress",
"end_session": "End session", "continue_practice": "Continue practice",
"tap_start_to_listen": "Tap the start button to listen", "end_session": "End session",
"practice_speaking": "Practice speaking", "tap_start_to_listen": "Tap the start button to listen",
"tap_microphone": "Tap the microphone to speak", "practice_speaking": "Practice speaking",
"reply": "Reply", "tap_microphone": "Tap the microphone to speak",
"cancel": "Cancel", "reply": "Reply",
"you_are_speaking": "You're speaking", "cancel": "Cancel",
"practice_completed": "Practice completed!", "you_are_speaking": "You're speaking",
"great_improvement": "You sound more confident this time, great improvement", "practice_completed": "Practice completed!",
"practice_again": "Practice again", "great_improvement":
"conversation_review": "Conversation review", "You sound more confident this time, great improvement",
"result": "Result", "practice_again": "Practice again",
"quick_tip": "Quick tip", "conversation_review": "Conversation review",
"retry": "Retry", "result": "Result",
"completed_a1": "Yay, you've completed A1", "quick_tip": "Quick tip",
"analyzing_speaking": "We're now analyzing your speaking skill", "retry": "Retry",
"view_profile": "View profile", "completed_a1": "Yay, you've completed A1",
"hi": "Hi", "analyzing_speaking": "We're now analyzing your speaking skill",
"edit_profile": "Edit profile", "view_profile": "View profile",
"first_name": "First name", "hi": "Hi",
"last_name": "Last name", "edit_profile": "Edit profile",
"gender": "Gender", "first_name": "First name",
"male": "Male", "last_name": "Last name",
"female": "Female", "gender": "Gender",
"phone_number": "Phone number", "male": "Male",
"country": "Country", "female": "Female",
"region": "Region", "phone_number": "Phone number",
"select_region": "Select region", "country": "Country",
"enter_your_city": "Enter your city", "region": "Region",
"occupation": "Occupation", "select_region": "Select region",
"select_occupation": "Select occupation", "enter_your_city": "Enter your city",
"save_changes": "Save changes", "occupation": "Occupation",
"my_progress": "My progress", "select_occupation": "Select occupation",
"track_your_achievement": "Track your achievements and learning streak", "save_changes": "Save changes",
"account_and_privacy": "Account & Privacy", "my_progress": "My progress",
"manage_settings": "Manage settings and app preference", "track_your_achievement": "Track your achievements and learning streak",
"support": "Support", "account_and_privacy": "Account & Privacy",
"get_help": "Get help through phone or Telegram", "manage_settings": "Manage settings and app preference",
"logout": "Logout", "support": "Support",
"app_settings": "App settings", "get_help": "Get help through phone or Telegram",
"legal_and_information": "Legal & Information", "logout": "Logout",
"change_language": "Change language", "app_settings": "App settings",
"terms_and_conditions": "Terms & Conditions", "legal_and_information": "Legal & Information",
"delete_account": "Delete account", "change_language": "Change language",
"language_preference": "Language preference", "terms_and_conditions": "Terms & Conditions",
"choose_your_language": "Choose your language", "delete_account": "Delete account",
"switch_language_anytime": "You can switch languages anytime", "language_preference": "Language preference",
"need_help": "Need help?", "choose_your_language": "Choose your language",
"call_support": "Call support", "switch_language_anytime": "You can switch languages anytime",
"talk_with_support": "Talk with our support team directly", "need_help": "Need help?",
"telegram_support": "Telegram support", "call_support": "Call support",
"chat_via_telegram": "Chat instantly via Telegram", "talk_with_support": "Talk with our support team directly",
"call_our_support": "Call our support team between 9 AM - 6 PM", "telegram_support": "Telegram support",
"tap_to_call": "Tap to call", "chat_via_telegram": "Chat instantly via Telegram",
"join_telegram": "Join Yimaru Academy on Telegram", "call_our_support": "Call our support team between 9 AM - 6 PM",
"connect_with_support_team": "Connect with our support team instantly on Telegram for quick assistance and community updates", "tap_to_call": "Tap to call",
"open_in_telegram": "Open in Telegram", "join_telegram": "Join Yimaru Academy on Telegram",
"search_for": "Search for", "connect_with_support_team":
"current_level": "Current Level", "Connect with our support team instantly on Telegram for quick assistance and community updates",
"keep_up_the_great_work": "Keep up the great work! You're doing amazing.", "open_in_telegram": "Open in Telegram",
"no_practice_available": "No practice available!", "search_for": "Search for",
"begin_module_practice": "Begin Module Practice", "current_level": "Current Level",
"lets_practice_lesson": "Lets Practice", "keep_up_the_great_work": "Keep up the great work! You're doing amazing.",
"lets_quickly_review": "Lets quickly review what youve learned in this module!", "no_practice_available": "No practice available!",
"lets_practice_module": "Let's practice what you just learnt!", "begin_module_practice": "Begin Module Practice",
"ask_you_few_actions": "Ill ask you a few questions, and you can respond naturally.", "lets_practice_lesson": "Lets Practice",
"begin_level_practice": "Begin Level Practice", "lets_quickly_review":
"lets_practice_course": "Lets Practice Course", "Lets quickly review what youve learned in this module!",
"lets_quick_review": "Lets quickly review what youve learned in this level!", "lets_practice_module": "Let's practice what you just learnt!",
"speaking": "is speaking...", "ask_you_few_actions":
"you_have_finished_practice": "You have finished your practice", "Ill ask you a few questions, and you can respond naturally.",
"view_results": "View My Results", "begin_level_practice": "Begin Level Practice",
"sample_answer": "Sample Answer", "lets_practice_course": "Lets Practice Course",
"your_answer": "Your Answer", "lets_quick_review":
"sound_confident": "You sound more confident this time - great improvement!", "Lets quickly review what youve learned in this level!",
"you_have_completed": "Yay, youve completed", "speaking": "is speaking...",
"yes": "Yes", "you_have_finished_practice": "You have finished your practice",
"no": "No", "view_results": "View My Results",
"want_to_quit": "Are you sure you want to quit?", "sample_answer": "Sample Answer",
"required_field": "The field is required", "your_answer": "Your Answer",
"enter_full_name": "Enter your full name", "sound_confident":
"invalid_email": "Invalid email format", "You sound more confident this time - great improvement!",
"phone_must_start_with": "Phone number must start with 251", "you_have_completed": "Yay, youve completed",
"phone_must_be": "Phone number must be 12 digits", "yes": "Yes",
"what_should_we_call_you": "What should we call you?", "no": "No",
"name_for_personalization": "Well use your name to personalize your learning journey.", "want_to_quit": "Are you sure you want to quit?",
"choose_your_gender": "Choose your gender?", "required_field": "The field is required",
"gender_for_personalization": "Well personalize your learning experience based on your gender.", "enter_full_name": "Enter your full name",
"age_range": "Which age range are you in?", "invalid_email": "Invalid email format",
"age_for_personalization": "Well personalize your learning experience based on your age.", "phone_must_start_with": "Phone number must start with 251",
"educational_background": "Whats your current educational level?", "phone_must_be": "Phone number must be 12 digits",
"education_for_personalization": "This helps us tailor your lessons to your experience.", "what_should_we_call_you": "What should we call you?",
"your_occupation": "Whats your occupation?", "name_for_personalization":
"occupation_for_personalization": "Well personalize your learning experience based on your occupation.", "Well use your name to personalize your learning journey.",
"location": "Where are you from?", "choose_your_gender": "Choose your gender?",
"select_country_region": "Select your country and region from the dropdown", "gender_for_personalization":
"select_country": "Select country", "Well personalize your learning experience based on your gender.",
"learning_goal": "Choose your learning goal.", "age_range": "Which age range are you in?",
"language_goal": "Whats your main goal for improving your English?", "age_for_personalization":
"your_goal": "Your goal helps us tailor your learning journey.", "Well personalize your learning experience based on your age.",
"write_your_goal": "Write your goal…", "educational_background": "Whats your current educational level?",
"challenge_you_face": "What challenge do you face most with English?", "education_for_personalization":
"evey_one_has_strugle": "Everyone has struggles, lets start fixing yours", "This helps us tailor your lessons to your experience.",
"write_your_challenge": "Write your challenge…", "your_occupation": "Whats your occupation?",
"topic_interest": "Which topics interest you most?", "occupation_for_personalization":
"favourite_topic": "Your favorite topics help us create fun, relatable lessons.", "Well personalize your learning experience based on your occupation.",
"your_interest": "Write your interest…", "location": "Where are you from?",
"want_quick_assessment": "Want a quick assessment to know your English level?", "select_country_region": "Select your country and region from the dropdown",
"answer_quick_questions": "Answer a few quick questions to help us understand your English proficiency.", "select_country": "Select country",
"skip": "Skip", "learning_goal": "Choose your learning goal.",
"finish_level": "Finish Level", "language_goal": "Whats your main goal for improving your English?",
"likely_speaker": "Youre likely speaker of", "your_goal": "Your goal helps us tailor your learning journey.",
"great_job": "Great Job! Heres your next step to keep improving.", "write_your_goal": "Write your goal…",
"lets_start_practice": "Let's start your practice", "challenge_you_face": "What challenge do you face most with English?",
"welcome_abroad": "Welcome aboard", "evey_one_has_strugle": "Everyone has struggles, lets start fixing yours",
"ready_to_explore": "Youre ready to explore your personalized lessons.", "write_your_challenge": "Write your challenge…",
"finish": "Finish", "topic_interest": "Which topics interest you most?",
"finish_all_practice_lesson": "Finish the previous lesson practice to take this practice", "favourite_topic":
"finish_all_practice_module": "Finish the lesson practices to take the Module Practice", "Your favorite topics help us create fun, relatable lessons.",
"finish_all_practice_course": "Finish the Module practices to take the Course practice", "your_interest": "Write your interest…",
"finish_all_practice_previouse_module": "Finish the previous Module practice to take this practice", "want_quick_assessment":
"finish_all_practice_previouse_course": "Finish the previous course practice to take this", "Want a quick assessment to know your English level?",
"track_journey": "Track your learning journey and see your growth over time.", "answer_quick_questions":
"learn_english": "Learn English", "Answer a few quick questions to help us understand your English proficiency.",
"keep_momentum": "Great job! Keep the momentum.", "skip": "Skip",
"completed_practices": "Completed Practices", "finish_level": "Finish Level",
"total_practices": "Total Practices", "likely_speaker": "Youre likely speaker of",
"progress_percentage": "Progress Percentage" "great_job": "Great Job! Heres your next step to keep improving.",
}; "lets_start_practice": "Let's start your practice",
static const Map<String, Map<String,dynamic>> mapLocales = {"am": _am, "en": _en}; "welcome_abroad": "Welcome aboard",
"ready_to_explore": "Youre ready to explore your personalized lessons.",
"finish": "Finish",
"finish_all_practice_lesson":
"Finish the previous lesson practice to take this practice",
"finish_all_practice_module":
"Finish the lesson practices to take the Module Practice",
"finish_all_practice_course":
"Finish the Module practices to take the Course practice",
"finish_all_practice_previouse_module":
"Finish the previous Module practice to take this practice",
"finish_all_practice_previouse_course":
"Finish the previous course practice to take this"
};
static const Map<String, Map<String, dynamic>> mapLocales = {
"am": _am,
"en": _en
};
} }

View File

@ -2,7 +2,7 @@
// ignore_for_file: constant_identifier_names // ignore_for_file: constant_identifier_names
abstract class LocaleKeys { abstract class LocaleKeys {
static const loading = 'loading'; static const loading = 'loading';
static const welcome_back = 'welcome_back'; static const welcome_back = 'welcome_back';
static const checking_user_info = 'checking_user_info'; static const checking_user_info = 'checking_user_info';
@ -161,7 +161,8 @@ abstract class LocaleKeys {
static const educational_background = 'educational_background'; static const educational_background = 'educational_background';
static const education_for_personalization = 'education_for_personalization'; static const education_for_personalization = 'education_for_personalization';
static const your_occupation = 'your_occupation'; static const your_occupation = 'your_occupation';
static const occupation_for_personalization = 'occupation_for_personalization'; static const occupation_for_personalization =
'occupation_for_personalization';
static const location = 'location'; static const location = 'location';
static const select_country_region = 'select_country_region'; static const select_country_region = 'select_country_region';
static const select_country = 'select_country'; static const select_country = 'select_country';
@ -188,13 +189,8 @@ abstract class LocaleKeys {
static const finish_all_practice_lesson = 'finish_all_practice_lesson'; static const finish_all_practice_lesson = 'finish_all_practice_lesson';
static const finish_all_practice_module = 'finish_all_practice_module'; static const finish_all_practice_module = 'finish_all_practice_module';
static const finish_all_practice_course = 'finish_all_practice_course'; static const finish_all_practice_course = 'finish_all_practice_course';
static const finish_all_practice_previouse_module = 'finish_all_practice_previouse_module'; static const finish_all_practice_previouse_module =
static const finish_all_practice_previouse_course = 'finish_all_practice_previouse_course'; 'finish_all_practice_previouse_module';
static const track_journey = 'track_journey'; static const finish_all_practice_previouse_course =
static const learn_english = 'learn_english'; 'finish_all_practice_previouse_course';
static const keep_momentum = 'keep_momentum';
static const completed_practices = 'completed_practices';
static const total_practices = 'total_practices';
static const progress_percentage = 'progress_percentage';
} }

View File

@ -2,18 +2,15 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
import 'package:yimaru_app/ui/common/app_colors.dart'; import 'package:yimaru_app/ui/common/app_colors.dart';
import 'package:yimaru_app/ui/common/enmus.dart';
import 'package:yimaru_app/ui/common/translations/locale_keys.g.dart'; import 'package:yimaru_app/ui/common/translations/locale_keys.g.dart';
import 'package:yimaru_app/ui/views/learn_program/learn_program_view.dart'; import 'package:yimaru_app/ui/views/learn_program/learn_program_view.dart';
import 'package:yimaru_app/ui/views/profile/profile_view.dart'; import 'package:yimaru_app/ui/views/profile/profile_view.dart';
import 'package:yimaru_app/ui/widgets/page_loading_indicator.dart';
import '../../widgets/coming_soon.dart'; import '../../widgets/coming_soon.dart';
import 'home_viewmodel.dart'; import 'home_viewmodel.dart';
class HomeView extends StackedView<HomeViewModel> { class HomeView extends StackedView<HomeViewModel> {
const HomeView({Key? key}) : super(key: key); const HomeView({Key? key}) : super(key: key);
@override @override
void onViewModelReady(HomeViewModel viewModel) async { void onViewModelReady(HomeViewModel viewModel) async {
await viewModel.inAppUpdate(); await viewModel.inAppUpdate();
@ -26,13 +23,7 @@ class HomeView extends StackedView<HomeViewModel> {
@override @override
Widget builder( Widget builder(
BuildContext context, HomeViewModel viewModel, Widget? child) => BuildContext context, HomeViewModel viewModel, Widget? child) =>
KeyedSubtree( _buildScaffold(viewModel);
key: ValueKey(context.locale.languageCode),
child: _buildScaffoldStack(viewModel));
Widget _buildScaffoldStack(HomeViewModel viewModel) => Stack(
children: [_buildScaffold(viewModel), _buildLogoutState(viewModel)],
);
Widget _buildScaffold(HomeViewModel viewModel) => Scaffold( Widget _buildScaffold(HomeViewModel viewModel) => Scaffold(
body: getViewForIndex(viewModel.currentPage), body: getViewForIndex(viewModel.currentPage),
@ -86,9 +77,4 @@ class HomeView extends StackedView<HomeViewModel> {
return const ProfileView(); return const ProfileView();
} }
} }
Widget _buildLogoutState(HomeViewModel viewModel) =>
viewModel.state == StateObjects.logout
? const PageLoadingIndicator()
: Container();
} }

View File

@ -5,7 +5,6 @@ import 'package:yimaru_app/services/status_checker_service.dart';
import 'package:yimaru_app/ui/common/app_strings.dart'; import 'package:yimaru_app/ui/common/app_strings.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart'; import 'package:stacked_services/stacked_services.dart';
import 'package:yimaru_app/ui/common/enmus.dart';
import '../../../services/authentication_service.dart'; import '../../../services/authentication_service.dart';
import '../../../services/in_app_update_service.dart'; import '../../../services/in_app_update_service.dart';
@ -13,13 +12,8 @@ import '../../../services/in_app_update_service.dart';
class HomeViewModel extends ReactiveViewModel { class HomeViewModel extends ReactiveViewModel {
// Dependency injection // Dependency injection
final _statusChecker = locator<StatusCheckerService>(); final _statusChecker = locator<StatusCheckerService>();
final _navigationService = locator<NavigationService>();
final _bottomSheetService = locator<BottomSheetService>(); final _bottomSheetService = locator<BottomSheetService>();
final _inAppUpdateService = locator<InAppUpdateService>(); final _inAppUpdateService = locator<InAppUpdateService>();
final _authenticationService = locator<AuthenticationService>(); final _authenticationService = locator<AuthenticationService>();
@override @override
@ -31,11 +25,6 @@ class HomeViewModel extends ReactiveViewModel {
User? get user => _user; User? get user => _user;
// Logout state
StateObjects get _state => _authenticationService.state;
StateObjects get state => _state;
// Bottom navigation // Bottom navigation
int _currentPage = 0; int _currentPage = 0;
@ -55,8 +44,6 @@ class HomeViewModel extends ReactiveViewModel {
rebuildUi(); rebuildUi();
} }
// Remote api calls // Remote api calls
// In-app update // In-app update

View File

@ -29,12 +29,9 @@ class LanguageViewModel extends ReactiveViewModel {
Future<void> setSelectedLanguage( Future<void> setSelectedLanguage(
{required BuildContext context, {required BuildContext context,
required Map<String, dynamic> title}) async { required Map<String, dynamic> title}) async =>
await _localizationService.setSelectedLanguage( await _localizationService.setSelectedLanguage(
context: context, title: title); context: context, title: title);
rebuildUi();
}
// Navigation // Navigation
void pop() => _navigationService.back(); void pop() => _navigationService.back();

View File

@ -26,12 +26,12 @@ class LearnLessonView extends StackedView<LearnLessonViewModel> {
required LearnLesson lesson, required LearnLesson lesson,
required BuildContext context, required BuildContext context,
required LearnLessonViewModel viewModel}) async { required LearnLessonViewModel viewModel}) async {
/* if (lesson.access?.isAccessible ?? false) { if (lesson.access?.isAccessible ?? false) {
await viewModel.navigateToLearnPractice(lesson.id ?? 0); await viewModel.navigateToLearnPractice(lesson.id ?? 0);
} else { } else {
await _showSheet(context: context, viewModel: viewModel); await _showSheet(context: context, viewModel: viewModel);
}*/ }
if (index > 1) { /* if (index > 1) {
if (viewModel.user?.subscriptionStatus?.toLowerCase() == 'subscribed') { if (viewModel.user?.subscriptionStatus?.toLowerCase() == 'subscribed') {
if (lesson.access?.isAccessible ?? false) { if (lesson.access?.isAccessible ?? false) {
await viewModel.navigateToLearnPractice(lesson.id ?? 0); await viewModel.navigateToLearnPractice(lesson.id ?? 0);
@ -47,7 +47,7 @@ class LearnLessonView extends StackedView<LearnLessonViewModel> {
} else { } else {
await _showSheet(context: context, viewModel: viewModel); await _showSheet(context: context, viewModel: viewModel);
} }
} }*/
} }
Future<void> _showSheet( Future<void> _showSheet(

View File

@ -31,10 +31,10 @@ class LearnLessonDetailView extends StackedView<LearnLessonDetailViewModel> {
Future<void> _onPractice( Future<void> _onPractice(
{required LearnLesson lesson, {required LearnLesson lesson,
required LearnLessonDetailViewModel viewModel}) async { required LearnLessonDetailViewModel viewModel}) async {
/* await viewModel.pause(); await viewModel.pause();
await viewModel.navigateToLearnPractice(lesson.id ?? 0); await viewModel.navigateToLearnPractice(lesson.id ?? 0);
*/
if (index > 1) { /* if (index > 1) {
if (viewModel.user?.subscriptionStatus?.toLowerCase() == 'subscribed') { if (viewModel.user?.subscriptionStatus?.toLowerCase() == 'subscribed') {
await viewModel.pause(); await viewModel.pause();
await viewModel.navigateToLearnPractice(lesson.id ?? 0); await viewModel.navigateToLearnPractice(lesson.id ?? 0);
@ -45,7 +45,7 @@ class LearnLessonDetailView extends StackedView<LearnLessonDetailViewModel> {
} else { } else {
await viewModel.pause(); await viewModel.pause();
await viewModel.navigateToLearnPractice(lesson.id ?? 0); await viewModel.navigateToLearnPractice(lesson.id ?? 0);
} }*/
} }
@override @override

View File

@ -306,7 +306,7 @@ class LearnPracticeViewModel extends ReactiveViewModel {
Future<void> _completeLearnPractices() async { Future<void> _completeLearnPractices() async {
if (await _statusChecker.checkConnection()) { if (await _statusChecker.checkConnection()) {
await _apiService.completeLearnPractice(_practices.first.id ?? 0); await _apiService.completeLearnPractice(_practices.first.id ?? 0);
await _learnService.getLearnProgress(); await _learnService.getLearnProgressSummary();
} }
} }

View File

@ -203,10 +203,10 @@ class OnboardingViewModel extends ReactiveViewModel
void setSelectedCountry(FieldOption? value) { void setSelectedCountry(FieldOption? value) {
_selectedCountry = value; _selectedCountry = value;
if (value?.code?.toLowerCase().trim() == 'et') { if (value?.label?.toLowerCase().trim() == 'ethiopia') {
_dropdownRegion = true; _dropdownRegion = true;
_selectedRegion = _regions _selectedRegion = _regions
.firstWhere((e) => e.code?.toLowerCase().trim().contains('addis_ababa') ?? false); .firstWhere((e) => e.label?.toLowerCase().trim() == 'addis ababa');
} else { } else {
_dropdownRegion = false; _dropdownRegion = false;
} }

View File

@ -166,7 +166,7 @@ class ProfileView extends StackedView<ProfileViewModel> {
List<Widget> _buildSettingsChildren(ProfileViewModel viewModel) => [ List<Widget> _buildSettingsChildren(ProfileViewModel viewModel) => [
// _buildDownloadsCard(viewModel), // _buildDownloadsCard(viewModel),
_buildProgressCard(viewModel), // _buildProgressCard(viewModel),
_buildAccountCard(viewModel), _buildAccountCard(viewModel),
_buildSupportCard(viewModel) _buildSupportCard(viewModel)
]; ];

View File

@ -68,10 +68,10 @@ class ProfileViewModel extends ReactiveViewModel {
DialogResponse? response = await _dialogService.showDialog( DialogResponse? response = await _dialogService.showDialog(
barrierDismissible: true, barrierDismissible: true,
cancelTitleColor: kcDarkGrey, cancelTitleColor: kcDarkGrey,
buttonTitleColor: kcPrimaryColor,
title: LocaleKeys.logout.tr(), title: LocaleKeys.logout.tr(),
cancelTitle: LocaleKeys.no.tr(), cancelTitle: LocaleKeys.no.tr(),
buttonTitle: LocaleKeys.yes.tr(), buttonTitle: LocaleKeys.yes.tr(),
buttonTitleColor: kcPrimaryColor,
description: LocaleKeys.want_to_quit.tr(), description: LocaleKeys.want_to_quit.tr(),
); );
return response?.confirmed; return response?.confirmed;
@ -119,6 +119,7 @@ class ProfileViewModel extends ReactiveViewModel {
} }
Future<void> _logout() async { Future<void> _logout() async {
await _googleAuthService.logout();
await _authenticationService.logout(); await _authenticationService.logout();
await navigateToLogin(); await navigateToLogin();
} }

View File

@ -93,7 +93,6 @@ class ProfileDetailView extends StackedView<ProfileDetailViewModel>
} }
void _onModelReady(ProfileDetailViewModel viewModel) { void _onModelReady(ProfileDetailViewModel viewModel) {
print('MY RESPONSE: ${viewModel.user?.region}');
phoneNumberController.text = '251900000000'; phoneNumberController.text = '251900000000';
emailController.text = viewModel.user?.email ?? ''; emailController.text = viewModel.user?.email ?? '';
lastNameController.text = viewModel.user?.lastName ?? ''; lastNameController.text = viewModel.user?.lastName ?? '';
@ -104,14 +103,9 @@ class ProfileDetailView extends StackedView<ProfileDetailViewModel>
viewModel.setSelectedOccupation(viewModel.occupations viewModel.setSelectedOccupation(viewModel.occupations
.where((e) => (e.code ?? '') == viewModel.user?.occupation) .where((e) => (e.code ?? '') == viewModel.user?.occupation)
.first); .first);
viewModel.setSelectedCountry(viewModel.countries viewModel.setSelectedCountry(viewModel.countries
.where((e) => (e.code ?? '') == viewModel.user?.country) .where((e) => (e.code ?? '') == viewModel.user?.country)
.first); .first);
if (viewModel.user?.country?.toLowerCase() == 'et') {
viewModel.setEthiopianRegion(viewModel.user?.region ?? '');
} else {
regionController.text = viewModel.user?.region ?? '';
}
} }
@override @override
@ -671,7 +665,6 @@ class ProfileDetailView extends StackedView<ProfileDetailViewModel>
Icons.search, Icons.search,
color: kcPrimaryColor, color: kcPrimaryColor,
); );
Widget _buildLowerColumn(ProfileDetailViewModel viewModel) => Column( Widget _buildLowerColumn(ProfileDetailViewModel viewModel) => Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: _buildLowerColumnChildren(viewModel), children: _buildLowerColumnChildren(viewModel),

View File

@ -134,20 +134,12 @@ class ProfileDetailViewModel extends ReactiveViewModel
List<FieldOption> get countries => _countries; List<FieldOption> get countries => _countries;
void setEthiopianRegion(String region) {
_dropdownRegion = true;
_selectedRegion =
_regions.firstWhere((r) => r.code?.toLowerCase() == region.toLowerCase());
rebuildUi();
}
void setSelectedCountry(FieldOption? value) { void setSelectedCountry(FieldOption? value) {
_selectedCountry = value; _selectedCountry = value;
if (value?.code?.toLowerCase().trim().contains('et') ?? false) { if (value?.label?.toLowerCase().trim() == 'ethiopia') {
_dropdownRegion = true; _dropdownRegion = true;
_selectedRegion = _regions.firstWhere( _selectedRegion = _regions
(e) => e.code?.toLowerCase().trim().contains('addis_ababa') ?? false); .firstWhere((e) => e.label?.toLowerCase().trim() == 'addis ababa');
} else { } else {
_dropdownRegion = false; _dropdownRegion = false;
} }

View File

@ -1,7 +1,5 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
import 'package:yimaru_app/ui/common/translations/locale_keys.g.dart';
import '../../common/app_colors.dart'; import '../../common/app_colors.dart';
import '../../common/ui_helpers.dart'; import '../../common/ui_helpers.dart';
@ -13,12 +11,6 @@ import 'progress_viewmodel.dart';
class ProgressView extends StackedView<ProgressViewModel> { class ProgressView extends StackedView<ProgressViewModel> {
const ProgressView({Key? key}) : super(key: key); const ProgressView({Key? key}) : super(key: key);
@override
void onViewModelReady(ProgressViewModel viewModel) async {
await viewModel.getProgressSummary();
super.onViewModelReady(viewModel);
}
@override @override
ProgressViewModel viewModelBuilder(BuildContext context) => ProgressViewModel viewModelBuilder(BuildContext context) =>
ProgressViewModel(); ProgressViewModel();
@ -62,9 +54,9 @@ class ProgressView extends StackedView<ProgressViewModel> {
); );
Widget _buildAppbar(ProgressViewModel viewModel) => SmallAppBar( Widget _buildAppbar(ProgressViewModel viewModel) => SmallAppBar(
title: 'My Progress',
showBackButton: true, showBackButton: true,
onPop: viewModel.pop, onPop: viewModel.pop,
title: LocaleKeys.my_progress.tr(),
); );
Widget _buildContentScrollViewWrapper(ProgressViewModel viewModel) => Widget _buildContentScrollViewWrapper(ProgressViewModel viewModel) =>
@ -89,12 +81,12 @@ class ProgressView extends StackedView<ProgressViewModel> {
verticalSpaceMedium, verticalSpaceMedium,
_buildLearningProgressCard(), _buildLearningProgressCard(),
verticalSpaceMedium, verticalSpaceMedium,
// _buildCourseProgressSection() _buildCourseProgressSection()
]; ];
Widget _buildText() => Text( Widget _buildText() => const Text(
LocaleKeys.track_journey.tr(), 'Track your learning journey and see your growth over time.',
style: style14DG400, style: TextStyle(color: kcDarkGrey),
); );
Widget _buildLearningProgressCard() => const LearningProgressCard(); Widget _buildLearningProgressCard() => const LearningProgressCard();

View File

@ -1,40 +1,12 @@
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart'; import 'package:stacked_services/stacked_services.dart';
import 'package:yimaru_app/services/learn_service.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.locator.dart';
import '../../../models/progress_summary.dart';
class ProgressViewModel extends ReactiveViewModel { class ProgressViewModel extends BaseViewModel {
// Dependency injection // Dependency injection
final _learnService = locator<LearnService>();
final _navigationService = locator<NavigationService>(); final _navigationService = locator<NavigationService>();
final _statusCheckerService = locator<StatusCheckerService>();
@override
List<ListenableServiceMixin> get listenableServices => [_learnService];
// Total practice count
int get _totalCount => _learnService.totalCount;
int get totalCount => _totalCount;
// Completed practice count
int get _completedCount => _learnService.completedCount;
int get completedCount => _completedCount;
// Total progress
int get _totalProgress => _learnService.totalProgress;
int get totalProgress => _totalProgress;
// Courses // Courses
final List<Map<String, dynamic>> _courses = [ final List<Map<String, dynamic>> _courses = [
{ {
@ -49,17 +21,4 @@ class ProgressViewModel extends ReactiveViewModel {
// Navigation // Navigation
void pop() => _navigationService.back(); void pop() => _navigationService.back();
// Remote api
// Learning progress
Future<void> getProgressSummary() async => runBusyFuture(_getProgressSummary(),
busyObject: StateObjects.progressSummary);
Future<void> _getProgressSummary() async {
if (await _statusCheckerService.checkConnection()) {
await _learnService.getProgressSummary();
}
}
} }

View File

@ -122,12 +122,10 @@ class StartupViewModel extends ReactiveViewModel {
await _authenticationService.saveUserData(user); await _authenticationService.saveUserData(user);
String? image = String image =
await _imageDownloaderService.downloader(user.profilePicture); await _imageDownloaderService.downloader(user.profilePicture);
if (image != null) { await _authenticationService.saveProfilePicture(image);
await _authenticationService.saveProfilePicture(image);
}
} }
} }
} }

View File

@ -7,6 +7,7 @@ import 'package:yimaru_app/ui/common/translations/locale_keys.g.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_container_shader.dart'; import 'package:yimaru_app/ui/widgets/custom_container_shader.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/ui_helpers.dart'; import '../common/ui_helpers.dart';

View File

@ -1,9 +1,4 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart';
import 'package:yimaru_app/ui/common/enmus.dart';
import 'package:yimaru_app/ui/common/translations/locale_keys.g.dart';
import 'package:yimaru_app/ui/views/progress/progress_viewmodel.dart';
import 'package:yimaru_app/ui/widgets/custom_column.dart'; import 'package:yimaru_app/ui/widgets/custom_column.dart';
import '../common/app_colors.dart'; import '../common/app_colors.dart';
@ -11,46 +6,45 @@ import '../common/ui_helpers.dart';
import 'custom_elevated_button.dart'; import 'custom_elevated_button.dart';
import 'custom_linear_progress_indicator.dart'; import 'custom_linear_progress_indicator.dart';
class LearningProgressCard extends ViewModelWidget<ProgressViewModel> { class LearningProgressCard extends StatelessWidget {
final GestureTapCallback? onTap; final GestureTapCallback? onTap;
const LearningProgressCard({super.key, this.onTap}); const LearningProgressCard({super.key, this.onTap});
@override @override
Widget build(BuildContext context, ProgressViewModel viewModel) => Widget build(BuildContext context) => _buildContainerWrapper();
_buildContainerWrapper(viewModel);
Widget _buildContainerWrapper(ProgressViewModel viewModel) => GestureDetector( Widget _buildContainerWrapper() => GestureDetector(
onTap: onTap, onTap: onTap,
child: _buildContainer(viewModel), child: _buildContainer(),
); );
Widget _buildContainer(ProgressViewModel viewModel) => Container( Widget _buildContainer() => Container(
height: 320, height: 320,
padding: const EdgeInsets.all(15), padding: const EdgeInsets.all(15),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5), borderRadius: BorderRadius.circular(5),
color: kcPrimaryColor.withOpacity(0.1), color: kcPrimaryColor.withOpacity(0.1),
), ),
child: _buildColumn(viewModel), child: _buildColumn(),
); );
Widget _buildColumn(ProgressViewModel viewModel) => Column( Widget _buildColumn() => Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: _buildColumnChildren(viewModel), children: _buildColumnChildren(),
); );
List<Widget> _buildColumnChildren(ProgressViewModel viewModel) => [ List<Widget> _buildColumnChildren() => [
_buildIcon(), _buildIcon(),
verticalSpaceSmall, verticalSpaceSmall,
_buildTitle(), _buildTitle(),
verticalSpaceTiny, verticalSpaceTiny,
_buildSubtitle(), _buildSubtitle(),
verticalSpaceSmall, verticalSpaceSmall,
_buildProgressIndicator(viewModel), _buildProgressIndicator(),
verticalSpaceSmall, verticalSpaceSmall,
_buildLearningStatus(viewModel), _buildLearningStatus(),
verticalSpaceMedium, verticalSpaceMedium,
_buildActionButton(), _buildActionButton(),
]; ];
@ -62,64 +56,47 @@ class LearningProgressCard extends ViewModelWidget<ProgressViewModel> {
); );
Widget _buildTitle() => Text( Widget _buildTitle() => Text(
LocaleKeys.learn_english.tr(), 'Learn English',
style: style16DG600, style: style16DG600,
); );
Widget _buildSubtitle() => Text( Widget _buildSubtitle() => const Text(
LocaleKeys.keep_momentum.tr(), 'Great job! Keep the momentum.',
maxLines: 2, maxLines: 2,
style: style14MG400, style: TextStyle(color: kcMediumGrey),
); );
Widget _buildProgressIndicator(ProgressViewModel viewModel) => Widget _buildProgressIndicator() => const CustomLinearProgressIndicator(
CustomLinearProgressIndicator( progress: 0,
activeColor: kcPrimaryColor, activeColor: kcPrimaryColor,
backgroundColor: kcVeryLightGrey, backgroundColor: kcVeryLightGrey,
progress: viewModel.busy(StateObjects.progressSummary)
? 0
: viewModel.totalProgress / 100,
); );
Widget _buildLearningStatus(ProgressViewModel viewModel) => Row( Widget _buildLearningStatus() => Row(
children: _buildLearningStatusChildren(viewModel), children: _buildLearningStatusChildren(),
); );
List<Widget> _buildLearningStatusChildren(ProgressViewModel viewModel) => [ List<Widget> _buildLearningStatusChildren() => [
_buildCompletedPractices(viewModel), _buildWatchedVideos(),
horizontalSpaceSmall, horizontalSpaceSmall,
_buildTotalPractices(viewModel), _buildCompletedPractices(),
horizontalSpaceSmall, horizontalSpaceSmall,
_buildProgressPercentage(viewModel), _buildTakenQuizzes()
]; ];
Widget _buildCompletedPractices(ProgressViewModel viewModel) => Expanded( Widget _buildWatchedVideos() => const Expanded(
child: CustomColumn( child: CustomColumn(title: '0', subtitle: 'Videos Watched'));
title: viewModel.busy(StateObjects.progressSummary) Widget _buildCompletedPractices() => const Expanded(
? '-' child: CustomColumn(title: '0', subtitle: 'Practices Completed'));
: viewModel.completedCount.toString(), Widget _buildTakenQuizzes() => const Expanded(
subtitle: LocaleKeys.completed_practices.tr())); child: CustomColumn(title: '0', subtitle: 'Quizzes Taken'));
Widget _buildTotalPractices(ProgressViewModel viewModel) => Expanded( Widget _buildActionButton() => const CustomElevatedButton(
child: CustomColumn(
title: viewModel.busy(StateObjects.progressSummary)
? '-'
: viewModel.totalCount.toString(),
subtitle: LocaleKeys.total_practices.tr()));
Widget _buildProgressPercentage(ProgressViewModel viewModel) => Expanded(
child: CustomColumn(
title: viewModel.busy(StateObjects.progressSummary)
? '-'
: '${viewModel.totalProgress.toString()}%',
subtitle: LocaleKeys.progress_percentage.tr()));
Widget _buildActionButton() => CustomElevatedButton(
height: 15, height: 15,
width: 200, width: 200,
borderRadius: 12, borderRadius: 12,
text: 'Continue Learning',
foregroundColor: kcWhite, foregroundColor: kcWhite,
backgroundColor: kcPrimaryColor, backgroundColor: kcPrimaryColor,
text: LocaleKeys.continue_learning.tr(),
); );
} }

View File

@ -1,5 +1,5 @@
name: yimaru_app name: yimaru_app
version: 0.1.31+33 version: 0.1.30+32
publish_to: 'none' publish_to: 'none'
description: A new Flutter project. description: A new Flutter project.