Merge branch 'release/0.1.30'

-feat(Payment): Add chapa as payment gateway for learn subscription
This commit is contained in:
BisratHailu 2026-05-30 00:03:25 +03:00
commit 2b2d449044
32 changed files with 638 additions and 614 deletions

View File

@ -49,7 +49,6 @@ import 'package:yimaru_app/services/vimeo_service.dart';
import 'package:yimaru_app/services/url_launcher_service.dart';
import 'package:yimaru_app/services/phone_caller_service.dart';
import 'package:yimaru_app/ui/views/learn_subscription/learn_subscription_view.dart';
import 'package:yimaru_app/ui/views/arif_pay/arif_pay_view.dart';
import 'package:yimaru_app/services/learn_service.dart';
import 'package:yimaru_app/ui/views/course_catalog/course_catalog_view.dart';
import 'package:yimaru_app/ui/views/course_unit/course_unit_view.dart';
@ -58,6 +57,7 @@ import 'package:yimaru_app/ui/views/landing/landing_view.dart';
import 'package:yimaru_app/ui/views/course_module/course_module_view.dart';
import 'package:yimaru_app/services/onboarding_service.dart';
import 'package:yimaru_app/ui/views/learn_course/learn_course_view.dart';
import 'package:yimaru_app/ui/views/payment/payment_view.dart';
// @stacked-import
@StackedApp(
@ -91,12 +91,12 @@ import 'package:yimaru_app/ui/views/learn_course/learn_course_view.dart';
MaterialRoute(page: LearnProgramView),
MaterialRoute(page: AssessmentView),
MaterialRoute(page: LearnSubscriptionView),
MaterialRoute(page: ArifPayView),
MaterialRoute(page: CourseCatalogView),
MaterialRoute(page: CourseUnitView),
MaterialRoute(page: LandingView),
MaterialRoute(page: CourseModuleView),
MaterialRoute(page: LearnCourseView),
MaterialRoute(page: PaymentView),
// @stacked-route
],
dependencies: [

View File

@ -9,7 +9,7 @@
import 'package:flutter/material.dart';
import 'package:flutter/material.dart' as _i37;
import 'package:stacked/stacked.dart' as _i1;
import 'package:stacked_services/stacked_services.dart' as _i46;
import 'package:stacked_services/stacked_services.dart' as _i47;
import 'package:yimaru_app/models/course.dart' as _i42;
import 'package:yimaru_app/models/course_catalog.dart' as _i44;
import 'package:yimaru_app/models/course_lesson.dart' as _i43;
@ -17,33 +17,33 @@ import 'package:yimaru_app/models/course_module.dart' as _i45;
import 'package:yimaru_app/models/learn_course.dart' as _i38;
import 'package:yimaru_app/models/learn_lesson.dart' as _i40;
import 'package:yimaru_app/models/learn_module.dart' as _i39;
import 'package:yimaru_app/models/learn_subscription.dart' as _i46;
import 'package:yimaru_app/ui/common/enmus.dart' as _i41;
import 'package:yimaru_app/ui/views/account_privacy/account_privacy_view.dart'
as _i9;
import 'package:yimaru_app/ui/views/arif_pay/arif_pay_view.dart' as _i31;
import 'package:yimaru_app/ui/views/assessment/assessment_view.dart' as _i29;
import 'package:yimaru_app/ui/views/call_support/call_support_view.dart'
as _i12;
import 'package:yimaru_app/ui/views/course/course_view.dart' as _i27;
import 'package:yimaru_app/ui/views/course_catalog/course_catalog_view.dart'
as _i32;
as _i31;
import 'package:yimaru_app/ui/views/course_lesson_detail/course_lesson_detail_view.dart'
as _i25;
import 'package:yimaru_app/ui/views/course_module/course_module_view.dart'
as _i35;
as _i34;
import 'package:yimaru_app/ui/views/course_payment/course_payment_view.dart'
as _i23;
import 'package:yimaru_app/ui/views/course_unit/course_unit_view.dart' as _i33;
import 'package:yimaru_app/ui/views/course_unit/course_unit_view.dart' as _i32;
import 'package:yimaru_app/ui/views/downloads/downloads_view.dart' as _i7;
import 'package:yimaru_app/ui/views/duolingo/duolingo_view.dart' as _i26;
import 'package:yimaru_app/ui/views/failure/failure_view.dart' as _i24;
import 'package:yimaru_app/ui/views/forget_password/forget_password_view.dart'
as _i20;
import 'package:yimaru_app/ui/views/home/home_view.dart' as _i2;
import 'package:yimaru_app/ui/views/landing/landing_view.dart' as _i34;
import 'package:yimaru_app/ui/views/landing/landing_view.dart' as _i33;
import 'package:yimaru_app/ui/views/language/language_view.dart' as _i13;
import 'package:yimaru_app/ui/views/learn_course/learn_course_view.dart'
as _i36;
as _i35;
import 'package:yimaru_app/ui/views/learn_lesson/learn_lesson_view.dart'
as _i19;
import 'package:yimaru_app/ui/views/learn_lesson_detail/learn_lesson_detail_view.dart'
@ -58,6 +58,7 @@ import 'package:yimaru_app/ui/views/learn_subscription/learn_subscription_view.d
as _i30;
import 'package:yimaru_app/ui/views/login/login_view.dart' as _i17;
import 'package:yimaru_app/ui/views/onboarding/onboarding_view.dart' as _i3;
import 'package:yimaru_app/ui/views/payment/payment_view.dart' as _i36;
import 'package:yimaru_app/ui/views/privacy_policy/privacy_policy_view.dart'
as _i14;
import 'package:yimaru_app/ui/views/profile/profile_view.dart' as _i5;
@ -131,8 +132,6 @@ class Routes {
static const learnSubscriptionView = '/learn-subscription-view';
static const arifPayView = '/arif-pay-view';
static const courseCatalogView = '/course-catalog-view';
static const courseUnitView = '/course-unit-view';
@ -143,6 +142,8 @@ class Routes {
static const learnCourseView = '/learn-course-view';
static const paymentView = '/payment-view';
static const all = <String>{
homeView,
onboardingView,
@ -173,12 +174,12 @@ class Routes {
learnProgramView,
assessmentView,
learnSubscriptionView,
arifPayView,
courseCatalogView,
courseUnitView,
landingView,
courseModuleView,
learnCourseView,
paymentView,
};
}
@ -300,29 +301,29 @@ class StackedRouter extends _i1.RouterBase {
Routes.learnSubscriptionView,
page: _i30.LearnSubscriptionView,
),
_i1.RouteDef(
Routes.arifPayView,
page: _i31.ArifPayView,
),
_i1.RouteDef(
Routes.courseCatalogView,
page: _i32.CourseCatalogView,
page: _i31.CourseCatalogView,
),
_i1.RouteDef(
Routes.courseUnitView,
page: _i33.CourseUnitView,
page: _i32.CourseUnitView,
),
_i1.RouteDef(
Routes.landingView,
page: _i34.LandingView,
page: _i33.LandingView,
),
_i1.RouteDef(
Routes.courseModuleView,
page: _i35.CourseModuleView,
page: _i34.CourseModuleView,
),
_i1.RouteDef(
Routes.learnCourseView,
page: _i36.LearnCourseView,
page: _i35.LearnCourseView,
),
_i1.RouteDef(
Routes.paymentView,
page: _i36.PaymentView,
),
];
@ -590,52 +591,52 @@ class StackedRouter extends _i1.RouterBase {
settings: data,
);
},
_i31.ArifPayView: (data) {
final args = data.getArgs<ArifPayViewArguments>(nullOk: false);
return _i37.MaterialPageRoute<dynamic>(
builder: (context) =>
_i31.ArifPayView(key: args.key, phone: args.phone),
settings: data,
);
},
_i32.CourseCatalogView: (data) {
_i31.CourseCatalogView: (data) {
final args = data.getArgs<CourseCatalogViewArguments>(
orElse: () => const CourseCatalogViewArguments(),
);
return _i37.MaterialPageRoute<dynamic>(
builder: (context) => _i32.CourseCatalogView(key: args.key),
builder: (context) => _i31.CourseCatalogView(key: args.key),
settings: data,
);
},
_i33.CourseUnitView: (data) {
_i32.CourseUnitView: (data) {
final args = data.getArgs<CourseUnitViewArguments>(nullOk: false);
return _i37.MaterialPageRoute<dynamic>(
builder: (context) =>
_i33.CourseUnitView(key: args.key, catalog: args.catalog),
_i32.CourseUnitView(key: args.key, catalog: args.catalog),
settings: data,
);
},
_i34.LandingView: (data) {
_i33.LandingView: (data) {
final args = data.getArgs<LandingViewArguments>(
orElse: () => const LandingViewArguments(),
);
return _i37.MaterialPageRoute<dynamic>(
builder: (context) => _i34.LandingView(key: args.key),
builder: (context) => _i33.LandingView(key: args.key),
settings: data,
);
},
_i35.CourseModuleView: (data) {
_i34.CourseModuleView: (data) {
final args = data.getArgs<CourseModuleViewArguments>(nullOk: false);
return _i37.MaterialPageRoute<dynamic>(
builder: (context) => _i35.CourseModuleView(
builder: (context) => _i34.CourseModuleView(
key: args.key, module: args.module, catalog: args.catalog),
settings: data,
);
},
_i36.LearnCourseView: (data) {
_i35.LearnCourseView: (data) {
final args = data.getArgs<LearnCourseViewArguments>(nullOk: false);
return _i37.MaterialPageRoute<dynamic>(
builder: (context) => _i36.LearnCourseView(key: args.key, id: args.id),
builder: (context) => _i35.LearnCourseView(key: args.key, id: args.id),
settings: data,
);
},
_i36.PaymentView: (data) {
final args = data.getArgs<PaymentViewArguments>(nullOk: false);
return _i37.MaterialPageRoute<dynamic>(
builder: (context) => _i36.PaymentView(
key: args.key, phone: args.phone, subscription: args.subscription),
settings: data,
);
},
@ -1378,33 +1379,6 @@ class LearnSubscriptionViewArguments {
}
}
class ArifPayViewArguments {
const ArifPayViewArguments({
this.key,
required this.phone,
});
final _i37.Key? key;
final String phone;
@override
String toString() {
return '{"key": "$key", "phone": "$phone"}';
}
@override
bool operator ==(covariant ArifPayViewArguments other) {
if (identical(this, other)) return true;
return other.key == key && other.phone == phone;
}
@override
int get hashCode {
return key.hashCode ^ phone.hashCode;
}
}
class CourseCatalogViewArguments {
const CourseCatalogViewArguments({this.key});
@ -1535,7 +1509,39 @@ class LearnCourseViewArguments {
}
}
extension NavigatorStateExtension on _i46.NavigationService {
class PaymentViewArguments {
const PaymentViewArguments({
this.key,
required this.phone,
required this.subscription,
});
final _i37.Key? key;
final String phone;
final _i46.LearnSubscription subscription;
@override
String toString() {
return '{"key": "$key", "phone": "$phone", "subscription": "$subscription"}';
}
@override
bool operator ==(covariant PaymentViewArguments other) {
if (identical(this, other)) return true;
return other.key == key &&
other.phone == phone &&
other.subscription == subscription;
}
@override
int get hashCode {
return key.hashCode ^ phone.hashCode ^ subscription.hashCode;
}
}
extension NavigatorStateExtension on _i47.NavigationService {
Future<dynamic> navigateToHomeView({
_i37.Key? key,
int? routerId,
@ -2030,23 +2036,6 @@ extension NavigatorStateExtension on _i46.NavigationService {
transition: transition);
}
Future<dynamic> navigateToArifPayView({
_i37.Key? key,
required String phone,
int? routerId,
bool preventDuplicates = true,
Map<String, String>? parameters,
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
transition,
}) async {
return navigateTo<dynamic>(Routes.arifPayView,
arguments: ArifPayViewArguments(key: key, phone: phone),
id: routerId,
preventDuplicates: preventDuplicates,
parameters: parameters,
transition: transition);
}
Future<dynamic> navigateToCourseCatalogView({
_i37.Key? key,
int? routerId,
@ -2132,6 +2121,25 @@ extension NavigatorStateExtension on _i46.NavigationService {
transition: transition);
}
Future<dynamic> navigateToPaymentView({
_i37.Key? key,
required String phone,
required _i46.LearnSubscription subscription,
int? routerId,
bool preventDuplicates = true,
Map<String, String>? parameters,
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
transition,
}) async {
return navigateTo<dynamic>(Routes.paymentView,
arguments: PaymentViewArguments(
key: key, phone: phone, subscription: subscription),
id: routerId,
preventDuplicates: preventDuplicates,
parameters: parameters,
transition: transition);
}
Future<dynamic> replaceWithHomeView({
_i37.Key? key,
int? routerId,
@ -2626,23 +2634,6 @@ extension NavigatorStateExtension on _i46.NavigationService {
transition: transition);
}
Future<dynamic> replaceWithArifPayView({
_i37.Key? key,
required String phone,
int? routerId,
bool preventDuplicates = true,
Map<String, String>? parameters,
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
transition,
}) async {
return replaceWith<dynamic>(Routes.arifPayView,
arguments: ArifPayViewArguments(key: key, phone: phone),
id: routerId,
preventDuplicates: preventDuplicates,
parameters: parameters,
transition: transition);
}
Future<dynamic> replaceWithCourseCatalogView({
_i37.Key? key,
int? routerId,
@ -2727,4 +2718,23 @@ extension NavigatorStateExtension on _i46.NavigationService {
parameters: parameters,
transition: transition);
}
Future<dynamic> replaceWithPaymentView({
_i37.Key? key,
required String phone,
required _i46.LearnSubscription subscription,
int? routerId,
bool preventDuplicates = true,
Map<String, String>? parameters,
Widget Function(BuildContext, Animation<double>, Animation<double>, Widget)?
transition,
}) async {
return replaceWith<dynamic>(Routes.paymentView,
arguments: PaymentViewArguments(
key: key, phone: phone, subscription: subscription),
id: routerId,
preventDuplicates: preventDuplicates,
parameters: parameters,
transition: transition);
}
}

View File

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

View File

@ -25,11 +25,9 @@ enum ProgressStatuses { pending, started, completed }
// Duolingo types
enum DuolingoAssessments { speaking, reading, writing, listening }
// Practice reason
enum PracticeReason { course, module, lesson, previousModule, previousCourse }
// State object
enum StateObjects {
none,

View File

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

View File

@ -27,10 +27,8 @@ class AssessmentResultScreen extends ViewModelWidget<AssessmentViewModel> {
children: _buildScaffoldChildren(viewModel),
);
List<Widget> _buildScaffoldChildren(AssessmentViewModel viewModel) => [
_buildAppBar(viewModel),
_buildExpandedBody(viewModel)
];
List<Widget> _buildScaffoldChildren(AssessmentViewModel viewModel) =>
[_buildAppBar(viewModel), _buildExpandedBody(viewModel)];
Widget _buildAppBar(AssessmentViewModel viewModel) => LargeAppBar(
showBackButton: true,

View File

@ -44,10 +44,8 @@ class StartLessonScreen extends ViewModelWidget<AssessmentViewModel> {
children: _buildScaffoldChildren(viewModel),
);
List<Widget> _buildScaffoldChildren(AssessmentViewModel viewModel) => [
_buildAppBar(viewModel),
_buildExpandedBody(viewModel)
];
List<Widget> _buildScaffoldChildren(AssessmentViewModel viewModel) =>
[_buildAppBar(viewModel), _buildExpandedBody(viewModel)];
Widget _buildAppBar(AssessmentViewModel viewModel) => LargeAppBar(
showBackButton: true,

View File

@ -86,10 +86,8 @@ class ResetPasswordScreen extends ViewModelWidget<ForgetPasswordViewModel> {
children: _buildScaffoldChildren(viewModel),
);
List<Widget> _buildScaffoldChildren(ForgetPasswordViewModel viewModel) => [
_buildAppBar(viewModel),
_buildExpandedBody(viewModel)
];
List<Widget> _buildScaffoldChildren(ForgetPasswordViewModel viewModel) =>
[_buildAppBar(viewModel), _buildExpandedBody(viewModel)];
Widget _buildAppBar(ForgetPasswordViewModel viewModel) => LargeAppBar(
showBackButton: true,

View File

@ -26,13 +26,12 @@ class LearnLessonView extends StackedView<LearnLessonViewModel> {
required LearnLesson lesson,
required BuildContext context,
required LearnLessonViewModel viewModel}) async {
if (lesson.access?.isAccessible ?? false) {
if (lesson.access?.isAccessible ?? false) {
await viewModel.navigateToLearnPractice(lesson.id ?? 0);
} else {
await _showSheet(context: context, viewModel: viewModel);
}
/*
if (index > 1) {
/* if (index > 1) {
if (viewModel.user?.subscriptionStatus?.toLowerCase() == 'subscribed') {
if (lesson.access?.isAccessible ?? false) {
await viewModel.navigateToLearnPractice(lesson.id ?? 0);
@ -226,7 +225,7 @@ class LearnLessonView extends StackedView<LearnLessonViewModel> {
itemBuilder: (context, index) => _buildTile(
index: index,
lesson: viewModel.lessons[index],
last: index == viewModel.lessons.length - 1 ,
last: index == viewModel.lessons.length - 1,
onPracticeTap: () async => await _onPractice(
index: index,
context: context,
@ -252,7 +251,6 @@ class LearnLessonView extends StackedView<LearnLessonViewModel> {
LearnLessonTile(
last: last,
index: index,
lesson: lesson,
onLessonTap: onLessonTap,
onPracticeTap: onPracticeTap,

View File

@ -59,14 +59,15 @@ class LearnLessonViewModel extends ReactiveViewModel {
await _navigationService.navigateToLearnSubscriptionView();
Future<void> navigateToLearnLessonDetail(
{
required int index,
required bool hasPractice,
{required int index,
required bool hasPractice,
required LearnLesson lesson,
required LearnModule module}) async =>
await _navigationService.navigateToLearnLessonDetailView(
index: index,
lesson: lesson, module: module, hasPractice: hasPractice);
index: index,
lesson: lesson,
module: module,
hasPractice: hasPractice);
// Remote api call

View File

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

View File

@ -24,7 +24,7 @@ class LearnModuleView extends StackedView<LearnModuleViewModel> {
{required BuildContext context,
required LearnModule module,
required LearnModuleViewModel viewModel}) async {
if (module.access?.completedCount == module.access?.totalCount ) {
if (module.access?.completedCount == module.access?.totalCount) {
await viewModel.navigateToLearnPractice(
id: module.id ?? 0, module: module.name ?? '');
} else {

View File

@ -31,6 +31,10 @@ class LearnSubscriptionViewModel extends FormViewModel {
int get selectedIndex => _selectedIndex;
LearnSubscription? _selectedSubscription;
LearnSubscription? get selectedSubscription => _selectedSubscription;
List<LearnSubscription> _subscriptions = [];
List<LearnSubscription> get subscriptions => _subscriptions;
@ -40,6 +44,13 @@ class LearnSubscriptionViewModel extends FormViewModel {
_focusPhoneNumber = true;
rebuildUi();
}
//Learn subscriptions
void setSelectedPricing(int index) {
_selectedIndex = index;
_selectedSubscription = _subscriptions[index];
rebuildUi();
}
// In-app navigation
@ -60,16 +71,11 @@ class LearnSubscriptionViewModel extends FormViewModel {
// Navigation
void pop() => _navigationService.back();
Future<void> navigateToArifPay(String phone) async {
Future<void> navigateToArifPay(
{required String phone, required LearnSubscription? subscription}) async {
pop();
await _navigationService.navigateToArifPayView(phone: phone);
}
//Learn subscriptions
void setSelectedPricing(int index) {
_selectedIndex = index;
rebuildUi();
await _navigationService.navigateToPaymentView(
phone: phone, subscription: subscription ?? _subscriptions[0]);
}
// Remote api call

View File

@ -178,8 +178,9 @@ class LearnSubscriptionFormScreen
? kcPrimaryColor
: kcPrimaryColor.withOpacity(0.1),
onTap: phoneNumberController.text.isNotEmpty
? () async =>
await viewModel.navigateToArifPay(phoneNumberController.text)
? () async => await viewModel.navigateToArifPay(
phone: phoneNumberController.text,
subscription: viewModel.selectedSubscription)
: null,
);

View File

@ -41,10 +41,8 @@ class AgeGroupFormScreen extends ViewModelWidget<OnboardingViewModel> {
children: _buildScaffoldChildren(viewModel),
);
List<Widget> _buildScaffoldChildren(OnboardingViewModel viewModel) => [
_buildAppBar(viewModel),
_buildExpandedBody(viewModel)
];
List<Widget> _buildScaffoldChildren(OnboardingViewModel viewModel) =>
[_buildAppBar(viewModel), _buildExpandedBody(viewModel)];
Widget _buildExpandedBody(OnboardingViewModel viewModel) =>
Expanded(child: _buildColumnScroller(viewModel));

View File

@ -42,10 +42,8 @@ class ChallengeFormScreen extends ViewModelWidget<OnboardingViewModel> {
children: _buildScaffoldChildren(viewModel),
);
List<Widget> _buildScaffoldChildren(OnboardingViewModel viewModel) => [
_buildAppBar(viewModel),
_buildExpandedBody(viewModel)
];
List<Widget> _buildScaffoldChildren(OnboardingViewModel viewModel) =>
[_buildAppBar(viewModel), _buildExpandedBody(viewModel)];
Widget _buildExpandedBody(OnboardingViewModel viewModel) =>
Expanded(child: _buildBodyScroller(viewModel));

View File

@ -58,10 +58,8 @@ class CountryRegionFormScreen extends ViewModelWidget<OnboardingViewModel> {
children: _buildScaffoldChildren(viewModel),
);
List<Widget> _buildScaffoldChildren(OnboardingViewModel viewModel) => [
_buildAppBar(viewModel),
_buildExpandedBody(viewModel)
];
List<Widget> _buildScaffoldChildren(OnboardingViewModel viewModel) =>
[_buildAppBar(viewModel), _buildExpandedBody(viewModel)];
Widget _buildExpandedBody(OnboardingViewModel viewModel) =>
Expanded(child: _buildBodyWrapper(viewModel));

View File

@ -43,10 +43,8 @@ class EducationalBackgroundFormScreen
children: _buildScaffoldChildren(viewModel),
);
List<Widget> _buildScaffoldChildren(OnboardingViewModel viewModel) => [
_buildAppBar(viewModel),
_buildExpandedBody(viewModel)
];
List<Widget> _buildScaffoldChildren(OnboardingViewModel viewModel) =>
[_buildAppBar(viewModel), _buildExpandedBody(viewModel)];
Widget _buildExpandedBody(OnboardingViewModel viewModel) =>
Expanded(child: _buildColumnScroller(viewModel));

View File

@ -40,10 +40,8 @@ class FullNameFormScreen extends ViewModelWidget<OnboardingViewModel> {
children: _buildScaffoldChildren(viewModel),
);
List<Widget> _buildScaffoldChildren(OnboardingViewModel viewModel) => [
_buildAppBar(viewModel),
_buildExpandedBody(viewModel)
];
List<Widget> _buildScaffoldChildren(OnboardingViewModel viewModel) =>
[_buildAppBar(viewModel), _buildExpandedBody(viewModel)];
Widget _buildExpandedBody(OnboardingViewModel viewModel) =>
Expanded(child: _buildBodyWrapper(viewModel));

View File

@ -40,10 +40,8 @@ class GenderFormScreen extends ViewModelWidget<OnboardingViewModel> {
children: _buildScaffoldChildren(viewModel),
);
List<Widget> _buildScaffoldChildren(OnboardingViewModel viewModel) => [
_buildAppBar(viewModel),
_buildExpandedBody(viewModel)
];
List<Widget> _buildScaffoldChildren(OnboardingViewModel viewModel) =>
[_buildAppBar(viewModel), _buildExpandedBody(viewModel)];
Widget _buildExpandedBody(OnboardingViewModel viewModel) =>
Expanded(child: _buildBodyWrapper(viewModel));

View File

@ -25,8 +25,6 @@ class LanguageGoalFormScreens extends ViewModelWidget<OnboardingViewModel> {
return Icons.book;
}
String getSubtitle(int index) {
switch (index) {
case 0:
@ -49,7 +47,6 @@ class LanguageGoalFormScreens extends ViewModelWidget<OnboardingViewModel> {
Map<String, dynamic> data = {
'language_goal': viewModel.selectedLanguageGoal?.code,
};
viewModel.addUserData(data);
@ -70,10 +67,8 @@ class LanguageGoalFormScreens extends ViewModelWidget<OnboardingViewModel> {
children: _buildScaffoldChildren(viewModel),
);
List<Widget> _buildScaffoldChildren(OnboardingViewModel viewModel) => [
_buildAppBar(viewModel),
_buildExpandedBody(viewModel)
];
List<Widget> _buildScaffoldChildren(OnboardingViewModel viewModel) =>
[_buildAppBar(viewModel), _buildExpandedBody(viewModel)];
Widget _buildExpandedBody(OnboardingViewModel viewModel) =>
Expanded(child: _buildBodyScroller(viewModel));
@ -135,12 +130,12 @@ class LanguageGoalFormScreens extends ViewModelWidget<OnboardingViewModel> {
Widget _buildLanguageGoals(OnboardingViewModel viewModel) => ListView.builder(
shrinkWrap: true,
itemCount: viewModel.languageGoals.length,
itemCount: viewModel.languageGoals.length,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) => _buildLanguageGoal(
icon: getIcon(index),
subtitle: getSubtitle(index),
title:viewModel.languageGoals[index].label ?? '',
title: viewModel.languageGoals[index].label ?? '',
selected:
viewModel.isSelectedLanguageGoal(viewModel.languageGoals[index]),
onTap: () =>

View File

@ -42,10 +42,8 @@ class LearningGoalFormScreen extends ViewModelWidget<OnboardingViewModel> {
children: _buildScaffoldChildren(viewModel),
);
List<Widget> _buildScaffoldChildren(OnboardingViewModel viewModel) => [
_buildAppBar(viewModel),
_buildExpandedBody(viewModel)
];
List<Widget> _buildScaffoldChildren(OnboardingViewModel viewModel) =>
[_buildAppBar(viewModel), _buildExpandedBody(viewModel)];
Widget _buildExpandedBody(OnboardingViewModel viewModel) =>
Expanded(child: _buildBodyScroller(viewModel));

View File

@ -43,10 +43,8 @@ class OccupationFormScreen extends ViewModelWidget<OnboardingViewModel> {
children: _buildScaffoldChildren(viewModel),
);
List<Widget> _buildScaffoldChildren(OnboardingViewModel viewModel) => [
_buildAppBar(viewModel),
_buildExpandedBody(viewModel)
];
List<Widget> _buildScaffoldChildren(OnboardingViewModel viewModel) =>
[_buildAppBar(viewModel), _buildExpandedBody(viewModel)];
Widget _buildExpandedBody(OnboardingViewModel viewModel) =>
Expanded(child: _buildBodyWrapper(viewModel));

View File

@ -45,10 +45,8 @@ class TopicFormScreen extends ViewModelWidget<OnboardingViewModel> {
children: _buildScaffoldChildren(viewModel),
);
List<Widget> _buildScaffoldChildren(OnboardingViewModel viewModel) => [
_buildAppBar(viewModel),
_buildExpandedBody(viewModel)
];
List<Widget> _buildScaffoldChildren(OnboardingViewModel viewModel) =>
[_buildAppBar(viewModel), _buildExpandedBody(viewModel)];
Widget _buildAppBar(OnboardingViewModel viewModel) => LargeAppBar(
showBackButton: true,

View File

@ -1,55 +1,61 @@
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:stacked/stacked.dart';
import 'package:yimaru_app/ui/common/app_constants.dart';
import 'package:yimaru_app/ui/common/enmus.dart';
import 'package:yimaru_app/ui/common/ui_helpers.dart';
import 'package:yimaru_app/ui/widgets/page_loading_indicator.dart';
import 'arif_pay_viewmodel.dart';
import '../../../models/learn_subscription.dart';
import '../../common/app_constants.dart';
import '../../common/enmus.dart';
import '../../common/ui_helpers.dart';
import '../../widgets/page_loading_indicator.dart';
import 'payment_viewmodel.dart';
class ArifPayView extends StackedView<ArifPayViewModel> {
class PaymentView extends StackedView<PaymentViewModel> {
final String phone;
final LearnSubscription subscription;
const ArifPayView({Key? key, required this.phone}) : super(key: key);
const PaymentView({Key? key, required this.phone, required this.subscription})
: super(key: key);
void _error(ArifPayViewModel viewModel) => viewModel.pop();
void _error(PaymentViewModel viewModel) => viewModel.pop();
Future<void> _success(ArifPayViewModel viewModel) async {
Future<void> _success(PaymentViewModel viewModel) async {
await viewModel.updatePaymentStatus();
await viewModel.replaceWithHome();
}
@override
void onViewModelReady(ArifPayViewModel viewModel) async {
await viewModel.createLearnSubscriptionRequest(phone);
void onViewModelReady(PaymentViewModel viewModel) async {
await viewModel.createLearnSubscriptionRequest(phone: phone,subscription: subscription);
super.onViewModelReady(viewModel);
}
@override
ArifPayViewModel viewModelBuilder(BuildContext context) => ArifPayViewModel();
PaymentViewModel viewModelBuilder(
BuildContext context,
) =>
PaymentViewModel();
@override
Widget builder(
BuildContext context,
ArifPayViewModel viewModel,
PaymentViewModel viewModel,
Widget? child,
) =>
_buildScaffoldWrapper(viewModel);
Widget _buildScaffoldWrapper(ArifPayViewModel viewModel) =>
Widget _buildScaffoldWrapper(PaymentViewModel viewModel) =>
Scaffold(body: _buildScaffoldState(viewModel));
Widget _buildScaffoldState(ArifPayViewModel viewModel) =>
Widget _buildScaffoldState(PaymentViewModel viewModel) =>
viewModel.busy(StateObjects.learnSubscription)
? const PageLoadingIndicator()
: _buildScaffold(viewModel);
Widget _buildScaffold(ArifPayViewModel viewModel) =>
Widget _buildScaffold(PaymentViewModel viewModel) =>
SafeArea(child: _buildBody(viewModel));
Widget _buildBody(ArifPayViewModel viewModel) => InAppWebView(
Widget _buildBody(PaymentViewModel viewModel) => InAppWebView(
initialUrlRequest:
URLRequest(url: WebUri(viewModel.request?.paymentUrl ?? '')),
onUpdateVisitedHistory: (controller, url, androidIsReload) async {

View File

@ -1,17 +1,17 @@
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';
import 'package:yimaru_app/ui/common/enmus.dart';
import '../../../app/app.locator.dart';
import '../../../app/app.router.dart';
import '../../../models/learn_subscription.dart';
import '../../../models/learn_subscription_request.dart';
import '../../../models/user.dart';
import '../../../services/api_service.dart';
import '../../../services/authentication_service.dart';
import '../../../services/status_checker_service.dart';
import '../../common/ui_helpers.dart';
import '../../common/enmus.dart';
class ArifPayViewModel extends ReactiveViewModel {
class PaymentViewModel extends ReactiveViewModel {
// Dependency injection
final _apiService = locator<ApiService>();
@ -30,6 +30,7 @@ class ArifPayViewModel extends ReactiveViewModel {
User? get _user => _authenticationService.user;
User? get user => _user;
// Learn subscription request
LearnSubscriptionRequest? _request;
@ -44,18 +45,18 @@ class ArifPayViewModel extends ReactiveViewModel {
// Remote api call
// Learn subscription
Future<void> createLearnSubscriptionRequest(String phone) async =>
await runBusyFuture(_createLearnSubscriptionRequest(phone),
Future<void> createLearnSubscriptionRequest({required String phone,required LearnSubscription subscription}) async =>
await runBusyFuture(_createLearnSubscriptionRequest(phone: phone,subscription: subscription),
busyObject: StateObjects.learnSubscription);
Future<void> _createLearnSubscriptionRequest(String phone) async {
print('MY SUMMARIES : PAYMENT');
Future<void> _createLearnSubscriptionRequest({required String phone,required LearnSubscription subscription}) async {
if (await _statusChecker.checkConnection()) {
Map<String, dynamic> data = {
'plan_id': 1,
'provider': 'CHAPA',
'phone': '251$phone',
'email': 'test@gmail.com',
'plan_id': subscription.id,
};
Map<String, dynamic> response =

View File

@ -183,7 +183,7 @@ class CourseModuleTileLarge extends ViewModelWidget<CourseModuleViewModel> {
Widget _buildSheet(CourseModuleViewModel viewModel) => FinishPracticeSheet(
onTap: viewModel.pop,
practice: PracticeReason.lesson,
practice: PracticeReason.lesson,
);
Widget _buildCourseModules(CourseModuleViewModel viewModel) =>

View File

@ -26,11 +26,11 @@ class LearnCourseTile extends ViewModelWidget<LearnCourseViewModel> {
Widget build(BuildContext context, LearnCourseViewModel viewModel) =>
_buildExpansionTileCardWrapper(viewModel);
Widget _buildExpansionTileCardWrapper(LearnCourseViewModel viewModel)=> GestureDetector(
onTap: !(course.access?.isAccessible ?? false) ? onPracticeTap:null,
child: _buildExpansionTileCard(viewModel),
);
Widget _buildExpansionTileCardWrapper(LearnCourseViewModel viewModel) =>
GestureDetector(
onTap: !(course.access?.isAccessible ?? false) ? onPracticeTap : null,
child: _buildExpansionTileCard(viewModel),
);
Widget _buildExpansionTileCard(LearnCourseViewModel viewModel) => Container(
margin: const EdgeInsets.only(bottom: 15),

View File

@ -25,11 +25,13 @@ class LearnModuleTile extends ViewModelWidget<LearnModuleViewModel> {
Widget build(BuildContext context, LearnModuleViewModel viewModel) =>
_buildExpansionTileCardWrapper(context: context, viewModel: viewModel);
Widget _buildExpansionTileCardWrapper( {required BuildContext context,
required LearnModuleViewModel viewModel})=> GestureDetector(
onTap: !(module.access?.isAccessible ?? false) ? onPracticeTap:null,
child: _buildExpansionTileCard(context: context,viewModel: viewModel),
);
Widget _buildExpansionTileCardWrapper(
{required BuildContext context,
required LearnModuleViewModel viewModel}) =>
GestureDetector(
onTap: !(module.access?.isAccessible ?? false) ? onPracticeTap : null,
child: _buildExpansionTileCard(context: context, viewModel: viewModel),
);
Widget _buildExpansionTileCard(
{required BuildContext context,
required LearnModuleViewModel viewModel}) =>

View File

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

View File

@ -4,7 +4,7 @@ import 'package:yimaru_app/app/app.locator.dart';
import '../helpers/test_helpers.dart';
void main() {
group('ArifPayViewModel Tests -', () {
group('PaymentViewModel Tests -', () {
setUp(() => registerServices());
tearDown(() => locator.reset());
});