├── .gitignore
├── .gradle
├── 6.1.1
│ ├── executionHistory
│ │ └── executionHistory.lock
│ ├── fileChanges
│ │ └── last-build.bin
│ ├── fileHashes
│ │ └── fileHashes.lock
│ └── gc.properties
├── buildOutputCleanup
│ ├── buildOutputCleanup.lock
│ └── cache.properties
├── checksums
│ └── checksums.lock
└── vcs-1
│ └── gc.properties
├── .metadata
├── README.md
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── geekysingh
│ │ │ │ └── flutter_clean_architecture
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── 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
│ │ │ └── values
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── core
├── .gitignore
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── lib
│ ├── common
│ │ └── status.dart
│ ├── core.dart
│ ├── core
│ │ ├── core_screen.dart
│ │ └── core_view_model.dart
│ ├── service
│ │ ├── dialog_service.dart
│ │ ├── navigation_service.dart
│ │ ├── snackbar_service.dart
│ │ └── toast_service.dart
│ └── src
│ │ └── di
│ │ ├── locator.config.dart
│ │ └── locator.dart
├── pubspec.lock
└── pubspec.yaml
├── data
├── .gitignore
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── lib
│ ├── data.dart
│ └── src
│ │ ├── common
│ │ └── constants.dart
│ │ ├── datasource
│ │ ├── local
│ │ │ ├── dao
│ │ │ │ └── article_dao.dart
│ │ │ ├── db
│ │ │ │ ├── app_database.dart
│ │ │ │ └── app_database.g.dart
│ │ │ └── entity
│ │ │ │ └── article_entity.dart
│ │ └── remote
│ │ │ ├── dto
│ │ │ ├── article_response.dart
│ │ │ └── article_response.g.dart
│ │ │ └── service
│ │ │ ├── article_service.dart
│ │ │ └── article_service.g.dart
│ │ ├── di
│ │ ├── locator.config.dart
│ │ └── locator.dart
│ │ ├── mapper
│ │ └── article_mapper.dart
│ │ └── repository
│ │ ├── article_repository.dart
│ │ └── base
│ │ └── base_repository.dart
├── pubspec.lock
└── pubspec.yaml
├── domain
├── .gitignore
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── lib
│ ├── domain.dart
│ └── src
│ │ ├── common
│ │ ├── error_type.dart
│ │ └── result.dart
│ │ ├── di
│ │ ├── locator.config.dart
│ │ └── locator.dart
│ │ ├── model
│ │ └── article_model.dart
│ │ ├── repository
│ │ └── article_repository.dart
│ │ └── usecase
│ │ ├── article_use_case.dart
│ │ ├── article_use_case_impl.dart
│ │ └── base
│ │ └── base_use_case.dart
├── pubspec.lock
└── pubspec.yaml
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Podfile
├── Podfile.lock
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
└── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-1024x1024@1x.png
│ │ ├── 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-83.5x83.5@2x.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── Runner-Bridging-Header.h
├── lib
└── main.dart
├── local.properties
├── presentation
├── .gitignore
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── assets
│ └── placeholder_image.jpeg
├── lib
│ ├── presentation.dart
│ └── src
│ │ ├── common
│ │ ├── constants
│ │ │ ├── app_strings.dart
│ │ │ └── assets.dart
│ │ └── routes
│ │ │ ├── router.dart
│ │ │ └── router.gr.dart
│ │ ├── di
│ │ ├── locator.config.dart
│ │ └── locator.dart
│ │ └── features
│ │ ├── articles
│ │ ├── details
│ │ │ ├── article_detail_screen.dart
│ │ │ └── article_detail_view_model.dart
│ │ └── list
│ │ │ ├── article_list_screen.dart
│ │ │ └── article_list_view_model.dart
│ │ └── login
│ │ ├── login_screen.dart
│ │ └── login_view_model.dart
├── pubspec.lock
└── pubspec.yaml
├── pubspec.lock
└── pubspec.yaml
/.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 |
--------------------------------------------------------------------------------
/.gradle/6.1.1/executionHistory/executionHistory.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GeekySingh/flutter_clean_architecture/1840e430863cdd144caff8194d5499837055b51f/.gradle/6.1.1/executionHistory/executionHistory.lock
--------------------------------------------------------------------------------
/.gradle/6.1.1/fileChanges/last-build.bin:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gradle/6.1.1/fileHashes/fileHashes.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GeekySingh/flutter_clean_architecture/1840e430863cdd144caff8194d5499837055b51f/.gradle/6.1.1/fileHashes/fileHashes.lock
--------------------------------------------------------------------------------
/.gradle/6.1.1/gc.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GeekySingh/flutter_clean_architecture/1840e430863cdd144caff8194d5499837055b51f/.gradle/6.1.1/gc.properties
--------------------------------------------------------------------------------
/.gradle/buildOutputCleanup/buildOutputCleanup.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GeekySingh/flutter_clean_architecture/1840e430863cdd144caff8194d5499837055b51f/.gradle/buildOutputCleanup/buildOutputCleanup.lock
--------------------------------------------------------------------------------
/.gradle/buildOutputCleanup/cache.properties:
--------------------------------------------------------------------------------
1 | #Tue Apr 06 18:26:45 IST 2021
2 | gradle.version=6.1.1
3 |
--------------------------------------------------------------------------------
/.gradle/checksums/checksums.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GeekySingh/flutter_clean_architecture/1840e430863cdd144caff8194d5499837055b51f/.gradle/checksums/checksums.lock
--------------------------------------------------------------------------------
/.gradle/vcs-1/gc.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GeekySingh/flutter_clean_architecture/1840e430863cdd144caff8194d5499837055b51f/.gradle/vcs-1/gc.properties
--------------------------------------------------------------------------------
/.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: 9b2d32b605630f28625709ebd9d78ab3016b2bf6
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Flutter Clean Architecture
2 |
3 | Guide to design Flutter application using Clean Architecture. Here is the detailed guide on Medium https://geekysingh.medium.com/clean-architecture-for-enterprise-flutter-application-dc254a71059
4 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 29
30 |
31 | sourceSets {
32 | main.java.srcDirs += 'src/main/kotlin'
33 | }
34 |
35 | lintOptions {
36 | disable 'InvalidPackage'
37 | }
38 |
39 | defaultConfig {
40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
41 | applicationId "com.geekysingh.flutter_clean_architecture"
42 | minSdkVersion 16
43 | targetSdkVersion 29
44 | versionCode flutterVersionCode.toInteger()
45 | versionName flutterVersionName
46 | }
47 |
48 | buildTypes {
49 | release {
50 | // TODO: Add your own signing config for the release build.
51 | // Signing with the debug keys for now, so `flutter run --release` works.
52 | signingConfig signingConfigs.debug
53 | }
54 | }
55 | }
56 |
57 | flutter {
58 | source '../..'
59 | }
60 |
61 | dependencies {
62 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
63 | }
64 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
8 |
12 |
19 |
23 |
27 |
32 |
36 |
37 |
38 |
39 |
40 |
41 |
43 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/geekysingh/flutter_clean_architecture/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.geekysingh.flutter_clean_architecture
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GeekySingh/flutter_clean_architecture/1840e430863cdd144caff8194d5499837055b51f/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GeekySingh/flutter_clean_architecture/1840e430863cdd144caff8194d5499837055b51f/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GeekySingh/flutter_clean_architecture/1840e430863cdd144caff8194d5499837055b51f/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GeekySingh/flutter_clean_architecture/1840e430863cdd144caff8194d5499837055b51f/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GeekySingh/flutter_clean_architecture/1840e430863cdd144caff8194d5499837055b51f/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.3.50'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.5.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | jcenter()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 | android.enableR8=true
5 |
--------------------------------------------------------------------------------
/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-5.6.2-all.zip
7 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/core/.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/app.flx
64 | **/ios/Flutter/app.zip
65 | **/ios/Flutter/flutter_assets/
66 | **/ios/Flutter/flutter_export_environment.sh
67 | **/ios/ServiceDefinitions.json
68 | **/ios/Runner/GeneratedPluginRegistrant.*
69 |
70 | # Exceptions to above rules.
71 | !**/ios/**/default.mode1v3
72 | !**/ios/**/default.mode2v3
73 | !**/ios/**/default.pbxuser
74 | !**/ios/**/default.perspectivev3
75 |
--------------------------------------------------------------------------------
/core/.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: 9b2d32b605630f28625709ebd9d78ab3016b2bf6
8 | channel: stable
9 |
10 | project_type: package
11 |
--------------------------------------------------------------------------------
/core/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [0.0.1] - TODO: Add release date.
2 |
3 | * TODO: Describe initial release.
4 |
--------------------------------------------------------------------------------
/core/LICENSE:
--------------------------------------------------------------------------------
1 | TODO: Add your license here.
2 |
--------------------------------------------------------------------------------
/core/README.md:
--------------------------------------------------------------------------------
1 | # core
2 |
3 | A new Flutter package.
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 |
--------------------------------------------------------------------------------
/core/lib/common/status.dart:
--------------------------------------------------------------------------------
1 | enum Status {LOADING, SUCCESS, ERROR}
--------------------------------------------------------------------------------
/core/lib/core.dart:
--------------------------------------------------------------------------------
1 | import 'package:auto_route/auto_route.dart';
2 | import 'package:core/src/di/locator.dart';
3 |
4 | class Core {
5 | static void init() {
6 | /// setup required locators for core module
7 | setupLocator();
8 | }
9 |
10 | static RootStackRouter routeBuilder(RootStackRouter router) {
11 | locator.registerLazySingleton(() => router);
12 | return router;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/core/lib/core/core_screen.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:stacked/stacked.dart';
3 |
4 | import 'core_view_model.dart';
5 |
6 | abstract class CoreScreen extends ViewModelBuilderWidget {
7 |
8 | }
--------------------------------------------------------------------------------
/core/lib/core/core_view_model.dart:
--------------------------------------------------------------------------------
1 |
2 |
3 | import 'package:core/common/status.dart';
4 | import 'package:core/service/navigation_service.dart';
5 | import 'package:core/src/di/locator.dart';
6 | import 'package:stacked/stacked.dart';
7 |
8 | abstract class CoreViewModel extends BaseViewModel {
9 |
10 | final NavigationService navigationService = locator();
11 |
12 | late Status _status;
13 | Status get status => _status;
14 |
15 | void loading() {
16 | _status = Status.LOADING;
17 | setBusy(true);
18 | }
19 |
20 | void loaded(bool success) {
21 | _status = success ? Status.SUCCESS : Status.ERROR;
22 | setBusy(false);
23 | setError(success ? null : true);
24 | }
25 |
26 | }
--------------------------------------------------------------------------------
/core/lib/service/dialog_service.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:adaptive_dialog/adaptive_dialog.dart';
3 | import 'package:auto_route/auto_route.dart';
4 | import 'package:flutter/widgets.dart';
5 | import 'package:injectable/injectable.dart';
6 |
7 | @lazySingleton
8 | class DialogService {
9 |
10 | final StackRouter _router;
11 | DialogService(this._router);
12 |
13 | BuildContext _getSafeContext() {
14 | final context = _router.navigatorKey.currentContext;
15 | return context != null ? context : throw ('Have you forgot to setup routes?');
16 | }
17 |
18 | Future error({required String title, required String message}) {
19 | return showOkAlertDialog(
20 | context: _getSafeContext(),
21 | title: title,
22 | message: message);
23 | }
24 |
25 | Future ask({required String title, required String message, required String positiveButton, required String negativeButton}) {
26 | return showOkCancelAlertDialog(
27 | context: _getSafeContext(),
28 | title: title,
29 | message: message,
30 | okLabel: positiveButton,
31 | cancelLabel: negativeButton);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/core/lib/service/navigation_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:auto_route/auto_route.dart';
2 | import 'package:injectable/injectable.dart';
3 |
4 | /// Singleton navigation service used for navigation between the screens.
5 | /// This service allows navigation from viewmodel without requiring the context
6 | /// details from the widget.
7 | @lazySingleton
8 | class NavigationService {
9 |
10 | final StackRouter _router;
11 | NavigationService(this._router);
12 |
13 | Future push(PageRouteInfo routeInfo) async {
14 | try {
15 | return _router.push(routeInfo);
16 | } on Exception catch (e) {
17 | print('Exception occurred in navigateTo: $e');
18 | }
19 | }
20 |
21 | Future popAndPush(PageRouteInfo routeInfo) async {
22 | try {
23 | return _router.popAndPush(routeInfo);
24 | } on Exception catch (e) {
25 | print('Exception occurred in navigateTo: $e');
26 | }
27 | }
28 |
29 | Future pushAndRemoveUntil(PageRouteInfo routeInfo) async {
30 | try {
31 | return _router.pushAndRemoveUntil(routeInfo,
32 | predicate: (route) => route.isFirst);
33 | } on Exception catch (e) {
34 | print('Exception occurred in navigateTo: $e');
35 | }
36 | }
37 |
38 | Future pop() {
39 | try {
40 | return _router.pop();
41 | } on Exception catch (e) {
42 | print('Exception occurred in pop: $e');
43 | return Future.value(false);
44 | }
45 | }
46 |
47 | void popToRoot() {
48 | try {
49 | return _router.popUntil((route) => route.isFirst);
50 | } on Exception catch (e) {
51 | print('Exception occurred in pop: $e');
52 | }
53 | }
54 |
55 | // Future push(String routeName, [Object? arguments]) async {
56 | // try {
57 | // return ExtendedNavigator?.root?.push(routeName, arguments: arguments);
58 | // } on Exception catch (e) {
59 | // print('Exception occurred in navigateTo: $e');
60 | // }
61 | // }
62 | //
63 | // Future popAndPush(String routeName, [Object? arguments]) async {
64 | // try {
65 | // return ExtendedNavigator?.root?.popAndPush(routeName, arguments: arguments);
66 | // } on Exception catch (e) {
67 | // print('Exception occurred in navigateTo: $e');
68 | // }
69 | // }
70 | //
71 | // Future pushAndRemoveUntil(String routeName, [Object? arguments]) async {
72 | // try {
73 | // return ExtendedNavigator?.root?.pushAndRemoveUntil(
74 | // routeName, (route) => route.isFirst, arguments: arguments);
75 | // } on Exception catch (e) {
76 | // print('Exception occurred in navigateTo: $e');
77 | // }
78 | // }
79 | //
80 | // void pop([Object? arguments]) {
81 | // try {
82 | // return ExtendedNavigator?.root?.pop(arguments);
83 | // } on Exception catch (e) {
84 | // print('Exception occurred in pop: $e');
85 | // }
86 | // }
87 | //
88 | // void popToRoot() {
89 | // try {
90 | // return ExtendedNavigator?.root?.popUntil((route) => route.isFirst);
91 | // } on Exception catch (e) {
92 | // print('Exception occurred in pop: $e');
93 | // }
94 | // }
95 | }
--------------------------------------------------------------------------------
/core/lib/service/snackbar_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:auto_route/auto_route.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter/widgets.dart';
4 | import 'package:injectable/injectable.dart';
5 |
6 | @lazySingleton
7 | class SnackbarService {
8 |
9 | final StackRouter _router;
10 | SnackbarService(this._router);
11 |
12 | BuildContext _getSafeContext() {
13 | final context = _router.navigatorKey.currentContext;
14 | return context != null
15 | ? context
16 | : throw ('Have you forgot to setup routes?');
17 | }
18 |
19 | void show(String message, {SnackBarAction? action}) {
20 | final snackBar = SnackBar(content: Text(message), action: action);
21 | ScaffoldMessenger.of(_getSafeContext()).showSnackBar(snackBar);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/core/lib/service/toast_service.dart:
--------------------------------------------------------------------------------
1 | // ignore: import_of_legacy_library_into_null_safe
2 | import 'package:flutter_flexible_toast/flutter_flexible_toast.dart';
3 | import 'package:injectable/injectable.dart';
4 |
5 | @lazySingleton
6 | class ToastService {
7 |
8 | show(String message) {
9 | FlutterFlexibleToast.showToast(
10 | message: message, radius: 8);
11 | }
12 |
13 | showInCenter(String message) {
14 | FlutterFlexibleToast.showToast(
15 | message: message,
16 | radius: 8,
17 | toastGravity: ToastGravity.CENTER);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/core/lib/src/di/locator.config.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | // **************************************************************************
4 | // InjectableConfigGenerator
5 | // **************************************************************************
6 |
7 | import 'package:auto_route/auto_route.dart' as _i4;
8 | import 'package:get_it/get_it.dart' as _i1;
9 | import 'package:injectable/injectable.dart' as _i2;
10 |
11 | import '../../service/dialog_service.dart' as _i3;
12 | import '../../service/navigation_service.dart' as _i5;
13 | import '../../service/snackbar_service.dart' as _i6;
14 | import '../../service/toast_service.dart'
15 | as _i7; // ignore_for_file: unnecessary_lambdas
16 |
17 | // ignore_for_file: lines_longer_than_80_chars
18 | /// initializes the registration of provided dependencies inside of [GetIt]
19 | _i1.GetIt $initGetIt(_i1.GetIt get,
20 | {String? environment, _i2.EnvironmentFilter? environmentFilter}) {
21 | final gh = _i2.GetItHelper(get, environment, environmentFilter);
22 | gh.lazySingleton<_i3.DialogService>(
23 | () => _i3.DialogService(get<_i4.StackRouter>()));
24 | gh.lazySingleton<_i5.NavigationService>(
25 | () => _i5.NavigationService(get<_i4.StackRouter>()));
26 | gh.lazySingleton<_i6.SnackbarService>(
27 | () => _i6.SnackbarService(get<_i4.StackRouter>()));
28 | gh.lazySingleton<_i7.ToastService>(() => _i7.ToastService());
29 | return get;
30 | }
31 |
--------------------------------------------------------------------------------
/core/lib/src/di/locator.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:get_it/get_it.dart';
3 | import 'package:injectable/injectable.dart';
4 |
5 | import 'locator.config.dart';
6 |
7 | final locator = GetIt.instance..allowReassignment = true;
8 |
9 | @injectableInit
10 | void setupLocator() {
11 | _init(locator);
12 | $initGetIt(locator);
13 | }
14 |
15 | void _init(GetIt locator) {
16 |
17 | }
--------------------------------------------------------------------------------
/core/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | _fe_analyzer_shared:
5 | dependency: transitive
6 | description:
7 | name: _fe_analyzer_shared
8 | url: "https://pub.dartlang.org"
9 | source: hosted
10 | version: "12.0.0"
11 | adaptive_dialog:
12 | dependency: "direct main"
13 | description:
14 | name: adaptive_dialog
15 | url: "https://pub.dartlang.org"
16 | source: hosted
17 | version: "0.10.0+5"
18 | analyzer:
19 | dependency: transitive
20 | description:
21 | name: analyzer
22 | url: "https://pub.dartlang.org"
23 | source: hosted
24 | version: "0.40.6"
25 | animations:
26 | dependency: transitive
27 | description:
28 | name: animations
29 | url: "https://pub.dartlang.org"
30 | source: hosted
31 | version: "2.0.0"
32 | args:
33 | dependency: transitive
34 | description:
35 | name: args
36 | url: "https://pub.dartlang.org"
37 | source: hosted
38 | version: "1.6.0"
39 | async:
40 | dependency: transitive
41 | description:
42 | name: async
43 | url: "https://pub.dartlang.org"
44 | source: hosted
45 | version: "2.5.0"
46 | auto_route:
47 | dependency: "direct main"
48 | description:
49 | name: auto_route
50 | url: "https://pub.dartlang.org"
51 | source: hosted
52 | version: "1.0.2"
53 | auto_route_generator:
54 | dependency: "direct dev"
55 | description:
56 | name: auto_route_generator
57 | url: "https://pub.dartlang.org"
58 | source: hosted
59 | version: "1.0.0-beta.11"
60 | boolean_selector:
61 | dependency: transitive
62 | description:
63 | name: boolean_selector
64 | url: "https://pub.dartlang.org"
65 | source: hosted
66 | version: "2.1.0"
67 | build:
68 | dependency: transitive
69 | description:
70 | name: build
71 | url: "https://pub.dartlang.org"
72 | source: hosted
73 | version: "1.6.2"
74 | build_config:
75 | dependency: transitive
76 | description:
77 | name: build_config
78 | url: "https://pub.dartlang.org"
79 | source: hosted
80 | version: "0.4.5"
81 | build_daemon:
82 | dependency: transitive
83 | description:
84 | name: build_daemon
85 | url: "https://pub.dartlang.org"
86 | source: hosted
87 | version: "2.1.7"
88 | build_resolvers:
89 | dependency: transitive
90 | description:
91 | name: build_resolvers
92 | url: "https://pub.dartlang.org"
93 | source: hosted
94 | version: "1.5.3"
95 | build_runner:
96 | dependency: "direct dev"
97 | description:
98 | name: build_runner
99 | url: "https://pub.dartlang.org"
100 | source: hosted
101 | version: "1.11.1"
102 | build_runner_core:
103 | dependency: transitive
104 | description:
105 | name: build_runner_core
106 | url: "https://pub.dartlang.org"
107 | source: hosted
108 | version: "6.1.7"
109 | built_collection:
110 | dependency: transitive
111 | description:
112 | name: built_collection
113 | url: "https://pub.dartlang.org"
114 | source: hosted
115 | version: "4.3.2"
116 | built_value:
117 | dependency: transitive
118 | description:
119 | name: built_value
120 | url: "https://pub.dartlang.org"
121 | source: hosted
122 | version: "7.1.0"
123 | characters:
124 | dependency: transitive
125 | description:
126 | name: characters
127 | url: "https://pub.dartlang.org"
128 | source: hosted
129 | version: "1.1.0"
130 | charcode:
131 | dependency: transitive
132 | description:
133 | name: charcode
134 | url: "https://pub.dartlang.org"
135 | source: hosted
136 | version: "1.2.0"
137 | checked_yaml:
138 | dependency: transitive
139 | description:
140 | name: checked_yaml
141 | url: "https://pub.dartlang.org"
142 | source: hosted
143 | version: "1.0.4"
144 | cli_util:
145 | dependency: transitive
146 | description:
147 | name: cli_util
148 | url: "https://pub.dartlang.org"
149 | source: hosted
150 | version: "0.2.0"
151 | clock:
152 | dependency: transitive
153 | description:
154 | name: clock
155 | url: "https://pub.dartlang.org"
156 | source: hosted
157 | version: "1.1.0"
158 | code_builder:
159 | dependency: transitive
160 | description:
161 | name: code_builder
162 | url: "https://pub.dartlang.org"
163 | source: hosted
164 | version: "3.7.0"
165 | collection:
166 | dependency: transitive
167 | description:
168 | name: collection
169 | url: "https://pub.dartlang.org"
170 | source: hosted
171 | version: "1.15.0"
172 | connectivity:
173 | dependency: "direct main"
174 | description:
175 | name: connectivity
176 | url: "https://pub.dartlang.org"
177 | source: hosted
178 | version: "2.0.2"
179 | connectivity_for_web:
180 | dependency: transitive
181 | description:
182 | name: connectivity_for_web
183 | url: "https://pub.dartlang.org"
184 | source: hosted
185 | version: "0.3.1+4"
186 | connectivity_macos:
187 | dependency: transitive
188 | description:
189 | name: connectivity_macos
190 | url: "https://pub.dartlang.org"
191 | source: hosted
192 | version: "0.1.0+7"
193 | connectivity_platform_interface:
194 | dependency: transitive
195 | description:
196 | name: connectivity_platform_interface
197 | url: "https://pub.dartlang.org"
198 | source: hosted
199 | version: "1.0.6"
200 | convert:
201 | dependency: transitive
202 | description:
203 | name: convert
204 | url: "https://pub.dartlang.org"
205 | source: hosted
206 | version: "2.1.1"
207 | crypto:
208 | dependency: transitive
209 | description:
210 | name: crypto
211 | url: "https://pub.dartlang.org"
212 | source: hosted
213 | version: "2.1.5"
214 | dart_style:
215 | dependency: transitive
216 | description:
217 | name: dart_style
218 | url: "https://pub.dartlang.org"
219 | source: hosted
220 | version: "1.3.10"
221 | fake_async:
222 | dependency: transitive
223 | description:
224 | name: fake_async
225 | url: "https://pub.dartlang.org"
226 | source: hosted
227 | version: "1.2.0"
228 | file:
229 | dependency: transitive
230 | description:
231 | name: file
232 | url: "https://pub.dartlang.org"
233 | source: hosted
234 | version: "5.2.1"
235 | fixnum:
236 | dependency: transitive
237 | description:
238 | name: fixnum
239 | url: "https://pub.dartlang.org"
240 | source: hosted
241 | version: "0.10.11"
242 | flutter:
243 | dependency: "direct main"
244 | description: flutter
245 | source: sdk
246 | version: "0.0.0"
247 | flutter_flexible_toast:
248 | dependency: "direct main"
249 | description:
250 | name: flutter_flexible_toast
251 | url: "https://pub.dartlang.org"
252 | source: hosted
253 | version: "0.1.4"
254 | flutter_test:
255 | dependency: "direct dev"
256 | description: flutter
257 | source: sdk
258 | version: "0.0.0"
259 | flutter_web_plugins:
260 | dependency: transitive
261 | description: flutter
262 | source: sdk
263 | version: "0.0.0"
264 | get_it:
265 | dependency: "direct main"
266 | description:
267 | name: get_it
268 | url: "https://pub.dartlang.org"
269 | source: hosted
270 | version: "6.0.0"
271 | glob:
272 | dependency: transitive
273 | description:
274 | name: glob
275 | url: "https://pub.dartlang.org"
276 | source: hosted
277 | version: "1.2.0"
278 | graphs:
279 | dependency: transitive
280 | description:
281 | name: graphs
282 | url: "https://pub.dartlang.org"
283 | source: hosted
284 | version: "0.2.0"
285 | http_multi_server:
286 | dependency: transitive
287 | description:
288 | name: http_multi_server
289 | url: "https://pub.dartlang.org"
290 | source: hosted
291 | version: "2.2.0"
292 | http_parser:
293 | dependency: transitive
294 | description:
295 | name: http_parser
296 | url: "https://pub.dartlang.org"
297 | source: hosted
298 | version: "3.1.4"
299 | injectable:
300 | dependency: "direct main"
301 | description:
302 | name: injectable
303 | url: "https://pub.dartlang.org"
304 | source: hosted
305 | version: "1.2.2"
306 | injectable_generator:
307 | dependency: "direct dev"
308 | description:
309 | name: injectable_generator
310 | url: "https://pub.dartlang.org"
311 | source: hosted
312 | version: "1.1.2"
313 | intl:
314 | dependency: transitive
315 | description:
316 | name: intl
317 | url: "https://pub.dartlang.org"
318 | source: hosted
319 | version: "0.16.1"
320 | io:
321 | dependency: transitive
322 | description:
323 | name: io
324 | url: "https://pub.dartlang.org"
325 | source: hosted
326 | version: "0.3.5"
327 | js:
328 | dependency: transitive
329 | description:
330 | name: js
331 | url: "https://pub.dartlang.org"
332 | source: hosted
333 | version: "0.6.3"
334 | json_annotation:
335 | dependency: transitive
336 | description:
337 | name: json_annotation
338 | url: "https://pub.dartlang.org"
339 | source: hosted
340 | version: "3.1.1"
341 | logger:
342 | dependency: "direct main"
343 | description:
344 | name: logger
345 | url: "https://pub.dartlang.org"
346 | source: hosted
347 | version: "1.0.0"
348 | logging:
349 | dependency: transitive
350 | description:
351 | name: logging
352 | url: "https://pub.dartlang.org"
353 | source: hosted
354 | version: "0.11.4"
355 | matcher:
356 | dependency: transitive
357 | description:
358 | name: matcher
359 | url: "https://pub.dartlang.org"
360 | source: hosted
361 | version: "0.12.10"
362 | meta:
363 | dependency: transitive
364 | description:
365 | name: meta
366 | url: "https://pub.dartlang.org"
367 | source: hosted
368 | version: "1.3.0"
369 | mime:
370 | dependency: transitive
371 | description:
372 | name: mime
373 | url: "https://pub.dartlang.org"
374 | source: hosted
375 | version: "0.9.7"
376 | nested:
377 | dependency: transitive
378 | description:
379 | name: nested
380 | url: "https://pub.dartlang.org"
381 | source: hosted
382 | version: "1.0.0"
383 | node_interop:
384 | dependency: transitive
385 | description:
386 | name: node_interop
387 | url: "https://pub.dartlang.org"
388 | source: hosted
389 | version: "1.2.1"
390 | node_io:
391 | dependency: transitive
392 | description:
393 | name: node_io
394 | url: "https://pub.dartlang.org"
395 | source: hosted
396 | version: "1.2.0"
397 | package_config:
398 | dependency: transitive
399 | description:
400 | name: package_config
401 | url: "https://pub.dartlang.org"
402 | source: hosted
403 | version: "1.9.3"
404 | path:
405 | dependency: transitive
406 | description:
407 | name: path
408 | url: "https://pub.dartlang.org"
409 | source: hosted
410 | version: "1.8.0"
411 | pedantic:
412 | dependency: transitive
413 | description:
414 | name: pedantic
415 | url: "https://pub.dartlang.org"
416 | source: hosted
417 | version: "1.9.2"
418 | plugin_platform_interface:
419 | dependency: transitive
420 | description:
421 | name: plugin_platform_interface
422 | url: "https://pub.dartlang.org"
423 | source: hosted
424 | version: "1.0.3"
425 | pool:
426 | dependency: transitive
427 | description:
428 | name: pool
429 | url: "https://pub.dartlang.org"
430 | source: hosted
431 | version: "1.4.0"
432 | provider:
433 | dependency: transitive
434 | description:
435 | name: provider
436 | url: "https://pub.dartlang.org"
437 | source: hosted
438 | version: "5.0.0"
439 | pub_semver:
440 | dependency: transitive
441 | description:
442 | name: pub_semver
443 | url: "https://pub.dartlang.org"
444 | source: hosted
445 | version: "1.4.4"
446 | pubspec_parse:
447 | dependency: transitive
448 | description:
449 | name: pubspec_parse
450 | url: "https://pub.dartlang.org"
451 | source: hosted
452 | version: "0.1.8"
453 | quiver:
454 | dependency: transitive
455 | description:
456 | name: quiver
457 | url: "https://pub.dartlang.org"
458 | source: hosted
459 | version: "2.1.5"
460 | shelf:
461 | dependency: transitive
462 | description:
463 | name: shelf
464 | url: "https://pub.dartlang.org"
465 | source: hosted
466 | version: "0.7.9"
467 | shelf_web_socket:
468 | dependency: transitive
469 | description:
470 | name: shelf_web_socket
471 | url: "https://pub.dartlang.org"
472 | source: hosted
473 | version: "0.2.4+1"
474 | sky_engine:
475 | dependency: transitive
476 | description: flutter
477 | source: sdk
478 | version: "0.0.99"
479 | source_gen:
480 | dependency: transitive
481 | description:
482 | name: source_gen
483 | url: "https://pub.dartlang.org"
484 | source: hosted
485 | version: "0.9.10+2"
486 | source_span:
487 | dependency: transitive
488 | description:
489 | name: source_span
490 | url: "https://pub.dartlang.org"
491 | source: hosted
492 | version: "1.8.0"
493 | stack_trace:
494 | dependency: transitive
495 | description:
496 | name: stack_trace
497 | url: "https://pub.dartlang.org"
498 | source: hosted
499 | version: "1.10.0"
500 | stacked:
501 | dependency: "direct main"
502 | description:
503 | name: stacked
504 | url: "https://pub.dartlang.org"
505 | source: hosted
506 | version: "2.0.2"
507 | stream_channel:
508 | dependency: transitive
509 | description:
510 | name: stream_channel
511 | url: "https://pub.dartlang.org"
512 | source: hosted
513 | version: "2.1.0"
514 | stream_transform:
515 | dependency: transitive
516 | description:
517 | name: stream_transform
518 | url: "https://pub.dartlang.org"
519 | source: hosted
520 | version: "1.2.0"
521 | string_scanner:
522 | dependency: transitive
523 | description:
524 | name: string_scanner
525 | url: "https://pub.dartlang.org"
526 | source: hosted
527 | version: "1.1.0"
528 | term_glyph:
529 | dependency: transitive
530 | description:
531 | name: term_glyph
532 | url: "https://pub.dartlang.org"
533 | source: hosted
534 | version: "1.2.0"
535 | test_api:
536 | dependency: transitive
537 | description:
538 | name: test_api
539 | url: "https://pub.dartlang.org"
540 | source: hosted
541 | version: "0.2.19"
542 | timing:
543 | dependency: transitive
544 | description:
545 | name: timing
546 | url: "https://pub.dartlang.org"
547 | source: hosted
548 | version: "0.1.1+3"
549 | typed_data:
550 | dependency: transitive
551 | description:
552 | name: typed_data
553 | url: "https://pub.dartlang.org"
554 | source: hosted
555 | version: "1.3.0"
556 | vector_math:
557 | dependency: transitive
558 | description:
559 | name: vector_math
560 | url: "https://pub.dartlang.org"
561 | source: hosted
562 | version: "2.1.0"
563 | watcher:
564 | dependency: transitive
565 | description:
566 | name: watcher
567 | url: "https://pub.dartlang.org"
568 | source: hosted
569 | version: "0.9.7+15"
570 | web_socket_channel:
571 | dependency: transitive
572 | description:
573 | name: web_socket_channel
574 | url: "https://pub.dartlang.org"
575 | source: hosted
576 | version: "1.2.0"
577 | yaml:
578 | dependency: transitive
579 | description:
580 | name: yaml
581 | url: "https://pub.dartlang.org"
582 | source: hosted
583 | version: "2.2.1"
584 | sdks:
585 | dart: ">=2.12.0 <3.0.0"
586 | flutter: ">=1.17.0"
587 |
--------------------------------------------------------------------------------
/core/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: core
2 | description: A new Flutter package.
3 | version: 0.0.1
4 | author: GeekySingh
5 | homepage: https://github.com/GeekySingh
6 | publish_to: none
7 |
8 | environment:
9 | sdk: ">=2.12.0 <3.0.0"
10 | flutter: ">=1.17.0"
11 |
12 | dependencies:
13 | flutter:
14 | sdk: flutter
15 |
16 | connectivity: ^2.0.2
17 | # state management
18 | stacked: ^2.0.2
19 | # navigation
20 | auto_route: ^1.0.2
21 | # logger
22 | logger: ^1.0.0
23 | # inversion of control
24 | get_it: ^6.0.0
25 | injectable: ^1.2.2
26 | # toast and dialog
27 | flutter_flexible_toast: ^0.1.4
28 | adaptive_dialog: ^0.10.0+5
29 |
30 | dev_dependencies:
31 | flutter_test:
32 | sdk: flutter
33 |
34 | build_runner:
35 | auto_route_generator:
36 | injectable_generator:
37 |
38 | # For information on the generic Dart part of this file, see the
39 | # following page: https://dart.dev/tools/pub/pubspec
40 |
41 | # The following section is specific to Flutter.
42 | flutter:
43 |
44 | # To add assets to your package, add an assets section, like this:
45 | # assets:
46 | # - images/a_dot_burr.jpeg
47 | # - images/a_dot_ham.jpeg
48 | #
49 | # For details regarding assets in packages, see
50 | # https://flutter.dev/assets-and-images/#from-packages
51 | #
52 | # An image asset can refer to one or more resolution-specific "variants", see
53 | # https://flutter.dev/assets-and-images/#resolution-aware.
54 |
55 | # To add custom fonts to your package, add a fonts section here,
56 | # in this "flutter" section. Each entry in this list should have a
57 | # "family" key with the font family name, and a "fonts" key with a
58 | # list giving the asset and other descriptors for the font. For
59 | # example:
60 | # fonts:
61 | # - family: Schyler
62 | # fonts:
63 | # - asset: fonts/Schyler-Regular.ttf
64 | # - asset: fonts/Schyler-Italic.ttf
65 | # style: italic
66 | # - family: Trajan Pro
67 | # fonts:
68 | # - asset: fonts/TrajanPro.ttf
69 | # - asset: fonts/TrajanPro_Bold.ttf
70 | # weight: 700
71 | #
72 | # For details regarding fonts in packages, see
73 | # https://flutter.dev/custom-fonts/#from-packages
74 |
--------------------------------------------------------------------------------
/data/.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/app.flx
64 | **/ios/Flutter/app.zip
65 | **/ios/Flutter/flutter_assets/
66 | **/ios/Flutter/flutter_export_environment.sh
67 | **/ios/ServiceDefinitions.json
68 | **/ios/Runner/GeneratedPluginRegistrant.*
69 |
70 | # Exceptions to above rules.
71 | !**/ios/**/default.mode1v3
72 | !**/ios/**/default.mode2v3
73 | !**/ios/**/default.pbxuser
74 | !**/ios/**/default.perspectivev3
75 |
--------------------------------------------------------------------------------
/data/.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: 9b2d32b605630f28625709ebd9d78ab3016b2bf6
8 | channel: stable
9 |
10 | project_type: package
11 |
--------------------------------------------------------------------------------
/data/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [0.0.1] - TODO: Add release date.
2 |
3 | * TODO: Describe initial release.
4 |
--------------------------------------------------------------------------------
/data/LICENSE:
--------------------------------------------------------------------------------
1 | TODO: Add your license here.
2 |
--------------------------------------------------------------------------------
/data/README.md:
--------------------------------------------------------------------------------
1 | # data
2 |
3 | A new Flutter package.
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 |
--------------------------------------------------------------------------------
/data/lib/data.dart:
--------------------------------------------------------------------------------
1 | library data;
2 |
3 | import 'package:data/src/di/locator.dart';
4 |
5 | class Data {
6 | static void init() {
7 | /// setup required locators for data module
8 | setupLocator();
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/data/lib/src/common/constants.dart:
--------------------------------------------------------------------------------
1 |
2 | abstract class Constants {
3 |
4 | static const BASE_URL = "https://api.nytimes.com/svc/";
5 | static const API_KEY = "qtVlLSfH968rf6nd2tqbLPDnHnA7NLEb";
6 |
7 | }
--------------------------------------------------------------------------------
/data/lib/src/datasource/local/dao/article_dao.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:data/src/datasource/local/entity/article_entity.dart';
3 | import 'package:floor/floor.dart';
4 |
5 | const _tableName = 'ArticleEntity';
6 |
7 | @dao
8 | abstract class ArticleDao {
9 |
10 | @Query('select * FROM $_tableName')
11 | Future> getArticles();
12 |
13 | @Insert(onConflict: OnConflictStrategy.replace)
14 | Future saveArticles(List articles);
15 |
16 | @Query('select * from $_tableName where id = :id')
17 | Future getArticleById(int id);
18 | }
--------------------------------------------------------------------------------
/data/lib/src/datasource/local/db/app_database.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'dart:async';
3 |
4 | import 'package:data/src/datasource/local/dao/article_dao.dart';
5 | import 'package:data/src/datasource/local/entity/article_entity.dart';
6 | import 'package:floor/floor.dart';
7 |
8 | import 'package:sqflite/sqflite.dart' as sqflite;
9 |
10 | part 'app_database.g.dart'; // the generated code will be there
11 |
12 | @Database(version: 1, entities: [ArticleEntity])
13 | abstract class AppDatabase extends FloorDatabase {
14 |
15 | ArticleDao get articleDao;
16 |
17 | }
--------------------------------------------------------------------------------
/data/lib/src/datasource/local/db/app_database.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'app_database.dart';
4 |
5 | // **************************************************************************
6 | // FloorGenerator
7 | // **************************************************************************
8 |
9 | class $FloorAppDatabase {
10 | /// Creates a database builder for a persistent database.
11 | /// Once a database is built, you should keep a reference to it and re-use it.
12 | static _$AppDatabaseBuilder databaseBuilder(String name) =>
13 | _$AppDatabaseBuilder(name);
14 |
15 | /// Creates a database builder for an in memory database.
16 | /// Information stored in an in memory database disappears when the process is killed.
17 | /// Once a database is built, you should keep a reference to it and re-use it.
18 | static _$AppDatabaseBuilder inMemoryDatabaseBuilder() =>
19 | _$AppDatabaseBuilder(null);
20 | }
21 |
22 | class _$AppDatabaseBuilder {
23 | _$AppDatabaseBuilder(this.name);
24 |
25 | final String? name;
26 |
27 | final List _migrations = [];
28 |
29 | Callback? _callback;
30 |
31 | /// Adds migrations to the builder.
32 | _$AppDatabaseBuilder addMigrations(List migrations) {
33 | _migrations.addAll(migrations);
34 | return this;
35 | }
36 |
37 | /// Adds a database [Callback] to the builder.
38 | _$AppDatabaseBuilder addCallback(Callback callback) {
39 | _callback = callback;
40 | return this;
41 | }
42 |
43 | /// Creates the database and initializes it.
44 | Future build() async {
45 | final path = name != null
46 | ? await sqfliteDatabaseFactory.getDatabasePath(name!)
47 | : ':memory:';
48 | final database = _$AppDatabase();
49 | database.database = await database.open(
50 | path,
51 | _migrations,
52 | _callback,
53 | );
54 | return database;
55 | }
56 | }
57 |
58 | class _$AppDatabase extends AppDatabase {
59 | _$AppDatabase([StreamController? listener]) {
60 | changeListener = listener ?? StreamController.broadcast();
61 | }
62 |
63 | ArticleDao? _articleDaoInstance;
64 |
65 | Future open(String path, List migrations,
66 | [Callback? callback]) async {
67 | final databaseOptions = sqflite.OpenDatabaseOptions(
68 | version: 1,
69 | onConfigure: (database) async {
70 | await database.execute('PRAGMA foreign_keys = ON');
71 | },
72 | onOpen: (database) async {
73 | await callback?.onOpen?.call(database);
74 | },
75 | onUpgrade: (database, startVersion, endVersion) async {
76 | await MigrationAdapter.runMigrations(
77 | database, startVersion, endVersion, migrations);
78 |
79 | await callback?.onUpgrade?.call(database, startVersion, endVersion);
80 | },
81 | onCreate: (database, version) async {
82 | await database.execute(
83 | 'CREATE TABLE IF NOT EXISTS `ArticleEntity` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `description` TEXT NOT NULL, `imageUrl` TEXT NOT NULL, `articleUrl` TEXT NOT NULL, `date` TEXT NOT NULL, PRIMARY KEY (`id`))');
84 |
85 | await callback?.onCreate?.call(database, version);
86 | },
87 | );
88 | return sqfliteDatabaseFactory.openDatabase(path, options: databaseOptions);
89 | }
90 |
91 | @override
92 | ArticleDao get articleDao {
93 | return _articleDaoInstance ??= _$ArticleDao(database, changeListener);
94 | }
95 | }
96 |
97 | class _$ArticleDao extends ArticleDao {
98 | _$ArticleDao(this.database, this.changeListener)
99 | : _queryAdapter = QueryAdapter(database),
100 | _articleEntityInsertionAdapter = InsertionAdapter(
101 | database,
102 | 'ArticleEntity',
103 | (ArticleEntity item) => {
104 | 'id': item.id,
105 | 'title': item.title,
106 | 'description': item.description,
107 | 'imageUrl': item.imageUrl,
108 | 'articleUrl': item.articleUrl,
109 | 'date': item.date
110 | });
111 |
112 | final sqflite.DatabaseExecutor database;
113 |
114 | final StreamController changeListener;
115 |
116 | final QueryAdapter _queryAdapter;
117 |
118 | final InsertionAdapter _articleEntityInsertionAdapter;
119 |
120 | @override
121 | Future> getArticles() async {
122 | return _queryAdapter.queryList('select * FROM ArticleEntity',
123 | mapper: (Map row) => ArticleEntity(
124 | id: row['id'] as int,
125 | title: row['title'] as String,
126 | description: row['description'] as String,
127 | imageUrl: row['imageUrl'] as String,
128 | articleUrl: row['articleUrl'] as String,
129 | date: row['date'] as String));
130 | }
131 |
132 | @override
133 | Future getArticleById(int id) async {
134 | return _queryAdapter.query('select * from ArticleEntity where id = ?1',
135 | mapper: (Map row) => ArticleEntity(
136 | id: row['id'] as int,
137 | title: row['title'] as String,
138 | description: row['description'] as String,
139 | imageUrl: row['imageUrl'] as String,
140 | articleUrl: row['articleUrl'] as String,
141 | date: row['date'] as String),
142 | arguments: [id]);
143 | }
144 |
145 | @override
146 | Future saveArticles(List articles) async {
147 | await _articleEntityInsertionAdapter.insertList(
148 | articles, OnConflictStrategy.replace);
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/data/lib/src/datasource/local/entity/article_entity.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:floor/floor.dart';
3 |
4 | @entity
5 | class ArticleEntity {
6 |
7 | @primaryKey
8 | final int id;
9 | final String title;
10 | final String description;
11 | final String imageUrl;
12 | final String articleUrl;
13 | final String date;
14 |
15 | ArticleEntity({required this.id, required this.title, required this.description, required this.imageUrl, required this.articleUrl, required this.date});
16 | }
--------------------------------------------------------------------------------
/data/lib/src/datasource/remote/dto/article_response.dart:
--------------------------------------------------------------------------------
1 |
2 |
3 | import 'package:json_annotation/json_annotation.dart';
4 |
5 | part 'article_response.g.dart';
6 |
7 | @JsonSerializable()
8 | class ArticleResponse {
9 |
10 | @JsonKey(name: 'results')
11 | final List articles;
12 |
13 | ArticleResponse(this.articles);
14 |
15 | factory ArticleResponse.fromJson(Map json) =>
16 | _$ArticleResponseFromJson(json);
17 |
18 | Map toJson() => _$ArticleResponseToJson(this);
19 | }
20 |
21 | @JsonSerializable()
22 | class Article {
23 | final int id;
24 | final List media;
25 | @JsonKey(name: 'published_date')
26 | final String publishedDate;
27 | final String title;
28 | final String abstract;
29 | final String updated;
30 | final String url;
31 |
32 | Article(this.id, this.media, this.publishedDate, this.title, this.abstract,
33 | this.updated, this.url);
34 |
35 | factory Article.fromJson(Map json) =>
36 | _$ArticleFromJson(json);
37 |
38 | Map toJson() => _$ArticleToJson(this);
39 |
40 | }
41 |
42 | @JsonSerializable()
43 | class Media {
44 | @JsonKey(name: 'media-metadata')
45 | final List? mediaMetadata;
46 |
47 | Media(this.mediaMetadata);
48 |
49 | factory Media.fromJson(Map json) =>
50 | _$MediaFromJson(json);
51 |
52 | Map toJson() => _$MediaToJson(this);
53 | }
54 |
55 | @JsonSerializable()
56 | class MediaMetaData {
57 | final String url;
58 |
59 | MediaMetaData(this.url);
60 |
61 | factory MediaMetaData.fromJson(Map json) =>
62 | _$MediaMetaDataFromJson(json);
63 |
64 | Map toJson() => _$MediaMetaDataToJson(this);
65 | }
--------------------------------------------------------------------------------
/data/lib/src/datasource/remote/dto/article_response.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'article_response.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | ArticleResponse _$ArticleResponseFromJson(Map json) {
10 | return ArticleResponse(
11 | (json['results'] as List)
12 | .map((e) => Article.fromJson(e as Map))
13 | .toList(),
14 | );
15 | }
16 |
17 | Map _$ArticleResponseToJson(ArticleResponse instance) =>
18 | {
19 | 'results': instance.articles,
20 | };
21 |
22 | Article _$ArticleFromJson(Map json) {
23 | return Article(
24 | json['id'] as int,
25 | (json['media'] as List)
26 | .map((e) => Media.fromJson(e as Map))
27 | .toList(),
28 | json['published_date'] as String,
29 | json['title'] as String,
30 | json['abstract'] as String,
31 | json['updated'] as String,
32 | json['url'] as String,
33 | );
34 | }
35 |
36 | Map _$ArticleToJson(Article instance) => {
37 | 'id': instance.id,
38 | 'media': instance.media,
39 | 'published_date': instance.publishedDate,
40 | 'title': instance.title,
41 | 'abstract': instance.abstract,
42 | 'updated': instance.updated,
43 | 'url': instance.url,
44 | };
45 |
46 | Media _$MediaFromJson(Map json) {
47 | return Media(
48 | (json['media-metadata'] as List?)
49 | ?.map((e) => MediaMetaData.fromJson(e as Map))
50 | .toList(),
51 | );
52 | }
53 |
54 | Map _$MediaToJson(Media instance) => {
55 | 'media-metadata': instance.mediaMetadata,
56 | };
57 |
58 | MediaMetaData _$MediaMetaDataFromJson(Map json) {
59 | return MediaMetaData(
60 | json['url'] as String,
61 | );
62 | }
63 |
64 | Map _$MediaMetaDataToJson(MediaMetaData instance) =>
65 | {
66 | 'url': instance.url,
67 | };
68 |
--------------------------------------------------------------------------------
/data/lib/src/datasource/remote/service/article_service.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:data/src/common/constants.dart';
3 | import 'package:data/src/datasource/remote/dto/article_response.dart';
4 | import 'package:dio/dio.dart';
5 | import 'package:retrofit/retrofit.dart';
6 |
7 | part 'article_service.g.dart';
8 |
9 | @RestApi()
10 | abstract class ArticleService {
11 |
12 | factory ArticleService(Dio dio, {String baseUrl}) = _ArticleService;
13 |
14 | @GET("mostpopular/v2/mostviewed/all-sections/7.json?api-key=${Constants.API_KEY}")
15 | Future getArticles();
16 |
17 | }
--------------------------------------------------------------------------------
/data/lib/src/datasource/remote/service/article_service.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'article_service.dart';
4 |
5 | // **************************************************************************
6 | // RetrofitGenerator
7 | // **************************************************************************
8 |
9 | class _ArticleService implements ArticleService {
10 | _ArticleService(this._dio, {this.baseUrl});
11 |
12 | final Dio _dio;
13 |
14 | String? baseUrl;
15 |
16 | @override
17 | Future getArticles() async {
18 | const _extra = {};
19 | final queryParameters = {};
20 | final _data = {};
21 | final _result = await _dio.fetch