diff --git a/android/app/src/main/res/drawable/cirlce_hwa.png b/android/app/src/main/res/drawable/cirlce_hwa.png new file mode 100644 index 0000000..648c07d Binary files /dev/null and b/android/app/src/main/res/drawable/cirlce_hwa.png differ diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml index 304732f..e92ac36 100644 --- a/android/app/src/main/res/drawable/launch_background.xml +++ b/android/app/src/main/res/drawable/launch_background.xml @@ -1,12 +1,10 @@ - - - - + android:src="@drawable/circle_hwa" /> + diff --git a/android/app/src/main/res/values/color.xml b/android/app/src/main/res/values/color.xml new file mode 100644 index 0000000..8cc3f65 --- /dev/null +++ b/android/app/src/main/res/values/color.xml @@ -0,0 +1,19 @@ + + + #FFFFFF + #FFFF00 + #FF00FF + #FF0000 + #C0C0C0 + #808080 + #808000 + #800080 + #800000 + #00FFFF + #00FF00 + #008080 + #008000 + #0000FF + #000080 + #000000 + \ No newline at end of file diff --git a/asset/image/cirlce_hwa.png b/asset/image/cirlce_hwa.png new file mode 100644 index 0000000..648c07d Binary files /dev/null and b/asset/image/cirlce_hwa.png differ diff --git a/asset/lang/en-US.json b/asset/lang/en-US.json index bf642bf..334e76b 100644 --- a/asset/lang/en-US.json +++ b/asset/lang/en-US.json @@ -1,74 +1,81 @@ { "welcome": "Welcome to My App", - "onBoard":{ - "page1": - {"title":"Make It Good","desc":"You are not alone. You have unique abiltiyto go to anther world"}, - "page2": - {"title":"Make It Good","desc":"You are not alone. You have unique abiltiyto go to anther world"}, - "page3": - {"title":"Make It Good","desc":"You are not alone. You have unique abiltiyto go to anther world"} + "onBoard": { + "page1": { + "title": "Make It Good", + "desc": "You are not alone. You have unique abiltiyto go to anther world" + }, + "page2": { + "title": "Make It Good", + "desc": "You are not alone. You have unique abiltiyto go to anther world" + }, + "page3": { + "title": "Make It Good", + "desc": "You are not alone. You have unique abiltiyto go to anther world" + } + }, + "splash": { + "welcome": "WELCOME TO HWA ARCHITECTURE SERIES" }, - - "login":{ - "tab1":"Login", - "tab2":"SignUp", - "email":"Email", - "password":"Password", - "forgotText":"Forgot Password", - "login":"Login", - "dontAccount":"Dont have account" + "login": { + "tab1": "Login", + "tab2": "SignUp", + "email": "Email", + "password": "Password", + "forgotText": "Forgot Password", + "login": "Login", + "dontAccount": "Dont have account" }, - "home":{ - "build":{ - "tabbar":{ - "tab1":"Latest", - "tab2":"Decorative", - "tab3":"Music", - "tab4":"Style" + "home": { + "build": { + "tabbar": { + "tab1": "Latest", + "tab2": "Decorative", + "tab3": "Music", + "tab4": "Style" }, - "subTitle":"Recommended" + "subTitle": "Recommended" }, - "social":{ - "cancel":"Cancel", - "next":"Next", - "search":"Search", - "findFriends":"Find Friends", - "follow":"Follow", - "following":"Following" + "social": { + "cancel": "Cancel", + "next": "Next", + "search": "Search", + "findFriends": "Find Friends", + "follow": "Follow", + "following": "Following" }, - "game":{ - "title":"Unity Game", - "newUpdate":"New Updated Games", - "viewAll":"View All", - "topDownload":"Top Downloads", - "tabbar":{ - "tab1":"RACING", - "tab2":"SIMULATION", - "tab3":"CASUAL", - "tab4":"CARTOONY", - "tab5":"TOYS" + "game": { + "title": "Unity Game", + "newUpdate": "New Updated Games", + "viewAll": "View All", + "topDownload": "Top Downloads", + "tabbar": { + "tab1": "RACING", + "tab2": "SIMULATION", + "tab3": "CASUAL", + "tab4": "CARTOONY", + "tab5": "TOYS" } }, - "burgers":{ - "favoriteProducts":"Best \nSelling", - "normalProducts":"Burgers" + "burgers": { + "favoriteProducts": "Best \nSelling", + "normalProducts": "Burgers" }, - "setting":{ - "title":"Settings", - "about":{ - "title":"About Project", - "contribitions":"Project Contributors" + "setting": { + "title": "Settings", + "about": { + "title": "About Project", + "contribitions": "Project Contributors" }, - "core":{ - "title":"Project Core", - "themeTitle":"Theme Change", - "themeDesc":"You can change applicaton theme.", - "langTitle":"Language Change", - "langDesc":"You can change applicaton language." + "core": { + "title": "Project Core", + "themeTitle": "Theme Change", + "themeDesc": "You can change applicaton theme.", + "langTitle": "Language Change", + "langDesc": "You can change applicaton language." }, - "exit":"Exit", - "applicationTour":"Application Tuor" - + "exit": "Exit", + "applicationTour": "Application Tuor" } } } \ No newline at end of file diff --git a/asset/lang/tr-TR.json b/asset/lang/tr-TR.json index 054121c..0ef5755 100644 --- a/asset/lang/tr-TR.json +++ b/asset/lang/tr-TR.json @@ -1,75 +1,81 @@ { "welcome": "Welcome to My App", - "onBoard":{ - "page1": - {"title":"Make It Good","desc":"You are not alone. You have unique abiltiyto go to anther world"}, - "page2": - {"title":"Make It Good","desc":"You are not alone. You have unique abiltiyto go to anther world"}, - "page3": - {"title":"Make It Good","desc":"You are not alone. You have unique abiltiyto go to anther world"} + "onBoard": { + "page1": { + "title": "Make It Good", + "desc": "You are not alone. You have unique abiltiyto go to anther world" + }, + "page2": { + "title": "Make It Good", + "desc": "You are not alone. You have unique abiltiyto go to anther world" + }, + "page3": { + "title": "Make It Good", + "desc": "You are not alone. You have unique abiltiyto go to anther world" + } + }, + "splash": { + "welcome": "HWA UYGULAMA MİMARİSİNE HOŞ GELDİNİZ" }, - - "login":{ - "tab1":"Login", - "tab2":"SignUp", - "email":"Email", - "password":"Password", - "forgotText":"Forgot Password", - "login":"Login", - "dontAccount":"Dont have account" + "login": { + "tab1": "Login", + "tab2": "SignUp", + "email": "Email", + "password": "Password", + "forgotText": "Forgot Password", + "login": "Login", + "dontAccount": "Dont have account" }, - "home":{ - "build":{ - "tabbar":{ - "tab1":"Latest", - "tab2":"Decorative", - "tab3":"Music", - "tab4":"Style" + "home": { + "build": { + "tabbar": { + "tab1": "Latest", + "tab2": "Decorative", + "tab3": "Music", + "tab4": "Style" }, - "subTitle":"Recommended" + "subTitle": "Recommended" }, - "social":{ - "cancel":"Cancel", - "next":"Next", - "search":"Search", - "findFriends":"Find Friends", - "follow":"Follow", - "following":"Following" + "social": { + "cancel": "Cancel", + "next": "Next", + "search": "Search", + "findFriends": "Find Friends", + "follow": "Follow", + "following": "Following" }, - "game":{ - "title":"Birlik Oyun", - "newUpdate":"Yeni Güncellenmiş Oyunlar", - "viewAll":"Görünüm Herşey", - "topDownload":"Üst İndirilenler", - "tabbar":{ - "tab1":"YARIŞ", - "tab2":"Simülasyon", - "tab3":"Gündelik", - "tab4":"Karikatüry", - "tab5":"Oyuncaklar" + "game": { + "title": "Birlik Oyun", + "newUpdate": "Yeni Güncellenmiş Oyunlar", + "viewAll": "Görünüm Herşey", + "topDownload": "Üst İndirilenler", + "tabbar": { + "tab1": "YARIŞ", + "tab2": "Simülasyon", + "tab3": "Gündelik", + "tab4": "Karikatüry", + "tab5": "Oyuncaklar" } }, - "burgers":{ - "favoriteProducts":"En Çok Satılanlar", - "normalProducts":"Burgerler" + "burgers": { + "favoriteProducts": "En Çok Satılanlar", + "normalProducts": "Burgerler" }, - "setting":{ - "title":"Ayarlar", - "about":{ - "title":"Proje Hakkında", - "contribitions":"Proje Katkıda Bulunanlar" + "setting": { + "title": "Ayarlar", + "about": { + "title": "Proje Hakkında", + "contribitions": "Proje Katkıda Bulunanlar" }, - "core":{ - "title":"Project Core", - - "themeTitle":"Tema değişikliği", - "themeDesc":"Uygulama temasını değiştirebilirsiniz.", - "langTitle":"Dil değişimi", - "langDesc":"Uygulama dilini değiştirebilirsiniz." + "core": { + "title": "Project Core", + "themeTitle": "Tema değişikliği", + "themeDesc": "Uygulama temasını değiştirebilirsiniz.", + "langTitle": "Dil değişimi", + "langDesc": "Uygulama dilini değiştirebilirsiniz." }, - "exit":"Exit", - "applicationTour":"Uygulama Turu" - + "exit": "Exit", + "applicationTour": "Uygulama Turu" } } } \ No newline at end of file diff --git a/ios/Podfile.lock b/ios/Podfile.lock index bf6d36c..69b339b 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -70,4 +70,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c -COCOAPODS: 1.10.0 +COCOAPODS: 1.10.1 diff --git a/ios/Runner/Assets.xcassets/Contents.json b/ios/Runner/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/ios/Runner/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Runner/Assets.xcassets/ic_circle_hwa.imageset/Contents.json b/ios/Runner/Assets.xcassets/ic_circle_hwa.imageset/Contents.json new file mode 100644 index 0000000..a273709 --- /dev/null +++ b/ios/Runner/Assets.xcassets/ic_circle_hwa.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "cirlce_hwa.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Runner/Assets.xcassets/ic_circle_hwa.imageset/cirlce_hwa.png b/ios/Runner/Assets.xcassets/ic_circle_hwa.imageset/cirlce_hwa.png new file mode 100644 index 0000000..648c07d Binary files /dev/null and b/ios/Runner/Assets.xcassets/ic_circle_hwa.imageset/cirlce_hwa.png differ diff --git a/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ios/Runner/Base.lproj/LaunchScreen.storyboard index f2e259c..aca8c57 100644 --- a/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ b/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -1,8 +1,11 @@ - - + + + - + + + @@ -14,24 +17,41 @@ + + + + + - + + + + + + - + - + + + + + + + + diff --git a/lib/core/base/model/base_view_model.dart b/lib/core/base/model/base_view_model.dart index 968b732..873b2aa 100644 --- a/lib/core/base/model/base_view_model.dart +++ b/lib/core/base/model/base_view_model.dart @@ -11,6 +11,9 @@ abstract class BaseViewModel { ICoreDioNullSafety? coreDio = NetworkManager.instance!.coreDio; VexanaManager? vexanaManager = VexanaManager.instance; + + VexanaManager get vexanaManagerComputed => VexanaManager.instance; + LocaleManager localeManager = LocaleManager.instance; NavigationService navigation = NavigationService.instance; diff --git a/lib/core/constants/image/image_constatns.dart b/lib/core/constants/image/image_constatns.dart index 3b02c9c..6f942d3 100644 --- a/lib/core/constants/image/image_constatns.dart +++ b/lib/core/constants/image/image_constatns.dart @@ -8,6 +8,7 @@ class ImageConstants { String get logo => toPng('veli'); String get hotDog => toPng('hotdogs'); + String get projeIcon => toPng('cirlce_hwa'); String toPng(String name) => 'asset/image/$name.png'; } diff --git a/lib/core/constants/navigation/navigation_constants.dart b/lib/core/constants/navigation/navigation_constants.dart index bb1b845..d32bd8d 100644 --- a/lib/core/constants/navigation/navigation_constants.dart +++ b/lib/core/constants/navigation/navigation_constants.dart @@ -1,6 +1,6 @@ class NavigationConstants { static const TEST_VIEW = '/test'; - + static const DEFAULT = '/'; static const SETTINGS_WEB_VIEW = '/settingsWebView'; static const ON_BOARD = '/onBoard'; } diff --git a/lib/core/init/cache/locale_manager.dart b/lib/core/init/cache/locale_manager.dart index c41409c..6c1ea96 100644 --- a/lib/core/init/cache/locale_manager.dart +++ b/lib/core/init/cache/locale_manager.dart @@ -36,7 +36,9 @@ class LocaleManager { await _preferences!.setBool(key.toString(), value); } - String getStringValue(PreferencesKeys key) => _preferences!.getString(key.toString()) ?? ''; + String getStringValue(PreferencesKeys key) => + _preferences?.getString(key.toString()) ?? ''; - bool getBoolValue(PreferencesKeys key) => _preferences!.getBool(key.toString()) ?? false; + bool getBoolValue(PreferencesKeys key) => + _preferences!.getBool(key.toString()) ?? false; } diff --git a/lib/core/init/lang/locale_keys.g.dart b/lib/core/init/lang/locale_keys.g.dart index 972ff69..7ea0b4b 100644 --- a/lib/core/init/lang/locale_keys.g.dart +++ b/lib/core/init/lang/locale_keys.g.dart @@ -12,6 +12,8 @@ abstract class LocaleKeys { static const onBoard_page3_desc = 'onBoard.page3.desc'; static const onBoard_page3 = 'onBoard.page3'; static const onBoard = 'onBoard'; + static const splash_welcome = 'splash.welcome'; + static const splash = 'splash'; static const login_tab1 = 'login.tab1'; static const login_tab2 = 'login.tab2'; static const login_email = 'login.email'; diff --git a/lib/core/init/navigation/navigation_route.dart b/lib/core/init/navigation/navigation_route.dart index 3ce8317..a648c86 100644 --- a/lib/core/init/navigation/navigation_route.dart +++ b/lib/core/init/navigation/navigation_route.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; +import 'package:fluttermvvmtemplate/view/authenticate/splash/view/splash_view.dart'; import '../../../product/exception/navigate_model_not_found.dart'; import '../../../view/authenticate/onboard/view/on_board_view.dart'; @@ -17,6 +18,9 @@ class NavigationRoute { Route generateRoute(RouteSettings args) { switch (args.name) { + case NavigationConstants.DEFAULT: + return normalNavigate(SplashView()); + case NavigationConstants.TEST_VIEW: return normalNavigate(TestsView()); diff --git a/lib/core/init/theme/app_theme_light.dart b/lib/core/init/theme/app_theme_light.dart index 1351a7c..be279d7 100644 --- a/lib/core/init/theme/app_theme_light.dart +++ b/lib/core/init/theme/app_theme_light.dart @@ -18,18 +18,23 @@ class AppThemeLight extends AppTheme with ILightTheme { colorScheme: _appColorScheme, textTheme: textTheme(), appBarTheme: ThemeData.light().appBarTheme.copyWith( - brightness: Brightness.light, color: Colors.transparent, elevation: 0, iconTheme: IconThemeData(color: Colors.black87, size: 21)), + brightness: Brightness.light, + color: Colors.transparent, + elevation: 0, + iconTheme: IconThemeData(color: Colors.black87, size: 21)), inputDecorationTheme: InputDecorationTheme( focusColor: Colors.black12, labelStyle: TextStyle(), fillColor: Colors.white, contentPadding: EdgeInsets.zero, filled: true, - enabledBorder: OutlineInputBorder(borderSide: BorderSide(width: 0.3)), + enabledBorder: + OutlineInputBorder(borderSide: BorderSide(width: 0.3)), // border: OutlineInputBorder(borderSide: BorderSide(width: 0.3)), focusedBorder: OutlineInputBorder()), scaffoldBackgroundColor: Color(0xfff1f3f8), - floatingActionButtonTheme: ThemeData.light().floatingActionButtonTheme.copyWith(), + floatingActionButtonTheme: + ThemeData.light().floatingActionButtonTheme.copyWith(), buttonTheme: ThemeData.light().buttonTheme.copyWith( colorScheme: ColorScheme.light( onError: Color(0xffFF2D55), @@ -49,9 +54,10 @@ class AppThemeLight extends AppTheme with ILightTheme { } TextTheme textTheme() { - return ThemeData.light() - .textTheme - .copyWith(headline1: textThemeLight!.headline1, headline2: textThemeLight!.headline2, overline: textThemeLight!.headline3); + return ThemeData.light().textTheme.copyWith( + headline1: textThemeLight!.headline1, + headline2: textThemeLight!.headline2, + overline: textThemeLight!.headline3); } ColorScheme get _appColorScheme { @@ -65,7 +71,7 @@ class AppThemeLight extends AppTheme with ILightTheme { error: Colors.red[900]!, onPrimary: Colors.greenAccent, onSecondary: Colors.black, //x - onSurface: Colors.white30, + onSurface: Colors.purple.shade300, onBackground: Colors.black12, onError: Color(0xFFF9B916), //xx brightness: Brightness.light); diff --git a/lib/main.dart b/lib/main.dart index cd1246f..1f08399 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -27,9 +27,7 @@ Future main() async { Future _init() async { WidgetsFlutterBinding.ensureInitialized(); - await LocaleManager.prefrencesInit(); await EasyLocalization.ensureInitialized(); - await DeviceUtility.instance?.initPackageInfo(); } class MyApp extends StatelessWidget { @@ -38,7 +36,6 @@ class MyApp extends StatelessWidget { return MaterialApp( debugShowCheckedModeBanner: false, theme: context.watch().currentTheme, - home: BurgersView(), localizationsDelegates: context.localizationDelegates, supportedLocales: context.supportedLocales, locale: context.locale, diff --git a/lib/product/enum/platform_project.dart b/lib/product/enum/platform_project.dart new file mode 100644 index 0000000..bca19a8 --- /dev/null +++ b/lib/product/enum/platform_project.dart @@ -0,0 +1,11 @@ +import 'dart:io'; + +enum PlatformProject { ANDROID, IOS } + +extension PlatformProjectExtension on PlatformProject { + int get versionNumber { + return Platform.isIOS + ? PlatformProject.IOS.index + : PlatformProject.ANDROID.index; + } +} diff --git a/lib/view/authenticate/splash/model/force_update_model.dart b/lib/view/authenticate/splash/model/force_update_model.dart new file mode 100644 index 0000000..df187fb --- /dev/null +++ b/lib/view/authenticate/splash/model/force_update_model.dart @@ -0,0 +1,26 @@ +import 'package:json_annotation/json_annotation.dart'; +import 'package:vexana/vexana.dart'; + +part 'force_update_model.g.dart'; + +@JsonSerializable() +class ForceUpdateModel extends INetworkModel { + bool? isForceUpdate; + String? type; + String? currentVersion; + ForceUpdateModel({ + this.isForceUpdate, + this.type, + this.currentVersion, + }); + + @override + ForceUpdateModel fromJson(Map json) { + return _$ForceUpdateModelFromJson(json); + } + + @override + Map toJson() { + return _$ForceUpdateModelToJson(this); + } +} diff --git a/lib/view/authenticate/splash/model/force_update_model.g.dart b/lib/view/authenticate/splash/model/force_update_model.g.dart new file mode 100644 index 0000000..a849013 --- /dev/null +++ b/lib/view/authenticate/splash/model/force_update_model.g.dart @@ -0,0 +1,22 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'force_update_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ForceUpdateModel _$ForceUpdateModelFromJson(Map json) { + return ForceUpdateModel( + isForceUpdate: json['isForceUpdate'] as bool?, + type: json['type'] as String?, + currentVersion: json['currentVersion'] as String?, + ); +} + +Map _$ForceUpdateModelToJson(ForceUpdateModel instance) => + { + 'isForceUpdate': instance.isForceUpdate, + 'type': instance.type, + 'currentVersion': instance.currentVersion, + }; diff --git a/lib/view/authenticate/splash/service/splash_service.dart b/lib/view/authenticate/splash/service/splash_service.dart new file mode 100644 index 0000000..9255724 --- /dev/null +++ b/lib/view/authenticate/splash/service/splash_service.dart @@ -0,0 +1,46 @@ +import 'package:flutter/cupertino.dart'; +import 'package:fluttermvvmtemplate/view/authenticate/splash/model/force_update_model.dart'; +import 'package:vexana/vexana.dart'; + +abstract class ISplashService { + final INetworkManager networkManager; + + ISplashService(this.networkManager); + + Future checkDeviceVersion( + {required String version, required String platform}); +} + +enum SplashServiceQuery { VERSION, PLATFORM } + +extension SplashServiceQueryExtension on SplashServiceQuery { + MapEntry toMapValue(String value) { + switch (this) { + case SplashServiceQuery.PLATFORM: + return MapEntry('platform', value); + case SplashServiceQuery.VERSION: + return MapEntry('version', value); + } + } +} + +class SplashService extends ISplashService { + final String _path = 'version'; + SplashService(INetworkManager networkManager) : super(networkManager); + + @override + Future checkDeviceVersion( + {required String version, required String platform}) async { + final response = + await networkManager.send( + _path, + parseModel: ForceUpdateModel(), + method: RequestType.GET, + queryParameters: Map.fromEntries([ + SplashServiceQuery.VERSION.toMapValue(version), + SplashServiceQuery.PLATFORM.toMapValue(platform) + ]), + ); + return response.data; + } +} diff --git a/lib/view/authenticate/splash/view/splash_view.dart b/lib/view/authenticate/splash/view/splash_view.dart new file mode 100644 index 0000000..cd2aebd --- /dev/null +++ b/lib/view/authenticate/splash/view/splash_view.dart @@ -0,0 +1,73 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:fluttermvvmtemplate/core/init/lang/locale_keys.g.dart'; +import 'package:kartal/kartal.dart'; + +import '../../../../core/base/view/base_widget.dart'; +import '../../../../core/constants/image/image_constatns.dart'; +import '../viewmodel/splash_view_model.dart'; + +class SplashView extends StatelessWidget { + const SplashView({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return BaseView( + viewModel: SplashViewModel(), + onModelReady: (model) { + model.setContext(context); + model.init(); + }, + onPageBuilder: (BuildContext context, SplashViewModel value) => + buildScaffoldBody(context, value), + ); + } + + Widget buildScaffoldBody(BuildContext context, SplashViewModel viewModel) { + return Scaffold( + backgroundColor: context.colorScheme.onSurface, + body: SafeArea( + child: Stack( + children: [ + buildCenterTextWelcome(context, viewModel), + buildAnimatedAlignIcon(viewModel, context), + ], + )), + ); + } + + Center buildCenterTextWelcome( + BuildContext context, SplashViewModel viewModel) { + return Center(child: Observer(builder: (_) { + return AnimatedOpacity( + duration: context.durationNormal, + opacity: viewModel.isFirstInit ? 0 : 1, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + LocaleKeys.splash_welcome.tr(), + style: context.textTheme.headline4?.copyWith( + fontWeight: FontWeight.w700, + color: context.colorScheme.primaryVariant), + textAlign: TextAlign.center, + ), + CircularProgressIndicator.adaptive() + ], + ), + ); + })); + } + + Widget buildAnimatedAlignIcon( + SplashViewModel viewModel, BuildContext context) { + return Observer(builder: (_) { + return AnimatedAlign( + alignment: + viewModel.isFirstInit ? Alignment.center : Alignment.bottomCenter, + duration: context.durationLow, + child: Image.asset(ImageConstants.instance.projeIcon)); + }); + } +} diff --git a/lib/view/authenticate/splash/viewmodel/device_and_cahe.dart b/lib/view/authenticate/splash/viewmodel/device_and_cahe.dart new file mode 100644 index 0000000..3a611dc --- /dev/null +++ b/lib/view/authenticate/splash/viewmodel/device_and_cahe.dart @@ -0,0 +1,15 @@ +import 'package:kartal/kartal.dart'; + +import '../../../../core/init/cache/locale_manager.dart'; + +mixin DeviceAndCache { + Future deviceandCacheInit() async { + if (DeviceUtility.instance == null) { + return; + } + await Future.wait([ + LocaleManager.prefrencesInit(), + DeviceUtility.instance!.initPackageInfo() + ]); + } +} diff --git a/lib/view/authenticate/splash/viewmodel/splash_view_model.dart b/lib/view/authenticate/splash/viewmodel/splash_view_model.dart new file mode 100644 index 0000000..fba93a5 --- /dev/null +++ b/lib/view/authenticate/splash/viewmodel/splash_view_model.dart @@ -0,0 +1,89 @@ +import 'dart:convert'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:fluttermvvmtemplate/core/constants/navigation/navigation_constants.dart'; +import 'package:kartal/kartal.dart'; +import 'package:logger/logger.dart'; +import 'package:mobx/mobx.dart'; + +import '../../../../core/base/model/base_view_model.dart'; +import '../../../../core/init/cache/locale_manager.dart'; +import '../../../../product/enum/platform_project.dart'; +import '../model/force_update_model.dart'; +import '../service/splash_service.dart'; +import 'device_and_cahe.dart'; + +part 'splash_view_model.g.dart'; + +class SplashViewModel = _SplashViewModelBase with _$SplashViewModel; + +abstract class _SplashViewModelBase with Store, BaseViewModel, DeviceAndCache { + @override + void setContext(BuildContext context) => this.context = context; + + @observable + bool isFirstInit = true; + + ISplashService? service; + + @override + void init() { + startAnimationOnView(); + WidgetsBinding.instance?.addPostFrameCallback((timeStamp) { + controlAppState(); + }); + } + + Future controlAppState() async { + await deviceandCacheInit(); + // MARK: CONCURENCY sample + final data = await compute(_UserVersionCreate.createNumber, 1); + print(data); + _networkInit(); + final isNeedForceUpdate = await _checkAppVersion(); + if (isNeedForceUpdate) { + showAboutDialog(context: context!, children: [Text('Neeed to Update')]); + } else { + // await navigation.navigateToPageClear(path: NavigationConstants.TEST_VIEW); + } + } + + void _networkInit() { + if (vexanaManager != null) { + service = SplashService(vexanaManagerComputed.networkManager); + } + } + + Future _checkAppVersion() async { + final response = await service?.checkDeviceVersion( + version: ''.version, platform: '${PlatformProject.IOS.versionNumber}'); + + if (response is ForceUpdateModel) { + return response.isForceUpdate ?? false; + } else { + return false; + } + } + + Future startAnimationOnView() async { + if (context == null) return; + await Future.delayed(context!.durationLow); + _changeFirstInit(); + } + + @action + void _changeFirstInit() { + isFirstInit = !isFirstInit; + } +} + +class _UserVersionCreate { + static String createNumber(int number) { + var model = ForceUpdateModel(currentVersion: '1.0.3'); + final data = jsonEncode(model); + final lastData = jsonDecode(data); + + return ForceUpdateModel().fromJson(lastData).currentVersion ?? ''; + } +} diff --git a/lib/view/authenticate/splash/viewmodel/splash_view_model.g.dart b/lib/view/authenticate/splash/viewmodel/splash_view_model.g.dart new file mode 100644 index 0000000..050d79b --- /dev/null +++ b/lib/view/authenticate/splash/viewmodel/splash_view_model.g.dart @@ -0,0 +1,47 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'splash_view_model.dart'; + +// ************************************************************************** +// StoreGenerator +// ************************************************************************** + +// ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic + +mixin _$SplashViewModel on _SplashViewModelBase, Store { + final _$isFirstInitAtom = Atom(name: '_SplashViewModelBase.isFirstInit'); + + @override + bool get isFirstInit { + _$isFirstInitAtom.reportRead(); + return super.isFirstInit; + } + + @override + set isFirstInit(bool value) { + _$isFirstInitAtom.reportWrite(value, super.isFirstInit, () { + super.isFirstInit = value; + }); + } + + final _$_SplashViewModelBaseActionController = + ActionController(name: '_SplashViewModelBase'); + + @override + void _changeFirstInit() { + final _$actionInfo = _$_SplashViewModelBaseActionController.startAction( + name: '_SplashViewModelBase._changeFirstInit'); + try { + return super._changeFirstInit(); + } finally { + _$_SplashViewModelBaseActionController.endAction(_$actionInfo); + } + } + + @override + String toString() { + return ''' +isFirstInit: ${isFirstInit} + '''; + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 49e63de..7462632 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: none # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 +version: 0.0.9 environment: sdk: '>=2.12.0 <3.0.0' diff --git a/test/feature/splash/splash_service_test.dart b/test/feature/splash/splash_service_test.dart new file mode 100644 index 0000000..78081ea --- /dev/null +++ b/test/feature/splash/splash_service_test.dart @@ -0,0 +1,18 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:fluttermvvmtemplate/core/init/network/vexana_manager.dart'; +import 'package:fluttermvvmtemplate/view/_product/_utilty/burger_network_enum.dart'; +import 'package:fluttermvvmtemplate/view/authenticate/splash/service/splash_service.dart'; +import 'package:fluttermvvmtemplate/view/home/burger/service/burger_serivce.dart'; + +void main() { + ISplashService? splashService; + setUp(() { + splashService = SplashService(VexanaManager.instance.networkManager); + }); + test('Fetch favorite Burgers', () async { + final response = await splashService?.checkDeviceVersion( + version: "0.0.9", platform: "1"); + + expect(response, isNotEmpty); + }); +}