diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 54d579f..5da9043 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -10,6 +10,7 @@ android:exported="true" android:launchMode="singleTop" android:taskAffinity="" + android:screenOrientation="portrait" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" diff --git a/assets/audios/home.mp3 b/assets/audios/home.mp3 index 637448f..156e017 100644 Binary files a/assets/audios/home.mp3 and b/assets/audios/home.mp3 differ diff --git a/assets/audios/home3.mp3 b/assets/audios/home3.mp3 new file mode 100644 index 0000000..637448f Binary files /dev/null and b/assets/audios/home3.mp3 differ diff --git a/assets/audios/question.mp3 b/assets/audios/question.mp3 index 495f6c1..4db365f 100644 Binary files a/assets/audios/question.mp3 and b/assets/audios/question.mp3 differ diff --git a/assets/audios/question3.mp3 b/assets/audios/question3.mp3 new file mode 100644 index 0000000..495f6c1 Binary files /dev/null and b/assets/audios/question3.mp3 differ diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist index 1dc6cf7..391a902 100644 --- a/ios/Flutter/AppFrameworkInfo.plist +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -20,7 +20,5 @@ ???? CFBundleVersion 1.0 - MinimumOSVersion - 13.0 diff --git a/ios/Podfile.lock b/ios/Podfile.lock index b4f7cce..03b68b3 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -12,9 +12,6 @@ PODS: - FlutterMacOS - package_info_plus (0.4.5): - Flutter - - path_provider_foundation (0.0.1): - - Flutter - - FlutterMacOS - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS @@ -34,7 +31,6 @@ DEPENDENCIES: - flutter_archive (from `.symlinks/plugins/flutter_archive/ios`) - just_audio (from `.symlinks/plugins/just_audio/darwin`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`) @@ -57,8 +53,6 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/just_audio/darwin" package_info_plus: :path: ".symlinks/plugins/package_info_plus/ios" - path_provider_foundation: - :path: ".symlinks/plugins/path_provider_foundation/darwin" shared_preferences_foundation: :path: ".symlinks/plugins/shared_preferences_foundation/darwin" url_launcher_ios: @@ -75,10 +69,9 @@ SPEC CHECKSUMS: flutter_archive: ad8edfd7f7d1bb12058d05424ba93e27d9930efe just_audio: 4e391f57b79cad2b0674030a00453ca5ce817eed package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 - path_provider_foundation: bb55f6dbba17d0dccd6737fe6f7f34fbd0376880 shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b - video_player_avfoundation: dd410b52df6d2466a42d28550e33e4146928280a + video_player_avfoundation: 3453f792138786248960ca029747fcd9f318ef52 wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556 ZIPFoundation: b8c29ea7ae353b309bc810586181fd073cb3312c diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 6266644..c30b367 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -2,12 +2,15 @@ import Flutter import UIKit @main -@objc class AppDelegate: FlutterAppDelegate { +@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { - GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } + + func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) { + GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry) + } } diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 3291dc0..145dbd5 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -2,11 +2,8 @@ - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - + CADisableMinimumFrameDurationOnPhone + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName @@ -29,6 +26,34 @@ $(FLUTTER_BUILD_NUMBER) LSRequiresIPhoneOS + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneClassName + UIWindowScene + UISceneConfigurationName + flutter + UISceneDelegateClassName + FlutterSceneDelegate + UISceneStoryboardFile + Main + + + + + UIApplicationSupportsIndirectInputEvents + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile @@ -36,19 +61,10 @@ UISupportedInterfaceOrientations UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - CADisableMinimumFrameDurationOnPhone - - UIApplicationSupportsIndirectInputEvents - diff --git a/lib/features/intro/presentation/bloc/intro_bloc.dart b/lib/features/intro/presentation/bloc/intro_bloc.dart index 2e8d66b..c314057 100644 --- a/lib/features/intro/presentation/bloc/intro_bloc.dart +++ b/lib/features/intro/presentation/bloc/intro_bloc.dart @@ -73,6 +73,7 @@ class IntroBloc extends Bloc { /// ------------Functions------------ Future goToHomePage() async { + currentPodController.pause(); await LocalStorage.saveData(key: MyConstants.firstIntro, value: 'true'); if (MyContext.get.mounted) { MyContext.get.goNamed(Routes.homePage); @@ -148,6 +149,7 @@ class IntroBloc extends Bloc { Emitter emit, ) async { _shouldResumeCurrentVideo = false; + currentPodController.pause(); switch (state.currentIntro) { case 0: podController2.play(); diff --git a/lib/features/language/presentation/ui/language_page.dart b/lib/features/language/presentation/ui/language_page.dart index eee449e..e69de29 100644 --- a/lib/features/language/presentation/ui/language_page.dart +++ b/lib/features/language/presentation/ui/language_page.dart @@ -1,325 +0,0 @@ -import 'package:auto_size_text/auto_size_text.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:go_router/go_router.dart'; -import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart'; -import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart'; -import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart'; -import 'package:hadi_hoda_flutter/core/constants/my_constants.dart'; -import 'package:hadi_hoda_flutter/core/routers/my_routes.dart'; -import 'package:hadi_hoda_flutter/core/status/base_status.dart'; -import 'package:hadi_hoda_flutter/core/utils/my_localization.dart'; -import 'package:hadi_hoda_flutter/core/utils/screen_size.dart'; -import 'package:hadi_hoda_flutter/core/utils/set_platform_size.dart'; -import 'package:hadi_hoda_flutter/core/widgets/button/my_blue_button.dart'; -import 'package:hadi_hoda_flutter/core/widgets/error/error_state.dart'; -import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; -import 'package:hadi_hoda_flutter/features/app/presentation/bloc/app_bloc.dart'; -import 'package:hadi_hoda_flutter/features/app/presentation/bloc/app_event.dart'; -import 'package:hadi_hoda_flutter/features/download/domain/entities/download_entity.dart'; -import 'package:hadi_hoda_flutter/features/download/presentation/bloc/download_bloc.dart'; -import 'package:hadi_hoda_flutter/features/download/presentation/bloc/download_event.dart'; -import 'package:hadi_hoda_flutter/features/language/presentation/bloc/language_bloc.dart'; -import 'package:hadi_hoda_flutter/features/language/presentation/bloc/language_event.dart'; -import 'package:hadi_hoda_flutter/features/language/presentation/bloc/language_state.dart'; -import 'package:wheel_chooser/wheel_chooser.dart'; - -import '../../../../core/widgets/animations/rotation_anim.dart'; -import '../../domain/entity/language_entity.dart'; - -class LanguagePage extends StatefulWidget { - const LanguagePage({super.key}); - - @override - State createState() => _LanguagePageState(); -} - -class _LanguagePageState extends State { - final controller = FixedExtentScrollController(initialItem: 50); - bool _isEnabled = false; - LanguageEntity? _selectedLanguage; - - @override - void initState() { - super.initState(); - _selectedLanguage = - context.read().state.selectedLanguage ?? - const LanguageEntity( - code: 'en', - title: '', - displayName: 'English (English', - ); - context.read().add(const GetLanguagesEvent()); - } - - @override - void dispose() { - controller.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Container( - height: context.heightScreen, - width: context.widthScreen, - decoration: BoxDecoration( - gradient: const LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [Color(0XFF00154C), Color(0XFF150532)], - ), - image: DecorationImage( - image: const AssetImage(MyAssets.pattern), - scale: 3, - repeat: ImageRepeat.repeat, - colorFilter: ColorFilter.mode( - Colors.white.withValues(alpha: 0.2), - BlendMode.srcIn, - ), - ), - ), - child: BlocConsumer( - listener: (context, state) async { - if (state.languages.isNotEmpty && !_isEnabled) { - int targetIndex = 0; - if (state.selectedLanguage != null) { - targetIndex = state.languages.indexWhere( - (l) => l.code == state.selectedLanguage!.code, - ); - if (targetIndex == -1) targetIndex = 0; - } - - await Future.delayed(const Duration(milliseconds: 50)); - if (controller.hasClients) { - await controller.animateToItem( - targetIndex, - duration: const Duration(seconds: 1), - curve: Curves.easeOutCirc, - ); - - if (state.selectedLanguage == null && context.mounted) { - context.read().add( - SelectLanguageEvent(state.languages[targetIndex]), - ); - } - } - setState(() => _isEnabled = true); - } - }, - builder: (context, state) { - if (state.getLanguagesStatus is BaseLoading) { - return Center(child: _loading(context)); - } - if (state.getLanguagesStatus is BaseError) { - return Padding( - padding: EdgeInsets.symmetric( - vertical: - MediaQuery.viewPaddingOf(context).bottom + MySpaces.s16, - horizontal: 60, - ), - child: ErrorState( - onTap: () { - context.read().add(const GetLanguagesEvent()); - }, - ), - ); - } - - final double itemSize = - setSize(context: context, mobile: 45, tablet: 60) ?? 45; - final selectStyle = MYTextStyle.titr1.copyWith( - // Keep same size as before (WheelChooser.choices) - fontSize: itemSize * 0.34, - color: Colors.white, - ); - final unSelectStyle = MYTextStyle.titr1.copyWith( - fontSize: itemSize * 0.34, - color: Colors.white.withValues(alpha: 0.5), - ); - return Padding( - padding: EdgeInsets.only( - left: setSize(context: context, mobile: 50, tablet: 0.3.w) ?? 0, - right: - setSize(context: context, mobile: 50, tablet: 0.3.w) ?? 0, - bottom: MySpaces.s40 + MediaQuery.paddingOf(context).bottom, - top: 60, - ), - child: Column( - children: [ - _title(context), - const SizedBox(height: 72), - Expanded( - child: ShaderMask( - shaderCallback: (rect) { - return const LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - Color(0x00FFF7FA), - Color(0x1AFFF7FA), - Color(0xFFFFFFFF), - Color(0x1AFEFCFD), - Color(0x00FEFCFD), - ], - ).createShader(rect); - }, - child: Stack( - children: [ - Center( - child: Container( - width: double.infinity, - alignment: Alignment.centerLeft, - height: itemSize, - padding: const EdgeInsets.symmetric( - horizontal: 18, - ), - decoration: BoxDecoration( - color: Colors.white.withValues(alpha: .2), - borderRadius: BorderRadius.circular(12), - ), - child: Transform.translate( - offset: - const Offset(-4, 0), - child: const MyImage(image: MyAssets.check), - ), - ), - ), - WheelChooser.custom( - controller: controller, - datas: null, - startPosition: null, - perspective: 0.00000001, - listWidth: double.infinity, - listHeight: double.infinity, - itemSize: itemSize, - isInfinite: true, - onValueChanged: (position) { - if (state.languages.isEmpty) return; - final pos = position is int - ? position - : int.tryParse(position.toString()) ?? 0; - final index = - ((pos % state.languages.length) + - state.languages.length) % - state.languages.length; - final lang = state.languages[index]; - setState(() { - _selectedLanguage = lang; - }); - }, - children: state.languages.map((lang) { - final isSelected = - _selectedLanguage?.code == lang.code; - return Center( - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 36, - ), - child: MediaQuery( - data: MediaQuery.of(context).copyWith( - textScaler: const TextScaler.linear(1.5), - ), - child: AutoSizeText( - lang.displayName, - textAlign: TextAlign.center, - maxLines: 2, - minFontSize: 10, - stepGranularity: 0.5, - overflow: TextOverflow.ellipsis, - style: isSelected - ? selectStyle - : unSelectStyle, - ), - ), - ), - ); - }).toList(), - ), - ], - ), - ), - ), - const SizedBox(height: 72), - _btn(context, state), - ], - ), - ); - }, - ), - ), - ); - } - - Widget _loading(BuildContext context) { - return RotationAnim( - child: MyImage( - image: MyAssets.loading, - size: setSize(context: context, mobile: 110, tablet: 145), - ), - ); - } - - Widget _title(BuildContext context) { - return Row( - spacing: MySpaces.s10, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const MyImage(image: MyAssets.lang, size: 28), - AutoSizeText( - context.translate.select_language, - minFontSize: 12, - maxFontSize: 20, - maxLines: 1, - textAlign: TextAlign.center, - style: MYTextStyle.titr0.copyWith(color: const Color(0XFF847AC4)), - ), - ], - ); - } - - Widget _btn(BuildContext context, LanguageState state) { - return MyBlueButton( - onTap: (_isEnabled && _selectedLanguage != null) - ? () async { - context.read().add( - SelectLanguageEvent(_selectedLanguage!), - ); - final downloadBloc = context.read(); - // 1. Cancel any previous downloads. - downloadBloc.add(CancelDownloadEvent()); - - // 2. Update App Locale - context.read().add( - ChangeLocaleEvent(_selectedLanguage!.locale), - ); - await Future.delayed(const Duration(milliseconds: 80)); - final lastDownloadedLevel = await downloadBloc - .lastDownloadedLevel(); - - if (!context.mounted) return; - - if (lastDownloadedLevel >= MyConstants.firstDownloadBatchCount) { - context.goNamed(Routes.homePage); - } else { - context.read().add( - const StartDownloadEvent( - toLevel: MyConstants.firstDownloadBatchCount, - ), - ); - - context.goNamed( - Routes.downloadPage, - extra: const DownloadPageConfig( - downloadToLevel: MyConstants.firstDownloadBatchCount, - redirectTo: Routes.homePage, - ), - ); - } - } - : null, - title: context.translate.select, - ); - } -} diff --git a/pubspec.yaml b/pubspec.yaml index eb3bd6c..9e9159a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: hadi_hoda_flutter description: "A new Flutter project." publish_to: 'none' -version: 1.1.4+114 +version: 1.1.6+116 environment: sdk: ^3.9.2