├── asset ├── app │ └── .env ├── image │ ├── hotdogs.png │ └── cirlce_hwa.png └── lang │ └── en-US.json ├── module ├── all_of_template │ ├── LICENSE │ ├── CHANGELOG.md │ ├── .vscode │ │ └── settings.json │ ├── lib │ │ ├── all_of_template.dart │ │ └── features │ │ │ ├── next_page.dart │ │ │ └── buy_view.dart │ ├── .metadata │ ├── test │ │ └── all_of_template_test.dart │ ├── analysis_options.yaml │ ├── README.md │ ├── pubspec.yaml │ └── .gitignore └── architecture_widgets │ ├── lib │ ├── src │ │ ├── avatar │ │ │ └── circle_avatar.dart │ │ ├── card │ │ │ └── not_found_navigation_widget.dart │ │ ├── container │ │ │ └── random_color_container.dart │ │ ├── text │ │ │ ├── locale_text.dart │ │ │ └── auto_locale_text.dart │ │ ├── column │ │ │ └── form_column.dart │ │ ├── button │ │ │ ├── icon_button.dart │ │ │ ├── title_text_button.dart │ │ │ └── normal_button.dart │ │ ├── decoration │ │ │ └── circle_decoration.dart │ │ ├── slider │ │ │ └── range_price_slider.dart │ │ └── list-view │ │ │ └── indicator_list_view.dart │ └── architecture_widgets.dart │ ├── LICENSE │ ├── CHANGELOG.md │ ├── .metadata │ ├── test │ └── architecture_widgets_test.dart │ ├── analysis_options.yaml │ ├── pubspec.yaml │ ├── README.md │ └── .gitignore ├── scripts ├── build.sh ├── lang.sh └── android_build.sh ├── ios ├── Gemfile ├── Runner │ ├── Runner-Bridging-Header.h │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── LaunchImage.imageset │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ ├── README.md │ │ │ └── Contents.json │ │ ├── ic_circle_hwa.imageset │ │ │ ├── cirlce_hwa.png │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ ├── AppDelegate.swift │ ├── Base.lproj │ │ └── Main.storyboard │ └── Info.plist ├── Flutter │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── AppFrameworkInfo.plist ├── Runner.xcodeproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ ├── WorkspaceSettings.xcsettings │ │ └── IDEWorkspaceChecks.plist ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── WorkspaceSettings.xcsettings │ │ └── IDEWorkspaceChecks.plist ├── fastlane │ ├── Appfile │ ├── README.md │ └── report.xml ├── .gitignore └── Podfile ├── lib ├── view │ ├── home │ │ ├── game │ │ │ ├── model │ │ │ │ ├── game_enums.dart │ │ │ │ ├── game_view_state.dart │ │ │ │ ├── slider_model.dart │ │ │ │ ├── game_model.dart │ │ │ │ ├── slider_model.g.dart │ │ │ │ └── game_model.g.dart │ │ │ ├── service │ │ │ │ ├── IGameService.dart │ │ │ │ └── game_service.dart │ │ │ ├── view │ │ │ │ └── subview │ │ │ │ │ └── game_view_cards.dart │ │ │ └── viewmodel │ │ │ │ ├── game_view_model.g.dart │ │ │ │ └── game_view_model.dart │ │ ├── build │ │ │ └── feed │ │ │ │ ├── service │ │ │ │ ├── IBuildFeedService.dart │ │ │ │ └── build_feed_service.dart │ │ │ │ ├── model │ │ │ │ ├── house_model.dart │ │ │ │ └── house_model.g.dart │ │ │ │ └── viewmodel │ │ │ │ └── build_feed_view_model.dart │ │ ├── social │ │ │ ├── service │ │ │ │ └── ISocialService.dart │ │ │ ├── model │ │ │ │ ├── social_user_model.g.dart │ │ │ │ └── social_user_model.dart │ │ │ └── view │ │ │ │ └── social_view_detial.dart │ │ └── burger │ │ │ ├── model │ │ │ ├── burger_model.dart │ │ │ └── burger_model.g.dart │ │ │ ├── service │ │ │ └── burger_serivce.dart │ │ │ └── viewmodel │ │ │ └── burger_view_model.dart │ ├── _product │ │ ├── _model │ │ │ └── query │ │ │ │ ├── friend_query.dart │ │ │ │ └── friend_query_enum.dart │ │ ├── _mixin │ │ │ └── network_helper.dart │ │ ├── _constants │ │ │ └── image_path_svg.dart │ │ ├── _utilty │ │ │ ├── decoration_helper.dart │ │ │ ├── service_helper.dart │ │ │ ├── thorottle_helper.dart │ │ │ └── burger_network_enum.dart │ │ ├── _widgets │ │ │ ├── button │ │ │ │ ├── login_button.dart │ │ │ │ └── face_book_button.dart │ │ │ ├── listview │ │ │ │ └── on_board_indicator.dart │ │ │ ├── avatar │ │ │ │ └── on_board_circle.dart │ │ │ ├── animation │ │ │ │ └── social_card_animation.dart │ │ │ ├── list-tile │ │ │ │ └── friend_card.dart │ │ │ └── card │ │ │ │ └── build_user_card.dart │ │ └── enum │ │ │ └── network_route_enum.dart │ ├── authenticate │ │ ├── onboard │ │ │ ├── model │ │ │ │ └── on_board_model.dart │ │ │ └── viewModel │ │ │ │ ├── on_board_view_model.dart │ │ │ │ └── on_board_view_model.g.dart │ │ ├── splash │ │ │ ├── viewmodel │ │ │ │ ├── device_and_cahe.dart │ │ │ │ └── splash_view_model.g.dart │ │ │ ├── model │ │ │ │ ├── force_update_model.dart │ │ │ │ └── force_update_model.g.dart │ │ │ └── service │ │ │ │ └── splash_service.dart │ │ ├── login │ │ │ ├── service │ │ │ │ ├── ILoginService.dart │ │ │ │ └── login_service.dart │ │ │ ├── model │ │ │ │ ├── login_model.dart │ │ │ │ ├── login_response_model.dart │ │ │ │ ├── login_response_model.g.dart │ │ │ │ └── login_model.g.dart │ │ │ ├── viewmodel │ │ │ │ └── login_view_model.dart │ │ │ └── view │ │ │ │ └── login_view_two.dart │ │ └── test │ │ │ ├── model │ │ │ ├── test_model.g.dart │ │ │ └── test_model.dart │ │ │ └── viewmodel │ │ │ ├── test_view_model.dart │ │ │ └── test_view_model.g.dart │ └── settings │ │ ├── viewmodel │ │ ├── subviewmodel │ │ │ └── about_view_model.dart │ │ ├── settings_view_model.g.dart │ │ └── settings_view_model.dart │ │ ├── model │ │ └── settings_dynamic.dart │ │ └── view │ │ └── subview │ │ └── settings_dynamic_view.dart ├── core │ ├── constants │ │ ├── enums │ │ │ ├── app_theme_enum.dart │ │ │ ├── http_request_enum.dart │ │ │ └── locale_keys_enum.dart │ │ ├── navigation │ │ │ └── navigation_constants.dart │ │ ├── image │ │ │ └── image_constatns.dart │ │ └── app │ │ │ └── app_constants.dart │ ├── init │ │ ├── theme │ │ │ ├── app_theme.dart │ │ │ └── light │ │ │ │ ├── padding_insets.dart │ │ │ │ ├── light_theme_interface.dart │ │ │ │ ├── color_scheme_light.dart │ │ │ │ └── text_theme_light.dart │ │ ├── navigation │ │ │ ├── INavigationService.dart │ │ │ ├── navigation_service.dart │ │ │ └── navigation_route.dart │ │ ├── network │ │ │ ├── IResponseModel.dart │ │ │ ├── network_core │ │ │ │ └── core_operations.dart │ │ │ ├── vexana_manager.dart │ │ │ ├── network_manager.dart │ │ │ ├── ICoreDio.dart │ │ │ └── core_dio.dart │ │ ├── lang │ │ │ └── language_manager.dart │ │ ├── notifier │ │ │ ├── provider_list.dart │ │ │ └── theme_notifer.dart │ │ ├── cache │ │ │ └── locale_manager.dart │ │ └── analytics │ │ │ └── analytics_manager.dart │ ├── base │ │ ├── model │ │ │ ├── base_model.dart │ │ │ ├── base_error.dart │ │ │ └── base_view_model.dart │ │ ├── state │ │ │ └── base_state.dart │ │ └── view │ │ │ └── base_widget.dart │ └── extension │ │ ├── widget_extension.dart │ │ ├── network_exntension.dart │ │ ├── string_extension.dart │ │ └── context_extension.dart ├── product │ ├── exception │ │ └── navigate_model_not_found.dart │ ├── enum │ │ ├── platform_project.dart │ │ └── lottie_path_enum.dart │ ├── model │ │ └── user.dart │ └── widget │ │ ├── card │ │ ├── game_card.dart │ │ └── burger_card.dart │ │ ├── grid │ │ └── game_grid_view.dart │ │ ├── button │ │ └── header_button.dart │ │ └── pageview │ │ └── game_slider.dart └── main.dart ├── web ├── favicon.png ├── icons │ ├── Icon-192.png │ └── Icon-512.png ├── manifest.json └── index.html ├── .vscode └── settings.json ├── android ├── gradle.properties ├── app │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── drawable │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable-v21 │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── values │ │ │ │ │ └── styles.xml │ │ │ │ └── values-night │ │ │ │ │ └── styles.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── sample │ │ │ │ │ └── MainActivity.kt │ │ │ └── AndroidManifest.xml │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ └── profile │ │ │ └── AndroidManifest.xml │ └── build.gradle ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore ├── settings.gradle └── build.gradle ├── macos ├── .gitignore ├── Runner │ ├── Configs │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ ├── Warnings.xcconfig │ │ └── AppInfo.xcconfig │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ ├── app_icon_128.png │ │ │ ├── app_icon_16.png │ │ │ ├── app_icon_256.png │ │ │ ├── app_icon_32.png │ │ │ ├── app_icon_512.png │ │ │ ├── app_icon_64.png │ │ │ ├── app_icon_1024.png │ │ │ └── Contents.json │ ├── AppDelegate.swift │ ├── Release.entitlements │ ├── DebugProfile.entitlements │ ├── MainFlutterWindow.swift │ └── Info.plist ├── Flutter │ ├── Flutter-Debug.xcconfig │ ├── Flutter-Release.xcconfig │ └── GeneratedPluginRegistrant.swift ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Runner.xcodeproj │ └── project.xcworkspace │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── test ├── core │ ├── extension │ │ └── string_extension_test.dart │ └── network │ │ ├── dio_mock_model.dart │ │ └── core_dio_test.dart ├── feature │ ├── test │ │ └── sample_view_test.dart │ ├── splash │ │ └── splash_service_test.dart │ ├── burger │ │ └── burger_test.dart │ ├── feed │ │ ├── feed_mockito.dart │ │ ├── social_network_mock.dart │ │ └── social_feed_test.dart │ └── onboard │ │ ├── onboard_mock_view_model.dart │ │ └── onboard_test.dart └── widget_test.dart ├── .metadata ├── analysis_options.yaml ├── .gitignore └── pubspec.yaml /asset/app/.env: -------------------------------------------------------------------------------- 1 | androidVersionName=0.0.1 2 | buildType=prod -------------------------------------------------------------------------------- /module/all_of_template/LICENSE: -------------------------------------------------------------------------------- 1 | TODO: Add your license here. 2 | -------------------------------------------------------------------------------- /module/architecture_widgets/lib/src/avatar/circle_avatar.dart: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /scripts/build.sh: -------------------------------------------------------------------------------- 1 | flutter packages pub run build_runner build -------------------------------------------------------------------------------- /module/architecture_widgets/LICENSE: -------------------------------------------------------------------------------- 1 | TODO: Add your license here. 2 | -------------------------------------------------------------------------------- /ios/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "fastlane" 4 | -------------------------------------------------------------------------------- /lib/view/home/game/model/game_enums.dart: -------------------------------------------------------------------------------- 1 | enum GameEnum { NEW, TOP } 2 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /lib/core/constants/enums/app_theme_enum.dart: -------------------------------------------------------------------------------- 1 | enum AppThemes { LIGHT, DARK } 2 | -------------------------------------------------------------------------------- /lib/core/constants/enums/http_request_enum.dart: -------------------------------------------------------------------------------- 1 | enum HttpTypes { GET, POST } 2 | -------------------------------------------------------------------------------- /module/all_of_template/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.0.1 2 | 3 | * TODO: Describe initial release. 4 | -------------------------------------------------------------------------------- /lib/core/constants/enums/locale_keys_enum.dart: -------------------------------------------------------------------------------- 1 | enum PreferencesKeys { TOKEN, IS_FIRST_APP } 2 | -------------------------------------------------------------------------------- /module/architecture_widgets/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.0.1 2 | 3 | * TODO: Describe initial release. 4 | -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/web/favicon.png -------------------------------------------------------------------------------- /module/all_of_template/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "kartal" 4 | ] 5 | } -------------------------------------------------------------------------------- /asset/image/hotdogs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/asset/image/hotdogs.png -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/web/icons/Icon-512.png -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "fluttermvvmtemplate", 4 | "vexana" 5 | ] 6 | } -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /asset/image/cirlce_hwa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/asset/image/cirlce_hwa.png -------------------------------------------------------------------------------- /macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/xcuserdata/ 7 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /scripts/lang.sh: -------------------------------------------------------------------------------- 1 | flutter pub run easy_localization:generate -O lib/core/init/lang -f keys -o locale_keys.g.dart --source-dir asset/lang -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /lib/core/init/theme/app_theme.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | abstract class AppTheme { 4 | ThemeData? theme; 5 | } 6 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /module/architecture_widgets/lib/architecture_widgets.dart: -------------------------------------------------------------------------------- 1 | library architecture_widgets; 2 | 3 | export 'src/slider/range_price_slider.dart'; 4 | -------------------------------------------------------------------------------- /lib/core/base/model/base_model.dart: -------------------------------------------------------------------------------- 1 | abstract class BaseModel { 2 | Map toJson(); 3 | T fromJson(Map json); 4 | } 5 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /lib/view/_product/_model/query/friend_query.dart: -------------------------------------------------------------------------------- 1 | class FriendQuery { 2 | 3 | FriendQuery({this.limit, this.q}); 4 | final int? limit; 5 | final String? q; 6 | } 7 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /lib/core/init/theme/light/padding_insets.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/rendering.dart'; 2 | 3 | class PaddingInsets { 4 | final lowPaddingAll = const EdgeInsets.all(5); 5 | } 6 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/ic_circle_hwa.imageset/cirlce_hwa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/ios/Runner/Assets.xcassets/ic_circle_hwa.imageset/cirlce_hwa.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /lib/view/_product/_mixin/network_helper.dart: -------------------------------------------------------------------------------- 1 | import 'package:logger/logger.dart'; 2 | 3 | mixin NetworkHelper { 4 | void showLog(dynamic message) { 5 | Logger().wtf(message); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /module/all_of_template/lib/all_of_template.dart: -------------------------------------------------------------------------------- 1 | library all_of_template; 2 | 3 | /// A Calculator. 4 | class Calculator { 5 | /// Returns [value] plus 1. 6 | int addOne(int value) => value + 1; 7 | } 8 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/sample/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.sample 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VB10/flutter-architecture-template/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /lib/core/extension/widget_extension.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | extension WidgetExtension on Widget { 4 | Widget get toSliver { 5 | return SliverToBoxAdapter(child: this); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/core/base/model/base_error.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluttermvvmtemplate/core/init/network/IResponseModel.dart'; 2 | 3 | class BaseError extends IErrorModel { 4 | BaseError(this.message); 5 | final String message; 6 | } 7 | -------------------------------------------------------------------------------- /lib/core/init/navigation/INavigationService.dart: -------------------------------------------------------------------------------- 1 | abstract class INavigationService { 2 | Future navigateToPage({String? path, Object? data}); 3 | Future navigateToPageClear({String? path, Object? data}); 4 | } 5 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/view/authenticate/onboard/model/on_board_model.dart: -------------------------------------------------------------------------------- 1 | class OnBoardModel { 2 | 3 | OnBoardModel(this.title, this.description, this.imagePath); 4 | final String title; 5 | final String description; 6 | final String imagePath; 7 | } 8 | -------------------------------------------------------------------------------- /lib/view/home/game/model/game_view_state.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: constant_identifier_names 2 | 3 | enum GameViewItems { 4 | SEARCH_BAR, 5 | TABBAR, 6 | SLIDER, 7 | NEW_UPDATE_GAMES_CARD, 8 | TOP_UPDATE_GAMES_CARD, 9 | } 10 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/ic_circle_hwa.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "cirlce_hwa.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /scripts/android_build.sh: -------------------------------------------------------------------------------- 1 | if [ $3 == "bundle" ] 2 | then 3 | flutter build appbundle --build-name=$1 --build-number=$2 4 | open build/app/outputs/bundle/release 5 | else 6 | flutter build apk --build-name=$1 --build-number=$2 7 | open build/app/outputs/flutter-apk 8 | fi 9 | 10 | 11 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip 7 | -------------------------------------------------------------------------------- /macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/product/exception/navigate_model_not_found.dart: -------------------------------------------------------------------------------- 1 | class NavigateException implements Exception { 2 | 3 | NavigateException(this.model); 4 | final dynamic model; 5 | 6 | @override 7 | String toString() { 8 | return 'This model variable doesnt found in route $model and $T'; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/product/enum/platform_project.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | enum PlatformProject { ANDROID, IOS } 4 | 5 | extension PlatformProjectExtension on PlatformProject { 6 | int get versionNumber { 7 | return Platform.isIOS 8 | ? PlatformProject.IOS.index 9 | : PlatformProject.ANDROID.index; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /test/core/extension/string_extension_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:fluttermvvmtemplate/core/extension/string_extension.dart'; 3 | 4 | main() { 5 | setUp(() {}); 6 | test("Email Regexp", () { 7 | String email = "joedoe@gmail.com"; 8 | expect(email.isValidEmail, null); 9 | }); 10 | } 11 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: cce6b3c5aeb12488d7dbec854a0b3adb4b720cd0 8 | channel: master 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /lib/core/constants/navigation/navigation_constants.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: constant_identifier_names 2 | 3 | class NavigationConstants { 4 | static const TEST_VIEW = '/test'; 5 | static const DEFAULT = '/'; 6 | static const SETTINGS_WEB_VIEW = '/settingsWebView'; 7 | static const ON_BOARD = '/onBoard'; 8 | 9 | static const BUY_VIEW = '/buyView'; 10 | } 11 | -------------------------------------------------------------------------------- /module/all_of_template/lib/features/next_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class NextPage extends StatelessWidget { 4 | const NextPage({Key? key}) : super(key: key); 5 | 6 | @override 7 | Widget build(BuildContext context) { 8 | return Scaffold( 9 | appBar: AppBar(), 10 | body: Text('Hello'), 11 | ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/product/model/user.dart: -------------------------------------------------------------------------------- 1 | class UserModel { 2 | 3 | UserModel(this.userName, this.userSurname); 4 | factory UserModel.fake() { 5 | return UserModel('Veli', 'Bacik'); 6 | } 7 | final String userName; 8 | final String userSurname; 9 | 10 | String get shortName => '${userName[0]}${userSurname[0]}'; 11 | String get fullName => '$userName $userSurname'; 12 | } 13 | -------------------------------------------------------------------------------- /module/all_of_template/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: f4abaa0735eba4dfd8f33f73363911d63931fe03 8 | channel: stable 9 | 10 | project_type: package 11 | -------------------------------------------------------------------------------- /test/feature/test/sample_view_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:fluttermvvmtemplate/core/init/network/ICoreDio.dart'; 3 | import 'package:fluttermvvmtemplate/core/init/network/network_manager.dart'; 4 | 5 | main() { 6 | setUp(() { 7 | final _ = NetworkManager.instance!.coreDio; 8 | }); 9 | test("Sample", () {}); 10 | } 11 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/fastlane/Appfile: -------------------------------------------------------------------------------- 1 | app_identifier("com.hwa.fluttermvvmtemplate") # The bundle identifier of your app 2 | apple_id("veli.bacik@vbt.com.tr") # Your Apple email address 3 | 4 | itc_team_id("95970990") # App Store Connect Team ID 5 | team_id("7LG7F3X8H6") # Developer Portal Team ID 6 | 7 | # For more information about the Appfile, see: 8 | # https://docs.fastlane.tools/advanced/#appfile 9 | -------------------------------------------------------------------------------- /module/architecture_widgets/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: f4abaa0735eba4dfd8f33f73363911d63931fe03 8 | channel: stable 9 | 10 | project_type: package 11 | -------------------------------------------------------------------------------- /module/architecture_widgets/test/architecture_widgets_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | 3 | 4 | void main() { 5 | test('adds one to input values', () { 6 | // final calculator = Calculator(); 7 | // expect(calculator.addOne(2), 3); 8 | // expect(calculator.addOne(-7), -6); 9 | // expect(calculator.addOne(0), 1); 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /lib/view/authenticate/splash/viewmodel/device_and_cahe.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluttermvvmtemplate/core/init/cache/locale_manager.dart'; 2 | import 'package:kartal/kartal.dart'; 3 | 4 | mixin DeviceAndCache { 5 | Future deviceandCacheInit() async { 6 | await Future.wait([ 7 | LocaleManager.prefrencesInit(), 8 | DeviceUtility.instance.initPackageInfo(), 9 | ]); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /lib/core/init/network/IResponseModel.dart: -------------------------------------------------------------------------------- 1 | abstract class IResponseModel { 2 | T? data; 3 | IErrorModel? error; 4 | } 5 | 6 | abstract class IErrorModel { 7 | void statusCode() {} 8 | } 9 | 10 | class ResponseModel extends IResponseModel { 11 | 12 | ResponseModel({this.data, this.error}); 13 | @override 14 | final T? data; 15 | @override 16 | final IErrorModel? error; 17 | } 18 | -------------------------------------------------------------------------------- /module/architecture_widgets/lib/src/card/not_found_navigation_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class NotFoundNavigationWidget extends StatelessWidget { 4 | const NotFoundNavigationWidget({Key? key}) : super(key: key); 5 | 6 | @override 7 | Widget build(BuildContext context) { 8 | return const Scaffold( 9 | body: Text('Not Found'), 10 | ); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/core/base/state/base_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | abstract class BaseState extends State { 4 | ThemeData get themeData => Theme.of(context); 5 | 6 | double dynamicHeight(double value) => 7 | MediaQuery.of(context).size.height * value; 8 | double dyanmicWidth(double value) => 9 | MediaQuery.of(context).size.width * value; 10 | } 11 | -------------------------------------------------------------------------------- /module/all_of_template/test/all_of_template_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | 3 | import 'package:all_of_template/all_of_template.dart'; 4 | 5 | void main() { 6 | test('adds one to input values', () { 7 | final calculator = Calculator(); 8 | expect(calculator.addOne(2), 3); 9 | expect(calculator.addOne(-7), -6); 10 | expect(calculator.addOne(0), 1); 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /lib/view/_product/_model/query/friend_query_enum.dart: -------------------------------------------------------------------------------- 1 | enum FriendQueryEnum { LIMIT, Q } 2 | 3 | extension FriendQueryEnumString on FriendQueryEnum { 4 | String get rawValue { 5 | switch (this) { 6 | case FriendQueryEnum.LIMIT: 7 | return 'limit'; 8 | case FriendQueryEnum.Q: 9 | return 'q'; 10 | default: 11 | throw Exception('Routes Not FouND'); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /module/architecture_widgets/lib/src/container/random_color_container.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | class RandomColorContainer extends StatelessWidget { 6 | const RandomColorContainer({Key? key}) : super(key: key); 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return ColoredBox(color: Colors.primaries[Random().nextInt(17)]); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/core/extension/network_exntension.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluttermvvmtemplate/core/constants/enums/http_request_enum.dart'; 2 | 3 | extension NetworkTypeExtension on HttpTypes? { 4 | String get rawValue { 5 | switch (this) { 6 | case HttpTypes.GET: 7 | return 'GET'; 8 | case HttpTypes.POST: 9 | return 'POST'; 10 | default: 11 | throw 'ERROR TYPE'; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:very_good_analysis/analysis_options.yaml 2 | 3 | 4 | analyzer: 5 | exclude: 6 | - "**/*.g.dart" 7 | - "**/*.freezed.dart" 8 | - "test/.test_coverage.dart" 9 | - "bin/cache/**" 10 | - "lib/generated_plugin_registrant.dart" 11 | - test 12 | - assets/translations 13 | 14 | linter: 15 | rules: 16 | public_member_api_docs: false 17 | library_private_types_in_public_api: false -------------------------------------------------------------------------------- /lib/core/constants/image/image_constatns.dart: -------------------------------------------------------------------------------- 1 | class ImageConstants { 2 | 3 | ImageConstants._init(); 4 | static ImageConstants? _instace; 5 | 6 | static ImageConstants get instance => _instace ??= ImageConstants._init(); 7 | 8 | String get logo => toPng('veli'); 9 | 10 | String get hotDog => toPng('hotdogs'); 11 | String get projeIcon => toPng('cirlce_hwa'); 12 | 13 | String toPng(String name) => 'asset/image/$name.png'; 14 | } 15 | -------------------------------------------------------------------------------- /module/architecture_widgets/lib/src/text/locale_text.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:fluttermvvmtemplate/core/extension/string_extension.dart'; 4 | 5 | class LocaleText extends StatelessWidget { 6 | final String value; 7 | 8 | const LocaleText({Key? key, required this.value}) : super(key: key); 9 | @override 10 | Widget build(BuildContext context) { 11 | return Text(value.locale); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/view/_product/_constants/image_path_svg.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluttermvvmtemplate/core/extension/string_extension.dart'; 2 | 3 | class SVGImagePaths { 4 | SVGImagePaths._init(); 5 | static SVGImagePaths? _instace; 6 | static SVGImagePaths get instance { 7 | return _instace ??= SVGImagePaths._init(); 8 | } 9 | 10 | final relaxSVG = 'relax'.toSVG; 11 | final astronautSVG = 'astronaut'.toSVG; 12 | final chattingSVG = 'chat'.toSVG; 13 | } 14 | -------------------------------------------------------------------------------- /lib/view/authenticate/login/service/ILoginService.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluttermvvmtemplate/view/authenticate/login/model/login_model.dart'; 2 | import 'package:fluttermvvmtemplate/view/authenticate/login/model/login_response_model.dart'; 3 | import 'package:vexana/vexana.dart'; 4 | 5 | abstract class ILoginService { 6 | ILoginService(this.manager); 7 | final INetworkManager manager; 8 | 9 | Future fetchUserControl(LoginModel model); 10 | } 11 | -------------------------------------------------------------------------------- /module/all_of_template/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:very_good_analysis/analysis_options.yaml 2 | 3 | 4 | analyzer: 5 | exclude: 6 | - "**/*.g.dart" 7 | - "**/*.freezed.dart" 8 | - "test/.test_coverage.dart" 9 | - "bin/cache/**" 10 | - "lib/generated_plugin_registrant.dart" 11 | - test 12 | - assets/translations 13 | 14 | linter: 15 | rules: 16 | public_member_api_docs: false 17 | library_private_types_in_public_api: false -------------------------------------------------------------------------------- /lib/view/home/build/feed/service/IBuildFeedService.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:fluttermvvmtemplate/view/home/build/feed/model/house_model.dart'; 3 | import 'package:vexana/vexana.dart'; 4 | 5 | abstract class IBuildFeedService { 6 | IBuildFeedService(this.manager, this.scaffoldyKey); 7 | final INetworkManager manager; 8 | final GlobalKey scaffoldyKey; 9 | 10 | Future?> fetchUserHouseList(); 11 | } 12 | -------------------------------------------------------------------------------- /module/architecture_widgets/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:very_good_analysis/analysis_options.yaml 2 | 3 | 4 | analyzer: 5 | exclude: 6 | - "**/*.g.dart" 7 | - "**/*.freezed.dart" 8 | - "test/.test_coverage.dart" 9 | - "bin/cache/**" 10 | - "lib/generated_plugin_registrant.dart" 11 | - test 12 | - assets/translations 13 | 14 | linter: 15 | rules: 16 | public_member_api_docs: false 17 | library_private_types_in_public_api: false -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/core/init/network/network_core/core_operations.dart: -------------------------------------------------------------------------------- 1 | part of '../core_dio.dart'; 2 | 3 | extension _CoreDioOperations on CoreDio { 4 | R? _responseParser(BaseModel model, dynamic data) { 5 | if (data is List>) { 6 | return data.map((e) => model.fromJson(e)).toList().cast() as R; 7 | } else if (data is Map) { 8 | return model.fromJson(data as Map) as R; 9 | } 10 | return data as R?; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/view/_product/_utilty/decoration_helper.dart: -------------------------------------------------------------------------------- 1 | import 'package:architecture_widgets/src/decoration/circle_decoration.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:fluttermvvmtemplate/core/extension/context_extension.dart'; 4 | 5 | class DecorationHelper { 6 | DecorationHelper({ 7 | this.context, 8 | }); 9 | BuildContext? context; 10 | 11 | Decoration get circleDecoriaton => CircleDecoration(color: context!.colors.surface, radius: 3); 12 | } 13 | -------------------------------------------------------------------------------- /macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController.init() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /lib/core/init/lang/language_manager.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class LanguageManager { 4 | 5 | LanguageManager._init(); 6 | static LanguageManager? _instance; 7 | static LanguageManager get instance { 8 | _instance ??= LanguageManager._init(); 9 | return _instance!; 10 | } 11 | 12 | final enLocale = const Locale('en', 'US'); 13 | final trLocale = const Locale('tr', 'TR'); 14 | 15 | List get supportedLocales => [enLocale, trLocale]; 16 | } 17 | -------------------------------------------------------------------------------- /module/architecture_widgets/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: architecture_widgets 2 | description: A new Flutter package project. 3 | version: 0.0.1 4 | homepage: home 5 | publish_to: none 6 | 7 | environment: 8 | sdk: ">=2.12.0 <3.0.0" 9 | flutter: ">=1.17.0" 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | 15 | fluttermvvmtemplate: 16 | path: ../../ 17 | 18 | dev_dependencies: 19 | flutter_test: 20 | sdk: flutter 21 | 22 | very_good_analysis: ^3.1.0 23 | 24 | 25 | flutter: -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /lib/core/init/theme/light/light_theme_interface.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluttermvvmtemplate/core/init/theme/light/color_scheme_light.dart'; 2 | import 'package:fluttermvvmtemplate/core/init/theme/light/padding_insets.dart'; 3 | import 'package:fluttermvvmtemplate/core/init/theme/light/text_theme_light.dart'; 4 | 5 | abstract class ILightTheme { 6 | TextThemeLight? textThemeLight = TextThemeLight.instance; 7 | ColorSchemeLight? colorSchemeLight = ColorSchemeLight.instance; 8 | PaddingInsets insets = PaddingInsets(); 9 | } 10 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /lib/view/settings/viewmodel/subviewmodel/about_view_model.dart: -------------------------------------------------------------------------------- 1 | part of '../settings_view_model.dart'; 2 | 3 | extension SettingsViewModelBaseNavigate on _SettingsViewModelBase { 4 | void navigateToContribution() { 5 | navigation.navigateToPage(path: NavigationConstants.SETTINGS_WEB_VIEW, data: SettingsDynamicModel.fakeArchitecturePR()); 6 | } 7 | 8 | void navigateToFakeContribution() { 9 | navigation.navigateToPage(path: NavigationConstants.SETTINGS_WEB_VIEW, data: SettingsDynamicModel.fakeNull()); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /module/all_of_template/README.md: -------------------------------------------------------------------------------- 1 | # all_of_template 2 | 3 | A new Flutter package project. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Dart 8 | [package](https://flutter.dev/developing-packages/), 9 | a library module containing code that can be shared easily across 10 | multiple Flutter or Dart projects. 11 | 12 | For help getting started with Flutter, view our 13 | [online documentation](https://flutter.dev/docs), which offers tutorials, 14 | samples, guidance on mobile development, and a full API reference. 15 | -------------------------------------------------------------------------------- /module/architecture_widgets/README.md: -------------------------------------------------------------------------------- 1 | # architecture_widgets 2 | 3 | A new Flutter package project. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Dart 8 | [package](https://flutter.dev/developing-packages/), 9 | a library module containing code that can be shared easily across 10 | multiple Flutter or Dart projects. 11 | 12 | For help getting started with Flutter, view our 13 | [online documentation](https://flutter.dev/docs), which offers tutorials, 14 | samples, guidance on mobile development, and a full API reference. 15 | -------------------------------------------------------------------------------- /lib/view/settings/model/settings_dynamic.dart: -------------------------------------------------------------------------------- 1 | class SettingsDynamicModel { 2 | 3 | SettingsDynamicModel(this.title, {this.url}); 4 | 5 | factory SettingsDynamicModel.fakeArchitecturePR() { 6 | return SettingsDynamicModel('Project Contributors', 7 | url: 'https://github.com/VB10/flutter-architecture-template/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc',); 8 | } 9 | 10 | factory SettingsDynamicModel.fakeNull() { 11 | return SettingsDynamicModel( 12 | 'Project Contributors', 13 | ); 14 | } 15 | final String? url; 16 | final String title; 17 | } 18 | -------------------------------------------------------------------------------- /lib/view/_product/_widgets/button/login_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:architecture_widgets/src/button/icon_button.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class MVVMLoginButton extends StatelessWidget { 5 | const MVVMLoginButton({Key? key, this.onComplete}) : super(key: key); 6 | final ValueChanged? onComplete; 7 | @override 8 | Widget build(BuildContext context) { 9 | return IconNormalButton( 10 | icon: Icons.access_alarm, 11 | onPressed: () { 12 | onComplete!('OKEY'); 13 | // BUSINESS CALL 14 | }, 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/core/extension/string_extension.dart: -------------------------------------------------------------------------------- 1 | import 'package:easy_localization/easy_localization.dart'; 2 | 3 | import 'package:fluttermvvmtemplate/core/constants/app/app_constants.dart'; 4 | 5 | extension StringLocalization on String { 6 | String get locale => this.tr(); 7 | 8 | String? get isValidEmail => contains(RegExp(ApplicationConstants.EMAIL_REGIEX)) ? null : 'Email does not valid'; 9 | 10 | bool get isValidEmails => RegExp(ApplicationConstants.EMAIL_REGIEX).hasMatch(this); 11 | } 12 | 13 | extension ImagePathExtension on String { 14 | String get toSVG => 'asset/svg/$this.svg'; 15 | } 16 | -------------------------------------------------------------------------------- /module/architecture_widgets/lib/src/column/form_column.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class FormColumn extends StatelessWidget { 4 | const FormColumn({Key? key, this.children}) : super(key: key); 5 | final List? children; 6 | @override 7 | Widget build(BuildContext context) { 8 | return Row( 9 | children: [ 10 | const Spacer(), 11 | Expanded( 12 | flex: 8, 13 | child: Column( 14 | children: children!, 15 | ), 16 | ), 17 | const Spacer(), 18 | ], 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/product/enum/lottie_path_enum.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:lottie/lottie.dart'; 3 | 4 | enum LottiePathEnum { SUNNY, MOON } 5 | 6 | extension LottiePathEnumExtension on LottiePathEnum { 7 | String get rawValue { 8 | switch (this) { 9 | case LottiePathEnum.MOON: 10 | return _pathValue('moon'); 11 | 12 | case LottiePathEnum.SUNNY: 13 | return _pathValue('sunny'); 14 | } 15 | } 16 | 17 | Widget get toWidget { 18 | return Lottie.asset(rawValue); 19 | } 20 | 21 | String _pathValue(String path) => 'asset/lottie/$path.json'; 22 | } 23 | -------------------------------------------------------------------------------- /lib/core/constants/app/app_constants.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: constant_identifier_names 2 | 3 | class ApplicationConstants { 4 | static const COMPANY_NAME = 'HWA'; 5 | 6 | // production'da olmadığımız sürece çalışmasını istemediğimiz fonksiyonlar için kullanacağız 7 | static const TEST_MODE = true; 8 | 9 | static const LANG_ASSET_PATH = 'asset/lang'; 10 | static const IPAD_NAME = 'IPAD'; 11 | static const FONT_FAMILY = 'POPPINS'; 12 | 13 | static const EMAIL_REGIEX = r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}\$'; 14 | 15 | static const APP_WEB_SITE = 'https://github.com/VB10/flutter-architecture-template'; 16 | } 17 | -------------------------------------------------------------------------------- /lib/view/authenticate/login/model/login_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | import 'package:vexana/vexana.dart'; 3 | 4 | part 'login_model.g.dart'; 5 | 6 | @JsonSerializable() 7 | class LoginModel extends INetworkModel { 8 | 9 | LoginModel({this.email, this.password}); 10 | final String? email; 11 | final String? password; 12 | 13 | @override 14 | LoginModel fromJson(Map json) { 15 | return _$LoginModelFromJson(json); 16 | } 17 | 18 | @override 19 | Map toJson() { 20 | return _$LoginModelToJson(this); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/view/authenticate/login/model/login_response_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | import 'package:vexana/vexana.dart'; 3 | 4 | part 'login_response_model.g.dart'; 5 | 6 | @JsonSerializable() 7 | class LoginResponseModel extends INetworkModel { 8 | 9 | LoginResponseModel({this.token}); 10 | final String? token; 11 | 12 | @override 13 | LoginResponseModel fromJson(Map json) { 14 | return _$LoginResponseModelFromJson(json); 15 | } 16 | 17 | @override 18 | Map toJson() { 19 | return _$LoginResponseModelToJson(this); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /module/architecture_widgets/lib/src/button/icon_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:architecture_widgets/src/button/normal_button.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class IconNormalButton extends StatelessWidget { 5 | const IconNormalButton({Key? key, this.onPressed, required this.icon}) 6 | : super( 7 | key: key, 8 | ); 9 | final VoidCallback? onPressed; 10 | final IconData icon; 11 | @override 12 | Widget build(BuildContext context) { 13 | return NormalButton( 14 | onPressed: onPressed, 15 | child: Center( 16 | child: Icon(icon), 17 | ), 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/view/_product/_utilty/service_helper.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:vexana/vexana.dart'; 3 | 4 | abstract class ServiceHelper { 5 | void showMessage( 6 | GlobalKey? scaffoldKey, 7 | IErrorModel? errorModel, 8 | ) { 9 | if (scaffoldKey == null || errorModel == null) return; 10 | 11 | if (scaffoldKey.currentContext == null) return; 12 | ScaffoldMessenger.of(scaffoldKey.currentContext!).showSnackBar( 13 | SnackBar( 14 | content: Text( 15 | errorModel.description ?? errorModel.statusCode.toString(), 16 | )), 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /module/architecture_widgets/lib/src/button/title_text_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:architecture_widgets/src/button/normal_button.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class TitleTextButton extends StatelessWidget { 5 | const TitleTextButton({Key? key, this.onPressed, required this.text}) 6 | : super( 7 | key: key, 8 | ); 9 | final VoidCallback? onPressed; 10 | final String text; 11 | @override 12 | Widget build(BuildContext context) { 13 | return NormalButton( 14 | onPressed: onPressed, 15 | child: Center( 16 | child: Text(text), 17 | ), 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/view/_product/enum/network_route_enum.dart: -------------------------------------------------------------------------------- 1 | enum NetworkRoutes { LOGIN, BUILD_HOME, FRIENDS, GAME, SLIDER } 2 | 3 | extension NetwrokRoutesString on NetworkRoutes { 4 | String get rawValue { 5 | switch (this) { 6 | case NetworkRoutes.LOGIN: 7 | return 'login'; 8 | case NetworkRoutes.BUILD_HOME: 9 | return 'house'; 10 | case NetworkRoutes.FRIENDS: 11 | return 'friends'; 12 | 13 | case NetworkRoutes.GAME: 14 | return 'games'; 15 | 16 | case NetworkRoutes.SLIDER: 17 | return 'slider'; 18 | default: 19 | throw Exception('Routes Not FouND'); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/view/home/game/model/slider_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | import 'package:vexana/vexana.dart'; 3 | 4 | part 'slider_model.g.dart'; 5 | 6 | @JsonSerializable() 7 | class SliderModel extends INetworkModel { 8 | 9 | SliderModel({this.image, this.text, this.detailId}); 10 | final String? image; 11 | final String? text; 12 | final String? detailId; 13 | 14 | @override 15 | SliderModel fromJson(Map json) { 16 | return _$SliderModelFromJson(json); 17 | } 18 | 19 | @override 20 | Map toJson() { 21 | return _$SliderModelToJson(this); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/view/_product/_widgets/listview/on_board_indicator.dart: -------------------------------------------------------------------------------- 1 | import 'package:architecture_widgets/src/list-view/indicator_list_view.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class OnBoardIndcator extends StatelessWidget { 5 | const OnBoardIndcator({Key? key, this.itemCount, this.currentIndex}) : super(key: key); 6 | final int? itemCount; 7 | final int? currentIndex; 8 | @override 9 | Widget build(BuildContext context) { 10 | return IndactorListView( 11 | currentIndex: currentIndex, 12 | itemCount: itemCount, 13 | onListItem: (index) { 14 | return const FlutterLogo(); 15 | }, 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /lib/view/home/game/service/IGameService.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:fluttermvvmtemplate/view/home/game/model/game_enums.dart'; 3 | import 'package:fluttermvvmtemplate/view/home/game/model/game_model.dart'; 4 | import 'package:fluttermvvmtemplate/view/home/game/model/slider_model.dart'; 5 | import 'package:vexana/vexana.dart'; 6 | 7 | abstract class IGameService { 8 | IGameService(this.manager, this.scaffoldyKey); 9 | final INetworkManager manager; 10 | final GlobalKey scaffoldyKey; 11 | 12 | Future?> fetchSliderItems(); 13 | Future?> fetchGameItems(GameEnum type); 14 | } 15 | -------------------------------------------------------------------------------- /lib/view/authenticate/login/model/login_response_model.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'login_response_model.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | LoginResponseModel _$LoginResponseModelFromJson(Map json) => 10 | LoginResponseModel( 11 | token: json['token'] as String?, 12 | ); 13 | 14 | Map _$LoginResponseModelToJson(LoginResponseModel instance) => 15 | { 16 | 'token': instance.token, 17 | }; 18 | -------------------------------------------------------------------------------- /lib/view/home/social/service/ISocialService.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:fluttermvvmtemplate/view/_product/_model/query/friend_query.dart'; 3 | import 'package:fluttermvvmtemplate/view/home/social/model/social_user_model.dart'; 4 | import 'package:vexana/vexana.dart'; 5 | 6 | abstract class ISocialServiceService { 7 | ISocialServiceService(this.manager, this.scaffoldyKey); 8 | final INetworkManager manager; 9 | final GlobalKey? scaffoldyKey; 10 | 11 | Future> fetchUserHouseList(FriendQuery query); 12 | Future> fetchUserNameQuery(String text); 13 | Future fetchUser(id); 14 | } 15 | -------------------------------------------------------------------------------- /lib/view/home/burger/model/burger_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | import 'package:vexana/vexana.dart'; 3 | 4 | part 'burger_model.g.dart'; 5 | 6 | @JsonSerializable() 7 | class BurgerModel extends INetworkModel { 8 | @JsonKey(name: '_id') 9 | String? id; 10 | String? image; 11 | String? name; 12 | int? price; 13 | int? rates; 14 | bool? isFavorite; 15 | String? updated; 16 | 17 | @override 18 | BurgerModel fromJson(Map json) { 19 | return _$BurgerModelFromJson(json); 20 | } 21 | 22 | @override 23 | Map toJson() { 24 | return _$BurgerModelToJson(this); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /lib/core/init/network/vexana_manager.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:vexana/vexana.dart'; 4 | 5 | class VexanaManager { 6 | 7 | VexanaManager._init(); 8 | static VexanaManager? _instace; 9 | static VexanaManager get instance { 10 | if (_instace != null) return _instace!; 11 | _instace = VexanaManager._init(); 12 | return _instace!; 13 | } 14 | 15 | static const String _iosBaseUrl = 'http://localhost:3000/'; 16 | static const String _androidBaseUrl = 'http://10.0.2.2:3000/'; 17 | 18 | INetworkManager networkManager = 19 | NetworkManager(isEnableLogger: true, options: BaseOptions(baseUrl: Platform.isAndroid ? _androidBaseUrl : _iosBaseUrl)); 20 | } 21 | -------------------------------------------------------------------------------- /lib/view/_product/_widgets/avatar/on_board_circle.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:fluttermvvmtemplate/core/extension/context_extension.dart'; 4 | 5 | class OnBoardCircle extends StatelessWidget { 6 | const OnBoardCircle({Key? key, required this.isSelected}) : super(key: key); 7 | final bool isSelected; 8 | @override 9 | Widget build(BuildContext context) { 10 | return Padding( 11 | padding: context.paddingLow, 12 | child: CircleAvatar( 13 | backgroundColor: context.colors.onError.withOpacity(isSelected ? 1 : 0.2), 14 | radius: isSelected ? context.width * 0.015 : context.width * 0.01, 15 | ), 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fluttermvvmtemplate", 3 | "short_name": "fluttermvvmtemplate", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /lib/view/authenticate/login/model/login_model.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'login_model.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | LoginModel _$LoginModelFromJson(Map json) => LoginModel( 10 | email: json['email'] as String?, 11 | password: json['password'] as String?, 12 | ); 13 | 14 | Map _$LoginModelToJson(LoginModel instance) => 15 | { 16 | 'email': instance.email, 17 | 'password': instance.password, 18 | }; 19 | -------------------------------------------------------------------------------- /macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = fluttermvvmtemplate 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.fluttermvvmtemplate 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2020 com.example. All rights reserved. 15 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:4.1.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /module/architecture_widgets/lib/src/text/auto_locale_text.dart: -------------------------------------------------------------------------------- 1 | import 'package:auto_size_text/auto_size_text.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import 'package:fluttermvvmtemplate/core/extension/string_extension.dart'; 5 | 6 | class AutoLocaleText extends StatelessWidget { 7 | const AutoLocaleText({Key? key, required this.value, this.textAlign, this.style}) 8 | : super( 9 | key: key, 10 | ); 11 | final String value; 12 | final TextAlign? textAlign; 13 | final TextStyle? style; 14 | @override 15 | Widget build(BuildContext context) { 16 | return AutoSizeText( 17 | value.locale, 18 | textAlign: textAlign, 19 | style: style, 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/view/authenticate/splash/model/force_update_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | import 'package:vexana/vexana.dart'; 3 | 4 | part 'force_update_model.g.dart'; 5 | 6 | @JsonSerializable() 7 | class ForceUpdateModel extends INetworkModel { 8 | ForceUpdateModel({ 9 | this.isForceUpdate, 10 | this.type, 11 | this.currentVersion, 12 | }); 13 | bool? isForceUpdate; 14 | String? type; 15 | String? currentVersion; 16 | 17 | @override 18 | ForceUpdateModel fromJson(Map json) { 19 | return _$ForceUpdateModelFromJson(json); 20 | } 21 | 22 | @override 23 | Map toJson() { 24 | return _$ForceUpdateModelToJson(this); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/core/init/theme/light/color_scheme_light.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ColorSchemeLight { 4 | 5 | ColorSchemeLight._init(); 6 | static ColorSchemeLight? _instace; 7 | static ColorSchemeLight? get instance { 8 | _instace ??= ColorSchemeLight._init(); 9 | return _instace; 10 | } 11 | 12 | final Color brown = const Color(0xffa87e6f); 13 | final Color red = const Color(0xffc10e0e); 14 | final Color white = const Color(0xffffffff); 15 | final Color gray = const Color(0xffa5a6ae); 16 | final Color lightGray = const Color(0xfff7f7f7); 17 | final Color darkGray = const Color(0xff676870); 18 | final Color black = const Color(0xff020306); 19 | 20 | final Color azure = const Color(0xff27928d); 21 | } 22 | -------------------------------------------------------------------------------- /lib/view/home/game/model/game_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | import 'package:vexana/vexana.dart'; 3 | 4 | part 'game_model.g.dart'; 5 | 6 | @JsonSerializable() 7 | class GameModel extends INetworkModel { 8 | GameModel({ 9 | this.sId, 10 | this.image, 11 | this.name, 12 | this.money, 13 | this.category, 14 | }); 15 | @JsonKey(name: '_id') 16 | String? sId; 17 | String? image; 18 | String? name; 19 | int? money; 20 | int? category; 21 | 22 | @override 23 | GameModel fromJson(Map json) { 24 | return _$GameModelFromJson(json); 25 | } 26 | 27 | @override 28 | Map toJson() { 29 | return _$GameModelToJson(this); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/view/home/game/model/slider_model.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'slider_model.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | SliderModel _$SliderModelFromJson(Map json) => SliderModel( 10 | image: json['image'] as String?, 11 | text: json['text'] as String?, 12 | detailId: json['detailId'] as String?, 13 | ); 14 | 15 | Map _$SliderModelToJson(SliderModel instance) => 16 | { 17 | 'image': instance.image, 18 | 'text': instance.text, 19 | 'detailId': instance.detailId, 20 | }; 21 | -------------------------------------------------------------------------------- /test/feature/splash/splash_service_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:fluttermvvmtemplate/core/init/network/vexana_manager.dart'; 3 | import 'package:fluttermvvmtemplate/view/_product/_utilty/burger_network_enum.dart'; 4 | import 'package:fluttermvvmtemplate/view/authenticate/splash/service/splash_service.dart'; 5 | import 'package:fluttermvvmtemplate/view/home/burger/service/burger_serivce.dart'; 6 | 7 | void main() { 8 | ISplashService? splashService; 9 | setUp(() { 10 | splashService = SplashService(VexanaManager.instance.networkManager); 11 | }); 12 | test('Fetch favorite Burgers', () async { 13 | final response = await splashService?.checkDeviceVersion( 14 | version: "0.0.9", platform: "1"); 15 | 16 | expect(response, isNotEmpty); 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /lib/view/authenticate/test/model/test_model.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'test_model.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | TestModel _$TestModelFromJson(Map json) => TestModel( 10 | userId: json['userId'] as int?, 11 | id: json['id'] as int?, 12 | title: json['title'] as String?, 13 | completed: json['completed'] as bool?, 14 | ); 15 | 16 | Map _$TestModelToJson(TestModel instance) => { 17 | 'userId': instance.userId, 18 | 'id': instance.id, 19 | 'title': instance.title, 20 | 'completed': instance.completed, 21 | }; 22 | -------------------------------------------------------------------------------- /lib/view/home/social/model/social_user_model.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'social_user_model.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | SocialUser _$SocialUserFromJson(Map json) => SocialUser( 10 | name: json['name'] as String?, 11 | company: json['company'] as String?, 12 | image: json['image'] as String?, 13 | )..id = json['_id'] as String?; 14 | 15 | Map _$SocialUserToJson(SocialUser instance) => 16 | { 17 | '_id': instance.id, 18 | 'name': instance.name, 19 | 'company': instance.company, 20 | 'image': instance.image, 21 | }; 22 | -------------------------------------------------------------------------------- /lib/view/settings/view/subview/settings_dynamic_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:fluttermvvmtemplate/core/constants/app/app_constants.dart'; 3 | import 'package:fluttermvvmtemplate/view/settings/model/settings_dynamic.dart'; 4 | import 'package:kartal/kartal.dart'; 5 | import 'package:webview_flutter/webview_flutter.dart'; 6 | 7 | class SettingsDynamicView extends StatelessWidget { 8 | const SettingsDynamicView({Key? key, required this.model}) : super(key: key); 9 | final SettingsDynamicModel model; 10 | @override 11 | Widget build(BuildContext context) { 12 | return Scaffold( 13 | appBar: AppBar(centerTitle: false, title: Text(model.title, style: context.textTheme.headline6)), 14 | body: WebView(initialUrl: model.url ?? ApplicationConstants.APP_WEB_SITE), 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /module/architecture_widgets/lib/src/button/normal_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class NormalButton extends StatelessWidget { 4 | const NormalButton({Key? key, this.child, this.onPressed}) : super(key: key); 5 | final Widget? child; 6 | 7 | final VoidCallback? onPressed; 8 | @override 9 | Widget build(BuildContext context) { 10 | return ElevatedButton( 11 | style: ButtonStyle( 12 | padding: MaterialStateProperty.all(const EdgeInsets.all(15)), 13 | elevation: MaterialStateProperty.all(10), 14 | ), 15 | onPressed: onPressed, 16 | child: child, 17 | ); 18 | } 19 | } 20 | 21 | // BEFORE: NULL SAFETY 22 | // return RaisedButton( 23 | // padding: EdgeInsets.all(15), 24 | // elevation: 10, 25 | // onPressed: onPressed, 26 | // child: child, 27 | // ); 28 | -------------------------------------------------------------------------------- /lib/core/init/notifier/provider_list.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluttermvvmtemplate/core/init/navigation/navigation_service.dart'; 2 | import 'package:fluttermvvmtemplate/core/init/notifier/theme_notifer.dart'; 3 | import 'package:provider/provider.dart'; 4 | import 'package:provider/single_child_widget.dart'; 5 | 6 | class ApplicationProvider { 7 | ApplicationProvider._init(); 8 | static ApplicationProvider? _instance; 9 | static ApplicationProvider get instance { 10 | _instance ??= ApplicationProvider._init(); 11 | return _instance!; 12 | } 13 | 14 | List singleItems = []; 15 | List dependItems = [ 16 | ChangeNotifierProvider( 17 | create: (context) => ThemeNotifier(), 18 | ), 19 | Provider.value(value: NavigationService.instance) 20 | ]; 21 | List uiChangesItems = []; 22 | } 23 | -------------------------------------------------------------------------------- /lib/view/authenticate/splash/model/force_update_model.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'force_update_model.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ForceUpdateModel _$ForceUpdateModelFromJson(Map json) => 10 | ForceUpdateModel( 11 | isForceUpdate: json['isForceUpdate'] as bool?, 12 | type: json['type'] as String?, 13 | currentVersion: json['currentVersion'] as String?, 14 | ); 15 | 16 | Map _$ForceUpdateModelToJson(ForceUpdateModel instance) => 17 | { 18 | 'isForceUpdate': instance.isForceUpdate, 19 | 'type': instance.type, 20 | 'currentVersion': instance.currentVersion, 21 | }; 22 | -------------------------------------------------------------------------------- /lib/view/home/game/model/game_model.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'game_model.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | GameModel _$GameModelFromJson(Map json) => GameModel( 10 | sId: json['_id'] as String?, 11 | image: json['image'] as String?, 12 | name: json['name'] as String?, 13 | money: json['money'] as int?, 14 | category: json['category'] as int?, 15 | ); 16 | 17 | Map _$GameModelToJson(GameModel instance) => { 18 | '_id': instance.sId, 19 | 'image': instance.image, 20 | 'name': instance.name, 21 | 'money': instance.money, 22 | 'category': instance.category, 23 | }; 24 | -------------------------------------------------------------------------------- /test/core/network/dio_mock_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluttermvvmtemplate/core/base/model/base_model.dart'; 2 | 3 | class PostModel extends BaseModel { 4 | int? userId; 5 | int? id; 6 | String? title; 7 | String? body; 8 | 9 | PostModel({this.userId, this.id, this.title, this.body}); 10 | 11 | PostModel.fromJson(Map json) { 12 | userId = json['userId'] as int?; 13 | id = json['id'] as int?; 14 | title = json['title'] as String?; 15 | body = json['body'] as String?; 16 | } 17 | 18 | @override 19 | Map toJson() { 20 | final data = {}; 21 | data['userId'] = userId; 22 | data['id'] = id; 23 | data['title'] = title; 24 | data['body'] = body; 25 | return data; 26 | } 27 | 28 | @override 29 | PostModel fromJson(Map json) { 30 | return PostModel.fromJson(json); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/view/_product/_utilty/thorottle_helper.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | class ThrottleStringHelper { 4 | ThrottleStringHelper() { 5 | _onSetMaxValue(); 6 | } 7 | String? _pastText; 8 | 9 | final int _maxTimerValue = 5; 10 | int _timerValue = 0; 11 | void onDelayTouch(String text, Function(String? text) onComplete) { 12 | _pastText = text; 13 | if (_timerValue == _maxTimerValue) { 14 | Timer.periodic(const Duration(milliseconds: 100), (timer) { 15 | _timerValue--; 16 | 17 | if (_timerValue == 0) { 18 | onComplete(_pastText); 19 | timer.cancel(); 20 | _onSetMaxValue(); 21 | } 22 | }); 23 | } else { 24 | _onSetMaxNearValue(); 25 | } 26 | } 27 | 28 | void _onSetMaxValue() { 29 | _timerValue = _maxTimerValue; 30 | } 31 | 32 | void _onSetMaxNearValue() { 33 | _timerValue = _maxTimerValue - 1; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 11.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/fastlane/README.md: -------------------------------------------------------------------------------- 1 | fastlane documentation 2 | ================ 3 | # Installation 4 | 5 | Make sure you have the latest version of the Xcode command line tools installed: 6 | 7 | ``` 8 | xcode-select --install 9 | ``` 10 | 11 | Install _fastlane_ using 12 | ``` 13 | [sudo] gem install fastlane -NV 14 | ``` 15 | or alternatively using `brew install fastlane` 16 | 17 | # Available Actions 18 | ## iOS 19 | ### ios beta 20 | ``` 21 | fastlane ios beta 22 | ``` 23 | Push a new beta build to TestFlight 24 | ### ios internal 25 | ``` 26 | fastlane ios internal 27 | ``` 28 | Push a new artifact build internal 29 | 30 | ---- 31 | 32 | This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run. 33 | More information about fastlane can be found on [fastlane.tools](https://fastlane.tools). 34 | The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools). 35 | -------------------------------------------------------------------------------- /lib/core/init/navigation/navigation_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | 3 | import 'package:fluttermvvmtemplate/core/init/navigation/INavigationService.dart'; 4 | 5 | class NavigationService implements INavigationService { 6 | NavigationService._init(); 7 | static final NavigationService _instance = NavigationService._init(); 8 | static NavigationService get instance => _instance; 9 | 10 | GlobalKey navigatorKey = GlobalKey(); 11 | final removeAllOldRoutes = (Route route) => false; 12 | 13 | @override 14 | Future navigateToPage({String? path, Object? data}) async { 15 | await navigatorKey.currentState!.pushNamed(path!, arguments: data); 16 | } 17 | 18 | @override 19 | Future navigateToPageClear({String? path, Object? data}) async { 20 | await navigatorKey.currentState!.pushNamedAndRemoveUntil(path!, removeAllOldRoutes, arguments: data); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ios/fastlane/report.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /lib/product/widget/card/game_card.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:fluttermvvmtemplate/core/extension/context_extension.dart'; 4 | import 'package:fluttermvvmtemplate/view/home/game/model/game_model.dart'; 5 | 6 | class GameCard extends StatelessWidget { 7 | const GameCard({Key? key, this.model, this.onPressed}) : super(key: key); 8 | final GameModel? model; 9 | final VoidCallback? onPressed; 10 | @override 11 | Widget build(BuildContext context) { 12 | return Card( 13 | child: Padding( 14 | padding: context.paddingLow, 15 | child: Column( 16 | crossAxisAlignment: CrossAxisAlignment.start, 17 | children: [ 18 | Expanded( 19 | child: Center(child: Image.network(model!.image!)), 20 | ), 21 | Text(model!.name!), 22 | Text('\$ ${model!.money}') 23 | ], 24 | ), 25 | ), 26 | ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lib/core/base/model/base_view_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:fluttermvvmtemplate/core/init/cache/locale_manager.dart'; 4 | import 'package:fluttermvvmtemplate/core/init/navigation/navigation_service.dart'; 5 | import 'package:fluttermvvmtemplate/core/init/network/ICoreDio.dart'; 6 | import 'package:fluttermvvmtemplate/core/init/network/network_manager.dart'; 7 | import 'package:fluttermvvmtemplate/core/init/network/vexana_manager.dart'; 8 | 9 | abstract class BaseViewModel { 10 | late BuildContext viewModelContext; 11 | 12 | ICoreDioNullSafety? coreDio = NetworkManager.instance!.coreDio; 13 | VexanaManager? vexanaManager = VexanaManager.instance; 14 | 15 | VexanaManager get vexanaManagerComputed => VexanaManager.instance; 16 | 17 | LocaleManager localeManager = LocaleManager.instance; 18 | NavigationService navigation = NavigationService.instance; 19 | 20 | void setContext(BuildContext context); 21 | void init(); 22 | } 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Exceptions to above rules. 44 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 45 | 46 | # google-services 47 | android/app/google-services.json -------------------------------------------------------------------------------- /lib/view/_product/_widgets/button/face_book_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:architecture_widgets/src/button/title_text_button.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class FaceBookButton extends StatelessWidget { 5 | const FaceBookButton({Key? key, this.onComplete}) : super(key: key); 6 | final void Function(FaceBookModel? data, {String? errorMessage})? onComplete; 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return TitleTextButton( 11 | text: 'Facebbok login', 12 | onPressed: () { 13 | const isLengthSixCharacter = 'asdasdasd'.length == 6; 14 | 15 | if (isLengthSixCharacter) { 16 | onComplete!(FaceBookModel('asdasd', 'ASdasd')); 17 | } else { 18 | onComplete!(null, errorMessage: 'Facebook user not found'); 19 | } 20 | }, 21 | ); 22 | } 23 | } 24 | 25 | class FaceBookModel { 26 | FaceBookModel(this.token, this.mail); 27 | final String token; 28 | final String mail; 29 | } 30 | -------------------------------------------------------------------------------- /module/architecture_widgets/lib/src/decoration/circle_decoration.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class CircleDecoration extends Decoration { 4 | CircleDecoration({required Color color, required double radius}) : _painter = _CirclePainter(color, radius); 5 | final BoxPainter _painter; 6 | 7 | @override 8 | BoxPainter createBoxPainter([VoidCallback? onChanged]) => _painter; 9 | } 10 | 11 | class _CirclePainter extends BoxPainter { 12 | _CirclePainter(Color color, this.radius) 13 | : _paint = Paint() 14 | ..color = color 15 | ..isAntiAlias = true; 16 | final Paint _paint; 17 | final double radius; 18 | 19 | late Offset circleOffset; 20 | 21 | @override 22 | void paint(Canvas canvas, Offset offset, ImageConfiguration cfg) { 23 | circleOffset = offset + 24 | Offset( 25 | cfg.size!.width / 2, 26 | cfg.size!.height - radius - 5, 27 | ); 28 | canvas.drawCircle(circleOffset, radius, _paint); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/product/widget/grid/game_grid_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:fluttermvvmtemplate/product/widget/card/game_card.dart'; 3 | import 'package:fluttermvvmtemplate/view/home/game/model/game_model.dart'; 4 | 5 | class GameGrid extends StatelessWidget { 6 | const GameGrid({Key? key, this.models, this.onPressed}) : super(key: key); 7 | final List? models; 8 | final void Function(GameModel item, int indx)? onPressed; 9 | @override 10 | Widget build(BuildContext context) { 11 | return GridView.builder( 12 | gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( 13 | crossAxisCount: 3, 14 | childAspectRatio: 0.8, 15 | ), 16 | itemCount: 3, 17 | shrinkWrap: true, 18 | physics: const NeverScrollableScrollPhysics(), 19 | itemBuilder: (context, index) => GameCard( 20 | model: models![index], 21 | onPressed: () { 22 | onPressed!(models![index], index); 23 | }, 24 | ), 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/view/home/burger/model/burger_model.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'burger_model.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | BurgerModel _$BurgerModelFromJson(Map json) => BurgerModel() 10 | ..id = json['_id'] as String? 11 | ..image = json['image'] as String? 12 | ..name = json['name'] as String? 13 | ..price = json['price'] as int? 14 | ..rates = json['rates'] as int? 15 | ..isFavorite = json['isFavorite'] as bool? 16 | ..updated = json['updated'] as String?; 17 | 18 | Map _$BurgerModelToJson(BurgerModel instance) => 19 | { 20 | '_id': instance.id, 21 | 'image': instance.image, 22 | 'name': instance.name, 23 | 'price': instance.price, 24 | 'rates': instance.rates, 25 | 'isFavorite': instance.isFavorite, 26 | 'updated': instance.updated, 27 | }; 28 | -------------------------------------------------------------------------------- /test/feature/burger/burger_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:fluttermvvmtemplate/core/init/network/vexana_manager.dart'; 3 | import 'package:fluttermvvmtemplate/view/_product/_utilty/burger_network_enum.dart'; 4 | import 'package:fluttermvvmtemplate/view/home/burger/service/burger_serivce.dart'; 5 | 6 | void main() { 7 | IBurgerService? burgerService; 8 | setUp(() { 9 | burgerService = BurgerService(VexanaManager.instance.networkManager); 10 | }); 11 | test('Fetch favorite Burgers', () async { 12 | final response = await burgerService?.fetchFavoriteBurgers(); 13 | 14 | expect(response, isNotEmpty); 15 | }); 16 | 17 | test('Fetch min 20 max 30 service', () async { 18 | final response = await burgerService?.fetchBurgersLimited(min: 20, max: 30); 19 | 20 | expect(response, isNotEmpty); 21 | }); 22 | 23 | test('Fetch sort rate', () async { 24 | final response = await burgerService?.fetchBurgersSorted(sort: BurgerSortValues.RATES); 25 | 26 | expect(response, isNotEmpty); 27 | }); 28 | } 29 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /lib/core/init/theme/light/text_theme_light.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class TextThemeLight { 4 | TextThemeLight._init(); 5 | static TextThemeLight? _instance; 6 | static TextThemeLight? get instance { 7 | _instance ??= TextThemeLight._init(); 8 | return _instance; 9 | } 10 | 11 | final TextStyle headline1 = const TextStyle( 12 | fontSize: 96, 13 | fontWeight: FontWeight.w300, 14 | letterSpacing: -1.5, 15 | ); 16 | final TextStyle headline2 = const TextStyle( 17 | fontSize: 60, 18 | fontWeight: FontWeight.w300, 19 | letterSpacing: -0.5, 20 | ); 21 | final TextStyle headline3 = const TextStyle( 22 | fontSize: 48, 23 | fontWeight: FontWeight.w400, 24 | ); 25 | final TextStyle headline4 = const TextStyle( 26 | fontSize: 34, 27 | fontWeight: FontWeight.w400, 28 | letterSpacing: 0.25, 29 | ); 30 | final TextStyle headline5 = const TextStyle( 31 | fontSize: 24, 32 | fontWeight: FontWeight.w400, 33 | ); 34 | final TextStyle overline = const TextStyle( 35 | fontSize: 10, 36 | fontWeight: FontWeight.w400, 37 | letterSpacing: 1.5, 38 | ); 39 | } 40 | -------------------------------------------------------------------------------- /lib/core/base/view/base_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mobx/mobx.dart'; 3 | 4 | class BaseView extends StatefulWidget { 5 | const BaseView({ 6 | Key? key, 7 | required this.viewModel, 8 | required this.onPageBuilder, 9 | required this.onModelReady, 10 | this.onDispose, 11 | }) : super(key: key); 12 | final Widget Function(BuildContext context, T value) onPageBuilder; 13 | final T viewModel; 14 | final void Function(T model) onModelReady; 15 | final VoidCallback? onDispose; 16 | 17 | @override 18 | _BaseViewState createState() => _BaseViewState(); 19 | } 20 | 21 | class _BaseViewState extends State> { 22 | late T model; 23 | @override 24 | void initState() { 25 | model = widget.viewModel; 26 | widget.onModelReady(model); 27 | super.initState(); 28 | } 29 | 30 | @override 31 | void dispose() { 32 | super.dispose(); 33 | if (widget.onDispose != null) widget.onDispose?.call(); 34 | } 35 | 36 | @override 37 | Widget build(BuildContext context) { 38 | return widget.onPageBuilder(context, model); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/view/authenticate/test/model/test_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:fluttermvvmtemplate/core/base/model/base_model.dart'; 3 | import 'package:json_annotation/json_annotation.dart'; 4 | 5 | part 'test_model.g.dart'; 6 | 7 | @JsonSerializable() 8 | class TestModel extends BaseModel with EquatableMixin { 9 | TestModel({this.userId, this.id, this.title, this.completed}); 10 | final int? userId; 11 | final int? id; 12 | final String? title; 13 | final bool? completed; 14 | 15 | @override 16 | Map toJson() { 17 | return _$TestModelToJson(this); 18 | } 19 | 20 | @override 21 | TestModel fromJson(Map json) { 22 | return _$TestModelFromJson(json); 23 | } 24 | 25 | @override 26 | List get props => [userId, id, title, completed]; 27 | 28 | TestModel copyWith({ 29 | int? userId, 30 | int? id, 31 | String? title, 32 | bool? completed, 33 | }) { 34 | return TestModel( 35 | userId: userId ?? this.userId, 36 | id: id ?? this.id, 37 | title: title ?? this.title, 38 | completed: completed ?? this.completed, 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:fluttermvvmtemplate/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /lib/core/init/network/network_manager.dart: -------------------------------------------------------------------------------- 1 | import 'package:dio/dio.dart'; 2 | 3 | import 'package:fluttermvvmtemplate/core/constants/enums/locale_keys_enum.dart'; 4 | import 'package:fluttermvvmtemplate/core/init/cache/locale_manager.dart'; 5 | import 'package:fluttermvvmtemplate/core/init/network/ICoreDio.dart'; 6 | import 'package:fluttermvvmtemplate/core/init/network/core_dio.dart'; 7 | 8 | class NetworkManager { 9 | NetworkManager._init() { 10 | final baseOptions = BaseOptions( 11 | baseUrl: 'https://jsonplaceholder.typicode.com/', 12 | headers: {'val': LocaleManager.instance.getStringValue(PreferencesKeys.TOKEN)}, 13 | ); 14 | // _dio = Dio(baseOptions); 15 | 16 | coreDio = CoreDio(baseOptions); 17 | 18 | // _dio.interceptors.add(InterceptorsWrapper( 19 | // onRequest: (options) { 20 | // options.path += "veli"; 21 | // }, 22 | // onError: (e) { 23 | // return BaseError(e.message); 24 | // }, 25 | // )); 26 | } 27 | static NetworkManager? _instance; 28 | static NetworkManager? get instance { 29 | _instance ??= NetworkManager._init(); 30 | return _instance; 31 | } 32 | 33 | ICoreDioNullSafety? coreDio; 34 | } 35 | -------------------------------------------------------------------------------- /macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /module/architecture_widgets/lib/src/slider/range_price_slider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class RangePriceSLider extends StatefulWidget { 4 | const RangePriceSLider({Key? key, required this.min, required this.max, required this.onCompleted}) : super(key: key); 5 | final double min; 6 | final double max; 7 | 8 | final void Function(RangeValues values) onCompleted; 9 | @override 10 | _RangePriceSLiderState createState() => _RangePriceSLiderState(); 11 | } 12 | 13 | class _RangePriceSLiderState extends State { 14 | late RangeValues _values; 15 | 16 | @override 17 | void initState() { 18 | super.initState(); 19 | _values = RangeValues(widget.min, widget.max); 20 | } 21 | 22 | @override 23 | Widget build(BuildContext context) { 24 | return RangeSlider( 25 | values: _values, 26 | max: widget.max, 27 | min: widget.min, 28 | labels: RangeLabels('${_values.start}', '${_values.end}'), 29 | activeColor: Colors.red, 30 | divisions: 10, 31 | onChanged: (value) { 32 | setState(() { 33 | _values = value; 34 | }); 35 | widget.onCompleted(_values); 36 | }, 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/view/_product/_widgets/animation/social_card_animation.dart: -------------------------------------------------------------------------------- 1 | import 'package:animations/animations.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import 'package:fluttermvvmtemplate/view/home/social/model/social_user_model.dart'; 5 | import 'package:fluttermvvmtemplate/view/home/social/view/social_view_detial.dart'; 6 | 7 | class OpenContainerSocailWrapper extends StatelessWidget { 8 | const OpenContainerSocailWrapper({ 9 | this.closedBuilder, 10 | this.onClosed, 11 | this.socialUser, 12 | }); 13 | final ContainerTransitionType _transitionType = ContainerTransitionType.fade; 14 | 15 | final OpenContainerBuilder? closedBuilder; 16 | final ClosedCallback? onClosed; 17 | final SocialUser? socialUser; 18 | @override 19 | Widget build(BuildContext context) { 20 | return OpenContainer( 21 | transitionType: _transitionType, 22 | openBuilder: (BuildContext context, VoidCallback _) { 23 | return SocialUserViewDetail( 24 | socialUser: socialUser, 25 | ); 26 | }, 27 | onClosed: onClosed, 28 | tappable: false, 29 | closedBuilder: closedBuilder as Widget Function(BuildContext, void Function()), 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import connectivity_plus_macos 9 | import firebase_analytics 10 | import firebase_core 11 | import package_info_plus_macos 12 | import path_provider_macos 13 | import shared_preferences_macos 14 | import sqflite 15 | import url_launcher_macos 16 | 17 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 18 | ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin")) 19 | FLTFirebaseAnalyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAnalyticsPlugin")) 20 | FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) 21 | FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin")) 22 | PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) 23 | SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) 24 | SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) 25 | UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) 26 | } 27 | -------------------------------------------------------------------------------- /lib/core/init/notifier/theme_notifer.dart: -------------------------------------------------------------------------------- 1 | import 'package:architecture_theme/theme/app_theme_light.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import 'package:fluttermvvmtemplate/core/constants/enums/app_theme_enum.dart'; 5 | 6 | class ThemeNotifier extends ChangeNotifier { 7 | ThemeData _currentTheme = AppThemeLight.instance.theme; 8 | 9 | AppThemes _currenThemeEnum = AppThemes.LIGHT; 10 | 11 | /// Applicaton theme enum. 12 | /// Deafult value is [AppThemes.LIGHT] 13 | AppThemes get currenThemeEnum => _currenThemeEnum; 14 | 15 | ThemeData get currentTheme => _currentTheme; 16 | 17 | void changeValue(AppThemes theme) { 18 | if (theme == AppThemes.LIGHT) { 19 | _currentTheme = ThemeData.light(); 20 | } else { 21 | _currentTheme = ThemeData.dark(); 22 | } 23 | notifyListeners(); 24 | } 25 | 26 | /// Change your app theme with [currenThemeEnum] value. 27 | void changeTheme() { 28 | if (_currenThemeEnum == AppThemes.LIGHT) { 29 | _currentTheme = ThemeData.dark(); 30 | _currenThemeEnum = AppThemes.DARK; 31 | } else { 32 | _currentTheme = AppThemeLight.instance.theme; 33 | _currenThemeEnum = AppThemes.LIGHT; 34 | } 35 | notifyListeners(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /lib/view/home/social/model/social_user_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | import 'package:vexana/vexana.dart'; 3 | 4 | part 'social_user_model.g.dart'; 5 | 6 | @JsonSerializable() 7 | class SocialUser extends INetworkModel { 8 | 9 | SocialUser({this.name, this.company, this.image}); 10 | 11 | SocialUser.fromJson(Map json) { 12 | id = json['_id'] as String?; 13 | name = json['name'] as String?; 14 | company = json['company'] as String?; 15 | image = json['image'] as String?; 16 | } 17 | @JsonKey(name: '_id') 18 | String? id; 19 | String? name; 20 | String? company; 21 | String? image; 22 | 23 | @override 24 | Map toJson() { 25 | return _$SocialUserToJson(this); 26 | } 27 | 28 | @override 29 | SocialUser fromJson(Map json) { 30 | return _$SocialUserFromJson(json); 31 | } 32 | 33 | @override 34 | bool operator ==(Object o) { 35 | if (identical(this, o)) return true; 36 | 37 | return o is SocialUser && o.id == id && o.name == name && o.company == company && o.image == image; 38 | } 39 | 40 | @override 41 | int get hashCode { 42 | return id.hashCode ^ name.hashCode ^ company.hashCode ^ image.hashCode; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | fluttermvvmtemplate 18 | 19 | 20 | 21 | 24 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /test/feature/feed/feed_mockito.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:fluttermvvmtemplate/view/home/social/model/social_user_model.dart'; 3 | import 'package:fluttermvvmtemplate/view/home/social/viewmodel/social_view_model.dart'; 4 | import 'package:mockito/mockito.dart'; 5 | 6 | import 'social_network_mock.dart'; 7 | 8 | class SocialBuildContext extends Mock implements BuildContext {} 9 | 10 | class SocialMockViewModel extends Mock implements SocialViewModel { 11 | SocialMockViewModel(SocialNetworkMock? mockService); 12 | @override 13 | bool isPageLoading = false; 14 | } 15 | 16 | class SocialFakeViewModel extends Fake implements SocialViewModel { 17 | SocialFakeViewModel(SocialNetworkMock mockService); 18 | @override 19 | BuildContext? context; 20 | 21 | @override 22 | bool isPageLoading = false; 23 | @override 24 | List socialUserList = []; 25 | 26 | @override 27 | Future fetchAllUserLoading(int index) async { 28 | isPageLoading = true; 29 | await Future.delayed(Duration(seconds: 1)); 30 | socialUserList = [SocialUser(name: '')]; 31 | isPageLoading = false; 32 | } 33 | 34 | @override 35 | void setContext(BuildContext? context) { 36 | this.context = context; 37 | } 38 | 39 | void changeLoading() { 40 | isPageLoading = !isPageLoading; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/view/_product/_widgets/list-tile/friend_card.dart: -------------------------------------------------------------------------------- 1 | import 'package:easy_localization/easy_localization.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:fluttermvvmtemplate/core/init/lang/locale_keys.g.dart'; 4 | import 'package:fluttermvvmtemplate/view/home/social/model/social_user_model.dart'; 5 | import 'package:kartal/kartal.dart'; 6 | 7 | class FriendCard extends StatelessWidget { 8 | const FriendCard({Key? key, this.user, this.onPressed}) : super(key: key); 9 | final SocialUser? user; 10 | final VoidCallback? onPressed; 11 | @override 12 | Widget build(BuildContext context) { 13 | if (user == null) { 14 | // throw Exception('User object is null $this'); 15 | return const SizedBox(); 16 | } 17 | return ListTile( 18 | leading: CircleAvatar(backgroundImage: NetworkImage(user!.image!)), 19 | title: Text(user!.name!), 20 | onTap: onPressed, 21 | subtitle: Text(user!.company!), 22 | trailing: ElevatedButton( 23 | onPressed: () {}, 24 | style: ElevatedButton.styleFrom( 25 | padding: EdgeInsets.zero, 26 | backgroundColor: context.colorScheme.background, 27 | foregroundColor: context.appTheme.buttonTheme.colorScheme?.onError, 28 | ), 29 | child: const Text(LocaleKeys.home_social_follow).tr(), 30 | ), 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/view/home/build/feed/model/house_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | import 'package:vexana/vexana.dart'; 3 | 4 | part 'house_model.g.dart'; 5 | 6 | @JsonSerializable() 7 | class HouseModel extends INetworkModel { 8 | 9 | HouseModel({this.id, this.title, this.description, this.image, this.user, this.iV}); 10 | @JsonKey(name: '_id') 11 | String? id; 12 | String? title; 13 | String? description; 14 | String? image; 15 | UserHouse? user; 16 | int? iV; 17 | 18 | @override 19 | HouseModel fromJson(Map json) { 20 | return _$HouseModelFromJson(json); 21 | } 22 | 23 | @override 24 | Map toJson() { 25 | return _$HouseModelToJson(this); 26 | } 27 | } 28 | 29 | @JsonSerializable() 30 | class UserHouse extends INetworkModel { 31 | 32 | UserHouse({this.id, this.name, this.image, this.date}); 33 | 34 | factory UserHouse.fromJson(Map json) { 35 | return _$UserHouseFromJson(json); 36 | } 37 | @JsonKey(name: '_id') 38 | String? id; 39 | String? name; 40 | String? image; 41 | String? date; 42 | 43 | @override 44 | UserHouse fromJson(Map json) { 45 | return _$UserHouseFromJson(json); 46 | } 47 | @override 48 | Map toJson() { 49 | return _$UserHouseToJson(this); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /module/all_of_template/lib/features/buy_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_of_template/features/next_page.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:kartal/kartal.dart'; 4 | 5 | class BuyView extends StatefulWidget { 6 | const BuyView({Key? key}) : super(key: key); 7 | 8 | @override 9 | _BuyViewState createState() => _BuyViewState(); 10 | } 11 | 12 | class _BuyViewState extends State { 13 | @override 14 | Widget build(BuildContext context) { 15 | return Scaffold( 16 | floatingActionButton: backHomeModuleButton(), 17 | appBar: AppBar( 18 | title: _titleWidget(context), 19 | ), 20 | body: Center( 21 | child: goNextPage(), 22 | ), 23 | ); 24 | } 25 | 26 | TextButton goNextPage() { 27 | return TextButton( 28 | onPressed: () { 29 | context.navigateToPage(const NextPage()); 30 | }, 31 | child: const Text('Go'), 32 | ); 33 | } 34 | 35 | FloatingActionButton backHomeModuleButton() { 36 | return FloatingActionButton( 37 | onPressed: () { 38 | Navigator.of(context).pop(); 39 | }, 40 | child: const Icon(Icons.arrow_back), 41 | ); 42 | } 43 | 44 | Text _titleWidget(BuildContext context) { 45 | return Text( 46 | 'Buy View', 47 | style: Theme.of(context).textTheme.headline1, 48 | ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /lib/view/home/build/feed/service/build_feed_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:fluttermvvmtemplate/view/_product/_utilty/service_helper.dart'; 3 | import 'package:fluttermvvmtemplate/view/_product/enum/network_route_enum.dart'; 4 | import 'package:fluttermvvmtemplate/view/home/build/feed/model/house_model.dart'; 5 | import 'package:fluttermvvmtemplate/view/home/build/feed/service/IBuildFeedService.dart'; 6 | import 'package:vexana/vexana.dart'; 7 | 8 | class BuildFeedService extends IBuildFeedService with ServiceHelper { 9 | BuildFeedService(INetworkManager manager, GlobalKey key) : super(manager, key); 10 | 11 | @override 12 | Future?> fetchUserHouseList() async { 13 | final response = await manager.send>( 14 | NetworkRoutes.BUILD_HOME.rawValue, 15 | parseModel: HouseModel(), 16 | method: RequestType.GET, 17 | ); 18 | showMessage(scaffoldyKey, response.error); 19 | return response.data; 20 | } 21 | } 22 | 23 | // BEFORE: null safety 24 | // @override 25 | // Future> fetchUserHouseList() async { 26 | // final response = 27 | // await manager.fetch>(NetworkRoutes.BUILD_HOME.rawValue, parseModel: HouseModel(), method: RequestType.GET); 28 | // showMessage(scaffoldyKey, response.error); 29 | // return response.data; 30 | // } 31 | -------------------------------------------------------------------------------- /lib/product/widget/card/burger_card.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_rating_bar/flutter_rating_bar.dart'; 3 | 4 | import 'package:fluttermvvmtemplate/view/home/burger/model/burger_model.dart'; 5 | 6 | class BurgerCard extends StatelessWidget { 7 | const BurgerCard({Key? key, this.model}) : super(key: key); 8 | final BurgerModel? model; 9 | @override 10 | Widget build(BuildContext context) { 11 | return Card( 12 | child: Column( 13 | children: [ 14 | Expanded(child: Image.network(model?.image ?? '')), 15 | Text('${model?.name}'), 16 | buildRatingBar(), 17 | Text('${model?.price} \$'), 18 | ], 19 | ), 20 | ); 21 | } 22 | 23 | RatingBar buildRatingBar() { 24 | return RatingBar.builder( 25 | initialRating: (model?.rates ?? 0).toDouble(), 26 | minRating: 1, 27 | allowHalfRating: true, 28 | ignoreGestures: true, 29 | itemSize: 10, 30 | itemBuilder: (context, _) => const Icon(Icons.star, color: Colors.amber), 31 | onRatingUpdate: print, 32 | ); 33 | } 34 | } 35 | 36 | extension BurgerCardExtension on BurgerCard { 37 | Widget buildList(List items) { 38 | return SingleChildScrollView( 39 | scrollDirection: Axis.horizontal, 40 | child: Row( 41 | children: items.map((e) => BurgerCard(model: e)).toList(), 42 | ), 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/core/init/cache/locale_manager.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluttermvvmtemplate/core/constants/enums/locale_keys_enum.dart'; 2 | import 'package:shared_preferences/shared_preferences.dart'; 3 | 4 | class LocaleManager { 5 | LocaleManager._init() { 6 | SharedPreferences.getInstance().then((value) { 7 | _preferences = value; 8 | }); 9 | } 10 | static final LocaleManager _instance = LocaleManager._init(); 11 | 12 | SharedPreferences? _preferences; 13 | static LocaleManager get instance => _instance; 14 | static Future prefrencesInit() async { 15 | instance._preferences ??= await SharedPreferences.getInstance(); 16 | } 17 | 18 | Future clearAll() async { 19 | await _preferences!.clear(); 20 | } 21 | 22 | Future clearAllSaveFirst() async { 23 | if (_preferences != null) { 24 | await _preferences!.clear(); 25 | await setBoolValue(PreferencesKeys.IS_FIRST_APP, true); 26 | } 27 | } 28 | 29 | Future setStringValue(PreferencesKeys key, String value) async { 30 | await _preferences!.setString(key.toString(), value); 31 | } 32 | 33 | Future setBoolValue(PreferencesKeys key, bool value) async { 34 | await _preferences!.setBool(key.toString(), value); 35 | } 36 | 37 | String getStringValue(PreferencesKeys key) => _preferences?.getString(key.toString()) ?? ''; 38 | 39 | bool getBoolValue(PreferencesKeys key) => _preferences!.getBool(key.toString()) ?? false; 40 | } 41 | -------------------------------------------------------------------------------- /lib/view/home/social/view/social_view_detial.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:fluttermvvmtemplate/core/init/network/vexana_manager.dart'; 3 | import 'package:fluttermvvmtemplate/view/home/social/model/social_user_model.dart'; 4 | import 'package:fluttermvvmtemplate/view/home/social/service/ISocialService.dart'; 5 | import 'package:fluttermvvmtemplate/view/home/social/service/socail_service.dart'; 6 | import 'package:kartal/kartal.dart'; 7 | import 'package:vexana/vexana.dart'; 8 | 9 | class SocialUserViewDetail extends StatelessWidget { 10 | SocialUserViewDetail({ 11 | Key? key, 12 | this.socialUser, 13 | }) : super(key: key); 14 | final SocialUser? socialUser; 15 | 16 | final INetworkManager manager = VexanaManager.instance.networkManager; 17 | 18 | ISocialServiceService get socialServiceService => SocailService(manager, null); 19 | @override 20 | Widget build(BuildContext context) { 21 | return Scaffold( 22 | appBar: AppBar(), 23 | body: socialServiceService.fetchUser(socialUser!.id).toBuild( 24 | onSuccess: (data) { 25 | return Center(child: Image.network(data!.image!)); 26 | }, 27 | loadingWidget: const CircularProgressIndicator(), 28 | notFoundWidget: const Center( 29 | child: Text('Not Found'), 30 | ), 31 | onError: const Text('errro'), 32 | ), 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /test/feature/feed/social_network_mock.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/src/material/scaffold.dart'; 2 | import 'package:flutter/src/widgets/framework.dart'; 3 | import 'package:fluttermvvmtemplate/view/home/social/model/social_user_model.dart'; 4 | import 'package:fluttermvvmtemplate/view/_product/_model/query/friend_query.dart'; 5 | import 'package:fluttermvvmtemplate/view/home/social/service/ISocialService.dart'; 6 | import 'package:fluttermvvmtemplate/view/home/social/service/socail_service.dart'; 7 | import 'package:vexana/src/interface/INetworkService.dart'; 8 | 9 | class SocialNetworkMock extends SocailService { 10 | SocialNetworkMock(INetworkManager manager, GlobalKey? scaffoldyKey) : super(manager, scaffoldyKey); 11 | } 12 | 13 | class SocialNetworkMockAll extends ISocialServiceService { 14 | SocialNetworkMockAll(INetworkManager manager, GlobalKey scaffoldyKey) : super(manager, scaffoldyKey); 15 | 16 | @override 17 | Future fetchUser(id) async { 18 | await Future.delayed(Duration(seconds: 1)); 19 | return SocialUser(name: id); 20 | } 21 | 22 | @override 23 | Future> fetchUserHouseList(FriendQuery query) { 24 | // TODO: implement fetchUserHouseList 25 | throw UnimplementedError(); 26 | } 27 | 28 | @override 29 | Future> fetchUserNameQuery(String text) { 30 | // TODO: implement fetchUserNameQuery 31 | throw UnimplementedError(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '11.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV["COCOAPODS_DISABLE_STATS"] = "true" 6 | 7 | project "Runner", { 8 | "Debug" => :debug, 9 | "Profile" => :release, 10 | "Release" => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join("..", "Flutter", "Generated.xcconfig"), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join("packages", "flutter_tools", "bin", "podhelper"), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target "Runner" do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /lib/view/authenticate/login/service/login_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluttermvvmtemplate/view/_product/enum/network_route_enum.dart'; 2 | import 'package:fluttermvvmtemplate/view/authenticate/login/model/login_model.dart'; 3 | import 'package:fluttermvvmtemplate/view/authenticate/login/model/login_response_model.dart'; 4 | import 'package:fluttermvvmtemplate/view/authenticate/login/service/ILoginService.dart'; 5 | import 'package:vexana/vexana.dart'; 6 | 7 | class LoginService extends ILoginService { 8 | LoginService(INetworkManager manager) : super(manager); 9 | 10 | @override 11 | Future fetchUserControl(LoginModel model) async { 12 | final response = await manager.send( 13 | NetworkRoutes.LOGIN.rawValue, 14 | parseModel: LoginResponseModel(), 15 | method: RequestType.POST, 16 | data: model, 17 | ); 18 | 19 | if (response.data is LoginResponseModel) { 20 | return response.data; 21 | } else { 22 | return null; 23 | } 24 | } 25 | } 26 | 27 | // BEFORE: null safety before 28 | // @override 29 | // Future fetchUserControl(LoginModel model) async { 30 | // final response = await manager.fetch(NetworkRoutes.LOGIN.rawValue, 31 | // parseModel: LoginResponseModel(), method: RequestType.POST, data: model); 32 | 33 | // if (response.data is LoginResponseModel) { 34 | // return response.data; 35 | // } else { 36 | // return null; 37 | // } 38 | // } 39 | -------------------------------------------------------------------------------- /module/architecture_widgets/lib/src/list-view/indicator_list_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class IndactorListView extends StatelessWidget { 4 | const IndactorListView({ 5 | Key? key, 6 | this.itemCount, 7 | this.onListItem, 8 | this.currentIndex, 9 | }) : super(key: key); 10 | final int? itemCount; 11 | 12 | final int? currentIndex; 13 | 14 | final Widget Function(int index)? onListItem; 15 | @override 16 | Widget build(BuildContext context) { 17 | return ListView.builder( 18 | scrollDirection: Axis.horizontal, 19 | itemCount: itemCount, 20 | shrinkWrap: true, 21 | itemBuilder: buildPadding, 22 | ); 23 | } 24 | 25 | Padding buildPadding(BuildContext context, int index) { 26 | return Padding( 27 | padding: const EdgeInsets.all(5), 28 | child: buildCircleAvatar(index, context), 29 | ); 30 | } 31 | 32 | CircleAvatar buildCircleAvatar(int index, BuildContext context) { 33 | return CircleAvatar( 34 | backgroundColor: isCurrentIndex(index) ? Colors.black12 : Colors.blue, 35 | radius: isCurrentIndex(index) ? _pageWidth(context) * 0.03 : _pageWidth(context) * 0.015, 36 | child: AnimatedOpacity( 37 | opacity: opacityValue(index), 38 | duration: const Duration(seconds: 1), 39 | child: onListItem!(index), 40 | ), 41 | ); 42 | } 43 | 44 | double _pageWidth(BuildContext context) => MediaQuery.of(context).size.width; 45 | 46 | double opacityValue(int index) => isCurrentIndex(index) ? 1 : 0; 47 | 48 | bool isCurrentIndex(int index) => currentIndex == index; 49 | } 50 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app_icon_16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app_icon_32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app_icon_32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app_icon_64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app_icon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app_icon_256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app_icon_256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app_icon_512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app_icon_512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app_icon_1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /lib/view/authenticate/splash/service/splash_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluttermvvmtemplate/view/authenticate/splash/model/force_update_model.dart'; 2 | import 'package:vexana/vexana.dart'; 3 | 4 | abstract class ISplashService { 5 | ISplashService(this.networkManager); 6 | final INetworkManager networkManager; 7 | 8 | Future checkDeviceVersion({ 9 | required String version, 10 | required String platform, 11 | }); 12 | } 13 | 14 | enum SplashServiceQuery { VERSION, PLATFORM } 15 | 16 | extension SplashServiceQueryExtension on SplashServiceQuery { 17 | MapEntry toMapValue(String value) { 18 | switch (this) { 19 | case SplashServiceQuery.PLATFORM: 20 | return MapEntry('platform', value); 21 | case SplashServiceQuery.VERSION: 22 | return MapEntry('version', value); 23 | } 24 | } 25 | } 26 | 27 | class SplashService extends ISplashService { 28 | SplashService(INetworkManager networkManager) : super(networkManager); 29 | final String _path = 'version'; 30 | 31 | @override 32 | Future checkDeviceVersion({ 33 | required String version, 34 | required String platform, 35 | }) async { 36 | final response = await networkManager.send( 37 | _path, 38 | parseModel: ForceUpdateModel(), 39 | method: RequestType.GET, 40 | queryParameters: Map.fromEntries( 41 | [ 42 | SplashServiceQuery.VERSION.toMapValue(version), 43 | SplashServiceQuery.PLATFORM.toMapValue(platform), 44 | ], 45 | ), 46 | ); 47 | return response.data; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lib/view/home/build/feed/model/house_model.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'house_model.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | HouseModel _$HouseModelFromJson(Map json) => HouseModel( 10 | id: json['_id'] as String?, 11 | title: json['title'] as String?, 12 | description: json['description'] as String?, 13 | image: json['image'] as String?, 14 | user: json['user'] == null 15 | ? null 16 | : UserHouse.fromJson((json['user'] as Map).map( 17 | (k, e) => MapEntry(k, e as Object), 18 | )), 19 | iV: json['iV'] as int?, 20 | ); 21 | 22 | Map _$HouseModelToJson(HouseModel instance) => 23 | { 24 | '_id': instance.id, 25 | 'title': instance.title, 26 | 'description': instance.description, 27 | 'image': instance.image, 28 | 'user': instance.user, 29 | 'iV': instance.iV, 30 | }; 31 | 32 | UserHouse _$UserHouseFromJson(Map json) => UserHouse( 33 | id: json['_id'] as String?, 34 | name: json['name'] as String?, 35 | image: json['image'] as String?, 36 | date: json['date'] as String?, 37 | ); 38 | 39 | Map _$UserHouseToJson(UserHouse instance) => { 40 | '_id': instance.id, 41 | 'name': instance.name, 42 | 'image': instance.image, 43 | 'date': instance.date, 44 | }; 45 | -------------------------------------------------------------------------------- /test/core/network/core_dio_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:dio/dio.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import 'package:fluttermvvmtemplate/core/constants/enums/http_request_enum.dart'; 4 | import 'package:fluttermvvmtemplate/core/init/network/ICoreDio.dart'; 5 | import 'core_dio_mock.dart'; 6 | import 'dio_mock_model.dart'; 7 | 8 | main() { 9 | late ICoreDioFullNulSafetyFull service; 10 | setUp(() { 11 | service = CoreDioMock(BaseOptions(baseUrl: 'https://jsonplaceholder.typicode.com')); 12 | }); 13 | test('CoreDio List', () async { 14 | final data = await service.send, PostModel>('/posts', type: HttpTypes.GET, parseModel: PostModel()); 15 | 16 | expect(data.data, isList); 17 | }); 18 | 19 | test('CoreDio List No Network', () async { 20 | final data = await service.fetchNoNetwork, PostModel>('/posts', type: HttpTypes.GET, parseModel: PostModel()); 21 | 22 | expect(data.data, isList); 23 | }); 24 | 25 | test('CoreDio Object', () async { 26 | final data = await service.send, PostModel>('/posts', type: HttpTypes.GET, parseModel: PostModel()); 27 | 28 | expect(data.data, isList); 29 | }); 30 | 31 | test('CoreDio Primitive', () async { 32 | final data = await service.send, PostModel>('/posts', type: HttpTypes.GET, parseModel: PostModel()); 33 | 34 | expect(data.data, isList); 35 | }); 36 | 37 | test('CoreDio Error', () async { 38 | final data = await service.fetchNoNetwork, PostModel>('/posts', type: HttpTypes.GET, parseModel: PostModel()); 39 | 40 | expect(data.data, isList); 41 | }); 42 | } 43 | -------------------------------------------------------------------------------- /test/feature/onboard/onboard_mock_view_model.dart: -------------------------------------------------------------------------------- 1 | //TODO: Test 2 | // class OnBoardMockViewModel implements OnBoardViewModel { 3 | // @override 4 | // BuildContext context; 5 | 6 | // @override 7 | // ICoreDio coreDio; 8 | 9 | // IStringHelper stringHelper; 10 | 11 | // @override 12 | // int currentPageIndex; 13 | 14 | // bool isLoading = false; 15 | 16 | // @override 17 | // List onBoarModel; 18 | 19 | // @override 20 | // void init() { 21 | // coreDio = CoreDio(BaseOptions(baseUrl: "https://jsonplaceholder.typicode.com")); 22 | // stringHelper = MockStringHelper(); 23 | // } 24 | 25 | // @override 26 | // void onPageChanged(int value) { 27 | // currentPageIndex = value; 28 | // } 29 | 30 | // Future onBoardGetModels() async { 31 | // final response = 32 | // await coreDio.fetch, PostModel>("/posts", type: HttpTypes.GET, parseModel: PostModel()); 33 | 34 | // if (response.data is List) { 35 | // onBoarModel = response.data.map((e) => OnBoardModel(stringHelper.toUpper(e.title))).toList().cast(); 36 | // } 37 | // } 38 | 39 | // Future getServiceRequest() async { 40 | // isLoading = true; 41 | // await onBoardGetModels(); 42 | // isLoading = false; 43 | // } 44 | 45 | // @override 46 | // void setContext(BuildContext context) {} 47 | // } 48 | 49 | // abstract class IStringHelper { 50 | // String toUpper(String data); 51 | // } 52 | 53 | // class MockStringHelper extends IStringHelper { 54 | // @override 55 | // String toUpper(String data) { 56 | // return data.toUpperCase(); 57 | // } 58 | // } 59 | -------------------------------------------------------------------------------- /test/feature/onboard/onboard_test.dart: -------------------------------------------------------------------------------- 1 | //TODO:TEST 2 | // main() { 3 | // OnBoardMockViewModel mockViewModel; 4 | // IStringHelper stringHelper; 5 | // setUp(() { 6 | // SharedPreferences.setMockInitialValues({"token": "asdasd"}); //set values here 7 | // mockViewModel = OnBoardMockViewModel(); 8 | // stringHelper = MockStringHelper(); 9 | // mockViewModel.init(); 10 | // }); 11 | // test("String Helper Upper Case", () { 12 | // String text = " Helelo"; 13 | // text = stringHelper.toUpper(text); 14 | // expect(text.contains(RegExp("[A-Z\s]+")), true); 15 | // }); 16 | 17 | // test("OnBoard Get Models", () async { 18 | // await mockViewModel.onBoardGetModels(); 19 | // expect(mockViewModel.onBoarModel, isNotEmpty); 20 | // }); 21 | 22 | // test("OnBoard Get Service Request", () async { 23 | // expect(mockViewModel.isLoading, false); 24 | // mockViewModel.getServiceRequest(); 25 | // expect(mockViewModel.isLoading, true); 26 | // }); 27 | 28 | // test("OnBoard On Page Changed", () { 29 | // mockViewModel.onPageChanged(5); 30 | // expect(5, mockViewModel.currentPageIndex); 31 | // }); 32 | 33 | // group("Test All", () { 34 | // int index = 0; 35 | // test("OnBoard Get Models", () async { 36 | // await mockViewModel.onBoardGetModels(); 37 | // index = mockViewModel.onBoarModel.length; 38 | // expect(mockViewModel.onBoarModel, isNotEmpty); 39 | // }); 40 | 41 | // test("OnBoard On Page Changed", () { 42 | // mockViewModel.onPageChanged(index); 43 | // expect(index, mockViewModel.currentPageIndex); 44 | // }); 45 | // }); 46 | // } 47 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: fluttermvvmtemplate 2 | description: A Flutter template project for everyone. 3 | 4 | publish_to: none 5 | 6 | version: 0.0.9 7 | 8 | environment: 9 | sdk: '>=2.12.0 <3.0.0' 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | 15 | # state management 16 | flutter_mobx: ^2.0.0 17 | mobx: ^2.0.1 18 | provider: ^6.0.4 19 | 20 | 21 | # network 22 | # dio: ^4.0.0-prev3 23 | vexana: ^3.0.1 24 | 25 | # database 26 | shared_preferences: ^2.0.5 27 | 28 | # language 29 | easy_localization: ^3.0.0 30 | 31 | # firebase 32 | firebase_core: ^2.1.1 33 | firebase_analytics: any 34 | 35 | # core utilities 36 | kartal: ^2.1.0 37 | logger: ^1.0.0 38 | webview_flutter: ^3.0.4 39 | equatable: ^2.0.5 40 | 41 | # ui utilities 42 | animations: ^2.0.0 43 | auto_size_text: ^3.0.0 44 | cached_network_image: ^3.0.0-nullsafety 45 | cupertino_icons: ^1.0.2 46 | flutter_rating_bar: ^4.0.0 47 | flutter_svg: ^1.1.6 48 | lottie: ^1.0.1 49 | shimmer: ^2.0.0-nullsafety.0 50 | 51 | architecture_theme: 52 | git: https://github.com/VB10/architecture_theme.git 53 | architecture_widgets: 54 | path: module/architecture_widgets 55 | all_of_template: 56 | path: module/all_of_template 57 | 58 | dev_dependencies: 59 | flutter_test: 60 | sdk: flutter 61 | 62 | build_runner: ^2.3.2 63 | json_annotation: ^4.0.1 64 | json_serializable: ^6.5.4 65 | mobx_codegen: ^2.0.1+3 66 | mockito: any 67 | very_good_analysis: ^3.1.0 68 | 69 | flutter: 70 | uses-material-design: true 71 | 72 | assets: 73 | - asset/lang/ 74 | - asset/svg/ 75 | - asset/image/ 76 | - asset/lottie/ -------------------------------------------------------------------------------- /lib/core/init/network/ICoreDio.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluttermvvmtemplate/core/base/model/base_model.dart'; 2 | import 'package:fluttermvvmtemplate/core/constants/enums/http_request_enum.dart'; 3 | import 'package:fluttermvvmtemplate/core/init/network/IResponseModel.dart'; 4 | 5 | abstract class ICoreDio { 6 | Future> fetch( 7 | String path, { 8 | required HttpTypes type, 9 | required T parseModel, 10 | dynamic data, 11 | Map? queryParameters, 12 | void Function(int, int)? onReceiveProgress, 13 | }); 14 | } 15 | // MARK: Null SAfety 16 | 17 | abstract class ICoreDioNullSafety { 18 | Future> send( 19 | String path, { 20 | required HttpTypes type, 21 | required BaseModel parseModel, 22 | dynamic data, 23 | Map? queryParameters, 24 | void Function(int, int)? onReceiveProgress, 25 | }); 26 | } 27 | 28 | abstract class ICoreDioFull extends ICoreDio { 29 | Future> fetchNoNetwork( 30 | String path, { 31 | required HttpTypes type, 32 | required T parseModel, 33 | dynamic data, 34 | Map? queryParameters, 35 | void Function(int, int)? onReceiveProgress, 36 | }); 37 | } 38 | 39 | // MARK: Nul SAfety 40 | abstract class ICoreDioFullNulSafetyFull extends ICoreDioNullSafety { 41 | Future> fetchNoNetwork( 42 | String path, { 43 | required HttpTypes type, 44 | required T parseModel, 45 | dynamic data, 46 | Map? queryParameters, 47 | void Function(int, int)? onReceiveProgress, 48 | }); 49 | } 50 | -------------------------------------------------------------------------------- /lib/view/home/game/view/subview/game_view_cards.dart: -------------------------------------------------------------------------------- 1 | part of '../game_view.dart'; 2 | 3 | extension _GameViewGamesCard on GameView { 4 | Widget buildColumnNewCard(GameViewModel viewModel) { 5 | return viewModel.onNewsGameItems().toBuild( 6 | onSuccess: (data) { 7 | return Column( 8 | children: [const HeaderButton(titleText: LocaleKeys.home_game_newUpdate), GameGrid(models: data)], 9 | ); 10 | }, 11 | loadingWidget: SizedBox( 12 | height: 200, 13 | width: 100, 14 | child: Shimmer.fromColors( 15 | baseColor: Colors.grey, 16 | highlightColor: Colors.grey[200]!, 17 | child: const ListTile( 18 | leading: CircleAvatar(), 19 | title: Text('data'), 20 | subtitle: Text('data'), 21 | ), 22 | ), 23 | ), 24 | data: [], 25 | notFoundWidget: const Text('data'), 26 | onError: const Text('data'), 27 | ); 28 | } 29 | 30 | Widget buildColumnUpdate(GameViewModel viewModel) { 31 | return viewModel.onNewsGameItems().toBuild( 32 | onSuccess: (data) { 33 | return Column( 34 | children: [ 35 | const HeaderButton(titleText: LocaleKeys.home_game_topDownload), 36 | GameGrid( 37 | models: data, 38 | ) 39 | ], 40 | ); 41 | }, 42 | loadingWidget: const CircularProgressIndicator(), 43 | notFoundWidget: const Text('data'), 44 | onError: const Text('data'), 45 | ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/product/widget/button/header_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:easy_localization/easy_localization.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:fluttermvvmtemplate/core/init/lang/locale_keys.g.dart'; 4 | import 'package:kartal/kartal.dart'; 5 | 6 | class HeaderButton extends StatelessWidget { 7 | const HeaderButton({Key? key, this.titleText, this.onPressed}) : super(key: key); 8 | final String? titleText; 9 | final VoidCallback? onPressed; 10 | @override 11 | Widget build(BuildContext context) { 12 | return Padding( 13 | padding: context.horizontalPaddingLow, 14 | child: Row( 15 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 16 | children: [buildTextTitle(context), buildFlatButtonRight(context)], 17 | ), 18 | ); 19 | } 20 | 21 | Text buildTextTitle(BuildContext context) { 22 | return Text( 23 | titleText!.tr(), 24 | style: context.textTheme.headline6!.copyWith(color: context.colorScheme.onError), 25 | ); 26 | } 27 | 28 | Widget buildFlatButtonRight(BuildContext context) { 29 | return TextButton( 30 | style: TextButton.styleFrom(padding: EdgeInsets.zero), 31 | onPressed: () { 32 | if (onPressed != null) { 33 | onPressed!(); 34 | } 35 | }, 36 | child: Wrap( 37 | crossAxisAlignment: WrapCrossAlignment.center, 38 | children: [ 39 | Text( 40 | LocaleKeys.home_game_viewAll.tr(), 41 | style: context.textTheme.subtitle2!.copyWith(color: context.colorScheme.onError), 42 | ), 43 | Icon(Icons.arrow_right, color: context.colorScheme.onError) 44 | ], 45 | ), 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /lib/view/authenticate/splash/viewmodel/splash_view_model.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'splash_view_model.dart'; 4 | 5 | // ************************************************************************** 6 | // StoreGenerator 7 | // ************************************************************************** 8 | 9 | // 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, no_leading_underscores_for_local_identifiers 10 | 11 | mixin _$SplashViewModel on _SplashViewModelBase, Store { 12 | late final _$isFirstInitAtom = 13 | Atom(name: '_SplashViewModelBase.isFirstInit', context: context); 14 | 15 | @override 16 | bool get isFirstInit { 17 | _$isFirstInitAtom.reportRead(); 18 | return super.isFirstInit; 19 | } 20 | 21 | @override 22 | set isFirstInit(bool value) { 23 | _$isFirstInitAtom.reportWrite(value, super.isFirstInit, () { 24 | super.isFirstInit = value; 25 | }); 26 | } 27 | 28 | late final _$_SplashViewModelBaseActionController = 29 | ActionController(name: '_SplashViewModelBase', context: context); 30 | 31 | @override 32 | void _changeFirstInit() { 33 | final _$actionInfo = _$_SplashViewModelBaseActionController.startAction( 34 | name: '_SplashViewModelBase._changeFirstInit'); 35 | try { 36 | return super._changeFirstInit(); 37 | } finally { 38 | _$_SplashViewModelBaseActionController.endAction(_$actionInfo); 39 | } 40 | } 41 | 42 | @override 43 | String toString() { 44 | return ''' 45 | isFirstInit: ${isFirstInit} 46 | '''; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/view/settings/viewmodel/settings_view_model.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'settings_view_model.dart'; 4 | 5 | // ************************************************************************** 6 | // StoreGenerator 7 | // ************************************************************************** 8 | 9 | // 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, no_leading_underscores_for_local_identifiers 10 | 11 | mixin _$SettingsViewModel on _SettingsViewModelBase, Store { 12 | late final _$appLocaleAtom = 13 | Atom(name: '_SettingsViewModelBase.appLocale', context: context); 14 | 15 | @override 16 | Locale? get appLocale { 17 | _$appLocaleAtom.reportRead(); 18 | return super.appLocale; 19 | } 20 | 21 | @override 22 | set appLocale(Locale? value) { 23 | _$appLocaleAtom.reportWrite(value, super.appLocale, () { 24 | super.appLocale = value; 25 | }); 26 | } 27 | 28 | late final _$_SettingsViewModelBaseActionController = 29 | ActionController(name: '_SettingsViewModelBase', context: context); 30 | 31 | @override 32 | void changeAppLocalization(Locale? locale) { 33 | final _$actionInfo = _$_SettingsViewModelBaseActionController.startAction( 34 | name: '_SettingsViewModelBase.changeAppLocalization'); 35 | try { 36 | return super.changeAppLocalization(locale); 37 | } finally { 38 | _$_SettingsViewModelBaseActionController.endAction(_$actionInfo); 39 | } 40 | } 41 | 42 | @override 43 | String toString() { 44 | return ''' 45 | appLocale: ${appLocale} 46 | '''; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | fluttermvvmtemplate 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0.3 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 2 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | 33 | UISupportedInterfaceOrientations~ipad 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationPortraitUpsideDown 37 | UIInterfaceOrientationLandscapeLeft 38 | UIInterfaceOrientationLandscapeRight 39 | 40 | UIViewControllerBasedStatusBarAppearance 41 | 42 | CFBundleLocalizations 43 | 44 | en 45 | tr 46 | 47 | CADisableMinimumFrameDurationOnPhone 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /lib/core/init/network/core_dio.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:dio/adapter.dart'; 4 | import 'package:dio/dio.dart'; 5 | 6 | import 'package:fluttermvvmtemplate/core/base/model/base_error.dart'; 7 | import 'package:fluttermvvmtemplate/core/base/model/base_model.dart'; 8 | import 'package:fluttermvvmtemplate/core/constants/enums/http_request_enum.dart'; 9 | import 'package:fluttermvvmtemplate/core/extension/network_exntension.dart'; 10 | import 'package:fluttermvvmtemplate/core/init/network/ICoreDio.dart'; 11 | import 'package:fluttermvvmtemplate/core/init/network/IResponseModel.dart'; 12 | 13 | part './network_core/core_operations.dart'; 14 | 15 | class CoreDio with DioMixin implements Dio, ICoreDioNullSafety { 16 | CoreDio(this.options) { 17 | options = options; 18 | interceptors.add(InterceptorsWrapper()); 19 | httpClientAdapter = DefaultHttpClientAdapter(); 20 | } 21 | @override 22 | final BaseOptions options; 23 | 24 | @override 25 | Future> send( 26 | String path, { 27 | required HttpTypes type, 28 | required BaseModel parseModel, 29 | dynamic data, 30 | Map? queryParameters, 31 | void Function(int, int)? onReceiveProgress, 32 | }) async { 33 | final response = await request( 34 | path, 35 | data: data, 36 | options: Options( 37 | method: type.rawValue, 38 | ), 39 | ); 40 | switch (response.statusCode) { 41 | case HttpStatus.ok: 42 | case HttpStatus.accepted: 43 | final model = _responseParser(parseModel, response.data); 44 | return ResponseModel(data: model); 45 | default: 46 | return ResponseModel(error: BaseError('message')); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lib/view/_product/_widgets/card/build_user_card.dart: -------------------------------------------------------------------------------- 1 | import 'package:auto_size_text/auto_size_text.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:fluttermvvmtemplate/view/home/build/feed/model/house_model.dart'; 4 | import 'package:kartal/kartal.dart'; 5 | 6 | class BuildUserCard extends StatelessWidget { 7 | const BuildUserCard({Key? key, required this.model, this.onPressedLikeId, this.isLiked = false}) : super(key: key); 8 | final HouseModel model; 9 | final bool isLiked; 10 | final Function(String? id)? onPressedLikeId; 11 | @override 12 | Widget build(BuildContext context) { 13 | return Column( 14 | crossAxisAlignment: CrossAxisAlignment.start, 15 | children: [ 16 | ListTile( 17 | contentPadding: EdgeInsets.zero, 18 | leading: CircleAvatar(backgroundImage: NetworkImage(model.user!.image!)), 19 | title: Text(model.user!.name!), 20 | subtitle: Text(model.user!.date!), 21 | trailing: buildIconButton(), 22 | ), 23 | context.emptySizedHeightBoxLow, 24 | buildWrap(context) 25 | ], 26 | ); 27 | } 28 | 29 | Widget buildWrap(BuildContext context) { 30 | return Column( 31 | children: [ 32 | AutoSizeText( 33 | model.title!, 34 | style: context.textTheme.headline6!.copyWith(fontWeight: FontWeight.w600), 35 | maxLines: 1, 36 | ), 37 | Text(model.description!), 38 | ], 39 | ); 40 | } 41 | 42 | IconButton buildIconButton() { 43 | return IconButton( 44 | icon: Icon( 45 | Icons.favorite, 46 | color: isLiked ? Colors.pink : Colors.black12, 47 | ), 48 | onPressed: () { 49 | onPressedLikeId!(model.id); 50 | }, 51 | ); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /lib/view/authenticate/test/viewmodel/test_view_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:fluttermvvmtemplate/core/base/model/base_view_model.dart'; 3 | import 'package:fluttermvvmtemplate/core/constants/enums/app_theme_enum.dart'; 4 | import 'package:fluttermvvmtemplate/core/constants/enums/http_request_enum.dart'; 5 | import 'package:fluttermvvmtemplate/core/init/notifier/theme_notifer.dart'; 6 | import 'package:fluttermvvmtemplate/view/authenticate/test/model/test_model.dart'; 7 | import 'package:mobx/mobx.dart'; 8 | import 'package:provider/provider.dart'; 9 | 10 | part 'test_view_model.g.dart'; 11 | 12 | class TestViewModel = _TestViewModelBase with _$TestViewModel; 13 | 14 | abstract class _TestViewModelBase with Store, BaseViewModel { 15 | @override 16 | void setContext(BuildContext context) { 17 | viewModelContext = context; 18 | } 19 | 20 | @override 21 | void init() {} 22 | 23 | @observable 24 | bool isLoading = false; 25 | 26 | @observable 27 | int number = 0; 28 | 29 | @computed 30 | bool get isEven => number % 2 == 0; 31 | 32 | @action 33 | void incrementNumber() { 34 | number++; 35 | } 36 | 37 | void changeTheme() { 38 | Provider.of(viewModelContext, listen: false).changeValue(AppThemes.DARK); 39 | } 40 | 41 | @action 42 | Future getSampleRequest() async { 43 | isLoading = true; 44 | 45 | final response = await coreDio!.send, TestModel>('x', type: HttpTypes.GET, parseModel: TestModel()); 46 | if (response.data is List) { 47 | } else {} 48 | isLoading = false; 49 | } 50 | } 51 | 52 | // BEFORE: null safety 53 | // final response = await coreDio.fetch, TestModel>("x", type: HttpTypes.GET, parseModel: TestModel()); 54 | -------------------------------------------------------------------------------- /module/all_of_template/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: all_of_template 2 | description: A new Flutter package project. 3 | version: 0.0.1 4 | homepage: home 5 | 6 | environment: 7 | sdk: ">=2.12.0 <3.0.0" 8 | flutter: ">=1.17.0" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | 14 | kartal: ^2.1.0 15 | 16 | dev_dependencies: 17 | flutter_test: 18 | sdk: flutter 19 | 20 | very_good_analysis: ^3.1.0 21 | 22 | # For information on the generic Dart part of this file, see the 23 | # following page: https://dart.dev/tools/pub/pubspec 24 | 25 | # The following section is specific to Flutter. 26 | flutter: 27 | 28 | # To add assets to your package, add an assets section, like this: 29 | # assets: 30 | # - images/a_dot_burr.jpeg 31 | # - images/a_dot_ham.jpeg 32 | # 33 | # For details regarding assets in packages, see 34 | # https://flutter.dev/assets-and-images/#from-packages 35 | # 36 | # An image asset can refer to one or more resolution-specific "variants", see 37 | # https://flutter.dev/assets-and-images/#resolution-aware. 38 | 39 | # To add custom fonts to your package, add a fonts section here, 40 | # in this "flutter" section. Each entry in this list should have a 41 | # "family" key with the font family name, and a "fonts" key with a 42 | # list giving the asset and other descriptors for the font. For 43 | # example: 44 | # fonts: 45 | # - family: Schyler 46 | # fonts: 47 | # - asset: fonts/Schyler-Regular.ttf 48 | # - asset: fonts/Schyler-Italic.ttf 49 | # style: italic 50 | # - family: Trajan Pro 51 | # fonts: 52 | # - asset: fonts/TrajanPro.ttf 53 | # - asset: fonts/TrajanPro_Bold.ttf 54 | # weight: 700 55 | # 56 | # For details regarding fonts in packages, see 57 | # https://flutter.dev/custom-fonts/#from-packages 58 | -------------------------------------------------------------------------------- /lib/view/settings/viewmodel/settings_view_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:easy_localization/easy_localization.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:fluttermvvmtemplate/core/base/model/base_view_model.dart'; 4 | import 'package:fluttermvvmtemplate/core/constants/navigation/navigation_constants.dart'; 5 | import 'package:fluttermvvmtemplate/core/init/lang/language_manager.dart'; 6 | import 'package:fluttermvvmtemplate/core/init/notifier/theme_notifer.dart'; 7 | import 'package:fluttermvvmtemplate/product/model/user.dart'; 8 | import 'package:fluttermvvmtemplate/view/settings/model/settings_dynamic.dart'; 9 | import 'package:mobx/mobx.dart'; 10 | import 'package:provider/provider.dart'; 11 | 12 | part 'settings_view_model.g.dart'; 13 | part 'subviewmodel/about_view_model.dart'; 14 | 15 | class SettingsViewModel = _SettingsViewModelBase with _$SettingsViewModel; 16 | 17 | abstract class _SettingsViewModelBase with Store, BaseViewModel { 18 | final userModel = UserModel.fake(); 19 | @override 20 | void setContext(BuildContext context) => viewModelContext = context; 21 | 22 | @observable 23 | Locale? appLocale = LanguageManager.instance.enLocale; 24 | 25 | @override 26 | void init() {} 27 | 28 | void changeAppTheme() { 29 | viewModelContext.read().changeTheme(); 30 | } 31 | 32 | @action 33 | void changeAppLocalization(Locale? locale) { 34 | if (locale != null) { 35 | appLocale = locale; 36 | viewModelContext.setLocale(locale); 37 | } 38 | } 39 | 40 | Future logutApp() async { 41 | await localeManager.clearAllSaveFirst(); 42 | await navigation.navigateToPageClear(path: NavigationConstants.TEST_VIEW); 43 | } 44 | 45 | Future navigateToOnBoard() async { 46 | await navigation.navigateToPage(path: NavigationConstants.ON_BOARD); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /module/all_of_template/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | build/ 32 | 33 | # Android related 34 | **/android/**/gradle-wrapper.jar 35 | **/android/.gradle 36 | **/android/captures/ 37 | **/android/gradlew 38 | **/android/gradlew.bat 39 | **/android/local.properties 40 | **/android/**/GeneratedPluginRegistrant.java 41 | 42 | # iOS/XCode related 43 | **/ios/**/*.mode1v3 44 | **/ios/**/*.mode2v3 45 | **/ios/**/*.moved-aside 46 | **/ios/**/*.pbxuser 47 | **/ios/**/*.perspectivev3 48 | **/ios/**/*sync/ 49 | **/ios/**/.sconsign.dblite 50 | **/ios/**/.tags* 51 | **/ios/**/.vagrant/ 52 | **/ios/**/DerivedData/ 53 | **/ios/**/Icon? 54 | **/ios/**/Pods/ 55 | **/ios/**/.symlinks/ 56 | **/ios/**/profile 57 | **/ios/**/xcuserdata 58 | **/ios/.generated/ 59 | **/ios/Flutter/App.framework 60 | **/ios/Flutter/Flutter.framework 61 | **/ios/Flutter/Flutter.podspec 62 | **/ios/Flutter/Generated.xcconfig 63 | **/ios/Flutter/ephemeral 64 | **/ios/Flutter/app.flx 65 | **/ios/Flutter/app.zip 66 | **/ios/Flutter/flutter_assets/ 67 | **/ios/Flutter/flutter_export_environment.sh 68 | **/ios/ServiceDefinitions.json 69 | **/ios/Runner/GeneratedPluginRegistrant.* 70 | 71 | # Exceptions to above rules. 72 | !**/ios/**/default.mode1v3 73 | !**/ios/**/default.mode2v3 74 | !**/ios/**/default.pbxuser 75 | !**/ios/**/default.perspectivev3 76 | -------------------------------------------------------------------------------- /module/architecture_widgets/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | build/ 32 | 33 | # Android related 34 | **/android/**/gradle-wrapper.jar 35 | **/android/.gradle 36 | **/android/captures/ 37 | **/android/gradlew 38 | **/android/gradlew.bat 39 | **/android/local.properties 40 | **/android/**/GeneratedPluginRegistrant.java 41 | 42 | # iOS/XCode related 43 | **/ios/**/*.mode1v3 44 | **/ios/**/*.mode2v3 45 | **/ios/**/*.moved-aside 46 | **/ios/**/*.pbxuser 47 | **/ios/**/*.perspectivev3 48 | **/ios/**/*sync/ 49 | **/ios/**/.sconsign.dblite 50 | **/ios/**/.tags* 51 | **/ios/**/.vagrant/ 52 | **/ios/**/DerivedData/ 53 | **/ios/**/Icon? 54 | **/ios/**/Pods/ 55 | **/ios/**/.symlinks/ 56 | **/ios/**/profile 57 | **/ios/**/xcuserdata 58 | **/ios/.generated/ 59 | **/ios/Flutter/App.framework 60 | **/ios/Flutter/Flutter.framework 61 | **/ios/Flutter/Flutter.podspec 62 | **/ios/Flutter/Generated.xcconfig 63 | **/ios/Flutter/ephemeral 64 | **/ios/Flutter/app.flx 65 | **/ios/Flutter/app.zip 66 | **/ios/Flutter/flutter_assets/ 67 | **/ios/Flutter/flutter_export_environment.sh 68 | **/ios/ServiceDefinitions.json 69 | **/ios/Runner/GeneratedPluginRegistrant.* 70 | 71 | # Exceptions to above rules. 72 | !**/ios/**/default.mode1v3 73 | !**/ios/**/default.mode2v3 74 | !**/ios/**/default.pbxuser 75 | !**/ios/**/default.perspectivev3 76 | -------------------------------------------------------------------------------- /lib/view/_product/_utilty/burger_network_enum.dart: -------------------------------------------------------------------------------- 1 | enum BurgerSortValues { NAME, PRICE, RATES, UPDATED } 2 | enum BurgerSortValuesType { ASC, DSC } 3 | 4 | enum BurgerNetworkPath { MAIN, PRICE } 5 | enum BurgerQueryParamaters { FAVORITE, SORT, SORT_TYPE, MIN, MAX } 6 | 7 | extension BurgerSortValuesExtension on BurgerSortValues { 8 | String get rawValue { 9 | switch (this) { 10 | case BurgerSortValues.NAME: 11 | return 'name'; 12 | case BurgerSortValues.PRICE: 13 | return 'price'; 14 | case BurgerSortValues.RATES: 15 | return 'rates'; 16 | case BurgerSortValues.UPDATED: 17 | return 'updated'; 18 | } 19 | } 20 | } 21 | 22 | extension BurgerSortValuesTypeExtension on BurgerSortValuesType { 23 | int get rawValue { 24 | switch (this) { 25 | case BurgerSortValuesType.ASC: 26 | return -1; 27 | case BurgerSortValuesType.DSC: 28 | return 1; 29 | } 30 | } 31 | } 32 | 33 | extension BurgerNetworkPathExtension on BurgerNetworkPath { 34 | String get rawValue { 35 | switch (this) { 36 | case BurgerNetworkPath.MAIN: 37 | return 'burgers'; 38 | case BurgerNetworkPath.PRICE: 39 | return 'burgers/price'; 40 | } 41 | } 42 | } 43 | 44 | extension BurgerQueryParamatersExtension on BurgerQueryParamaters { 45 | MapEntry rawValue(dynamic value) { 46 | switch (this) { 47 | case BurgerQueryParamaters.FAVORITE: 48 | return MapEntry('isFavorite', value); 49 | case BurgerQueryParamaters.SORT: 50 | return MapEntry('sort', value); 51 | case BurgerQueryParamaters.SORT_TYPE: 52 | return MapEntry('sortType', value); 53 | case BurgerQueryParamaters.MIN: 54 | return MapEntry('min', value); 55 | case BurgerQueryParamaters.MAX: 56 | return MapEntry('max', value); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /lib/view/home/game/viewmodel/game_view_model.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'game_view_model.dart'; 4 | 5 | // ************************************************************************** 6 | // StoreGenerator 7 | // ************************************************************************** 8 | 9 | // 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, no_leading_underscores_for_local_identifiers 10 | 11 | mixin _$GameViewModel on _GameViewModelBase, Store { 12 | late final _$isLoadingAtom = 13 | Atom(name: '_GameViewModelBase.isLoading', context: context); 14 | 15 | @override 16 | bool get isLoading { 17 | _$isLoadingAtom.reportRead(); 18 | return super.isLoading; 19 | } 20 | 21 | @override 22 | set isLoading(bool value) { 23 | _$isLoadingAtom.reportWrite(value, super.isLoading, () { 24 | super.isLoading = value; 25 | }); 26 | } 27 | 28 | late final _$fetchSliderItemsAsyncAction = 29 | AsyncAction('_GameViewModelBase.fetchSliderItems', context: context); 30 | 31 | @override 32 | Future fetchSliderItems() { 33 | return _$fetchSliderItemsAsyncAction.run(() => super.fetchSliderItems()); 34 | } 35 | 36 | late final _$_GameViewModelBaseActionController = 37 | ActionController(name: '_GameViewModelBase', context: context); 38 | 39 | @override 40 | void changeLoading() { 41 | final _$actionInfo = _$_GameViewModelBaseActionController.startAction( 42 | name: '_GameViewModelBase.changeLoading'); 43 | try { 44 | return super.changeLoading(); 45 | } finally { 46 | _$_GameViewModelBaseActionController.endAction(_$actionInfo); 47 | } 48 | } 49 | 50 | @override 51 | String toString() { 52 | return ''' 53 | isLoading: ${isLoading} 54 | '''; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/product/widget/pageview/game_slider.dart: -------------------------------------------------------------------------------- 1 | import 'package:cached_network_image/cached_network_image.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:fluttermvvmtemplate/view/home/game/model/slider_model.dart'; 4 | import 'package:kartal/kartal.dart'; 5 | 6 | class GameSlider extends StatefulWidget { 7 | const GameSlider({Key? key, this.sliderModel}) : super(key: key); 8 | final List? sliderModel; 9 | 10 | @override 11 | _GameSliderState createState() => _GameSliderState(); 12 | } 13 | 14 | class _GameSliderState extends State { 15 | int _selectedValueIndex = 0; 16 | @override 17 | Widget build(BuildContext context) { 18 | return Column( 19 | children: [Expanded(flex: 10, child: buildPageView()), Expanded(child: buildListViewCirleIndicator())], 20 | ); 21 | } 22 | 23 | PageView buildPageView() { 24 | return PageView.builder( 25 | controller: PageController(viewportFraction: 0.8), 26 | onPageChanged: _changeValue, 27 | itemCount: widget.sliderModel!.length, 28 | itemBuilder: (context, index) => buildCardImage(index), 29 | ); 30 | } 31 | 32 | void _changeValue(int index) { 33 | _selectedValueIndex = index; 34 | setState(() {}); 35 | } 36 | 37 | Widget buildCardImage(int index) => CachedNetworkImage(imageUrl: widget.sliderModel![index].image!); 38 | 39 | ListView buildListViewCirleIndicator() { 40 | return ListView.builder( 41 | itemCount: widget.sliderModel!.length, 42 | shrinkWrap: true, 43 | scrollDirection: Axis.horizontal, 44 | itemBuilder: (context, index) => Padding( 45 | padding: EdgeInsets.all(context.dynamicWidth(0.01)), 46 | child: CircleAvatar( 47 | backgroundColor: 48 | _selectedValueIndex == index ? context.colorScheme.onError : context.colorScheme.onError.withOpacity(0.1), 49 | radius: 10, 50 | ), 51 | ), 52 | ); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /lib/view/home/build/feed/viewmodel/build_feed_view_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:fluttermvvmtemplate/core/base/model/base_view_model.dart'; 3 | import 'package:fluttermvvmtemplate/view/_product/_utilty/decoration_helper.dart'; 4 | import 'package:fluttermvvmtemplate/view/home/build/feed/model/house_model.dart'; 5 | import 'package:fluttermvvmtemplate/view/home/build/feed/service/IBuildFeedService.dart'; 6 | import 'package:fluttermvvmtemplate/view/home/build/feed/service/build_feed_service.dart'; 7 | import 'package:mobx/mobx.dart'; 8 | 9 | part 'build_feed_view_model.g.dart'; 10 | 11 | class BuildFeedViewModel = _BuildFeedViewModelBase with _$BuildFeedViewModel; 12 | 13 | abstract class _BuildFeedViewModelBase with Store, BaseViewModel { 14 | @override 15 | void setContext(BuildContext context) => viewModelContext = context; 16 | 17 | GlobalKey scaffoldKey = GlobalKey(); 18 | late DecorationHelper helper; 19 | late IBuildFeedService feedService; 20 | @observable 21 | List likeItems = []; 22 | 23 | @action 24 | void onLikeItemPressed(String id) { 25 | if (likeItems.contains(id)) { 26 | likeItems.remove(id); 27 | } else { 28 | likeItems.add(id); 29 | } 30 | 31 | likeItems = likeItems; 32 | } 33 | 34 | @observable 35 | List? houseModels = []; 36 | 37 | @computed 38 | HouseModel get sliderHouse => houseModels!.first; 39 | 40 | @observable 41 | bool isLoaindg = false; 42 | 43 | @override 44 | void init() { 45 | helper = DecorationHelper(context: viewModelContext); 46 | feedService = BuildFeedService(vexanaManager!.networkManager, scaffoldKey); 47 | } 48 | 49 | @action 50 | void _changeLoading() { 51 | isLoaindg = !isLoaindg; 52 | } 53 | 54 | @action 55 | Future getListAll() async { 56 | _changeLoading(); 57 | houseModels = await feedService.fetchUserHouseList(); 58 | 59 | _changeLoading(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:easy_localization/easy_localization.dart'; 2 | import 'package:firebase_core/firebase_core.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:fluttermvvmtemplate/core/constants/app/app_constants.dart'; 5 | import 'package:fluttermvvmtemplate/core/init/analytics/analytics_manager.dart'; 6 | import 'package:fluttermvvmtemplate/core/init/lang/language_manager.dart'; 7 | import 'package:fluttermvvmtemplate/core/init/navigation/navigation_route.dart'; 8 | import 'package:fluttermvvmtemplate/core/init/navigation/navigation_service.dart'; 9 | import 'package:fluttermvvmtemplate/core/init/notifier/provider_list.dart'; 10 | import 'package:fluttermvvmtemplate/core/init/notifier/theme_notifer.dart'; 11 | import 'package:provider/provider.dart'; 12 | 13 | Future main() async { 14 | await _init(); 15 | runApp( 16 | MultiProvider( 17 | providers: [...ApplicationProvider.instance.dependItems], 18 | child: EasyLocalization( 19 | supportedLocales: LanguageManager.instance.supportedLocales, 20 | path: ApplicationConstants.LANG_ASSET_PATH, 21 | startLocale: LanguageManager.instance.enLocale, 22 | child: MyApp(), 23 | ), 24 | ), 25 | ); 26 | } 27 | 28 | Future _init() async { 29 | WidgetsFlutterBinding.ensureInitialized(); 30 | await EasyLocalization.ensureInitialized(); 31 | await Firebase.initializeApp(); 32 | } 33 | 34 | class MyApp extends StatelessWidget { 35 | @override 36 | Widget build(BuildContext context) { 37 | return MaterialApp( 38 | debugShowCheckedModeBanner: false, 39 | theme: context.watch().currentTheme, 40 | localizationsDelegates: context.localizationDelegates, 41 | supportedLocales: context.supportedLocales, 42 | locale: context.locale, 43 | onGenerateRoute: NavigationRoute.instance.generateRoute, 44 | navigatorKey: NavigationService.instance.navigatorKey, 45 | navigatorObservers: AnalyticsManager.instance.observer, 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 30 30 | 31 | compileOptions { 32 | sourceCompatibility JavaVersion.VERSION_1_8 33 | targetCompatibility JavaVersion.VERSION_1_8 34 | } 35 | 36 | kotlinOptions { 37 | jvmTarget = '1.8' 38 | } 39 | 40 | sourceSets { 41 | main.java.srcDirs += 'src/main/kotlin' 42 | } 43 | 44 | defaultConfig { 45 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 46 | applicationId "com.example.sample" 47 | minSdkVersion 16 48 | targetSdkVersion 30 49 | versionCode flutterVersionCode.toInteger() 50 | versionName flutterVersionName 51 | } 52 | 53 | buildTypes { 54 | release { 55 | // TODO: Add your own signing config for the release build. 56 | // Signing with the debug keys for now, so `flutter run --release` works. 57 | signingConfig signingConfigs.debug 58 | } 59 | } 60 | } 61 | 62 | flutter { 63 | source '../..' 64 | } 65 | 66 | dependencies { 67 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 68 | } 69 | -------------------------------------------------------------------------------- /lib/core/init/analytics/analytics_manager.dart: -------------------------------------------------------------------------------- 1 | import 'package:firebase_analytics/firebase_analytics.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:fluttermvvmtemplate/core/constants/app/app_constants.dart'; 4 | 5 | class AnalyticsManager { 6 | AnalyticsManager._init() { 7 | init(); 8 | } 9 | static final AnalyticsManager _instance = AnalyticsManager._init(); 10 | static AnalyticsManager get instance => _instance; 11 | 12 | static final _analytics = FirebaseAnalytics.instance; 13 | 14 | final List observer = 15 | ApplicationConstants.TEST_MODE ? [] : [FirebaseAnalyticsObserver(analytics: _analytics)]; 16 | 17 | // Firebase e her zaman veri göndermek istemeyebiliriz. 18 | // Örneğin inapppurchase yapacağımızda ApplicationConstants.TEST_MODE false olursa 19 | // gerçekten ödeme yapılmış gibi ücret bilgisi yansır. 20 | // Bu istenmeyen bir durumdur, gerçek verileri manipüle eder.. 21 | Future init() async { 22 | await _analytics.setAnalyticsCollectionEnabled(ApplicationConstants.TEST_MODE ? false : true); 23 | } 24 | 25 | Future customEvent(String name) async { 26 | //her şey yapılabilir 27 | await _analytics.logEvent(name: name); 28 | } 29 | 30 | //USER ANALYTICS 31 | //kayıt sırasında user ıd yi almak için 32 | Future setUserAnalytics({String? userID, String? name, String? value}) async { 33 | await _analytics.setUserId(id: userID); 34 | 35 | //kullanıcılara rol vermek için kullanılabilir (ADMİN-KULLANICI-PREMIUMS VS VS) 36 | //bunu yapacaksak öncelikle 37 | //firebase consola git 38 | //custom definision tıkla 39 | //sap üstte create custom dimensions bas 40 | //user property ye bu parametrdeki name ile aynı ismi ver 41 | //scope den user ı seç 42 | //dimension name ya raporda gözükecek olan başlığı yaz 43 | //descriptiona ufak bi açıklamasını yaz 44 | if (name != null && value != null) { 45 | await _analytics.setUserProperty(name: name, value: value); 46 | } 47 | } 48 | 49 | Future userLogin(String signUpMethod) async { 50 | await _analytics.logLogin(loginMethod: signUpMethod); 51 | } 52 | 53 | Future userSignUp(String signUpMethod) async { 54 | await _analytics.logSignUp(signUpMethod: signUpMethod); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/core/extension/context_extension.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | extension ContextExtension on BuildContext { 6 | MediaQueryData get mediaQuery => MediaQuery.of(this); 7 | } 8 | 9 | extension MediaQueryExtension on BuildContext { 10 | double get height => mediaQuery.size.height; 11 | double get width => mediaQuery.size.width; 12 | 13 | double get lowValue => height * 0.01; 14 | double get normalValue => height * 0.02; 15 | double get mediumValue => height * 0.04; 16 | double get highValue => height * 0.1; 17 | } 18 | 19 | extension ThemeExtension on BuildContext { 20 | ThemeData get theme => Theme.of(this); 21 | TextTheme get textTheme => theme.textTheme; 22 | ColorScheme get colors => theme.colorScheme; 23 | } 24 | 25 | extension PaddingExtensionAll on BuildContext { 26 | EdgeInsets get paddingLow => EdgeInsets.all(lowValue); 27 | EdgeInsets get paddingNormal => EdgeInsets.all(normalValue); 28 | EdgeInsets get paddingMedium => EdgeInsets.all(mediumValue); 29 | EdgeInsets get paddingHigh => EdgeInsets.all(highValue); 30 | } 31 | 32 | extension PaddingExtensionSymetric on BuildContext { 33 | EdgeInsets get paddingLowVertical => EdgeInsets.symmetric(vertical: lowValue); 34 | EdgeInsets get paddingNormalVertical => 35 | EdgeInsets.symmetric(vertical: normalValue); 36 | EdgeInsets get paddingMediumVertical => 37 | EdgeInsets.symmetric(vertical: mediumValue); 38 | EdgeInsets get paddingHighVertical => 39 | EdgeInsets.symmetric(vertical: highValue); 40 | 41 | EdgeInsets get paddingLowHorizontal => 42 | EdgeInsets.symmetric(horizontal: lowValue); 43 | EdgeInsets get paddingNormalHorizontal => 44 | EdgeInsets.symmetric(horizontal: normalValue); 45 | EdgeInsets get paddingMediumHorizontal => 46 | EdgeInsets.symmetric(horizontal: mediumValue); 47 | EdgeInsets get paddingHighHorizontal => 48 | EdgeInsets.symmetric(horizontal: highValue); 49 | } 50 | 51 | extension PageExtension on BuildContext { 52 | Color get randomColor => Colors.primaries[Random().nextInt(17)]; 53 | } 54 | 55 | extension DurationExtension on BuildContext { 56 | Duration get lowDuration => const Duration(milliseconds: 500); 57 | Duration get normalDuration => const Duration(seconds: 1); 58 | } 59 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 13 | 17 | 21 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 37 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /lib/view/home/game/viewmodel/game_view_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:fluttermvvmtemplate/core/base/model/base_view_model.dart'; 3 | import 'package:fluttermvvmtemplate/core/init/lang/locale_keys.g.dart'; 4 | import 'package:fluttermvvmtemplate/view/home/game/model/game_enums.dart'; 5 | import 'package:fluttermvvmtemplate/view/home/game/model/game_model.dart'; 6 | import 'package:fluttermvvmtemplate/view/home/game/model/slider_model.dart'; 7 | import 'package:fluttermvvmtemplate/view/home/game/service/game_service.dart'; 8 | import 'package:mobx/mobx.dart'; 9 | 10 | part 'game_view_model.g.dart'; 11 | 12 | class GameViewModel = _GameViewModelBase with _$GameViewModel; 13 | 14 | abstract class _GameViewModelBase with Store, BaseViewModel { 15 | _GameViewModelBase(this.gameService); 16 | final List gameTabItems = [ 17 | LocaleKeys.home_game_tabbar_tab1, 18 | LocaleKeys.home_game_tabbar_tab2, 19 | LocaleKeys.home_game_tabbar_tab3, 20 | LocaleKeys.home_game_tabbar_tab4, 21 | LocaleKeys.home_game_tabbar_tab5 22 | ]; 23 | 24 | final GameService gameService; 25 | 26 | List? sliderItems = []; 27 | List newsGameItems = []; 28 | List topGameITems = []; 29 | 30 | @override 31 | void setContext(BuildContext context) => viewModelContext = context; 32 | 33 | @observable 34 | bool isLoading = false; 35 | 36 | @override 37 | void init() { 38 | fetchSliderItems(); 39 | } 40 | 41 | @action 42 | Future fetchSliderItems() async { 43 | changeLoading(); 44 | final response = await gameService.fetchSliderItems(); 45 | sliderItems = response; 46 | changeLoading(); 47 | } 48 | 49 | Future?> onNewsGameItems() async { 50 | if (newsGameItems.isNotEmpty) return newsGameItems; 51 | final response = await gameService.fetchGameItems(GameEnum.NEW); 52 | newsGameItems = response ?? []; 53 | 54 | return response; 55 | } 56 | 57 | Future?> onTopGameItems() async { 58 | if (newsGameItems.isNotEmpty) return newsGameItems; 59 | final response = await gameService.fetchGameItems(GameEnum.TOP); 60 | newsGameItems = response ?? []; 61 | 62 | return response; 63 | } 64 | 65 | @action 66 | void changeLoading() { 67 | isLoading = !isLoading; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /lib/view/authenticate/onboard/viewModel/on_board_view_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:fluttermvvmtemplate/core/base/model/base_view_model.dart'; 3 | import 'package:fluttermvvmtemplate/core/constants/enums/locale_keys_enum.dart'; 4 | import 'package:fluttermvvmtemplate/core/constants/navigation/navigation_constants.dart'; 5 | import 'package:fluttermvvmtemplate/core/init/lang/locale_keys.g.dart'; 6 | import 'package:fluttermvvmtemplate/view/_product/_constants/image_path_svg.dart'; 7 | import 'package:fluttermvvmtemplate/view/authenticate/onboard/model/on_board_model.dart'; 8 | import 'package:mobx/mobx.dart'; 9 | 10 | part 'on_board_view_model.g.dart'; 11 | 12 | class OnBoardViewModel = _OnBoardViewModelBase with _$OnBoardViewModel; 13 | 14 | abstract class _OnBoardViewModelBase with Store, BaseViewModel { 15 | @override 16 | void setContext(BuildContext context) { 17 | viewModelContext = context; 18 | } 19 | 20 | List onBoardItems = []; 21 | 22 | @observable 23 | bool isLoading = false; 24 | 25 | @observable 26 | int currentIndex = 0; 27 | 28 | @action 29 | void changeCurrentIndex(int value) { 30 | currentIndex = value; 31 | } 32 | 33 | @override 34 | void init() { 35 | onBoardItems.addAll([ 36 | OnBoardModel( 37 | LocaleKeys.onBoard_page1_title, 38 | LocaleKeys.onBoard_page1_desc, 39 | SVGImagePaths.instance.astronautSVG, 40 | ), 41 | OnBoardModel( 42 | LocaleKeys.onBoard_page1_title, 43 | LocaleKeys.onBoard_page2_desc, 44 | SVGImagePaths.instance.chattingSVG, 45 | ), 46 | OnBoardModel( 47 | LocaleKeys.onBoard_page1_title, 48 | LocaleKeys.onBoard_page2_desc, 49 | SVGImagePaths.instance.chattingSVG, 50 | ), 51 | OnBoardModel(LocaleKeys.onBoard_page3_title, LocaleKeys.onBoard_page3_desc, SVGImagePaths.instance.relaxSVG), 52 | ]); 53 | } 54 | 55 | @action 56 | void changeLoading() { 57 | isLoading = !isLoading; 58 | } 59 | 60 | Future completeToOnBoard() async { 61 | changeLoading(); 62 | await localeManager.setBoolValue(PreferencesKeys.IS_FIRST_APP, true); 63 | changeLoading(); 64 | if (navigation.navigatorKey.currentState!.canPop()) { 65 | navigation.navigatorKey.currentState!.pop(); 66 | } else { 67 | await navigation.navigateToPageClear(path: NavigationConstants.TEST_VIEW); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /lib/view/home/game/service/game_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:fluttermvvmtemplate/view/_product/_utilty/service_helper.dart'; 3 | import 'package:fluttermvvmtemplate/view/_product/enum/network_route_enum.dart'; 4 | import 'package:fluttermvvmtemplate/view/home/game/model/game_enums.dart'; 5 | import 'package:fluttermvvmtemplate/view/home/game/model/game_model.dart'; 6 | import 'package:fluttermvvmtemplate/view/home/game/model/slider_model.dart'; 7 | import 'package:fluttermvvmtemplate/view/home/game/service/IGameService.dart'; 8 | import 'package:vexana/vexana.dart'; 9 | 10 | class GameService extends IGameService with ServiceHelper { 11 | GameService(INetworkManager manager, GlobalKey scaffoldyKey) : super(manager, scaffoldyKey); 12 | 13 | @override 14 | Future?> fetchGameItems(GameEnum type) async { 15 | final response = await manager.send>( 16 | NetworkRoutes.GAME.rawValue, 17 | urlSuffix: '/${type.index + 1}', 18 | parseModel: GameModel(), 19 | method: RequestType.GET, 20 | ); 21 | showMessage(scaffoldyKey, response.error); 22 | 23 | await Future.delayed(const Duration(seconds: 5)); 24 | return response.data; 25 | } 26 | 27 | @override 28 | Future?> fetchSliderItems() async { 29 | final response = await manager.send>( 30 | NetworkRoutes.SLIDER.rawValue, 31 | parseModel: SliderModel(), 32 | method: RequestType.GET, 33 | ); 34 | showMessage(scaffoldyKey, response.error); 35 | return response.data; 36 | } 37 | } 38 | 39 | // BEFORE: Null safety 40 | 41 | // @override 42 | // Future> fetchGameItems(GameEnum type) async { 43 | // final response = await manager.fetch>(NetworkRoutes.GAME.rawValue, 44 | // urlSuffix: '/${type.index + 1}', parseModel: GameModel(), method: RequestType.GET); 45 | // showMessage(scaffoldyKey, response.error); 46 | 47 | // await Future.delayed(Duration(seconds: 5)); 48 | // return response.data; 49 | // } 50 | 51 | // @override 52 | // Future> fetchSliderItems() async { 53 | // final response = 54 | // await manager.fetch>(NetworkRoutes.SLIDER.rawValue, parseModel: SliderModel(), method: RequestType.GET); 55 | // showMessage(scaffoldyKey, response.error); 56 | // return response.data; 57 | // } 58 | -------------------------------------------------------------------------------- /lib/core/init/navigation/navigation_route.dart: -------------------------------------------------------------------------------- 1 | import 'package:all_of_template/features/buy_view.dart'; 2 | import 'package:architecture_widgets/src/card/not_found_navigation_widget.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:fluttermvvmtemplate/core/constants/navigation/navigation_constants.dart'; 5 | import 'package:fluttermvvmtemplate/product/exception/navigate_model_not_found.dart'; 6 | import 'package:fluttermvvmtemplate/view/authenticate/onboard/view/on_board_view.dart'; 7 | import 'package:fluttermvvmtemplate/view/authenticate/splash/view/splash_view.dart'; 8 | import 'package:fluttermvvmtemplate/view/authenticate/test/view/test_view.dart'; 9 | import 'package:fluttermvvmtemplate/view/settings/model/settings_dynamic.dart'; 10 | import 'package:fluttermvvmtemplate/view/settings/view/subview/settings_dynamic_view.dart'; 11 | 12 | class NavigationRoute { 13 | NavigationRoute._init(); 14 | static final NavigationRoute _instance = NavigationRoute._init(); 15 | static NavigationRoute get instance => _instance; 16 | 17 | Route generateRoute(RouteSettings args) { 18 | switch (args.name) { 19 | case NavigationConstants.DEFAULT: 20 | return normalNavigate(const SplashView(), NavigationConstants.DEFAULT); 21 | 22 | case NavigationConstants.TEST_VIEW: 23 | return normalNavigate(TestsView(), NavigationConstants.TEST_VIEW); 24 | 25 | case NavigationConstants.BUY_VIEW: 26 | return normalNavigate(const BuyView(), NavigationConstants.BUY_VIEW); 27 | 28 | case NavigationConstants.ON_BOARD: 29 | return normalNavigate(const OnBoardView(), NavigationConstants.ON_BOARD); 30 | 31 | case NavigationConstants.SETTINGS_WEB_VIEW: 32 | if (args.arguments is SettingsDynamicModel) { 33 | return normalNavigate( 34 | SettingsDynamicView(model: args.arguments as SettingsDynamicModel), 35 | NavigationConstants.SETTINGS_WEB_VIEW, 36 | ); 37 | } 38 | throw NavigateException(args.arguments); 39 | 40 | default: 41 | return MaterialPageRoute( 42 | builder: (context) => const NotFoundNavigationWidget(), 43 | ); 44 | } 45 | } 46 | 47 | MaterialPageRoute normalNavigate(Widget widget, String pageName) { 48 | return MaterialPageRoute( 49 | builder: (context) => widget, 50 | //analytciste görülecek olan sayfa ismi için pageName veriyoruz 51 | settings: RouteSettings(name: pageName), 52 | ); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /lib/view/home/burger/service/burger_serivce.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluttermvvmtemplate/view/_product/_mixin/network_helper.dart'; 2 | import 'package:fluttermvvmtemplate/view/_product/_utilty/burger_network_enum.dart'; 3 | import 'package:fluttermvvmtemplate/view/home/burger/model/burger_model.dart'; 4 | import 'package:vexana/vexana.dart'; 5 | 6 | abstract class IBurgerService { 7 | IBurgerService(this.manager); 8 | final INetworkManager manager; 9 | 10 | Future> fetchFavoriteBurgers(); 11 | 12 | Future> fetchBurgersLimited({double? max = 50, double? min = 0}); 13 | Future> fetchBurgersSorted({ 14 | required BurgerSortValues sort, 15 | BurgerSortValuesType types = BurgerSortValuesType.ASC, 16 | }); 17 | } 18 | 19 | class BurgerService extends IBurgerService with NetworkHelper { 20 | BurgerService(INetworkManager manager) : super(manager); 21 | 22 | @override 23 | Future> fetchBurgersLimited({double? max = 50, double? min = 0}) async { 24 | final response = await manager.send>( 25 | BurgerNetworkPath.PRICE.rawValue, 26 | parseModel: BurgerModel(), 27 | method: RequestType.GET, 28 | queryParameters: Map.fromEntries( 29 | [BurgerQueryParamaters.MIN.rawValue(min?.toInt()), BurgerQueryParamaters.MAX.rawValue(max?.toInt())], 30 | ), 31 | ); 32 | 33 | return response.data ?? []; 34 | } 35 | 36 | @override 37 | Future> fetchBurgersSorted({ 38 | required BurgerSortValues sort, 39 | BurgerSortValuesType types = BurgerSortValuesType.ASC, 40 | }) async { 41 | final response = await manager.send>( 42 | BurgerNetworkPath.MAIN.rawValue, 43 | parseModel: BurgerModel(), 44 | method: RequestType.GET, 45 | queryParameters: Map.fromEntries([ 46 | BurgerQueryParamaters.SORT.rawValue(sort.rawValue), 47 | BurgerQueryParamaters.SORT_TYPE.rawValue(types.rawValue) 48 | ]), 49 | ); 50 | 51 | return response.data ?? []; 52 | } 53 | 54 | @override 55 | Future> fetchFavoriteBurgers() async { 56 | final response = await manager.send>( 57 | BurgerNetworkPath.MAIN.rawValue, 58 | parseModel: BurgerModel(), 59 | method: RequestType.GET, 60 | queryParameters: Map.fromEntries([BurgerQueryParamaters.FAVORITE.rawValue(true)]), 61 | ); 62 | showLog(response); 63 | return response.data ?? []; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /lib/view/authenticate/onboard/viewModel/on_board_view_model.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'on_board_view_model.dart'; 4 | 5 | // ************************************************************************** 6 | // StoreGenerator 7 | // ************************************************************************** 8 | 9 | // 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, no_leading_underscores_for_local_identifiers 10 | 11 | mixin _$OnBoardViewModel on _OnBoardViewModelBase, Store { 12 | late final _$isLoadingAtom = 13 | Atom(name: '_OnBoardViewModelBase.isLoading', context: context); 14 | 15 | @override 16 | bool get isLoading { 17 | _$isLoadingAtom.reportRead(); 18 | return super.isLoading; 19 | } 20 | 21 | @override 22 | set isLoading(bool value) { 23 | _$isLoadingAtom.reportWrite(value, super.isLoading, () { 24 | super.isLoading = value; 25 | }); 26 | } 27 | 28 | late final _$currentIndexAtom = 29 | Atom(name: '_OnBoardViewModelBase.currentIndex', context: context); 30 | 31 | @override 32 | int get currentIndex { 33 | _$currentIndexAtom.reportRead(); 34 | return super.currentIndex; 35 | } 36 | 37 | @override 38 | set currentIndex(int value) { 39 | _$currentIndexAtom.reportWrite(value, super.currentIndex, () { 40 | super.currentIndex = value; 41 | }); 42 | } 43 | 44 | late final _$_OnBoardViewModelBaseActionController = 45 | ActionController(name: '_OnBoardViewModelBase', context: context); 46 | 47 | @override 48 | void changeCurrentIndex(int value) { 49 | final _$actionInfo = _$_OnBoardViewModelBaseActionController.startAction( 50 | name: '_OnBoardViewModelBase.changeCurrentIndex'); 51 | try { 52 | return super.changeCurrentIndex(value); 53 | } finally { 54 | _$_OnBoardViewModelBaseActionController.endAction(_$actionInfo); 55 | } 56 | } 57 | 58 | @override 59 | void changeLoading() { 60 | final _$actionInfo = _$_OnBoardViewModelBaseActionController.startAction( 61 | name: '_OnBoardViewModelBase.changeLoading'); 62 | try { 63 | return super.changeLoading(); 64 | } finally { 65 | _$_OnBoardViewModelBaseActionController.endAction(_$actionInfo); 66 | } 67 | } 68 | 69 | @override 70 | String toString() { 71 | return ''' 72 | isLoading: ${isLoading}, 73 | currentIndex: ${currentIndex} 74 | '''; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /lib/view/authenticate/test/viewmodel/test_view_model.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'test_view_model.dart'; 4 | 5 | // ************************************************************************** 6 | // StoreGenerator 7 | // ************************************************************************** 8 | 9 | // 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, no_leading_underscores_for_local_identifiers 10 | 11 | mixin _$TestViewModel on _TestViewModelBase, Store { 12 | Computed? _$isEvenComputed; 13 | 14 | @override 15 | bool get isEven => (_$isEvenComputed ??= 16 | Computed(() => super.isEven, name: '_TestViewModelBase.isEven')) 17 | .value; 18 | 19 | late final _$isLoadingAtom = 20 | Atom(name: '_TestViewModelBase.isLoading', context: context); 21 | 22 | @override 23 | bool get isLoading { 24 | _$isLoadingAtom.reportRead(); 25 | return super.isLoading; 26 | } 27 | 28 | @override 29 | set isLoading(bool value) { 30 | _$isLoadingAtom.reportWrite(value, super.isLoading, () { 31 | super.isLoading = value; 32 | }); 33 | } 34 | 35 | late final _$numberAtom = 36 | Atom(name: '_TestViewModelBase.number', context: context); 37 | 38 | @override 39 | int get number { 40 | _$numberAtom.reportRead(); 41 | return super.number; 42 | } 43 | 44 | @override 45 | set number(int value) { 46 | _$numberAtom.reportWrite(value, super.number, () { 47 | super.number = value; 48 | }); 49 | } 50 | 51 | late final _$getSampleRequestAsyncAction = 52 | AsyncAction('_TestViewModelBase.getSampleRequest', context: context); 53 | 54 | @override 55 | Future getSampleRequest() { 56 | return _$getSampleRequestAsyncAction.run(() => super.getSampleRequest()); 57 | } 58 | 59 | late final _$_TestViewModelBaseActionController = 60 | ActionController(name: '_TestViewModelBase', context: context); 61 | 62 | @override 63 | void incrementNumber() { 64 | final _$actionInfo = _$_TestViewModelBaseActionController.startAction( 65 | name: '_TestViewModelBase.incrementNumber'); 66 | try { 67 | return super.incrementNumber(); 68 | } finally { 69 | _$_TestViewModelBaseActionController.endAction(_$actionInfo); 70 | } 71 | } 72 | 73 | @override 74 | String toString() { 75 | return ''' 76 | isLoading: ${isLoading}, 77 | number: ${number}, 78 | isEven: ${isEven} 79 | '''; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /lib/view/authenticate/login/viewmodel/login_view_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:fluttermvvmtemplate/core/base/model/base_view_model.dart'; 3 | import 'package:fluttermvvmtemplate/core/constants/enums/locale_keys_enum.dart'; 4 | import 'package:fluttermvvmtemplate/core/init/network/vexana_manager.dart'; 5 | import 'package:fluttermvvmtemplate/view/authenticate/login/model/login_model.dart'; 6 | import 'package:fluttermvvmtemplate/view/authenticate/login/service/ILoginService.dart'; 7 | import 'package:fluttermvvmtemplate/view/authenticate/login/service/login_service.dart'; 8 | import 'package:mobx/mobx.dart'; 9 | 10 | part 'login_view_model.g.dart'; 11 | 12 | class LoginViewModel = _LoginViewModelBase with _$LoginViewModel; 13 | 14 | abstract class _LoginViewModelBase with Store, BaseViewModel { 15 | GlobalKey formState = GlobalKey(); 16 | GlobalKey scaffoldState = GlobalKey(); 17 | late ILoginService loginService; 18 | 19 | TextEditingController emailController = TextEditingController(); 20 | TextEditingController passwordController = TextEditingController(); 21 | 22 | @override 23 | void setContext(BuildContext context) => viewModelContext = context; 24 | 25 | @override 26 | void init() { 27 | loginService = LoginService(VexanaManager.instance.networkManager); 28 | } 29 | 30 | @observable 31 | bool isLoading = false; 32 | 33 | @observable 34 | bool isLockOpen = false; 35 | 36 | @action 37 | Future fetchLoginService() async { 38 | isLoadingChange(); 39 | if (formState.currentState!.validate()) { 40 | final response = await loginService.fetchUserControl( 41 | LoginModel( 42 | email: emailController.text, 43 | password: passwordController.text, 44 | ), 45 | ); 46 | 47 | if (response != null) { 48 | if (response.token?.isEmpty ?? true) return; 49 | if (scaffoldState.currentContext != null) { 50 | ScaffoldMessenger.of(scaffoldState.currentContext!).showSnackBar( 51 | SnackBar( 52 | content: Text(response.token!), 53 | ), 54 | ); 55 | } 56 | await localeManager.setStringValue( 57 | PreferencesKeys.TOKEN, 58 | response.token!, 59 | ); 60 | } 61 | } 62 | isLoadingChange(); 63 | } 64 | 65 | void dispose() { 66 | emailController.dispose(); 67 | passwordController.dispose(); 68 | } 69 | 70 | @action 71 | void isLoadingChange() { 72 | isLoading = !isLoading; 73 | } 74 | 75 | @action 76 | void isLockStateChange() { 77 | isLockOpen = !isLockOpen; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /lib/view/authenticate/login/view/login_view_two.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class UserView extends StatelessWidget { 4 | @override 5 | Widget build(BuildContext context) { 6 | return DefaultTabController( 7 | length: 2, 8 | child: Scaffold( 9 | body: Stack( 10 | children: [ 11 | Positioned( 12 | right: 0, 13 | left: 0, 14 | height: MediaQuery.of(context).size.height * 0.4, 15 | child: Column( 16 | children: [ 17 | Expanded(flex: 9, child: Container(color: Colors.red, child: const FlutterLogo(size: 200))), 18 | Container( 19 | decoration: const BoxDecoration( 20 | color: Colors.yellow, 21 | borderRadius: BorderRadius.vertical(bottom: Radius.circular(30)), 22 | ), 23 | child: const Padding( 24 | padding: EdgeInsets.only(left: 30, right: 30, bottom: 5), 25 | child: TabBar( 26 | indicatorSize: TabBarIndicatorSize.label, 27 | tabs: [ 28 | Tab( 29 | text: ' Login ', 30 | ), 31 | Tab(icon: Icon(Icons.radio)), 32 | ], 33 | ), 34 | ), 35 | ), 36 | // Spacer(flex: 12) 37 | ], 38 | ), 39 | ), 40 | Positioned.fill( 41 | top: MediaQuery.of(context).size.height * 0.4, 42 | child: Center( 43 | child: SingleChildScrollView( 44 | child: SizedBox( 45 | height: MediaQuery.of(context).size.height * 0.25, 46 | child: Column( 47 | mainAxisAlignment: MainAxisAlignment.center, 48 | children: const [ 49 | TextField(), 50 | TextField(), 51 | ElevatedButton( 52 | onPressed: null, 53 | child: Text(''), 54 | ), 55 | ElevatedButton( 56 | onPressed: null, 57 | child: Text(''), 58 | ) 59 | ], 60 | ), 61 | ), 62 | ), 63 | ), 64 | ) 65 | ], 66 | ), 67 | ), 68 | ); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /test/feature/feed/social_feed_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import 'package:fluttermvvmtemplate/view/_product/_model/query/friend_query.dart'; 4 | import 'package:mockito/mockito.dart'; 5 | import 'package:vexana/vexana.dart'; 6 | 7 | import 'feed_mockito.dart'; 8 | import 'social_network_mock.dart'; 9 | 10 | void main() { 11 | BuildContext? context; 12 | SocialNetworkMock? mockService; 13 | INetworkManager networkManager; 14 | late SocialMockViewModel socialMockViewModel; 15 | 16 | setUp(() { 17 | context = SocialBuildContext(); 18 | networkManager = NetworkManager(options: BaseOptions()); 19 | 20 | mockService = SocialNetworkMock(networkManager, null); 21 | socialMockViewModel = SocialMockViewModel(mockService); 22 | }); 23 | 24 | test('Context Test', () async { 25 | verify(socialMockViewModel.setContext(context)); 26 | }); 27 | 28 | test('Loading Test 2 ', () async { 29 | socialMockViewModel.fetchAllUserLoading(1); 30 | expect(socialMockViewModel.isPageLoading, true); 31 | await Future.delayed(Duration(seconds: 1)); 32 | expect(socialMockViewModel.isPageLoading, false); 33 | }); 34 | 35 | test('User All Loading', () async { 36 | socialMockViewModel.isPageLoadingLazyLoad = false; 37 | socialMockViewModel.socialUserList = []; 38 | socialMockViewModel.isLazyLoadDataFinish = false; 39 | 40 | await socialMockViewModel.fetchAllUserLoading(-1); 41 | expect(socialMockViewModel.socialUserList.isNotEmpty, true); 42 | expect(socialMockViewModel.page > 0, true); 43 | expect(socialMockViewModel.isPageLoading, false); 44 | }); 45 | 46 | test('List check', () async { 47 | socialMockViewModel.setContext(context); 48 | 49 | await socialMockViewModel.fetchAllUserLoading(1); 50 | // when(socialMockViewModel.fetchAllUserLoading(0)).thenReturn(Future.value()); 51 | 52 | expect(socialMockViewModel.socialUserList.length, 1); 53 | }); 54 | test('Loading Test', () async { 55 | await socialMockViewModel.fetchAllUserLoading(0); 56 | verifyNever(socialMockViewModel.isPageLoading); 57 | // verify(socialMockViewModel.isPageLoading).called(2); 58 | }); 59 | test('Fetch User Id', () async { 60 | final response = await mockService!.fetchUser(10); 61 | expect(response, isNotNull); 62 | }); 63 | 64 | test('Fetch House Id', () async { 65 | final response = await mockService!.fetchUserHouseList(FriendQuery()); 66 | expect(response, isNotEmpty); 67 | }); 68 | 69 | test('Fetch User Name Query', () async { 70 | final response = await mockService!.fetchUserNameQuery('hello'); 71 | expect(response, isNotEmpty); 72 | }); 73 | } 74 | -------------------------------------------------------------------------------- /lib/view/home/burger/viewmodel/burger_view_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:fluttermvvmtemplate/core/base/model/base_view_model.dart'; 3 | import 'package:fluttermvvmtemplate/view/_product/_utilty/burger_network_enum.dart'; 4 | import 'package:fluttermvvmtemplate/view/home/burger/model/burger_model.dart'; 5 | import 'package:fluttermvvmtemplate/view/home/burger/service/burger_serivce.dart'; 6 | import 'package:kartal/kartal.dart'; 7 | import 'package:mobx/mobx.dart'; 8 | 9 | part 'burger_view_model.g.dart'; 10 | 11 | class BurgerViewModel = _BurgerViewModelBase with _$BurgerViewModel; 12 | 13 | abstract class _BurgerViewModelBase with Store, BaseViewModel { 14 | _BurgerViewModelBase(this.burgerService); 15 | final IBurgerService burgerService; 16 | 17 | @observable 18 | bool isLoading = false; 19 | 20 | @observable 21 | bool isLoadingMain = false; 22 | @observable 23 | List favoriteBurgerModel = []; 24 | @observable 25 | List mainBurgerModel = []; 26 | @override 27 | void setContext(BuildContext context) => viewModelContext = context; 28 | 29 | RangeValues? _values; 30 | 31 | bool _isAscending = true; 32 | @override 33 | void init() { 34 | fetchFavorite(); 35 | } 36 | 37 | @action 38 | void _changeLoading() { 39 | isLoading = !isLoading; 40 | } 41 | 42 | @action 43 | void _changeLoadingMain() { 44 | isLoadingMain = !isLoadingMain; 45 | } 46 | 47 | @action 48 | Future fetchFavorite() async { 49 | _changeLoading(); 50 | favoriteBurgerModel = await burgerService.fetchFavoriteBurgers(); 51 | _changeLoading(); 52 | } 53 | 54 | @action 55 | Future fetchNormalItems() async { 56 | if (mainBurgerModel.isNotEmpty) return; 57 | _changeLoadingMain(); 58 | mainBurgerModel = await burgerService.fetchBurgersSorted(sort: BurgerSortValues.RATES); 59 | _changeLoadingMain(); 60 | } 61 | 62 | void changeRangeValues(RangeValues values) { 63 | _values = values; 64 | } 65 | 66 | void changeAscending(bool value) { 67 | _isAscending = value; 68 | } 69 | 70 | @action 71 | Future fetchMinMax() async { 72 | viewModelContext.navigation.pop(); 73 | _changeLoadingMain(); 74 | mainBurgerModel = await burgerService.fetchBurgersLimited(max: _values?.end, min: _values?.start); 75 | _changeLoadingMain(); 76 | } 77 | 78 | Future fetchSort(BurgerSortValues value) async { 79 | viewModelContext.navigation.pop(); 80 | _changeLoadingMain(); 81 | mainBurgerModel = await burgerService.fetchBurgersSorted( 82 | sort: value, 83 | types: _isAscending ? BurgerSortValuesType.ASC : BurgerSortValuesType.DSC, 84 | ); 85 | _changeLoadingMain(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /asset/lang/en-US.json: -------------------------------------------------------------------------------- 1 | { 2 | "welcome": "Welcome to My App", 3 | "onBoard": { 4 | "page1": { 5 | "title": "Make It Good", 6 | "desc": "You are not alone. You have unique abiltiyto go to anther world" 7 | }, 8 | "page2": { 9 | "title": "Make It Good", 10 | "desc": "You are not alone. You have unique abiltiyto go to anther world" 11 | }, 12 | "page3": { 13 | "title": "Make It Good", 14 | "desc": "You are not alone. You have unique abiltiyto go to anther world" 15 | } 16 | }, 17 | "splash": { 18 | "welcome": "WELCOME TO HWA ARCHITECTURE SERIES" 19 | }, 20 | "login": { 21 | "tab1": "Login", 22 | "tab2": "SignUp", 23 | "email": "Email", 24 | "password": "Password", 25 | "forgotText": "Forgot Password", 26 | "login": "Login", 27 | "dontAccount": "Dont have account" 28 | }, 29 | "home": { 30 | "build": { 31 | "tabbar": { 32 | "tab1": "Latest", 33 | "tab2": "Decorative", 34 | "tab3": "Music", 35 | "tab4": "Style" 36 | }, 37 | "subTitle": "Recommended" 38 | }, 39 | "social": { 40 | "cancel": "Cancel", 41 | "next": "Next", 42 | "search": "Search", 43 | "findFriends": "Find Friends", 44 | "follow": "Follow", 45 | "following": "Following" 46 | }, 47 | "game": { 48 | "title": "Unity Game", 49 | "newUpdate": "New Updated Games", 50 | "viewAll": "View All", 51 | "topDownload": "Top Downloads", 52 | "tabbar": { 53 | "tab1": "RACING", 54 | "tab2": "SIMULATION", 55 | "tab3": "CASUAL", 56 | "tab4": "CARTOONY", 57 | "tab5": "TOYS" 58 | } 59 | }, 60 | "burgers": { 61 | "favoriteProducts": "Best \nSelling", 62 | "normalProducts": "Burgers" 63 | }, 64 | "setting": { 65 | "title": "Settings", 66 | "about": { 67 | "title": "About Project", 68 | "contribitions": "Project Contributors" 69 | }, 70 | "core": { 71 | "title": "Project Core", 72 | "themeTitle": "Theme Change", 73 | "themeDesc": "You can change applicaton theme.", 74 | "langTitle": "Language Change", 75 | "langDesc": "You can change applicaton language." 76 | }, 77 | "exit": "Exit", 78 | "applicationTour": "Application Tuor" 79 | } 80 | } 81 | } --------------------------------------------------------------------------------