├── .fvm ├── flutter_sdk └── fvm_config.json ├── .fvmrc ├── .github └── workflows │ └── dart.yml ├── .gitignore ├── .metadata ├── .run ├── DEV.run.xml ├── MOCK.run.xml └── PROD.run.xml ├── Makefile ├── README.md ├── analysis_options.yaml ├── android ├── .gitignore ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── organization │ │ │ │ └── sample_project │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable-v21 │ │ │ └── launch_background.xml │ │ │ ├── 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-night │ │ │ └── styles.xml │ │ │ └── values │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── assets └── locales │ ├── en-US.json │ └── hi-IN.json ├── data ├── .gitignore ├── .metadata ├── README.md ├── analysis_options.yaml ├── lib │ ├── api_constants │ │ └── api_paths.dart │ ├── base │ │ └── base_repository.dart │ ├── config │ │ ├── app_config.dart │ │ ├── app_config_type.dart │ │ └── environment.dart │ ├── datasource │ │ ├── api_client │ │ │ ├── network_datasource.dart │ │ │ └── network_datasource_type.dart │ │ ├── local_database │ │ │ └── app_database.dart │ │ ├── shared_preference │ │ │ ├── local_datasource.dart │ │ │ └── local_datasource_type.dart │ │ └── translations │ │ │ └── translation_datasource.dart │ ├── di │ │ ├── data_injection.dart │ │ └── datasource_module.dart │ ├── mocks │ │ └── mocks.dart │ ├── models │ │ ├── app_multipart.dart │ │ └── reasponse_dto.dart │ ├── repositories │ │ ├── comments │ │ │ ├── comments_repository.dart │ │ │ └── comments_repository_type.dart │ │ ├── sections │ │ │ ├── sections_repository.dart │ │ │ └── sections_repository_type.dart │ │ └── tasks │ │ │ ├── tasks_repository.dart │ │ │ └── tasks_repository_type.dart │ └── utils │ │ ├── method_defination.dart │ │ └── platform_dependent.dart ├── pubspec.yaml └── test │ └── data_test.dart ├── domain ├── .gitignore ├── .metadata ├── README.md ├── analysis_options.yaml ├── lib │ ├── base │ │ ├── api_paths.dart │ │ └── error_response.dart │ ├── di │ │ └── domain_injection.dart │ ├── mocks.dart │ ├── model │ │ ├── comments │ │ │ ├── comment.dart │ │ │ ├── comment.g.dart │ │ │ ├── comments_response.dart │ │ │ └── comments_response.g.dart │ │ ├── sections │ │ │ ├── section.dart │ │ │ ├── section.g.dart │ │ │ ├── sections_response.dart │ │ │ └── sections_response.g.dart │ │ ├── tasks │ │ │ ├── task.dart │ │ │ ├── task.g.dart │ │ │ ├── tasks_response.dart │ │ │ └── tasks_response.g.dart │ │ └── users │ │ │ ├── user.dart │ │ │ ├── user.g.dart │ │ │ ├── users_response.dart │ │ │ └── users_response.g.dart │ ├── usecase │ │ └── kanban │ │ │ ├── kanban_usecase.dart │ │ │ └── kanban_usecase_type.dart │ └── util │ │ ├── validation │ │ ├── email_validator.dart │ │ ├── mobile_number_validator.dart │ │ ├── name_validator.dart │ │ ├── otp_validator.dart │ │ ├── password_validator.dart │ │ ├── referral_code_validator.dart │ │ ├── validation_facade.dart │ │ └── validation_facade_type.dart │ │ └── validator_mixin.dart ├── pubspec.yaml └── test │ └── domain_test.dart ├── environments ├── .env.dev ├── .env.prod ├── .gitignore ├── Makefile ├── lib │ └── env │ │ ├── env_dev.dart │ │ ├── env_dev.g.dart │ │ ├── env_prod.dart │ │ └── env_prod.g.dart ├── pubspec.yaml └── test │ └── env_test.dart ├── 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 ├── di │ └── AppConfigure.dart ├── entry_point │ ├── main_dev.dart │ ├── main_mock.dart │ ├── main_prod.dart │ └── my_app.dart ├── environment │ ├── development │ │ └── development_env.dart │ └── production │ │ └── production_env.dart ├── generated_plugin_registrant.dart ├── presentation │ ├── kanban_board │ │ ├── bloc │ │ │ ├── kanban_bloc.dart │ │ │ └── kanban_state.dart │ │ ├── kanban_screen.dart │ │ └── widgets │ │ │ ├── kanban_drag_target.dart │ │ │ └── kanban_draggable.dart │ └── splash │ │ └── splash_page.dart ├── router │ ├── gen_route.dart │ ├── named_route.dart │ ├── navigation_controller.dart │ └── routes.dart └── util │ ├── app_global.dart │ ├── app_mixin.dart │ ├── app_router.dart │ ├── assets │ ├── app_color.dart │ ├── app_locale.dart │ └── app_text.dart │ ├── connectivity_mixin.dart │ ├── constants.dart │ ├── navigation │ └── navigation_helper.dart │ ├── util.dart │ └── widget │ └── app_primary_button.dart ├── pubspec.yaml └── test └── widget_test.dart /.fvm/flutter_sdk: -------------------------------------------------------------------------------- 1 | /Users/Azlaan/fvm/versions/3.22.2 -------------------------------------------------------------------------------- /.fvm/fvm_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "flutterSdkVersion": "3.22.2" 3 | } -------------------------------------------------------------------------------- /.fvmrc: -------------------------------------------------------------------------------- 1 | { 2 | "flutter": "3.22.2", 3 | "flavors": {} 4 | } -------------------------------------------------------------------------------- /.github/workflows/dart.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | 6 | name: Dart 7 | 8 | on: 9 | push: 10 | branches: [ "development" ] 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v3 18 | 19 | - name: Install Flutter 20 | uses: britannio/action-install-flutter@v1.1 21 | 22 | - name: Install dependencies 23 | run: flutter pub get 24 | 25 | - name: Generate Files 26 | run: flutter pub run build_runner build --delete-conflicting-outputs 27 | 28 | - name: Build AAB 29 | run: flutter build appbundle --debug -t lib/entry_point/main_mock.dart 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | **/ios/Flutter/.last_build_id 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .packages 31 | .pub-cache/ 32 | .pub/ 33 | /build/ 34 | 35 | # Symbolication related 36 | app.*.symbols 37 | 38 | # Obfuscation related 39 | app.*.map.json 40 | 41 | # Android Studio will place build artifacts here 42 | /android/app/debug 43 | /android/app/profile 44 | /android/app/release 45 | pubspec.lock -------------------------------------------------------------------------------- /.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. 5 | 6 | version: 7 | revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 8 | channel: stable 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 17 | base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 18 | - platform: android 19 | create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 20 | base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 21 | - platform: ios 22 | create_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 23 | base_revision: b06b8b2710955028a6b562f5aa6fe62941d6febf 24 | 25 | # User provided section 26 | 27 | # List of Local paths (relative to this file) that should be 28 | # ignored by the migrate tool. 29 | # 30 | # Files that are not part of the templates will be ignored by default. 31 | unmanaged_files: 32 | - 'lib/main.dart' 33 | - 'ios/Runner.xcodeproj/project.pbxproj' 34 | -------------------------------------------------------------------------------- /.run/DEV.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.run/MOCK.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.run/PROD.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ### Makefile for tasks app ### 2 | 3 | SHELL := /bin/bash 4 | 5 | gen-f: ## Generate files 6 | flutter pub run build_runner build --delete-conflicting-outputs 7 | 8 | gen-domain-f: ## Generate files 9 | cd domain && flutter pub run build_runner build --delete-conflicting-outputs 10 | 11 | gen-data-f: ## Generate files 12 | cd data && flutter pub run build_runner build --delete-conflicting-outputs 13 | 14 | 15 | gen: ## Generate files 16 | fvm flutter pub run build_runner build --delete-conflicting-outputs 17 | 18 | gen-domain: ## Generate files 19 | cd domain && fvm flutter pub run build_runner build --delete-conflicting-outputs && cd .. 20 | 21 | gen-data: ## Generate files 22 | cd data && fvm flutter pub run build_runner build --delete-conflicting-outputs && cd .. 23 | 24 | app-setup: ## Setup fvm and get Dependencies 25 | dart pub global activate fvm 26 | fvm install 3.22.2 27 | fvm use 3.22.2 28 | make gen-env 29 | make fvm-get 30 | 31 | 32 | pub-get: ## Clean Pub Get 33 | make app-clean 34 | cd data && flutter pub get && flutter pub run build_runner build --delete-conflicting-outputs && cd .. 35 | cd domain && flutter pub get && flutter pub run build_runner build --delete-conflicting-outputs && cd .. 36 | flutter pub get && flutter pub run build_runner build --delete-conflicting-outputs 37 | 38 | app-clean: ## Clean Pub Get 39 | cd data && flutter clean && cd .. 40 | cd domain && flutter clean && cd .. 41 | flutter clean 42 | 43 | fvm-get: ## Clean Pub Get 44 | make fvm-clean 45 | cd data && fvm flutter pub get && fvm flutter pub run build_runner build --delete-conflicting-outputs && cd .. 46 | cd domain && fvm flutter pub get && fvm flutter pub run build_runner build --delete-conflicting-outputs && cd .. 47 | fvm flutter pub get && fvm flutter pub run build_runner build --delete-conflicting-outputs 48 | 49 | fvm-clean: ## Clean Pub Get 50 | cd data && fvm flutter clean && cd .. 51 | cd domain && fvm flutter clean && cd .. 52 | fvm flutter clean 53 | 54 | clean-pods: ## To cleat pods and install it again 55 | -rm ios/Podfile.lock 56 | fvm flutter precache --ios 57 | cd ios && pod cache clean --all && pod cache clean 'FortifySec' --all && pod repo update && pod install 58 | 59 | gen-env: ## Clean Pub Get 60 | -rm environments/lib/env/env_dev.g.dart 61 | -rm environments/lib/env/env_prod.g.dart 62 | cd environments && fvm flutter clean && fvm flutter pub get && fvm flutter pub run build_runner build --delete-conflicting-outputs && cd .. 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Kanban Taskmanager - by Azlaan Khan 2 | 3 | This app is a Todo Task manager app in KanBan form. 4 | I am using https://app.todoist.com/ 5 | I have created a project under this site and fetching its data to show in app 6 | All functionality is not yet implemented but is sufficient to understand. 7 | This project will demonstrate you the use of Clean Architecture with Bloc. 8 | 9 | ## Getting Started 10 | 11 | To run the project you need to configure with Flutter 3.22.2. 12 | I have created a Make file script for you, you can directly run those script or take a reference from it 13 | 14 | ### Steps To Run the Project 15 | 16 | - Setup Flutter 3.22.2 17 | - Setup FVM 18 | - Terminal Command: make app-setup 19 | - Dependencies Download: 20 | - With FVM 21 | - Terminal Command: make fvm-get 22 | - Without FVM 23 | - Terminal Command: make pub-get 24 | 25 | ### API Setup 26 | 27 | - Todo Api Developer console: 28 | - https://developer.todoist.com/rest/v2/#overview 29 | - To Create an app visit here: 30 | - https://developer.todoist.com/appconsole.html 31 | - After creating app copy Test Token and paste it inside 32 | 33 | ### Entry Point 34 | 35 | You can Run any of below: 36 | - entry_point/main_mock.dart 37 | - entry_point/main_dev.dart 38 | - entry_point/main_prod.dart 39 | 40 | ### Manual Commands Step by Step if you are not using make file commands 41 | - cd data && flutter clean && flutter pub get && cd .. 42 | - cd domain && flutter clean && flutter pub get && cd .. 43 | - flutter clean && flutter pub get 44 | - cd data && flutter pub run build_runner build --delete-conflicting-outputs && cd .. 45 | - cd domain && flutter pub run build_runner build --delete-conflicting-outputs && cd .. 46 | - flutter pub run build_runner build --delete-conflicting-outputs 47 | 48 | ### About Azlaan Khan 49 | Azlaan has been working in the IT industry since last 8 years. 50 | He has contributed in many apps of Different domains. 51 | Have skills to work in Almost any mobile technology and also sometimes work on backend techs. 52 | 53 | Linkedin: https://www.linkedin.com/in/azlaan-khan-74b615a5 54 | 55 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 27 | 28 | # Additional information about this file can be found at 29 | # https://dart.dev/guides/language/analysis-options 30 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 flutter.compileSdkVersion 30 | ndkVersion flutter.ndkVersion 31 | 32 | compileOptions { 33 | sourceCompatibility JavaVersion.VERSION_1_8 34 | targetCompatibility JavaVersion.VERSION_1_8 35 | } 36 | 37 | kotlinOptions { 38 | jvmTarget = '1.8' 39 | } 40 | 41 | sourceSets { 42 | main.java.srcDirs += 'src/main/kotlin' 43 | } 44 | 45 | defaultConfig { 46 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 47 | applicationId "com.organization.sample_project" 48 | // You can update the following values to match your application needs. 49 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. 50 | minSdkVersion flutter.minSdkVersion 51 | targetSdkVersion flutter.targetSdkVersion 52 | versionCode flutterVersionCode.toInteger() 53 | versionName flutterVersionName 54 | } 55 | 56 | buildTypes { 57 | release { 58 | // TODO: Add your own signing config for the release build. 59 | // Signing with the debug keys for now, so `flutter run --release` works. 60 | signingConfig signingConfigs.debug 61 | } 62 | } 63 | } 64 | 65 | flutter { 66 | source '../..' 67 | } 68 | 69 | dependencies { 70 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 71 | } 72 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 8 | 16 | 20 | 24 | 25 | 26 | 27 | 28 | 29 | 31 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/organization/sample_project/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.organization.sample_project 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /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/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.7.10' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.2.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 | } 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/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip 6 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /assets/locales/en-US.json: -------------------------------------------------------------------------------- 1 | { 2 | "app_name": "App Name", 3 | "language": "Language" 4 | } -------------------------------------------------------------------------------- /assets/locales/hi-IN.json: -------------------------------------------------------------------------------- 1 | { 2 | "app_name": "मेरा ऐप", 3 | "next": "अगला" 4 | } -------------------------------------------------------------------------------- /data/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | **/ios/Flutter/.last_build_id 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .packages 31 | .pub-cache/ 32 | .pub/ 33 | /build/ 34 | 35 | # Web related 36 | lib/generated_plugin_registrant.dart 37 | 38 | # Symbolication related 39 | app.*.symbols 40 | 41 | # Obfuscation related 42 | app.*.map.json 43 | 44 | # Android Studio will place build artifacts here 45 | /android/app/debug 46 | /android/app/profile 47 | /android/app/release 48 | 49 | # Ignored files 50 | .DS_Store 51 | .atom/ 52 | !.idea/ 53 | .idea/* 54 | !.idea/workspace.xml 55 | android/.idea 56 | .vscode/ 57 | .packages 58 | .pub/ 59 | .dart_tool/ 60 | flutter_export_environment.sh 61 | Podfile.lock 62 | Pods/ 63 | .symlinks/ 64 | **/Flutter/App.framework/ 65 | **/Flutter/Flutter.framework/ 66 | **/Flutter/Generated.xcconfig 67 | **/Flutter/flutter_assets/ 68 | ServiceDefinitions.json 69 | xcuserdata/ 70 | **/DerivedData/ 71 | local.properties 72 | keystore.properties 73 | .gradle/ 74 | gradlew 75 | gradlew.bat 76 | gradle-wrapper.jar 77 | .flutter-plugins-dependencies 78 | *.iml 79 | GeneratedPluginRegistrant.h 80 | GeneratedPluginRegistrant.m 81 | GeneratedPluginRegistrant.java 82 | build/ 83 | .flutter-plugins 84 | .project 85 | .classpath 86 | .settings 87 | 88 | coverage/ 89 | .last_build_id 90 | report.xml 91 | .fvm/flutter_sdk 92 | pubspec.lock 93 | */oss_licenses.g.dart -------------------------------------------------------------------------------- /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. 5 | 6 | version: 7 | revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 8 | channel: stable 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 17 | base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 18 | - platform: android 19 | create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 20 | base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 21 | - platform: ios 22 | create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 23 | base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 24 | 25 | # User provided section 26 | 27 | # List of Local paths (relative to this file) that should be 28 | # ignored by the migrate tool. 29 | # 30 | # Files that are not part of the templates will be ignored by default. 31 | unmanaged_files: 32 | - 'lib/main.dart' 33 | - 'ios/Runner.xcodeproj/project.pbxproj' 34 | -------------------------------------------------------------------------------- /data/README.md: -------------------------------------------------------------------------------- 1 | # data 2 | 3 | A new Flutter project. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) 13 | 14 | For help getting started with Flutter development, view the 15 | [online documentation](https://docs.flutter.dev/), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /data/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 27 | 28 | # Additional information about this file can be found at 29 | # https://dart.dev/guides/language/analysis-options 30 | -------------------------------------------------------------------------------- /data/lib/api_constants/api_paths.dart: -------------------------------------------------------------------------------- 1 | class ApiPaths { 2 | static String tasks = "/tasks"; 3 | static String sections = "/sections"; 4 | static String comments = "/comments"; 5 | } 6 | -------------------------------------------------------------------------------- /data/lib/base/base_repository.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_data/config/app_config_type.dart'; 2 | import 'package:azl_data/datasource/api_client/network_datasource.dart'; 3 | import 'package:azl_data/di/datasource_module.dart'; 4 | import 'package:azl_data/models/app_multipart.dart'; 5 | import 'package:azl_data/models/reasponse_dto.dart'; 6 | 7 | class BaseRepository with DatasourceModule { 8 | BaseRepository({required this.appConfig}); 9 | 10 | final AppConfigType appConfig; 11 | 12 | Future callGetApi( 13 | {required String url, 14 | Map? body, 15 | Map? queryParameter, 16 | Map? headers, 17 | required String apiPath}) async { 18 | headers = {}; 19 | ResponseDto response = await apiClient.apiRequest( 20 | url: url, 21 | method: RequestMethod.GET, 22 | body: body, 23 | queryParameter: queryParameter, 24 | headers: headers, 25 | apiPath: apiPath); 26 | return response; 27 | } 28 | 29 | Future callPostApi( 30 | {required String url, 31 | Map? body, 32 | Map? queryParameter, 33 | Map? headers, 34 | required String apiPath}) async { 35 | ResponseDto response = await apiClient.apiRequest( 36 | url: url, 37 | method: RequestMethod.POST, 38 | body: body, 39 | queryParameter: queryParameter, 40 | headers: headers, 41 | apiPath: apiPath); 42 | return response; 43 | } 44 | 45 | Future callDeleteApi( 46 | {required String url, 47 | required RequestMethod method, 48 | Map? body, 49 | Map? queryParameter, 50 | Map? headers, 51 | required String apiPath}) async { 52 | ResponseDto response = await apiClient.apiRequest( 53 | url: url, method: RequestMethod.DELETE, apiPath: apiPath); 54 | return response; 55 | } 56 | 57 | Future callPutApi( 58 | {required String url, 59 | Map? body, 60 | Map? queryParameter, 61 | Map? headers, 62 | required String apiPath}) async { 63 | ResponseDto response = await apiClient.apiRequest( 64 | url: url, 65 | method: RequestMethod.PUT, 66 | body: body, 67 | queryParameter: queryParameter, 68 | headers: headers, 69 | apiPath: apiPath); 70 | return response; 71 | } 72 | 73 | Future callPatchApi( 74 | {required String url, 75 | Map? body, 76 | Map? queryParameter, 77 | Map? headers, 78 | required String apiPath}) async { 79 | ResponseDto response = await apiClient.apiRequest( 80 | url: url, 81 | method: RequestMethod.PATCH, 82 | body: body, 83 | queryParameter: queryParameter, 84 | headers: headers, 85 | apiPath: apiPath); 86 | return response; 87 | } 88 | 89 | Future callMultipartApi( 90 | {required String url, 91 | required AppMultiPartRequest multiPart, 92 | Map? headers, 93 | required String apiPath}) async { 94 | ResponseDto response = await apiClient.multipartRequest( 95 | url: url, multiPart: multiPart, headers: headers, apiPath: apiPath); 96 | return response; 97 | } 98 | 99 | Map mapHeaders(Map? headers) { 100 | Map newHeaders = headers ?? {}; 101 | if (appConfig.token?.isNotEmpty ?? false) { 102 | newHeaders.putIfAbsent("Authorization", () => appConfig.token ?? ""); 103 | } 104 | return newHeaders; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /data/lib/config/app_config.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_data/config/app_config_type.dart'; 2 | import 'package:azl_data/config/environment.dart'; 3 | import 'package:http/src/response.dart'; 4 | 5 | class AppConfig implements AppConfigType { 6 | static final AppConfig shared = AppConfig._instance(); 7 | 8 | factory AppConfig({required Environment env, bool? enableMock = false}) { 9 | shared.env = env; 10 | shared.enableMock = enableMock; 11 | return shared; 12 | } 13 | 14 | AppConfig._instance(); 15 | 16 | Environment? env; 17 | 18 | @override 19 | enableIntercept(Response response) { 20 | print(response.body); 21 | } 22 | 23 | @override 24 | String getBaseUrl1() { 25 | return (env?.baseUrl ?? '') + (env?.path1 ?? ''); 26 | } 27 | 28 | @override 29 | String? token; 30 | 31 | @override 32 | bool? enableMock; 33 | } 34 | -------------------------------------------------------------------------------- /data/lib/config/app_config_type.dart: -------------------------------------------------------------------------------- 1 | import 'package:http/src/response.dart'; 2 | 3 | abstract class AppConfigType { 4 | String getBaseUrl1(); 5 | 6 | String? token; 7 | 8 | bool? enableMock; 9 | 10 | enableIntercept(Response response); 11 | } 12 | -------------------------------------------------------------------------------- /data/lib/config/environment.dart: -------------------------------------------------------------------------------- 1 | class Environment { 2 | Environment( 3 | {required this.baseUrl, 4 | required this.path1, 5 | this.path2 = '', 6 | required this.token}); 7 | 8 | final String baseUrl; 9 | final String path1; 10 | final String? path2; 11 | final String token; 12 | } 13 | -------------------------------------------------------------------------------- /data/lib/datasource/api_client/network_datasource.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:azl_data/config/app_config.dart'; 4 | import 'package:azl_data/datasource/api_client/network_datasource_type.dart'; 5 | import 'package:azl_data/models/app_multipart.dart'; 6 | import 'package:azl_data/models/reasponse_dto.dart'; 7 | import 'package:http/http.dart'; 8 | 9 | enum RequestMethod { GET, POST, PATCH, DELETE, PUT } 10 | 11 | class NetworkDatasource implements NetworkDatasourceType { 12 | static final NetworkDatasource _instance = NetworkDatasource._internal(); 13 | 14 | // using a factory is important 15 | // because it promises to return _an_ object of this type 16 | // but it doesn't promise to make a new one. 17 | factory NetworkDatasource() { 18 | return _instance; 19 | } 20 | 21 | // This named constructor is the "real" constructor 22 | // It'll be called exactly once, by the static property assignment above 23 | // it's also private, so it can only be called in this class 24 | NetworkDatasource._internal(); 25 | 26 | final Client _innerClient = Client(); 27 | final List _interceptors = []; 28 | 29 | //AppHttpClient(this._innerClient); 30 | 31 | void addInterceptor(Function(BaseRequest request) interceptor) { 32 | _interceptors.add(interceptor); 33 | } 34 | 35 | Future get(Uri url) async { 36 | Request request = Request('GET', url); 37 | await _applyInterceptors(request); 38 | final response = await _innerClient.send(request); 39 | return Response.fromStream(response); 40 | } 41 | 42 | Future _applyInterceptors(BaseRequest request) async { 43 | if (AppConfig.shared.token?.isNotEmpty ?? false) { 44 | request.headers 45 | .putIfAbsent("Authorization", () => AppConfig.shared.token ?? ""); 46 | } 47 | request.headers 48 | .putIfAbsent("Content-Type", () => "application/json; charset=UTF-8"); 49 | request.headers 50 | .putIfAbsent("Accept", () => "application/json; charset=UTF-8"); 51 | /* for (var interceptor in _interceptors) { 52 | await interceptor(request); 53 | }*/ 54 | } 55 | 56 | @override 57 | Future apiRequest({required String url, 58 | required RequestMethod method, 59 | Map? body, 60 | Map? queryParameter, 61 | Map? headers, 62 | required String apiPath}) async { 63 | final Uri uri = 64 | Uri.parse(generateUrl(url: url, path: apiPath, params: queryParameter)); 65 | try { 66 | Request request = Request(method.name, uri); 67 | request.headers.addAll(headers ?? {}); 68 | if (AppConfig.shared.token?.isNotEmpty ?? false) { 69 | request.headers 70 | .putIfAbsent("Authorization", () => AppConfig.shared.token ?? ""); 71 | } 72 | request.headers 73 | .putIfAbsent("Content-Type", () => "application/json; charset=UTF-8"); 74 | request.headers 75 | .putIfAbsent("Accept", () => "application/json; charset=UTF-8"); 76 | if (method != RequestMethod.GET) { 77 | request.body = jsonEncode(body); 78 | } 79 | 80 | //await _applyInterceptors(request); 81 | var streamResponse = await _innerClient.send(request); 82 | Response response = await Response.fromStream(streamResponse); 83 | 84 | return getAppResponse(response); 85 | } catch (e) { 86 | return getAppResponse(Response( 87 | jsonEncode({ 88 | "url": uri.path, 89 | "error": e, 90 | "request": body, 91 | "headers": headers, 92 | "method": method 93 | }), 94 | 505)); 95 | } 96 | } 97 | 98 | @override 99 | Future multipartRequest({required String url, 100 | required AppMultiPartRequest multiPart, 101 | Map? headers, 102 | required String apiPath}) async { 103 | final Uri uri = Uri.parse(generateUrl(url: url, path: apiPath)); 104 | try { 105 | //Response response; 106 | MultipartRequest request = MultipartRequest("POST", uri); 107 | request.fields.addAll(multiPart.fields ?? {}); 108 | request.files.addAll(multiPart.files ?? []); 109 | request.headers.addAll(headers ?? {}); 110 | await _applyInterceptors(request); 111 | var streamResponse = await _innerClient.send(request); 112 | Response response = await Response.fromStream(streamResponse); 113 | return getAppResponse(response); 114 | } catch (e) { 115 | return getAppResponse(Response( 116 | jsonEncode({ 117 | "url": uri.path, 118 | "error": e, 119 | "request": multiPart, 120 | "headers": headers, 121 | "method": "MULTIPART" 122 | }), 123 | 505)); 124 | } 125 | } 126 | 127 | ResponseDto getAppResponse(Response response) { 128 | try { 129 | if (response.statusCode == 200) { 130 | final jsonData = jsonDecode(response.body); 131 | return ResponseDto(success: true, response: jsonData); 132 | } else if (response.statusCode == 505) { 133 | return ResponseDto(success: false, errorResponse: response); 134 | } else { 135 | final jsonData = jsonDecode(response.body); 136 | return ResponseDto(success: false, response: jsonData); 137 | } 138 | } catch (e) { 139 | return ResponseDto(success: false, errorResponse: e, isException: true); 140 | } 141 | } 142 | 143 | String generateUrl( 144 | {required String url, Map? params, String? path}) { 145 | if (params == null) return url + (path ?? ''); 146 | List queryString = []; 147 | params.forEach((key, value) { 148 | if (value != null) { 149 | queryString.add('$key=$value'); 150 | } 151 | }); 152 | String queryPath = queryString.join('&'); 153 | return url + (path != null ? "$path?" : "") + queryPath; 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /data/lib/datasource/api_client/network_datasource_type.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_data/models/app_multipart.dart'; 2 | import 'package:azl_data/models/reasponse_dto.dart'; 3 | 4 | import 'network_datasource.dart'; 5 | 6 | abstract class NetworkDatasourceType { 7 | Future apiRequest( 8 | {required String url, 9 | required RequestMethod method, 10 | Map? body, 11 | Map? queryParameter, 12 | Map? headers, 13 | required String apiPath}); 14 | 15 | Future multipartRequest( 16 | {required String url, 17 | required AppMultiPartRequest multiPart, 18 | Map? headers, 19 | required String apiPath}); 20 | } 21 | -------------------------------------------------------------------------------- /data/lib/datasource/local_database/app_database.dart: -------------------------------------------------------------------------------- 1 | /* 2 | // database.dart 3 | 4 | // required package imports 5 | import 'dart:async'; 6 | import 'package:floor/floor.dart'; 7 | import 'package:sqflite/sqflite.dart' as sqflite; 8 | 9 | 10 | part 'app_database.g.dart'; // the generated code will be there 11 | 12 | @Database(version: 1, entities: [TodoTask]) 13 | abstract class AppDatabase extends FloorDatabase { 14 | TasksDao get personDao; 15 | }*/ 16 | -------------------------------------------------------------------------------- /data/lib/datasource/shared_preference/local_datasource.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:azl_data/utils/method_defination.dart'; 4 | import 'package:azl_data/datasource/shared_preference/local_datasource_type.dart'; 5 | import 'package:shared_preferences/shared_preferences.dart'; 6 | 7 | class LocalDatasource implements LocalDatasourceType { 8 | static final LocalDatasource _instance = LocalDatasource._internal(); 9 | 10 | // using a factory is important 11 | // because it promises to return _an_ object of this type 12 | // but it doesn't promise to make a new one. 13 | factory LocalDatasource() { 14 | return _instance; 15 | } 16 | 17 | // This named constructor is the "real" constructor 18 | // It'll be called exactly once, by the static property assignment above 19 | // it's also private, so it can only be called in this class 20 | LocalDatasource._internal(); 21 | 22 | @override 23 | Future getString(String key, String? defaultValue) async { 24 | SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); 25 | return (await sharedPreferences.getString(key) ?? defaultValue); 26 | } 27 | 28 | @override 29 | Future getBool(String key, bool? defaultValue) async { 30 | SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); 31 | return (await sharedPreferences.getBool(key) ?? defaultValue); 32 | } 33 | 34 | @override 35 | Future getDouble(String key, double? defaultValue) async { 36 | SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); 37 | return (await sharedPreferences.getDouble(key) ?? defaultValue); 38 | } 39 | 40 | @override 41 | Future getInt(String key, int? defaultValue) async { 42 | SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); 43 | return (await sharedPreferences.getInt(key) ?? defaultValue); 44 | } 45 | 46 | @override 47 | Future getObject(String key, FromJson converter) async { 48 | SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); 49 | String? stringObj = await sharedPreferences.getString(key); 50 | if (stringObj != null) { 51 | return converter(jsonDecode(stringObj) as Map); 52 | } else { 53 | return null; 54 | } 55 | } 56 | 57 | @override 58 | Future setBool(String key, bool value) async { 59 | SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); 60 | return await sharedPreferences.setBool(key, value); 61 | } 62 | 63 | @override 64 | Future setDouble(String key, double value) async { 65 | SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); 66 | return await sharedPreferences.setDouble(key, value); 67 | } 68 | 69 | @override 70 | Future setInt(String key, int value) async { 71 | SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); 72 | return await sharedPreferences.setInt(key, value); 73 | } 74 | 75 | @override 76 | Future setObject(String key, Map value) async { 77 | SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); 78 | return await sharedPreferences.setString(key, jsonEncode(value)); 79 | } 80 | 81 | @override 82 | Future setString(String key, String value) async { 83 | SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); 84 | return await sharedPreferences.setString(key, value); 85 | } 86 | 87 | @override 88 | Future clearAll() async { 89 | SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); 90 | return await sharedPreferences.clear(); 91 | } 92 | 93 | @override 94 | Future clearKey(String key) async { 95 | SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); 96 | return await sharedPreferences.remove(key); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /data/lib/datasource/shared_preference/local_datasource_type.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_data/utils/method_defination.dart'; 2 | 3 | abstract class LocalDatasourceType { 4 | Future getString(String key, String? defaultValue); 5 | 6 | Future getInt(String key, int? defaultValue); 7 | 8 | Future getBool(String key, bool? defaultValue); 9 | 10 | Future getDouble(String key, double? defaultValue); 11 | 12 | Future getObject(String key, FromJson converter); 13 | 14 | Future setString(String key, String value); 15 | 16 | Future setInt(String key, int value); 17 | 18 | Future setBool(String key, bool value); 19 | 20 | Future setDouble(String key, double value); 21 | 22 | Future setObject(String key, Map value); 23 | 24 | Future clearKey(String key); 25 | 26 | Future clearAll(); 27 | } 28 | -------------------------------------------------------------------------------- /data/lib/datasource/translations/translation_datasource.dart: -------------------------------------------------------------------------------- 1 | class LocaleTexts { 2 | static const appName = "app_name"; 3 | static const next = "next"; 4 | static const language = "language"; 5 | static const selectLanguage = "select_language"; 6 | static const en = "English"; 7 | static const hi = "Hindi"; 8 | static const no_internet = "no_internet"; 9 | } 10 | -------------------------------------------------------------------------------- /data/lib/di/data_injection.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_data/datasource/api_client/network_datasource.dart'; 2 | import 'package:azl_data/datasource/api_client/network_datasource_type.dart'; 3 | import 'package:azl_data/datasource/shared_preference/local_datasource.dart'; 4 | import 'package:azl_data/datasource/shared_preference/local_datasource_type.dart'; 5 | import 'package:get_it/get_it.dart'; 6 | 7 | class DataInjection { 8 | static GetIt getIt = GetIt.instance; 9 | 10 | static void configure() { 11 | getIt.registerLazySingleton( 12 | () => NetworkDatasource(), 13 | ); 14 | 15 | getIt.registerLazySingleton( 16 | () => LocalDatasource(), 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /data/lib/di/datasource_module.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_data/datasource/api_client/network_datasource_type.dart'; 2 | import 'package:azl_data/datasource/shared_preference/local_datasource_type.dart'; 3 | import 'package:azl_data/di/data_injection.dart'; 4 | 5 | mixin DatasourceModule { 6 | /// API/REST Client 7 | NetworkDatasourceType get apiClient { 8 | return DataInjection.getIt(); 9 | } 10 | 11 | /// Local Storage 12 | LocalDatasourceType get sharesPreference { 13 | return DataInjection.getIt(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /data/lib/mocks/mocks.dart: -------------------------------------------------------------------------------- 1 | const tasksMock = [ 2 | { 3 | "id": "8103832962", 4 | "assigner_id": null, 5 | "assignee_id": null, 6 | "project_id": "2334529325", 7 | "section_id": "157876129", 8 | "parent_id": null, 9 | "order": 1, 10 | "content": "Login Screen", 11 | "description": 12 | "Create Login Screen ui where email and password field will be there and used can click on Login Button", 13 | "is_completed": false, 14 | "labels": [], 15 | "priority": 4, 16 | "comment_count": 1, 17 | "creator_id": "49528973", 18 | "created_at": "2024-06-10T12:41:49.575948Z", 19 | "due": null, 20 | "url": "https://todoist.com/app/task/8103832962", 21 | "duration": null 22 | }, 23 | { 24 | "id": "8106563966", 25 | "assigner_id": null, 26 | "assignee_id": null, 27 | "project_id": "2334529325", 28 | "section_id": "157876158", 29 | "parent_id": null, 30 | "order": 1, 31 | "content": "Signup Screen", 32 | "description": 33 | "Create Signup Screen ui where email and password and confirm password field will be there and used can click on Login Button", 34 | "is_completed": false, 35 | "labels": [], 36 | "priority": 2, 37 | "comment_count": 0, 38 | "creator_id": "49528973", 39 | "created_at": "2024-06-11T07:26:02.878989Z", 40 | "due": null, 41 | "url": "https://todoist.com/app/task/8106563966", 42 | "duration": null 43 | }, 44 | { 45 | "id": "8110122935", 46 | "assigner_id": null, 47 | "assignee_id": null, 48 | "project_id": "2334529325", 49 | "section_id": "157876129", 50 | "parent_id": null, 51 | "order": 2, 52 | "content": "Dashboard", 53 | "description": "", 54 | "is_completed": false, 55 | "labels": [], 56 | "priority": 1, 57 | "comment_count": 0, 58 | "creator_id": "49528973", 59 | "created_at": "2024-06-12T08:00:28.710604Z", 60 | "due": null, 61 | "url": "https://todoist.com/app/task/8110122935", 62 | "duration": null 63 | }, 64 | { 65 | "id": "8110123226", 66 | "assigner_id": null, 67 | "assignee_id": null, 68 | "project_id": "2334529325", 69 | "section_id": "157876129", 70 | "parent_id": null, 71 | "order": 3, 72 | "content": "Details", 73 | "description": "", 74 | "is_completed": false, 75 | "labels": [], 76 | "priority": 1, 77 | "comment_count": 0, 78 | "creator_id": "49528973", 79 | "created_at": "2024-06-12T08:00:36.552492Z", 80 | "due": null, 81 | "url": "https://todoist.com/app/task/8110123226", 82 | "duration": null 83 | }, 84 | { 85 | "id": "8110123306", 86 | "assigner_id": null, 87 | "assignee_id": null, 88 | "project_id": "2334529325", 89 | "section_id": "157876129", 90 | "parent_id": null, 91 | "order": 4, 92 | "content": "Profile", 93 | "description": "", 94 | "is_completed": false, 95 | "labels": [], 96 | "priority": 1, 97 | "comment_count": 0, 98 | "creator_id": "49528973", 99 | "created_at": "2024-06-12T08:00:38.980693Z", 100 | "due": null, 101 | "url": "https://todoist.com/app/task/8110123306", 102 | "duration": null 103 | }, 104 | { 105 | "id": "8110123652", 106 | "assigner_id": null, 107 | "assignee_id": null, 108 | "project_id": "2334529325", 109 | "section_id": "157876129", 110 | "parent_id": null, 111 | "order": 5, 112 | "content": "Setting", 113 | "description": "", 114 | "is_completed": false, 115 | "labels": [], 116 | "priority": 1, 117 | "comment_count": 0, 118 | "creator_id": "49528973", 119 | "created_at": "2024-06-12T08:00:48.773665Z", 120 | "due": null, 121 | "url": "https://todoist.com/app/task/8110123652", 122 | "duration": null 123 | }, 124 | { 125 | "id": "8110123802", 126 | "assigner_id": null, 127 | "assignee_id": null, 128 | "project_id": "2334529325", 129 | "section_id": "157876152", 130 | "parent_id": null, 131 | "order": 1, 132 | "content": "Secure", 133 | "description": "", 134 | "is_completed": false, 135 | "labels": [], 136 | "priority": 1, 137 | "comment_count": 0, 138 | "creator_id": "49528973", 139 | "created_at": "2024-06-12T08:00:52.553871Z", 140 | "due": null, 141 | "url": "https://todoist.com/app/task/8110123802", 142 | "duration": null 143 | }, 144 | { 145 | "id": "8110539090", 146 | "assigner_id": null, 147 | "assignee_id": null, 148 | "project_id": "2334529325", 149 | "section_id": "157876129", 150 | "parent_id": null, 151 | "order": 7, 152 | "content": "Signup Screen", 153 | "description": 154 | "Create Signup Screen ui where email and password and confirm password field will be there and used can click on Login Button", 155 | "is_completed": false, 156 | "labels": [], 157 | "priority": 2, 158 | "comment_count": 0, 159 | "creator_id": "49528973", 160 | "created_at": "2024-06-12T10:13:48.949095Z", 161 | "due": null, 162 | "url": "https://todoist.com/app/task/8110539090", 163 | "duration": null 164 | }, 165 | { 166 | "id": "8113084127", 167 | "assigner_id": null, 168 | "assignee_id": null, 169 | "project_id": "2334529325", 170 | "section_id": "157876129", 171 | "parent_id": null, 172 | "order": 8, 173 | "content": "Logout Screen", 174 | "description": "Create Logout Screen ui where", 175 | "is_completed": false, 176 | "labels": [], 177 | "priority": 2, 178 | "comment_count": 0, 179 | "creator_id": "49528973", 180 | "created_at": "2024-06-13T05:02:55.475602Z", 181 | "due": null, 182 | "url": "https://todoist.com/app/task/8113084127", 183 | "duration": null 184 | } 185 | ]; 186 | 187 | const sectionsMock = [ 188 | {"id": "157876129", "project_id": "2334529325", "order": 1, "name": "Todo"}, 189 | { 190 | "id": "157876152", 191 | "project_id": "2334529325", 192 | "order": 2, 193 | "name": "In Progress" 194 | }, 195 | {"id": "157876158", "project_id": "2334529325", "order": 3, "name": "Done"} 196 | ]; 197 | -------------------------------------------------------------------------------- /data/lib/models/app_multipart.dart: -------------------------------------------------------------------------------- 1 | import 'package:http/http.dart'; 2 | 3 | class AppMultiPartRequest { 4 | final Map? fields; 5 | final List? files; 6 | 7 | AppMultiPartRequest({this.fields, this.files}); 8 | } 9 | -------------------------------------------------------------------------------- /data/lib/models/reasponse_dto.dart: -------------------------------------------------------------------------------- 1 | int EXCEPTION_RESPONSE = 500; 2 | int FAILURE_RESPONSE = 400; 3 | 4 | class ResponseDto { 5 | final bool success; 6 | final dynamic response; 7 | final dynamic errorResponse; 8 | final bool noInternet; 9 | final bool isException; 10 | final int responseCode; 11 | 12 | ResponseDto( 13 | {this.success = false, 14 | this.response, 15 | this.noInternet = false, 16 | this.isException = false, 17 | this.responseCode = 0, 18 | this.errorResponse}); 19 | } 20 | -------------------------------------------------------------------------------- /data/lib/repositories/comments/comments_repository.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_data/api_constants/api_paths.dart'; 2 | import 'package:azl_data/mocks/mocks.dart'; 3 | import 'package:azl_data/models/reasponse_dto.dart'; 4 | import 'package:azl_data/repositories/comments/comments_repository_type.dart'; 5 | 6 | class CommentsRepository extends CommentsRepositoryType { 7 | CommentsRepository({required super.appConfig}); 8 | 9 | @override 10 | Future getComments() async { 11 | ResponseDto myResponse; 12 | if (appConfig.enableMock ?? false) { 13 | myResponse = 14 | ResponseDto(success: true, response: {"comments": tasksMock}); 15 | } else { 16 | myResponse = await callGetApi( 17 | url: appConfig.getBaseUrl1(), apiPath: ApiPaths.tasks); 18 | } 19 | return myResponse; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /data/lib/repositories/comments/comments_repository_type.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_data/base/base_repository.dart'; 2 | import 'package:azl_data/models/reasponse_dto.dart'; 3 | 4 | abstract class CommentsRepositoryType extends BaseRepository { 5 | CommentsRepositoryType({required super.appConfig}); 6 | 7 | Future getComments(); 8 | } 9 | -------------------------------------------------------------------------------- /data/lib/repositories/sections/sections_repository.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_data/api_constants/api_paths.dart'; 2 | import 'package:azl_data/mocks/mocks.dart'; 3 | import 'package:azl_data/models/reasponse_dto.dart'; 4 | import 'package:azl_data/repositories/sections/sections_repository_type.dart'; 5 | 6 | class SectionsRepository extends SectionsRepositoryType { 7 | SectionsRepository({required super.appConfig}); 8 | 9 | @override 10 | Future getSections() async { 11 | ResponseDto myResponse; 12 | if (appConfig.enableMock ?? false) { 13 | myResponse = 14 | ResponseDto(success: true, response: sectionsMock); 15 | } else { 16 | myResponse = await callGetApi( 17 | url: appConfig.getBaseUrl1(), apiPath: ApiPaths.sections); 18 | } 19 | return myResponse; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /data/lib/repositories/sections/sections_repository_type.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_data/base/base_repository.dart'; 2 | import 'package:azl_data/models/reasponse_dto.dart'; 3 | 4 | abstract class SectionsRepositoryType extends BaseRepository { 5 | SectionsRepositoryType({required super.appConfig}); 6 | 7 | Future getSections(); 8 | } 9 | -------------------------------------------------------------------------------- /data/lib/repositories/tasks/tasks_repository.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_data/api_constants/api_paths.dart'; 2 | import 'package:azl_data/mocks/mocks.dart'; 3 | import 'package:azl_data/models/reasponse_dto.dart'; 4 | import 'package:azl_data/repositories/tasks/tasks_repository_type.dart'; 5 | 6 | class TasksRepository extends TasksRepositoryType { 7 | TasksRepository({required super.appConfig}); 8 | 9 | @override 10 | Future getTasks() async { 11 | ResponseDto myResponse; 12 | if (appConfig.enableMock ?? false) { 13 | myResponse = ResponseDto(success: true, response: tasksMock); 14 | } else { 15 | myResponse = await callGetApi( 16 | url: appConfig.getBaseUrl1(), apiPath: ApiPaths.tasks); 17 | } 18 | return myResponse; 19 | } 20 | 21 | @override 22 | Future createTask({required Map task}) async { 23 | ResponseDto myResponse; 24 | if (appConfig.enableMock ?? false) { 25 | myResponse = ResponseDto(success: true, response: tasksMock); 26 | } else { 27 | myResponse = await callPostApi( 28 | url: appConfig.getBaseUrl1(), apiPath: ApiPaths.tasks); 29 | } 30 | return myResponse; 31 | } 32 | 33 | @override 34 | Future updateTask( 35 | {required Map task, required String taskId}) async { 36 | ResponseDto myResponse; 37 | if (appConfig.enableMock ?? false) { 38 | myResponse = ResponseDto(success: true, response: tasksMock); 39 | } else { 40 | myResponse = await callPostApi( 41 | url: appConfig.getBaseUrl1(), apiPath: "${ApiPaths.tasks}/$taskId", body: task); 42 | } 43 | return myResponse; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /data/lib/repositories/tasks/tasks_repository_type.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_data/base/base_repository.dart'; 2 | import 'package:azl_data/models/reasponse_dto.dart'; 3 | 4 | abstract class TasksRepositoryType extends BaseRepository { 5 | TasksRepositoryType({required super.appConfig}); 6 | 7 | Future getTasks(); 8 | 9 | Future createTask({required Map task}); 10 | 11 | Future updateTask( 12 | {required Map task, required String taskId}); 13 | } 14 | -------------------------------------------------------------------------------- /data/lib/utils/method_defination.dart: -------------------------------------------------------------------------------- 1 | typedef T FromJson(Map json); -------------------------------------------------------------------------------- /data/lib/utils/platform_dependent.dart: -------------------------------------------------------------------------------- 1 | abstract class PlatformDependents{ 2 | bool isInternetConnected(); 3 | } -------------------------------------------------------------------------------- /data/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: azl_data 2 | description: Clean Data Layer 3 | 4 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 5 | 6 | version: 1.0.0+1 7 | 8 | environment: 9 | sdk: '>=3.4.3 <4.0.0' 10 | 11 | dependencies: 12 | http: ^0.13.6 13 | shared_preferences: ^2.1.1 14 | get_it: ^7.7.0 15 | floor: ^1.5.0 16 | 17 | dev_dependencies: 18 | flutter_lints: ^2.0.1 19 | floor_generator: ^1.4.2 20 | build_runner: ^2.4.4 21 | -------------------------------------------------------------------------------- /data/test/data_test.dart: -------------------------------------------------------------------------------- 1 | /* 2 | import 'package:http/http.dart'; 3 | 4 | import 'package:azl_data/datasource/api_client/network_datasource.dart'; 5 | */ 6 | 7 | main() async { 8 | /*Response response = await NetworkDatasource().apiRequest( 9 | url: 'https://6423b770001cb9fc20449630.mockapi.io/api/', 10 | method: RequestMethod.GET, 11 | apiPath: 'v1/kanban_board'); 12 | 13 | print(response.body);*/ 14 | } 15 | 16 | String generateUrl( 17 | {required String url, Map? params, String? path}) { 18 | if (params == null) return url + (path ?? ''); 19 | List queryString = []; 20 | params.forEach((key, value) { 21 | if (value != null) { 22 | queryString.add('$key=$value'); 23 | } 24 | }); 25 | String queryPath = queryString.join('&'); 26 | return url + (path != null ? "$path?" : "") + queryPath; 27 | } 28 | -------------------------------------------------------------------------------- /domain/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | **/ios/Flutter/.last_build_id 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .packages 31 | .pub-cache/ 32 | .pub/ 33 | /build/ 34 | 35 | # Web related 36 | lib/generated_plugin_registrant.dart 37 | 38 | # Symbolication related 39 | app.*.symbols 40 | 41 | # Obfuscation related 42 | app.*.map.json 43 | 44 | # Android Studio will place build artifacts here 45 | /android/app/debug 46 | /android/app/profile 47 | /android/app/release 48 | 49 | # Ignored files 50 | .DS_Store 51 | .atom/ 52 | !.idea/ 53 | .idea/* 54 | !.idea/workspace.xml 55 | android/.idea 56 | .vscode/ 57 | .packages 58 | .pub/ 59 | .dart_tool/ 60 | flutter_export_environment.sh 61 | Podfile.lock 62 | Pods/ 63 | .symlinks/ 64 | **/Flutter/App.framework/ 65 | **/Flutter/Flutter.framework/ 66 | **/Flutter/Generated.xcconfig 67 | **/Flutter/flutter_assets/ 68 | ServiceDefinitions.json 69 | xcuserdata/ 70 | **/DerivedData/ 71 | local.properties 72 | keystore.properties 73 | .gradle/ 74 | gradlew 75 | gradlew.bat 76 | gradle-wrapper.jar 77 | .flutter-plugins-dependencies 78 | *.iml 79 | GeneratedPluginRegistrant.h 80 | GeneratedPluginRegistrant.m 81 | GeneratedPluginRegistrant.java 82 | build/ 83 | .flutter-plugins 84 | .project 85 | .classpath 86 | .settings 87 | 88 | 89 | coverage/ 90 | .last_build_id 91 | report.xml 92 | .fvm/flutter_sdk 93 | pubspec.lock 94 | */oss_licenses.g.dart -------------------------------------------------------------------------------- /domain/.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. 5 | 6 | version: 7 | revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 8 | channel: stable 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 17 | base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 18 | - platform: android 19 | create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 20 | base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 21 | - platform: ios 22 | create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 23 | base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 24 | 25 | # User provided section 26 | 27 | # List of Local paths (relative to this file) that should be 28 | # ignored by the migrate tool. 29 | # 30 | # Files that are not part of the templates will be ignored by default. 31 | unmanaged_files: 32 | - 'lib/main.dart' 33 | - 'ios/Runner.xcodeproj/project.pbxproj' 34 | -------------------------------------------------------------------------------- /domain/README.md: -------------------------------------------------------------------------------- 1 | # domain 2 | 3 | Clean Domain Layer 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) 13 | 14 | For help getting started with Flutter development, view the 15 | [online documentation](https://docs.flutter.dev/), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /domain/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 27 | 28 | # Additional information about this file can be found at 29 | # https://dart.dev/guides/language/analysis-options 30 | -------------------------------------------------------------------------------- /domain/lib/base/api_paths.dart: -------------------------------------------------------------------------------- 1 | class ApiPaths { 2 | static String tasks = "/tasks"; 3 | static String sections = "/sections"; 4 | static String comments = "/comments"; 5 | } 6 | -------------------------------------------------------------------------------- /domain/lib/base/error_response.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | 3 | class ErrorResponse extends Equatable implements Exception { 4 | final String message; 5 | 6 | const ErrorResponse(this.message); 7 | 8 | @override 9 | List get props => [message]; 10 | } 11 | 12 | class CodeErrorResponse extends ErrorResponse { 13 | final int code; 14 | 15 | const CodeErrorResponse(this.code, String message) : super(message); 16 | } 17 | 18 | class NoDataErrorResponse extends ErrorResponse { 19 | const NoDataErrorResponse() : super('No data!'); 20 | } 21 | 22 | class NoConnectionErrorResponse extends ErrorResponse { 23 | const NoConnectionErrorResponse() : super('No connection!'); 24 | } 25 | 26 | class UnknownErrorResponse extends ErrorResponse { 27 | const UnknownErrorResponse() : super('Unknown Failure!'); 28 | } 29 | 30 | class KnownException implements Exception { 31 | KnownException(this.message); 32 | 33 | final String message; 34 | } 35 | -------------------------------------------------------------------------------- /domain/lib/di/domain_injection.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_data/config/app_config.dart'; 2 | import 'package:azl_data/config/app_config_type.dart'; 3 | import 'package:azl_data/config/environment.dart'; 4 | import 'package:azl_data/di/data_injection.dart'; 5 | import 'package:azl_data/repositories/sections/sections_repository.dart'; 6 | import 'package:azl_data/repositories/sections/sections_repository_type.dart'; 7 | import 'package:azl_data/repositories/tasks/tasks_repository.dart'; 8 | import 'package:azl_data/repositories/tasks/tasks_repository_type.dart'; 9 | import 'package:azl_domain/usecase/kanban/kanban_usecase.dart'; 10 | import 'package:azl_domain/usecase/kanban/kanban_usecase_type.dart'; 11 | import 'package:get_it/get_it.dart'; 12 | 13 | class DomainInjection { 14 | static GetIt getIt = GetIt.instance; 15 | 16 | static void configure(Environment environment, bool enable) { 17 | DataInjection.configure(); 18 | 19 | getIt.registerFactory( 20 | () => AppConfig(env: environment, enableMock: enable), 21 | ); 22 | 23 | getIt.registerFactory( 24 | () => TasksRepository(appConfig: getIt()), 25 | ); 26 | getIt.registerFactory( 27 | () => SectionsRepository(appConfig: getIt()), 28 | ); 29 | 30 | getIt.registerFactory( 31 | () => KanbanUseCase(taskRepository: getIt(), sectionsRepository: getIt()), 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /domain/lib/mocks.dart: -------------------------------------------------------------------------------- 1 | const tasksMock = [ 2 | { 3 | "id": "8103832962", 4 | "assigner_id": null, 5 | "assignee_id": null, 6 | "project_id": "2334529325", 7 | "section_id": "157876129", 8 | "parent_id": null, 9 | "order": 1, 10 | "content": "Login Screen", 11 | "description": 12 | "Create Login Screen ui where email and password field will be there and used can click on Login Button", 13 | "is_completed": false, 14 | "labels": [], 15 | "priority": 4, 16 | "comment_count": 1, 17 | "creator_id": "49528973", 18 | "created_at": "2024-06-10T12:41:49.575948Z", 19 | "due": null, 20 | "url": "https://todoist.com/app/task/8103832962", 21 | "duration": null 22 | }, 23 | { 24 | "id": "8106563966", 25 | "assigner_id": null, 26 | "assignee_id": null, 27 | "project_id": "2334529325", 28 | "section_id": "157876158", 29 | "parent_id": null, 30 | "order": 1, 31 | "content": "Signup Screen", 32 | "description": 33 | "Create Signup Screen ui where email and password and confirm password field will be there and used can click on Login Button", 34 | "is_completed": false, 35 | "labels": [], 36 | "priority": 2, 37 | "comment_count": 0, 38 | "creator_id": "49528973", 39 | "created_at": "2024-06-11T07:26:02.878989Z", 40 | "due": null, 41 | "url": "https://todoist.com/app/task/8106563966", 42 | "duration": null 43 | }, 44 | { 45 | "id": "8110122935", 46 | "assigner_id": null, 47 | "assignee_id": null, 48 | "project_id": "2334529325", 49 | "section_id": "157876129", 50 | "parent_id": null, 51 | "order": 2, 52 | "content": "Dashboard", 53 | "description": "", 54 | "is_completed": false, 55 | "labels": [], 56 | "priority": 1, 57 | "comment_count": 0, 58 | "creator_id": "49528973", 59 | "created_at": "2024-06-12T08:00:28.710604Z", 60 | "due": null, 61 | "url": "https://todoist.com/app/task/8110122935", 62 | "duration": null 63 | }, 64 | { 65 | "id": "8110123226", 66 | "assigner_id": null, 67 | "assignee_id": null, 68 | "project_id": "2334529325", 69 | "section_id": "157876129", 70 | "parent_id": null, 71 | "order": 3, 72 | "content": "Details", 73 | "description": "", 74 | "is_completed": false, 75 | "labels": [], 76 | "priority": 1, 77 | "comment_count": 0, 78 | "creator_id": "49528973", 79 | "created_at": "2024-06-12T08:00:36.552492Z", 80 | "due": null, 81 | "url": "https://todoist.com/app/task/8110123226", 82 | "duration": null 83 | }, 84 | { 85 | "id": "8110123306", 86 | "assigner_id": null, 87 | "assignee_id": null, 88 | "project_id": "2334529325", 89 | "section_id": "157876129", 90 | "parent_id": null, 91 | "order": 4, 92 | "content": "Profile", 93 | "description": "", 94 | "is_completed": false, 95 | "labels": [], 96 | "priority": 1, 97 | "comment_count": 0, 98 | "creator_id": "49528973", 99 | "created_at": "2024-06-12T08:00:38.980693Z", 100 | "due": null, 101 | "url": "https://todoist.com/app/task/8110123306", 102 | "duration": null 103 | }, 104 | { 105 | "id": "8110123652", 106 | "assigner_id": null, 107 | "assignee_id": null, 108 | "project_id": "2334529325", 109 | "section_id": "157876129", 110 | "parent_id": null, 111 | "order": 5, 112 | "content": "Setting", 113 | "description": "", 114 | "is_completed": false, 115 | "labels": [], 116 | "priority": 1, 117 | "comment_count": 0, 118 | "creator_id": "49528973", 119 | "created_at": "2024-06-12T08:00:48.773665Z", 120 | "due": null, 121 | "url": "https://todoist.com/app/task/8110123652", 122 | "duration": null 123 | }, 124 | { 125 | "id": "8110123802", 126 | "assigner_id": null, 127 | "assignee_id": null, 128 | "project_id": "2334529325", 129 | "section_id": "157876152", 130 | "parent_id": null, 131 | "order": 1, 132 | "content": "Secure", 133 | "description": "", 134 | "is_completed": false, 135 | "labels": [], 136 | "priority": 1, 137 | "comment_count": 0, 138 | "creator_id": "49528973", 139 | "created_at": "2024-06-12T08:00:52.553871Z", 140 | "due": null, 141 | "url": "https://todoist.com/app/task/8110123802", 142 | "duration": null 143 | } 144 | ]; 145 | 146 | const sectionsMock = [ 147 | {"id": "157876129", "project_id": "2334529325", "order": 1, "name": "Todo"}, 148 | { 149 | "id": "157876152", 150 | "project_id": "2334529325", 151 | "order": 2, 152 | "name": "In Progress" 153 | }, 154 | {"id": "157876158", "project_id": "2334529325", "order": 3, "name": "Done"} 155 | ]; 156 | -------------------------------------------------------------------------------- /domain/lib/model/comments/comment.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'comment.g.dart'; 4 | 5 | @JsonSerializable(ignoreUnannotated: false) 6 | class Comment { 7 | @JsonKey(name: 'content') 8 | final String? content; 9 | @JsonKey(name: 'id') 10 | final String? id; 11 | @JsonKey(name: 'posted_at') 12 | final String? postedAt; 13 | @JsonKey(name: 'project_id') 14 | final String? projectId; 15 | @JsonKey(name: 'task_id') 16 | final String? taskId; 17 | @JsonKey(name: 'attachment') 18 | final Attachment? attachment; 19 | 20 | Comment({this.content, this.id, this.postedAt, this.projectId, this.taskId, this.attachment}); 21 | 22 | factory Comment.fromJson(Map json) => _$CommentFromJson(json); 23 | 24 | Map toJson() => _$CommentToJson(this); 25 | } 26 | 27 | @JsonSerializable(ignoreUnannotated: false) 28 | class Attachment { 29 | @JsonKey(name: 'file_name') 30 | final String? fileName; 31 | @JsonKey(name: 'file_type') 32 | final String? fileType; 33 | @JsonKey(name: 'file_url') 34 | final String? fileUrl; 35 | @JsonKey(name: 'resource_type') 36 | final String? resourceType; 37 | 38 | Attachment({this.fileName, this.fileType, this.fileUrl, this.resourceType}); 39 | 40 | factory Attachment.fromJson(Map json) => _$AttachmentFromJson(json); 41 | 42 | Map toJson() => _$AttachmentToJson(this); 43 | } 44 | 45 | -------------------------------------------------------------------------------- /domain/lib/model/comments/comment.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'comment.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | Comment _$CommentFromJson(Map json) => Comment( 10 | content: json['content'] as String?, 11 | id: json['id'] as String?, 12 | postedAt: json['posted_at'] as String?, 13 | projectId: json['project_id'] as String?, 14 | taskId: json['task_id'] as String?, 15 | attachment: json['attachment'] == null 16 | ? null 17 | : Attachment.fromJson(json['attachment'] as Map), 18 | ); 19 | 20 | Map _$CommentToJson(Comment instance) => { 21 | 'content': instance.content, 22 | 'id': instance.id, 23 | 'posted_at': instance.postedAt, 24 | 'project_id': instance.projectId, 25 | 'task_id': instance.taskId, 26 | 'attachment': instance.attachment, 27 | }; 28 | 29 | Attachment _$AttachmentFromJson(Map json) => Attachment( 30 | fileName: json['file_name'] as String?, 31 | fileType: json['file_type'] as String?, 32 | fileUrl: json['file_url'] as String?, 33 | resourceType: json['resource_type'] as String?, 34 | ); 35 | 36 | Map _$AttachmentToJson(Attachment instance) => 37 | { 38 | 'file_name': instance.fileName, 39 | 'file_type': instance.fileType, 40 | 'file_url': instance.fileUrl, 41 | 'resource_type': instance.resourceType, 42 | }; 43 | -------------------------------------------------------------------------------- /domain/lib/model/comments/comments_response.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_domain/model/comments/comment.dart'; 2 | import 'package:json_annotation/json_annotation.dart'; 3 | 4 | part 'comments_response.g.dart'; 5 | 6 | @JsonSerializable(ignoreUnannotated: false) 7 | class CommentsResponse { 8 | @JsonKey(name: 'comments') 9 | final List? comments; 10 | 11 | CommentsResponse({this.comments}); 12 | 13 | factory CommentsResponse.fromJson(Map json) => 14 | _$CommentsResponseFromJson(json); 15 | 16 | Map toJson() => _$CommentsResponseToJson(this); 17 | } 18 | -------------------------------------------------------------------------------- /domain/lib/model/comments/comments_response.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'comments_response.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | CommentsResponse _$CommentsResponseFromJson(Map json) => 10 | CommentsResponse( 11 | comments: (json['comments'] as List?) 12 | ?.map((e) => Comment.fromJson(e as Map)) 13 | .toList(), 14 | ); 15 | 16 | Map _$CommentsResponseToJson(CommentsResponse instance) => 17 | { 18 | 'comments': instance.comments, 19 | }; 20 | -------------------------------------------------------------------------------- /domain/lib/model/sections/section.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'section.g.dart'; 4 | 5 | @JsonSerializable(ignoreUnannotated: false) 6 | class Section { 7 | @JsonKey(name: 'id') 8 | final String? id; 9 | @JsonKey(name: 'project_id') 10 | final String? projectId; 11 | @JsonKey(name: 'order') 12 | final int? order; 13 | @JsonKey(name: 'name') 14 | final String? name; 15 | 16 | Section({this.id, this.projectId, this.order, this.name}); 17 | 18 | factory Section.fromJson(Map json) => _$SectionFromJson(json); 19 | 20 | Map toJson() => _$SectionToJson(this); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /domain/lib/model/sections/section.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'section.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | Section _$SectionFromJson(Map json) => Section( 10 | id: json['id'] as String?, 11 | projectId: json['project_id'] as String?, 12 | order: (json['order'] as num?)?.toInt(), 13 | name: json['name'] as String?, 14 | ); 15 | 16 | Map _$SectionToJson(Section instance) => { 17 | 'id': instance.id, 18 | 'project_id': instance.projectId, 19 | 'order': instance.order, 20 | 'name': instance.name, 21 | }; 22 | -------------------------------------------------------------------------------- /domain/lib/model/sections/sections_response.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_domain/model/sections/section.dart'; 2 | import 'package:json_annotation/json_annotation.dart'; 3 | 4 | part 'sections_response.g.dart'; 5 | 6 | @JsonSerializable(ignoreUnannotated: false) 7 | class SectionsResponse { 8 | @JsonKey(name: 'sections') 9 | final List
? sections; 10 | 11 | SectionsResponse({this.sections}); 12 | 13 | factory SectionsResponse.fromJson(Map json) => 14 | _$SectionsResponseFromJson(json); 15 | 16 | Map toJson() => _$SectionsResponseToJson(this); 17 | } 18 | -------------------------------------------------------------------------------- /domain/lib/model/sections/sections_response.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'sections_response.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | SectionsResponse _$SectionsResponseFromJson(Map json) => 10 | SectionsResponse( 11 | sections: (json['sections'] as List?) 12 | ?.map((e) => Section.fromJson(e as Map)) 13 | .toList(), 14 | ); 15 | 16 | Map _$SectionsResponseToJson(SectionsResponse instance) => 17 | { 18 | 'sections': instance.sections, 19 | }; 20 | -------------------------------------------------------------------------------- /domain/lib/model/tasks/task.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'task.g.dart'; 4 | 5 | @JsonSerializable(ignoreUnannotated: false) 6 | class TodoTask { 7 | @JsonKey(name: 'creator_id') 8 | final String? creatorId; 9 | @JsonKey(name: 'created_at') 10 | final String? createdAt; 11 | @JsonKey(name: 'assignee_id') 12 | final String? assigneeId; 13 | @JsonKey(name: 'assigner_id') 14 | final String? assignerId; 15 | @JsonKey(name: 'comment_count') 16 | final int? commentCount; 17 | @JsonKey(name: 'is_completed') 18 | final bool? isCompleted; 19 | @JsonKey(name: 'content') 20 | final String? content; 21 | @JsonKey(name: 'description') 22 | final String? description; 23 | @JsonKey(name: 'due') 24 | final Due? due; 25 | @JsonKey(name: 'duration') 26 | final int? duration; 27 | @JsonKey(name: 'id') 28 | final String? id; 29 | @JsonKey(name: 'labels') 30 | final List? labels; 31 | @JsonKey(name: 'order') 32 | final int? order; 33 | @JsonKey(name: 'priority') 34 | final int? priority; 35 | @JsonKey(name: 'project_id') 36 | final String? projectId; 37 | @JsonKey(name: 'section_id') 38 | final String? sectionId; 39 | @JsonKey(name: 'parent_id') 40 | final String? parentId; 41 | @JsonKey(name: 'url') 42 | final String? url; 43 | 44 | TodoTask({this.creatorId, this.createdAt, this.assigneeId, this.assignerId, this.commentCount, this.isCompleted, this.content, this.description, this.due, this.duration, this.id, this.labels, this.order, this.priority, this.projectId, this.sectionId, this.parentId, this.url}); 45 | 46 | factory TodoTask.fromJson(Map json) => _$TodoTaskFromJson(json); 47 | 48 | Map toJson() => _$TodoTaskToJson(this); 49 | 50 | TodoTask copyWith({ 51 | String? creatorId, 52 | String? createdAt, 53 | String? assigneeId, 54 | String? assignerId, 55 | int? commentCount, 56 | bool? isCompleted, 57 | String? content, 58 | String? description, 59 | Due? due, 60 | int? duration, 61 | String? id, 62 | List? labels, 63 | int? order, 64 | int? priority, 65 | String? projectId, 66 | String? sectionId, 67 | String? parentId, 68 | String? url, 69 | }) { 70 | return TodoTask( 71 | creatorId: creatorId ?? this.creatorId, 72 | createdAt: createdAt ?? this.createdAt, 73 | assigneeId: assigneeId ?? this.assigneeId, 74 | assignerId: assignerId ?? this.assignerId, 75 | commentCount: commentCount ?? this.commentCount, 76 | isCompleted: isCompleted ?? this.isCompleted, 77 | content: content ?? this.content, 78 | description: description ?? this.description, 79 | due: due ?? this.due, 80 | duration: duration ?? this.duration, 81 | id: id ?? this.id, 82 | labels: labels ?? this.labels, 83 | order: order ?? this.order, 84 | priority: priority ?? this.priority, 85 | projectId: projectId ?? this.projectId, 86 | sectionId: sectionId ?? this.sectionId, 87 | parentId: parentId ?? this.parentId, 88 | url: url ?? this.url, 89 | ); 90 | } 91 | } 92 | 93 | @JsonSerializable(ignoreUnannotated: false) 94 | class Due { 95 | @JsonKey(name: 'date') 96 | final String? date; 97 | @JsonKey(name: 'is_recurring') 98 | final bool? isRecurring; 99 | @JsonKey(name: 'datetime') 100 | final String? datetime; 101 | @JsonKey(name: 'string') 102 | final String? string; 103 | @JsonKey(name: 'timezone') 104 | final String? timezone; 105 | 106 | Due({this.date, this.isRecurring, this.datetime, this.string, this.timezone}); 107 | 108 | factory Due.fromJson(Map json) => _$DueFromJson(json); 109 | 110 | Map toJson() => _$DueToJson(this); 111 | } 112 | 113 | -------------------------------------------------------------------------------- /domain/lib/model/tasks/task.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'task.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | TodoTask _$TodoTaskFromJson(Map json) => TodoTask( 10 | creatorId: json['creator_id'] as String?, 11 | createdAt: json['created_at'] as String?, 12 | assigneeId: json['assignee_id'] as String?, 13 | assignerId: json['assigner_id'] as String?, 14 | commentCount: (json['comment_count'] as num?)?.toInt(), 15 | isCompleted: json['is_completed'] as bool?, 16 | content: json['content'] as String?, 17 | description: json['description'] as String?, 18 | due: json['due'] == null 19 | ? null 20 | : Due.fromJson(json['due'] as Map), 21 | duration: (json['duration'] as num?)?.toInt(), 22 | id: json['id'] as String?, 23 | labels: 24 | (json['labels'] as List?)?.map((e) => e as String).toList(), 25 | order: (json['order'] as num?)?.toInt(), 26 | priority: (json['priority'] as num?)?.toInt(), 27 | projectId: json['project_id'] as String?, 28 | sectionId: json['section_id'] as String?, 29 | parentId: json['parent_id'] as String?, 30 | url: json['url'] as String?, 31 | ); 32 | 33 | Map _$TodoTaskToJson(TodoTask instance) => { 34 | 'creator_id': instance.creatorId, 35 | 'created_at': instance.createdAt, 36 | 'assignee_id': instance.assigneeId, 37 | 'assigner_id': instance.assignerId, 38 | 'comment_count': instance.commentCount, 39 | 'is_completed': instance.isCompleted, 40 | 'content': instance.content, 41 | 'description': instance.description, 42 | 'due': instance.due, 43 | 'duration': instance.duration, 44 | 'id': instance.id, 45 | 'labels': instance.labels, 46 | 'order': instance.order, 47 | 'priority': instance.priority, 48 | 'project_id': instance.projectId, 49 | 'section_id': instance.sectionId, 50 | 'parent_id': instance.parentId, 51 | 'url': instance.url, 52 | }; 53 | 54 | Due _$DueFromJson(Map json) => Due( 55 | date: json['date'] as String?, 56 | isRecurring: json['is_recurring'] as bool?, 57 | datetime: json['datetime'] as String?, 58 | string: json['string'] as String?, 59 | timezone: json['timezone'] as String?, 60 | ); 61 | 62 | Map _$DueToJson(Due instance) => { 63 | 'date': instance.date, 64 | 'is_recurring': instance.isRecurring, 65 | 'datetime': instance.datetime, 66 | 'string': instance.string, 67 | 'timezone': instance.timezone, 68 | }; 69 | -------------------------------------------------------------------------------- /domain/lib/model/tasks/tasks_response.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_domain/model/tasks/task.dart'; 2 | import 'package:json_annotation/json_annotation.dart'; 3 | 4 | part 'tasks_response.g.dart'; 5 | 6 | @JsonSerializable(ignoreUnannotated: false) 7 | class TasksResponse { 8 | @JsonKey(name: 'tasks') 9 | final List? tasks; 10 | 11 | TasksResponse({this.tasks}); 12 | 13 | factory TasksResponse.fromJson(Map json) => 14 | _$TasksResponseFromJson(json); 15 | 16 | Map toJson() => _$TasksResponseToJson(this); 17 | } 18 | -------------------------------------------------------------------------------- /domain/lib/model/tasks/tasks_response.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'tasks_response.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | TasksResponse _$TasksResponseFromJson(Map json) => 10 | TasksResponse( 11 | tasks: (json['tasks'] as List?) 12 | ?.map((e) => TodoTask.fromJson(e as Map)) 13 | .toList(), 14 | ); 15 | 16 | Map _$TasksResponseToJson(TasksResponse instance) => 17 | { 18 | 'tasks': instance.tasks, 19 | }; 20 | -------------------------------------------------------------------------------- /domain/lib/model/users/user.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'user.g.dart'; 4 | 5 | @JsonSerializable() 6 | class User { 7 | @JsonKey(name: 'createdAt') 8 | String? createdAt; 9 | @JsonKey(name: 'name') 10 | String? name; 11 | @JsonKey(name: 'avatar') 12 | String? avatar; 13 | @JsonKey(name: 'id') 14 | String? id; 15 | 16 | User({this.createdAt, this.name, this.avatar, this.id}); 17 | 18 | factory User.fromJson(Map json) => _$UserFromJson(json); 19 | 20 | Map toJson() => _$UserToJson(this); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /domain/lib/model/users/user.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'user.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | User _$UserFromJson(Map json) => User( 10 | createdAt: json['createdAt'] as String?, 11 | name: json['name'] as String?, 12 | avatar: json['avatar'] as String?, 13 | id: json['id'] as String?, 14 | ); 15 | 16 | Map _$UserToJson(User instance) => { 17 | 'createdAt': instance.createdAt, 18 | 'name': instance.name, 19 | 'avatar': instance.avatar, 20 | 'id': instance.id, 21 | }; 22 | -------------------------------------------------------------------------------- /domain/lib/model/users/users_response.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_domain/model/users/user.dart'; 2 | import 'package:json_annotation/json_annotation.dart'; 3 | 4 | part 'users_response.g.dart'; 5 | 6 | @JsonSerializable() 7 | class UsersResponse { 8 | @JsonKey(name: 'users') 9 | List? users; 10 | 11 | UsersResponse({this.users}); 12 | 13 | factory UsersResponse.fromJson(Map json) => _$UsersResponseFromJson(json); 14 | 15 | Map toJson() => _$UsersResponseToJson(this); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /domain/lib/model/users/users_response.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'users_response.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | UsersResponse _$UsersResponseFromJson(Map json) => 10 | UsersResponse( 11 | users: (json['users'] as List?) 12 | ?.map((e) => User.fromJson(e as Map)) 13 | .toList(), 14 | ); 15 | 16 | Map _$UsersResponseToJson(UsersResponse instance) => 17 | { 18 | 'users': instance.users, 19 | }; 20 | -------------------------------------------------------------------------------- /domain/lib/usecase/kanban/kanban_usecase.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_data/models/reasponse_dto.dart'; 2 | import 'package:azl_data/repositories/sections/sections_repository_type.dart'; 3 | import 'package:azl_data/repositories/tasks/tasks_repository_type.dart'; 4 | import 'package:azl_domain/base/error_response.dart'; 5 | import 'package:azl_domain/model/sections/section.dart'; 6 | import 'package:azl_domain/model/tasks/task.dart'; 7 | import 'package:azl_domain/usecase/kanban/kanban_usecase_type.dart'; 8 | import 'package:dartz/dartz.dart'; 9 | 10 | class KanbanUseCase extends KanbanUseCaseType { 11 | KanbanUseCase( 12 | {required this.taskRepository, required this.sectionsRepository}); 13 | 14 | final TasksRepositoryType taskRepository; 15 | final SectionsRepositoryType sectionsRepository; 16 | 17 | @override 18 | Future>> getSections() async { 19 | ResponseDto result = await sectionsRepository.getSections(); 20 | if (result.success) { 21 | List
sections = (result.response as List) 22 | .map((e) => Section.fromJson(e as Map)) 23 | .toList(); 24 | return Right(sections); 25 | } else { 26 | return Left(CodeErrorResponse(100, result.errorResponse)); 27 | } 28 | } 29 | 30 | @override 31 | Future>> getTasks() async { 32 | ResponseDto result = await taskRepository.getTasks(); 33 | if (result.success) { 34 | List tasks = (result.response as List) 35 | .map((e) => TodoTask.fromJson(e as Map)) 36 | .toList(); 37 | return Right(tasks); 38 | } else { 39 | return Left(CodeErrorResponse(100, result.errorResponse)); 40 | } 41 | } 42 | 43 | @override 44 | Future> createTask( 45 | {required TodoTask task}) async { 46 | ResponseDto result = await taskRepository.createTask(task: task.toJson()); 47 | if (result.success) { 48 | return Right(TodoTask.fromJson(result.response)); 49 | } else { 50 | return Left(CodeErrorResponse(100, result.errorResponse)); 51 | } 52 | } 53 | 54 | @override 55 | Future> updateTask( 56 | {required TodoTask task}) async { 57 | ResponseDto result = await taskRepository.updateTask( 58 | task: task.toJson(), taskId: task.id ?? ""); 59 | if (result.success) { 60 | return Right(TodoTask.fromJson(result.response)); 61 | } else { 62 | return Left(CodeErrorResponse(100, result.errorResponse)); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /domain/lib/usecase/kanban/kanban_usecase_type.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_domain/base/error_response.dart'; 2 | import 'package:azl_domain/model/sections/section.dart'; 3 | import 'package:azl_domain/model/tasks/task.dart'; 4 | import 'package:dartz/dartz.dart'; 5 | 6 | abstract class KanbanUseCaseType { 7 | Future>> getTasks(); 8 | 9 | Future>> getSections(); 10 | 11 | Future> updateTask({required TodoTask task}); 12 | 13 | Future> createTask({required TodoTask task}); 14 | } 15 | -------------------------------------------------------------------------------- /domain/lib/util/validation/email_validator.dart: -------------------------------------------------------------------------------- 1 | class EmailValidator { 2 | bool isValid(String email) { 3 | return _isValid(email.trim()); 4 | } 5 | 6 | bool _isValid(String email) { 7 | if (email.isEmpty) return false; 8 | 9 | List parts = email.split("@"); 10 | if (parts.length != 2) return false; 11 | if (_hasMultipleDots(parts[1])) return false; 12 | 13 | return RegExp( 14 | r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$') 15 | .hasMatch(email); 16 | } 17 | 18 | bool _hasMultipleDots(String email) { 19 | int firstIndex = email.indexOf("."); 20 | int lastIndex = email.lastIndexOf("."); 21 | return firstIndex != lastIndex; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /domain/lib/util/validation/mobile_number_validator.dart: -------------------------------------------------------------------------------- 1 | class MobileNumberValidator { 2 | bool isValid(String mobileNo) => _isValid(mobileNo.trim()); 3 | 4 | bool _isValid(String value) { 5 | if (value.isEmpty) return false; 6 | if (!RegExp(r"(^\+\d{8,16}$)|(^\d{8,16}$)").hasMatch(value)) { 7 | return false; 8 | } 9 | return true; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /domain/lib/util/validation/name_validator.dart: -------------------------------------------------------------------------------- 1 | class NameValidator { 2 | bool isValid(String name) { 3 | return _isValid(name.trim()); 4 | } 5 | 6 | bool _isValid(String name) { 7 | if (name.isEmpty) return false; 8 | if (name.length < 3) return false; 9 | return true; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /domain/lib/util/validation/otp_validator.dart: -------------------------------------------------------------------------------- 1 | class OtpValidator { 2 | bool isValid(String otp) { 3 | return _isValid(otp.trim()); 4 | } 5 | 6 | bool _isValid(String value) { 7 | if (value.isEmpty) return false; 8 | if (value.length < 4) return false; 9 | return true; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /domain/lib/util/validation/password_validator.dart: -------------------------------------------------------------------------------- 1 | class PasswordValidator { 2 | bool isTooShort(String password) { 3 | return password.trim().length < 7; 4 | } 5 | 6 | bool isNumberSequence(String password) { 7 | return _isSequenceOfNumbers(password.trim()); 8 | } 9 | 10 | bool hasConsecutiveRepeatingChars(String password) { 11 | return _hasConsecutiveRepeatingCharacter(password.trim()); 12 | } 13 | 14 | bool _isSequenceOfNumbers(String password) { 15 | var pattern = '0123456789012345789'; 16 | var reversePattern = '98765432109876543210'; 17 | return pattern.contains(password) || reversePattern.contains(password); 18 | } 19 | 20 | bool _hasConsecutiveRepeatingCharacter(String value) { 21 | return RegExp(r"((.)\2{2,})").hasMatch(value); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /domain/lib/util/validation/referral_code_validator.dart: -------------------------------------------------------------------------------- 1 | class ReferralCodeValidator { 2 | bool isValid(String referralCode) => _isValid(referralCode.trim()); 3 | 4 | bool _isValid(String value) { 5 | if (value.isEmpty) return true; 6 | if (value.length < 6) return false; 7 | return true; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /domain/lib/util/validation/validation_facade.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_domain/util/validation/email_validator.dart'; 2 | import 'package:azl_domain/util/validation/mobile_number_validator.dart'; 3 | import 'package:azl_domain/util/validation/name_validator.dart'; 4 | import 'package:azl_domain/util/validation/otp_validator.dart'; 5 | import 'package:azl_domain/util/validation/password_validator.dart'; 6 | import 'package:azl_domain/util/validation/referral_code_validator.dart'; 7 | import 'package:azl_domain/util/validation/validation_facade_type.dart'; 8 | 9 | class ValidationFacade implements ValidationFacadeType { 10 | final EmailValidator emailValidator; 11 | final PasswordValidator passwordValidator; 12 | final NameValidator nameValidator; 13 | final OtpValidator otpValidator; 14 | final MobileNumberValidator mobileNumberValidator; 15 | final ReferralCodeValidator referralCodeValidator; 16 | 17 | const ValidationFacade({ 18 | required this.emailValidator, 19 | required this.passwordValidator, 20 | required this.nameValidator, 21 | required this.mobileNumberValidator, 22 | required this.referralCodeValidator, 23 | required this.otpValidator, 24 | }); 25 | 26 | @override 27 | bool isEmailValid(String email) { 28 | return emailValidator.isValid(email); 29 | } 30 | 31 | @override 32 | bool isPasswordTooShort(String password) { 33 | return passwordValidator.isTooShort(password); 34 | } 35 | 36 | @override 37 | bool isPasswordNumberSequence(String password) { 38 | return passwordValidator.isNumberSequence(password); 39 | } 40 | 41 | @override 42 | bool hasConsecutiveRepeatingCharsInPassword(String password) { 43 | return passwordValidator.hasConsecutiveRepeatingChars(password); 44 | } 45 | 46 | @override 47 | bool isNameValid(String name) { 48 | return nameValidator.isValid(name); 49 | } 50 | 51 | @override 52 | bool isOtpValid(String otp) { 53 | return otpValidator.isValid(otp); 54 | } 55 | 56 | @override 57 | bool isMobileNumberValid(String mobile) { 58 | return mobileNumberValidator.isValid(mobile); 59 | } 60 | 61 | @override 62 | bool isReferralCodeValid(String referralCode) { 63 | return referralCodeValidator.isValid(referralCode); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /domain/lib/util/validation/validation_facade_type.dart: -------------------------------------------------------------------------------- 1 | abstract class ValidationFacadeType { 2 | bool isEmailValid(String email); 3 | 4 | bool isPasswordTooShort(String password); 5 | 6 | bool isPasswordNumberSequence(String password); 7 | 8 | bool hasConsecutiveRepeatingCharsInPassword(String password); 9 | 10 | bool isNameValid(String name); 11 | 12 | bool isOtpValid(String otp); 13 | 14 | bool isMobileNumberValid(String mobile); 15 | 16 | bool isReferralCodeValid(String referralCode); 17 | } 18 | -------------------------------------------------------------------------------- /domain/lib/util/validator_mixin.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_domain/util/validation/email_validator.dart'; 2 | import 'package:azl_domain/util/validation/mobile_number_validator.dart'; 3 | import 'package:azl_domain/util/validation/name_validator.dart'; 4 | import 'package:azl_domain/util/validation/otp_validator.dart'; 5 | import 'package:azl_domain/util/validation/password_validator.dart'; 6 | import 'package:azl_domain/util/validation/referral_code_validator.dart'; 7 | import 'package:azl_domain/util/validation/validation_facade.dart'; 8 | 9 | mixin ValidatorMixin { 10 | EmailValidator get emailValidator { 11 | return EmailValidator(); 12 | } 13 | 14 | PasswordValidator get passwordValidator { 15 | return PasswordValidator(); 16 | } 17 | 18 | NameValidator get nameValidator { 19 | return NameValidator(); 20 | } 21 | 22 | MobileNumberValidator get mobileNumberValidator { 23 | return MobileNumberValidator(); 24 | } 25 | 26 | ReferralCodeValidator get referralCodeValidator { 27 | return ReferralCodeValidator(); 28 | } 29 | 30 | OtpValidator get otpValidator { 31 | return OtpValidator(); 32 | } 33 | 34 | ValidationFacade get validator { 35 | return ValidationFacade( 36 | emailValidator: emailValidator, 37 | passwordValidator: passwordValidator, 38 | nameValidator: nameValidator, 39 | mobileNumberValidator: mobileNumberValidator, 40 | referralCodeValidator: referralCodeValidator, 41 | otpValidator: otpValidator, 42 | ); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /domain/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: azl_domain 2 | description: Clean Domain Layer 3 | 4 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 5 | 6 | version: 1.0.0+1 7 | 8 | environment: 9 | sdk: '>=3.4.3 <4.0.0' 10 | 11 | dependencies: 12 | 13 | equatable: ^2.0.5 14 | dartz: ^0.10.1 15 | get_it: ^7.7.0 16 | azl_data: 17 | path: ../data 18 | 19 | dev_dependencies: 20 | json_serializable: ^6.6.2 21 | build_runner: ^2.4.4 22 | flutter_lints: ^2.0.1 23 | test: ^1.25.2 -------------------------------------------------------------------------------- /domain/test/domain_test.dart: -------------------------------------------------------------------------------- 1 | 2 | 3 | main() async {} 4 | -------------------------------------------------------------------------------- /environments/.env.dev: -------------------------------------------------------------------------------- 1 | BASEDOMAIN=https://api.todoist.com 2 | URLPATH1=/rest/v2 3 | TOKEN=e837b02cf644a0dbff56b53367ac89137608ead3 -------------------------------------------------------------------------------- /environments/.env.prod: -------------------------------------------------------------------------------- 1 | BASEDOMAIN=https://api.todoist.com 2 | URLPATH1=/rest/v2 3 | TOKEN=e837b02cf644a0dbff56b53367ac89137608ead3 -------------------------------------------------------------------------------- /environments/.gitignore: -------------------------------------------------------------------------------- 1 | pubspec.lock -------------------------------------------------------------------------------- /environments/Makefile: -------------------------------------------------------------------------------- 1 | ### Makefile for tasks app ### 2 | 3 | SHELL := /bin/bash 4 | 5 | gen: ## Generate files 6 | flutter pub run build_runner build --delete-conflicting-outputs 7 | 8 | get: ## Clean Pub Get 9 | flutter pub get && flutter pub run build_runner build --delete-conflicting-outputs 10 | 11 | clean: ## Clean Pub Get 12 | flutter clean 13 | 14 | fvm-gen: ## Generate files 15 | fvm flutter pub run build_runner build --delete-conflicting-outputs 16 | 17 | fvm-get: ## Clean Pub Get 18 | fvm flutter clean && fvm flutter pub get && fvm flutter pub run build_runner build --delete-conflicting-outputs 19 | 20 | fvm-clean: ## Clean Pub Get 21 | fvm flutter clean -------------------------------------------------------------------------------- /environments/lib/env/env_dev.dart: -------------------------------------------------------------------------------- 1 | import 'package:envied/envied.dart'; 2 | 3 | part 'env_dev.g.dart'; 4 | 5 | @Envied(path: '.env.dev') 6 | abstract class EnvDev { 7 | @EnviedField(obfuscate: true, varName: "BASEDOMAIN") 8 | static String BASEDOMAIN = _EnvDev.BASEDOMAIN; 9 | 10 | @EnviedField(obfuscate: true, varName: "URLPATH1") 11 | static String URLPATH1 = _EnvDev.URLPATH1; 12 | 13 | @EnviedField(obfuscate: true, varName: "TOKEN") 14 | static String TOKEN = _EnvDev.TOKEN; 15 | } -------------------------------------------------------------------------------- /environments/lib/env/env_dev.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'env_dev.dart'; 4 | 5 | // ************************************************************************** 6 | // EnviedGenerator 7 | // ************************************************************************** 8 | 9 | // coverage:ignore-file 10 | // ignore_for_file: type=lint 11 | final class _EnvDev { 12 | static const List _enviedkeyBASEDOMAIN = [ 13 | 37240825, 14 | 4219015953, 15 | 1550601355, 16 | 156983402, 17 | 1607553104, 18 | 2385801536, 19 | 1599880704, 20 | 1586192239, 21 | 1207458289, 22 | 3028281213, 23 | 9396940, 24 | 1066822305, 25 | 4095668152, 26 | 2874474430, 27 | 3234839705, 28 | 1883853701, 29 | 95009097, 30 | 852189137, 31 | 2358807880, 32 | 2186311290, 33 | 4082407277, 34 | 1704001414, 35 | 2834270468, 36 | ]; 37 | 38 | static const List _envieddataBASEDOMAIN = [ 39 | 37240721, 40 | 4219016037, 41 | 1550601471, 42 | 156983322, 43 | 1607553059, 44 | 2385801594, 45 | 1599880751, 46 | 1586192192, 47 | 1207458192, 48 | 3028281101, 49 | 9396901, 50 | 1066822287, 51 | 4095668172, 52 | 2874474449, 53 | 3234839805, 54 | 1883853802, 55 | 95009056, 56 | 852189090, 57 | 2358807868, 58 | 2186311252, 59 | 4082407182, 60 | 1704001513, 61 | 2834270569, 62 | ]; 63 | 64 | static final String BASEDOMAIN = String.fromCharCodes(List.generate( 65 | _envieddataBASEDOMAIN.length, 66 | (int i) => i, 67 | growable: false, 68 | ).map((int i) => _envieddataBASEDOMAIN[i] ^ _enviedkeyBASEDOMAIN[i])); 69 | 70 | static const List _enviedkeyURLPATH1 = [ 71 | 3324258939, 72 | 2789995814, 73 | 335981134, 74 | 2924948064, 75 | 2436489070, 76 | 3396181418, 77 | 2524425970, 78 | 2509725336, 79 | ]; 80 | 81 | static const List _envieddataURLPATH1 = [ 82 | 3324258900, 83 | 2789995860, 84 | 335981099, 85 | 2924947987, 86 | 2436488986, 87 | 3396181381, 88 | 2524425860, 89 | 2509725354, 90 | ]; 91 | 92 | static final String URLPATH1 = String.fromCharCodes(List.generate( 93 | _envieddataURLPATH1.length, 94 | (int i) => i, 95 | growable: false, 96 | ).map((int i) => _envieddataURLPATH1[i] ^ _enviedkeyURLPATH1[i])); 97 | 98 | static const List _enviedkeyTOKEN = [ 99 | 4276330386, 100 | 101134621, 101 | 1410759969, 102 | 3704294820, 103 | 1236295113, 104 | 1776535832, 105 | 2408286316, 106 | 2700066512, 107 | 52910602, 108 | 486487790, 109 | 686193607, 110 | 4127552719, 111 | 4150901794, 112 | 2872301452, 113 | 1325458633, 114 | 62181149, 115 | 2867182629, 116 | 1575197167, 117 | 2769250773, 118 | 723024200, 119 | 800549162, 120 | 3788992503, 121 | 2441781948, 122 | 4214937957, 123 | 2722627508, 124 | 3794981835, 125 | 3469948260, 126 | 1873423505, 127 | 2271471209, 128 | 3610437790, 129 | 4212367218, 130 | 469847302, 131 | 2060282486, 132 | 1110812603, 133 | 2809213121, 134 | 589901911, 135 | 4161686456, 136 | 1589541241, 137 | 2714285015, 138 | 1798782697, 139 | ]; 140 | 141 | static const List _envieddataTOKEN = [ 142 | 4276330487, 143 | 101134629, 144 | 1410759954, 145 | 3704294803, 146 | 1236295083, 147 | 1776535848, 148 | 2408286302, 149 | 2700066483, 150 | 52910700, 151 | 486487768, 152 | 686193651, 153 | 4127552763, 154 | 4150901827, 155 | 2872301500, 156 | 1325458605, 157 | 62181247, 158 | 2867182659, 159 | 1575197065, 160 | 2769250784, 161 | 723024254, 162 | 800549192, 163 | 3788992450, 164 | 2441781903, 165 | 4214937942, 166 | 2722627458, 167 | 3794981884, 168 | 3469948165, 169 | 1873423602, 170 | 2271471185, 171 | 3610437799, 172 | 4212367171, 173 | 469847349, 174 | 2060282433, 175 | 1110812557, 176 | 2809213169, 177 | 589901935, 178 | 4161686493, 179 | 1589541144, 180 | 2714284979, 181 | 1798782682, 182 | ]; 183 | 184 | static final String TOKEN = String.fromCharCodes(List.generate( 185 | _envieddataTOKEN.length, 186 | (int i) => i, 187 | growable: false, 188 | ).map((int i) => _envieddataTOKEN[i] ^ _enviedkeyTOKEN[i])); 189 | } 190 | -------------------------------------------------------------------------------- /environments/lib/env/env_prod.dart: -------------------------------------------------------------------------------- 1 | import 'package:envied/envied.dart'; 2 | 3 | part 'env_prod.g.dart'; 4 | 5 | @Envied(path: '.env.prod') 6 | abstract class EnvProd { 7 | @EnviedField(obfuscate: true, varName: "BASEDOMAIN") 8 | static String BASEDOMAIN = _EnvProd.BASEDOMAIN; 9 | 10 | @EnviedField(obfuscate: true, varName: "URLPATH1") 11 | static String URLPATH1 = _EnvProd.URLPATH1; 12 | 13 | @EnviedField(obfuscate: true, varName: "TOKEN") 14 | static String TOKEN = _EnvProd.TOKEN; 15 | } 16 | -------------------------------------------------------------------------------- /environments/lib/env/env_prod.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'env_prod.dart'; 4 | 5 | // ************************************************************************** 6 | // EnviedGenerator 7 | // ************************************************************************** 8 | 9 | // coverage:ignore-file 10 | // ignore_for_file: type=lint 11 | final class _EnvProd { 12 | static const List _enviedkeyBASEDOMAIN = [ 13 | 4077577027, 14 | 2124485942, 15 | 1357353278, 16 | 2507268534, 17 | 190913585, 18 | 2772806471, 19 | 1084104473, 20 | 3060131772, 21 | 2867367450, 22 | 1005818707, 23 | 2070617823, 24 | 2439980746, 25 | 3982438243, 26 | 2924253498, 27 | 2157590679, 28 | 3336090228, 29 | 2645489, 30 | 4222116475, 31 | 218678916, 32 | 4066133475, 33 | 3875324268, 34 | 1766124699, 35 | 1389665884, 36 | ]; 37 | 38 | static const List _envieddataBASEDOMAIN = [ 39 | 4077577003, 40 | 2124485954, 41 | 1357353290, 42 | 2507268550, 43 | 190913602, 44 | 2772806525, 45 | 1084104502, 46 | 3060131731, 47 | 2867367547, 48 | 1005818659, 49 | 2070617782, 50 | 2439980772, 51 | 3982438167, 52 | 2924253525, 53 | 2157590771, 54 | 3336090139, 55 | 2645400, 56 | 4222116360, 57 | 218679024, 58 | 4066133453, 59 | 3875324175, 60 | 1766124788, 61 | 1389665841, 62 | ]; 63 | 64 | static final String BASEDOMAIN = String.fromCharCodes(List.generate( 65 | _envieddataBASEDOMAIN.length, 66 | (int i) => i, 67 | growable: false, 68 | ).map((int i) => _envieddataBASEDOMAIN[i] ^ _enviedkeyBASEDOMAIN[i])); 69 | 70 | static const List _enviedkeyURLPATH1 = [ 71 | 3247900005, 72 | 1040109302, 73 | 506617944, 74 | 2492135329, 75 | 2185804009, 76 | 282730051, 77 | 2522617404, 78 | 3727283859, 79 | ]; 80 | 81 | static const List _envieddataURLPATH1 = [ 82 | 3247899978, 83 | 1040109188, 84 | 506617917, 85 | 2492135378, 86 | 2185803933, 87 | 282730092, 88 | 2522617418, 89 | 3727283873, 90 | ]; 91 | 92 | static final String URLPATH1 = String.fromCharCodes(List.generate( 93 | _envieddataURLPATH1.length, 94 | (int i) => i, 95 | growable: false, 96 | ).map((int i) => _envieddataURLPATH1[i] ^ _enviedkeyURLPATH1[i])); 97 | 98 | static const List _enviedkeyTOKEN = [ 99 | 3643855378, 100 | 3542815550, 101 | 4050439824, 102 | 4142128084, 103 | 1674837145, 104 | 2118975408, 105 | 186968358, 106 | 1399299562, 107 | 2653540876, 108 | 1196741608, 109 | 2855483844, 110 | 1118153667, 111 | 2407797759, 112 | 1358437077, 113 | 1391517846, 114 | 4189968393, 115 | 719949223, 116 | 2843151288, 117 | 3202404208, 118 | 2718880120, 119 | 1625903469, 120 | 1081348426, 121 | 2093284425, 122 | 338011589, 123 | 2932770041, 124 | 3414464853, 125 | 694483947, 126 | 42967306, 127 | 2190445437, 128 | 2028427566, 129 | 2259387522, 130 | 486532221, 131 | 3958132665, 132 | 1101456894, 133 | 2271698328, 134 | 2080684320, 135 | 3414115574, 136 | 857432271, 137 | 858767000, 138 | 3505397706, 139 | ]; 140 | 141 | static const List _envieddataTOKEN = [ 142 | 3643855479, 143 | 3542815494, 144 | 4050439843, 145 | 4142128099, 146 | 1674837243, 147 | 2118975360, 148 | 186968340, 149 | 1399299465, 150 | 2653540970, 151 | 1196741598, 152 | 2855483888, 153 | 1118153719, 154 | 2407797662, 155 | 1358437093, 156 | 1391517938, 157 | 4189968491, 158 | 719949249, 159 | 2843151326, 160 | 3202404165, 161 | 2718880078, 162 | 1625903375, 163 | 1081348479, 164 | 2093284474, 165 | 338011638, 166 | 2932769999, 167 | 3414464866, 168 | 694483850, 169 | 42967401, 170 | 2190445381, 171 | 2028427543, 172 | 2259387571, 173 | 486532174, 174 | 3958132622, 175 | 1101456840, 176 | 2271698344, 177 | 2080684312, 178 | 3414115475, 179 | 857432238, 180 | 858767100, 181 | 3505397753, 182 | ]; 183 | 184 | static final String TOKEN = String.fromCharCodes(List.generate( 185 | _envieddataTOKEN.length, 186 | (int i) => i, 187 | growable: false, 188 | ).map((int i) => _envieddataTOKEN[i] ^ _enviedkeyTOKEN[i])); 189 | } 190 | -------------------------------------------------------------------------------- /environments/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: environments 2 | description: Used to fetch different environments. 3 | 4 | environment: 5 | sdk: '>=3.4.3 <4.0.0' 6 | 7 | dependencies: 8 | envied: 0.5.4+1 9 | 10 | dev_dependencies: 11 | envied_generator: 0.5.4+1 12 | build_runner: 2.4.8 -------------------------------------------------------------------------------- /environments/test/env_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:environments/env/env_prod.dart'; 2 | 3 | main() { 4 | print("BASEURL IS :: ${EnvProd.BASEDOMAIN}"); 5 | print("PATH IS :: ${EnvProd.URLPATH1}"); 6 | print("TOEN IS :: ${EnvProd.TOKEN}"); 7 | } 8 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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 | 12.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '12.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 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - shared_preferences_foundation (0.0.1): 4 | - Flutter 5 | - FlutterMacOS 6 | - sqflite (0.0.3): 7 | - Flutter 8 | - FlutterMacOS 9 | 10 | DEPENDENCIES: 11 | - Flutter (from `Flutter`) 12 | - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) 13 | - sqflite (from `.symlinks/plugins/sqflite/darwin`) 14 | 15 | EXTERNAL SOURCES: 16 | Flutter: 17 | :path: Flutter 18 | shared_preferences_foundation: 19 | :path: ".symlinks/plugins/shared_preferences_foundation/darwin" 20 | sqflite: 21 | :path: ".symlinks/plugins/sqflite/darwin" 22 | 23 | SPEC CHECKSUMS: 24 | Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 25 | shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 26 | sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec 27 | 28 | PODFILE CHECKSUM: c4c93c5f6502fe2754f48404d3594bf779584011 29 | 30 | COCOAPODS: 1.15.2 31 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 05BB2BA960EB5784FC90C8A2 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A192E44098823E10DF8CB1C7 /* Pods_Runner.framework */; }; 11 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 13 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 14 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 15 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 16 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXCopyFilesBuildPhase section */ 20 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 21 | isa = PBXCopyFilesBuildPhase; 22 | buildActionMask = 2147483647; 23 | dstPath = ""; 24 | dstSubfolderSpec = 10; 25 | files = ( 26 | ); 27 | name = "Embed Frameworks"; 28 | runOnlyForDeploymentPostprocessing = 0; 29 | }; 30 | /* End PBXCopyFilesBuildPhase section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 34 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 35 | 2F2E315D64DAE282EB7E0BAC /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 36 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 37 | 6BD528030749932660BD6578 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 38 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 39 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 40 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 41 | 818E627E6369C09286C1A9CA /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 42 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 43 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 44 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 46 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 47 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 48 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 49 | A192E44098823E10DF8CB1C7 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | 05BB2BA960EB5784FC90C8A2 /* Pods_Runner.framework in Frameworks */, 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXFrameworksBuildPhase section */ 62 | 63 | /* Begin PBXGroup section */ 64 | 3DB167F9F45E35584B817AAC /* Pods */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 6BD528030749932660BD6578 /* Pods-Runner.debug.xcconfig */, 68 | 818E627E6369C09286C1A9CA /* Pods-Runner.release.xcconfig */, 69 | 2F2E315D64DAE282EB7E0BAC /* Pods-Runner.profile.xcconfig */, 70 | ); 71 | name = Pods; 72 | path = Pods; 73 | sourceTree = ""; 74 | }; 75 | 63E7F028A9B2EC628C8A9247 /* Frameworks */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | A192E44098823E10DF8CB1C7 /* Pods_Runner.framework */, 79 | ); 80 | name = Frameworks; 81 | sourceTree = ""; 82 | }; 83 | 9740EEB11CF90186004384FC /* Flutter */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 87 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 88 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 89 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 90 | ); 91 | name = Flutter; 92 | sourceTree = ""; 93 | }; 94 | 97C146E51CF9000F007C117D = { 95 | isa = PBXGroup; 96 | children = ( 97 | 9740EEB11CF90186004384FC /* Flutter */, 98 | 97C146F01CF9000F007C117D /* Runner */, 99 | 97C146EF1CF9000F007C117D /* Products */, 100 | 3DB167F9F45E35584B817AAC /* Pods */, 101 | 63E7F028A9B2EC628C8A9247 /* Frameworks */, 102 | ); 103 | sourceTree = ""; 104 | }; 105 | 97C146EF1CF9000F007C117D /* Products */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 97C146EE1CF9000F007C117D /* Runner.app */, 109 | ); 110 | name = Products; 111 | sourceTree = ""; 112 | }; 113 | 97C146F01CF9000F007C117D /* Runner */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 117 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 118 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 119 | 97C147021CF9000F007C117D /* Info.plist */, 120 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 121 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 122 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 123 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 124 | ); 125 | path = Runner; 126 | sourceTree = ""; 127 | }; 128 | /* End PBXGroup section */ 129 | 130 | /* Begin PBXNativeTarget section */ 131 | 97C146ED1CF9000F007C117D /* Runner */ = { 132 | isa = PBXNativeTarget; 133 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 134 | buildPhases = ( 135 | 707252999D20F2867B8EF30F /* [CP] Check Pods Manifest.lock */, 136 | 9740EEB61CF901F6004384FC /* Run Script */, 137 | 97C146EA1CF9000F007C117D /* Sources */, 138 | 97C146EB1CF9000F007C117D /* Frameworks */, 139 | 97C146EC1CF9000F007C117D /* Resources */, 140 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 141 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 142 | 6F190919E068FCD40554466B /* [CP] Embed Pods Frameworks */, 143 | ); 144 | buildRules = ( 145 | ); 146 | dependencies = ( 147 | ); 148 | name = Runner; 149 | productName = Runner; 150 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 151 | productType = "com.apple.product-type.application"; 152 | }; 153 | /* End PBXNativeTarget section */ 154 | 155 | /* Begin PBXProject section */ 156 | 97C146E61CF9000F007C117D /* Project object */ = { 157 | isa = PBXProject; 158 | attributes = { 159 | LastUpgradeCheck = 1510; 160 | ORGANIZATIONNAME = ""; 161 | TargetAttributes = { 162 | 97C146ED1CF9000F007C117D = { 163 | CreatedOnToolsVersion = 7.3.1; 164 | LastSwiftMigration = 1100; 165 | }; 166 | }; 167 | }; 168 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 169 | compatibilityVersion = "Xcode 9.3"; 170 | developmentRegion = en; 171 | hasScannedForEncodings = 0; 172 | knownRegions = ( 173 | en, 174 | Base, 175 | ); 176 | mainGroup = 97C146E51CF9000F007C117D; 177 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 178 | projectDirPath = ""; 179 | projectRoot = ""; 180 | targets = ( 181 | 97C146ED1CF9000F007C117D /* Runner */, 182 | ); 183 | }; 184 | /* End PBXProject section */ 185 | 186 | /* Begin PBXResourcesBuildPhase section */ 187 | 97C146EC1CF9000F007C117D /* Resources */ = { 188 | isa = PBXResourcesBuildPhase; 189 | buildActionMask = 2147483647; 190 | files = ( 191 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 192 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 193 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 194 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | }; 198 | /* End PBXResourcesBuildPhase section */ 199 | 200 | /* Begin PBXShellScriptBuildPhase section */ 201 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 202 | isa = PBXShellScriptBuildPhase; 203 | alwaysOutOfDate = 1; 204 | buildActionMask = 2147483647; 205 | files = ( 206 | ); 207 | inputPaths = ( 208 | "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", 209 | ); 210 | name = "Thin Binary"; 211 | outputPaths = ( 212 | ); 213 | runOnlyForDeploymentPostprocessing = 0; 214 | shellPath = /bin/sh; 215 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 216 | }; 217 | 6F190919E068FCD40554466B /* [CP] Embed Pods Frameworks */ = { 218 | isa = PBXShellScriptBuildPhase; 219 | buildActionMask = 2147483647; 220 | files = ( 221 | ); 222 | inputFileListPaths = ( 223 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", 224 | ); 225 | name = "[CP] Embed Pods Frameworks"; 226 | outputFileListPaths = ( 227 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", 228 | ); 229 | runOnlyForDeploymentPostprocessing = 0; 230 | shellPath = /bin/sh; 231 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 232 | showEnvVarsInLog = 0; 233 | }; 234 | 707252999D20F2867B8EF30F /* [CP] Check Pods Manifest.lock */ = { 235 | isa = PBXShellScriptBuildPhase; 236 | buildActionMask = 2147483647; 237 | files = ( 238 | ); 239 | inputFileListPaths = ( 240 | ); 241 | inputPaths = ( 242 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 243 | "${PODS_ROOT}/Manifest.lock", 244 | ); 245 | name = "[CP] Check Pods Manifest.lock"; 246 | outputFileListPaths = ( 247 | ); 248 | outputPaths = ( 249 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 250 | ); 251 | runOnlyForDeploymentPostprocessing = 0; 252 | shellPath = /bin/sh; 253 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 254 | showEnvVarsInLog = 0; 255 | }; 256 | 9740EEB61CF901F6004384FC /* Run Script */ = { 257 | isa = PBXShellScriptBuildPhase; 258 | alwaysOutOfDate = 1; 259 | buildActionMask = 2147483647; 260 | files = ( 261 | ); 262 | inputPaths = ( 263 | ); 264 | name = "Run Script"; 265 | outputPaths = ( 266 | ); 267 | runOnlyForDeploymentPostprocessing = 0; 268 | shellPath = /bin/sh; 269 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 270 | }; 271 | /* End PBXShellScriptBuildPhase section */ 272 | 273 | /* Begin PBXSourcesBuildPhase section */ 274 | 97C146EA1CF9000F007C117D /* Sources */ = { 275 | isa = PBXSourcesBuildPhase; 276 | buildActionMask = 2147483647; 277 | files = ( 278 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 279 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 280 | ); 281 | runOnlyForDeploymentPostprocessing = 0; 282 | }; 283 | /* End PBXSourcesBuildPhase section */ 284 | 285 | /* Begin PBXVariantGroup section */ 286 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 287 | isa = PBXVariantGroup; 288 | children = ( 289 | 97C146FB1CF9000F007C117D /* Base */, 290 | ); 291 | name = Main.storyboard; 292 | sourceTree = ""; 293 | }; 294 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 295 | isa = PBXVariantGroup; 296 | children = ( 297 | 97C147001CF9000F007C117D /* Base */, 298 | ); 299 | name = LaunchScreen.storyboard; 300 | sourceTree = ""; 301 | }; 302 | /* End PBXVariantGroup section */ 303 | 304 | /* Begin XCBuildConfiguration section */ 305 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 306 | isa = XCBuildConfiguration; 307 | buildSettings = { 308 | ALWAYS_SEARCH_USER_PATHS = NO; 309 | CLANG_ANALYZER_NONNULL = YES; 310 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 311 | CLANG_CXX_LIBRARY = "libc++"; 312 | CLANG_ENABLE_MODULES = YES; 313 | CLANG_ENABLE_OBJC_ARC = YES; 314 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 315 | CLANG_WARN_BOOL_CONVERSION = YES; 316 | CLANG_WARN_COMMA = YES; 317 | CLANG_WARN_CONSTANT_CONVERSION = YES; 318 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 319 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 320 | CLANG_WARN_EMPTY_BODY = YES; 321 | CLANG_WARN_ENUM_CONVERSION = YES; 322 | CLANG_WARN_INFINITE_RECURSION = YES; 323 | CLANG_WARN_INT_CONVERSION = YES; 324 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 325 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 326 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 327 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 328 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 329 | CLANG_WARN_STRICT_PROTOTYPES = YES; 330 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 331 | CLANG_WARN_UNREACHABLE_CODE = YES; 332 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 333 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 334 | COPY_PHASE_STRIP = NO; 335 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 336 | ENABLE_NS_ASSERTIONS = NO; 337 | ENABLE_STRICT_OBJC_MSGSEND = YES; 338 | GCC_C_LANGUAGE_STANDARD = gnu99; 339 | GCC_NO_COMMON_BLOCKS = YES; 340 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 341 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 342 | GCC_WARN_UNDECLARED_SELECTOR = YES; 343 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 344 | GCC_WARN_UNUSED_FUNCTION = YES; 345 | GCC_WARN_UNUSED_VARIABLE = YES; 346 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 347 | MTL_ENABLE_DEBUG_INFO = NO; 348 | SDKROOT = iphoneos; 349 | SUPPORTED_PLATFORMS = iphoneos; 350 | TARGETED_DEVICE_FAMILY = "1,2"; 351 | VALIDATE_PRODUCT = YES; 352 | }; 353 | name = Profile; 354 | }; 355 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 356 | isa = XCBuildConfiguration; 357 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 358 | buildSettings = { 359 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 360 | CLANG_ENABLE_MODULES = YES; 361 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 362 | DEVELOPMENT_TEAM = 6QTVP9MP3C; 363 | ENABLE_BITCODE = NO; 364 | INFOPLIST_FILE = Runner/Info.plist; 365 | LD_RUNPATH_SEARCH_PATHS = ( 366 | "$(inherited)", 367 | "@executable_path/Frameworks", 368 | ); 369 | PRODUCT_BUNDLE_IDENTIFIER = com.organization.sampleProject; 370 | PRODUCT_NAME = "$(TARGET_NAME)"; 371 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 372 | SWIFT_VERSION = 5.0; 373 | VERSIONING_SYSTEM = "apple-generic"; 374 | }; 375 | name = Profile; 376 | }; 377 | 97C147031CF9000F007C117D /* Debug */ = { 378 | isa = XCBuildConfiguration; 379 | buildSettings = { 380 | ALWAYS_SEARCH_USER_PATHS = NO; 381 | CLANG_ANALYZER_NONNULL = YES; 382 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 383 | CLANG_CXX_LIBRARY = "libc++"; 384 | CLANG_ENABLE_MODULES = YES; 385 | CLANG_ENABLE_OBJC_ARC = YES; 386 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 387 | CLANG_WARN_BOOL_CONVERSION = YES; 388 | CLANG_WARN_COMMA = YES; 389 | CLANG_WARN_CONSTANT_CONVERSION = YES; 390 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 391 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 392 | CLANG_WARN_EMPTY_BODY = YES; 393 | CLANG_WARN_ENUM_CONVERSION = YES; 394 | CLANG_WARN_INFINITE_RECURSION = YES; 395 | CLANG_WARN_INT_CONVERSION = YES; 396 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 397 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 398 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 399 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 400 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 401 | CLANG_WARN_STRICT_PROTOTYPES = YES; 402 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 403 | CLANG_WARN_UNREACHABLE_CODE = YES; 404 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 405 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 406 | COPY_PHASE_STRIP = NO; 407 | DEBUG_INFORMATION_FORMAT = dwarf; 408 | ENABLE_STRICT_OBJC_MSGSEND = YES; 409 | ENABLE_TESTABILITY = YES; 410 | GCC_C_LANGUAGE_STANDARD = gnu99; 411 | GCC_DYNAMIC_NO_PIC = NO; 412 | GCC_NO_COMMON_BLOCKS = YES; 413 | GCC_OPTIMIZATION_LEVEL = 0; 414 | GCC_PREPROCESSOR_DEFINITIONS = ( 415 | "DEBUG=1", 416 | "$(inherited)", 417 | ); 418 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 419 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 420 | GCC_WARN_UNDECLARED_SELECTOR = YES; 421 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 422 | GCC_WARN_UNUSED_FUNCTION = YES; 423 | GCC_WARN_UNUSED_VARIABLE = YES; 424 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 425 | MTL_ENABLE_DEBUG_INFO = YES; 426 | ONLY_ACTIVE_ARCH = YES; 427 | SDKROOT = iphoneos; 428 | TARGETED_DEVICE_FAMILY = "1,2"; 429 | }; 430 | name = Debug; 431 | }; 432 | 97C147041CF9000F007C117D /* Release */ = { 433 | isa = XCBuildConfiguration; 434 | buildSettings = { 435 | ALWAYS_SEARCH_USER_PATHS = NO; 436 | CLANG_ANALYZER_NONNULL = YES; 437 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 438 | CLANG_CXX_LIBRARY = "libc++"; 439 | CLANG_ENABLE_MODULES = YES; 440 | CLANG_ENABLE_OBJC_ARC = YES; 441 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 442 | CLANG_WARN_BOOL_CONVERSION = YES; 443 | CLANG_WARN_COMMA = YES; 444 | CLANG_WARN_CONSTANT_CONVERSION = YES; 445 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 446 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 447 | CLANG_WARN_EMPTY_BODY = YES; 448 | CLANG_WARN_ENUM_CONVERSION = YES; 449 | CLANG_WARN_INFINITE_RECURSION = YES; 450 | CLANG_WARN_INT_CONVERSION = YES; 451 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 452 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 453 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 454 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 455 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 456 | CLANG_WARN_STRICT_PROTOTYPES = YES; 457 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 458 | CLANG_WARN_UNREACHABLE_CODE = YES; 459 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 460 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 461 | COPY_PHASE_STRIP = NO; 462 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 463 | ENABLE_NS_ASSERTIONS = NO; 464 | ENABLE_STRICT_OBJC_MSGSEND = YES; 465 | GCC_C_LANGUAGE_STANDARD = gnu99; 466 | GCC_NO_COMMON_BLOCKS = YES; 467 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 468 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 469 | GCC_WARN_UNDECLARED_SELECTOR = YES; 470 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 471 | GCC_WARN_UNUSED_FUNCTION = YES; 472 | GCC_WARN_UNUSED_VARIABLE = YES; 473 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 474 | MTL_ENABLE_DEBUG_INFO = NO; 475 | SDKROOT = iphoneos; 476 | SUPPORTED_PLATFORMS = iphoneos; 477 | SWIFT_COMPILATION_MODE = wholemodule; 478 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 479 | TARGETED_DEVICE_FAMILY = "1,2"; 480 | VALIDATE_PRODUCT = YES; 481 | }; 482 | name = Release; 483 | }; 484 | 97C147061CF9000F007C117D /* Debug */ = { 485 | isa = XCBuildConfiguration; 486 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 487 | buildSettings = { 488 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 489 | CLANG_ENABLE_MODULES = YES; 490 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 491 | DEVELOPMENT_TEAM = 6QTVP9MP3C; 492 | ENABLE_BITCODE = NO; 493 | INFOPLIST_FILE = Runner/Info.plist; 494 | LD_RUNPATH_SEARCH_PATHS = ( 495 | "$(inherited)", 496 | "@executable_path/Frameworks", 497 | ); 498 | PRODUCT_BUNDLE_IDENTIFIER = com.organization.sampleProject; 499 | PRODUCT_NAME = "$(TARGET_NAME)"; 500 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 501 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 502 | SWIFT_VERSION = 5.0; 503 | VERSIONING_SYSTEM = "apple-generic"; 504 | }; 505 | name = Debug; 506 | }; 507 | 97C147071CF9000F007C117D /* Release */ = { 508 | isa = XCBuildConfiguration; 509 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 510 | buildSettings = { 511 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 512 | CLANG_ENABLE_MODULES = YES; 513 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 514 | DEVELOPMENT_TEAM = 6QTVP9MP3C; 515 | ENABLE_BITCODE = NO; 516 | INFOPLIST_FILE = Runner/Info.plist; 517 | LD_RUNPATH_SEARCH_PATHS = ( 518 | "$(inherited)", 519 | "@executable_path/Frameworks", 520 | ); 521 | PRODUCT_BUNDLE_IDENTIFIER = com.organization.sampleProject; 522 | PRODUCT_NAME = "$(TARGET_NAME)"; 523 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 524 | SWIFT_VERSION = 5.0; 525 | VERSIONING_SYSTEM = "apple-generic"; 526 | }; 527 | name = Release; 528 | }; 529 | /* End XCBuildConfiguration section */ 530 | 531 | /* Begin XCConfigurationList section */ 532 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 533 | isa = XCConfigurationList; 534 | buildConfigurations = ( 535 | 97C147031CF9000F007C117D /* Debug */, 536 | 97C147041CF9000F007C117D /* Release */, 537 | 249021D3217E4FDB00AE95B9 /* Profile */, 538 | ); 539 | defaultConfigurationIsVisible = 0; 540 | defaultConfigurationName = Release; 541 | }; 542 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 543 | isa = XCConfigurationList; 544 | buildConfigurations = ( 545 | 97C147061CF9000F007C117D /* Debug */, 546 | 97C147071CF9000F007C117D /* Release */, 547 | 249021D4217E4FDB00AE95B9 /* Profile */, 548 | ); 549 | defaultConfigurationIsVisible = 0; 550 | defaultConfigurationName = Release; 551 | }; 552 | /* End XCConfigurationList section */ 553 | }; 554 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 555 | } 556 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.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 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/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/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/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/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/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/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/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/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/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/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/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/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/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/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/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/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/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/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/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/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/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/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/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/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azlaan95/Flutter-Clean-Architecture/7a9a1f14b5c53fd41c304d181d23a6db1aa51ece/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /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. -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.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 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Sample Project 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | sample_project 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIViewControllerBasedStatusBarAppearance 45 | 46 | CADisableMinimumFrameDurationOnPhone 47 | 48 | UIApplicationSupportsIndirectInputEvents 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /lib/di/AppConfigure.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_domain/di/domain_injection.dart'; 2 | import 'package:azl_data/config/environment.dart'; 3 | 4 | class AppConfigure { 5 | static configure(Environment environment, {bool enableMock = false}) { 6 | DomainInjection.configure(environment, enableMock); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /lib/entry_point/main_dev.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_data/config/app_config.dart'; 2 | import 'package:environments/env/env_dev.dart'; 3 | import 'package:kanban_taskmanager/di/AppConfigure.dart'; 4 | import 'package:kanban_taskmanager/environment/development/development_env.dart'; 5 | 6 | import 'my_app.dart'; 7 | 8 | Future main() async { 9 | AppConfigure.configure(DevelopmentEnvironment.development()); 10 | AppConfig.shared.token = "Bearer ${EnvDev.TOKEN}"; 11 | await myMain(); 12 | } 13 | -------------------------------------------------------------------------------- /lib/entry_point/main_mock.dart: -------------------------------------------------------------------------------- 1 | import 'package:kanban_taskmanager/di/AppConfigure.dart'; 2 | import 'package:kanban_taskmanager/environment/development/development_env.dart'; 3 | 4 | import 'my_app.dart'; 5 | 6 | Future main() async { 7 | AppConfigure.configure(DevelopmentEnvironment.development(), 8 | enableMock: false); 9 | await myMain(); 10 | } 11 | -------------------------------------------------------------------------------- /lib/entry_point/main_prod.dart: -------------------------------------------------------------------------------- 1 | import 'package:kanban_taskmanager/di/AppConfigure.dart'; 2 | import 'package:kanban_taskmanager/environment/development/development_env.dart'; 3 | 4 | import 'my_app.dart'; 5 | 6 | Future main() async { 7 | AppConfigure.configure(DevelopmentEnvironment.development()); 8 | await myMain(); 9 | } 10 | -------------------------------------------------------------------------------- /lib/entry_point/my_app.dart: -------------------------------------------------------------------------------- 1 | import 'package:easy_localization/easy_localization.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 4 | import 'package:kanban_taskmanager/router/gen_route.dart'; 5 | import 'package:kanban_taskmanager/router/navigation_controller.dart'; 6 | import 'package:kanban_taskmanager/util/app_global.dart' as global; 7 | import 'package:kanban_taskmanager/util/assets/app_locale.dart'; 8 | 9 | Future myMain() async { 10 | WidgetsFlutterBinding.ensureInitialized(); 11 | await EasyLocalization.ensureInitialized(); 12 | await ScreenUtil.ensureScreenSize(); 13 | 14 | runApp(EasyLocalization( 15 | supportedLocales: [AppLocales.en.language, AppLocales.hi.language], 16 | path: AppLocales.path, 17 | fallbackLocale: AppLocales.en.language, 18 | startLocale: AppLocales.en.language, 19 | child: const MyApp(), 20 | )); 21 | } 22 | 23 | class MyApp extends StatefulWidget { 24 | const MyApp({Key? key}) : super(key: key); 25 | 26 | @override 27 | State createState() => MyAppState(); 28 | } 29 | 30 | class MyAppState extends State { 31 | @override 32 | void initState() { 33 | super.initState(); 34 | } 35 | 36 | @override 37 | Widget build(BuildContext context) { 38 | ScreenUtil.init(context); 39 | return SafeArea( 40 | child: MaterialApp( 41 | debugShowCheckedModeBanner: false, 42 | localizationsDelegates: context.localizationDelegates, 43 | supportedLocales: context.supportedLocales, 44 | locale: context.locale, 45 | navigatorObservers: [global.navigationObserver], 46 | theme: global.them, 47 | onGenerateRoute: generateRoute, 48 | navigatorKey: NavigationController.globalNavigatorKey, 49 | ), 50 | ); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/environment/development/development_env.dart: -------------------------------------------------------------------------------- 1 | import 'package:environments/env/env_dev.dart'; 2 | import 'package:azl_data/config/environment.dart'; 3 | 4 | extension DevelopmentEnvironment on Environment { 5 | static Environment development() { 6 | return Environment( 7 | baseUrl: EnvDev.BASEDOMAIN, 8 | path1: EnvDev.URLPATH1, 9 | token: EnvDev.TOKEN); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /lib/environment/production/production_env.dart: -------------------------------------------------------------------------------- 1 | import 'package:environments/env/env_prod.dart'; 2 | import 'package:azl_data/config/environment.dart'; 3 | 4 | extension ProductionEnvironment on Environment { 5 | static Environment production() { 6 | return Environment( 7 | baseUrl: EnvProd.BASEDOMAIN, 8 | path1: EnvProd.URLPATH1, 9 | token: EnvProd.TOKEN); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /lib/generated_plugin_registrant.dart: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // ignore_for_file: directives_ordering 6 | // ignore_for_file: lines_longer_than_80_chars 7 | // ignore_for_file: depend_on_referenced_packages 8 | 9 | import 'package:shared_preferences_web/shared_preferences_web.dart'; 10 | 11 | import 'package:flutter_web_plugins/flutter_web_plugins.dart'; 12 | 13 | // ignore: public_member_api_docs 14 | void registerPlugins(Registrar registrar) { 15 | SharedPreferencesPlugin.registerWith(registrar); 16 | registrar.registerMessageHandler(); 17 | } 18 | -------------------------------------------------------------------------------- /lib/presentation/kanban_board/bloc/kanban_bloc.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | import 'dart:math'; 3 | 4 | import 'package:azl_domain/model/sections/section.dart'; 5 | import 'package:azl_domain/model/tasks/task.dart'; 6 | import 'package:azl_domain/usecase/kanban/kanban_usecase_type.dart'; 7 | import 'package:flutter_bloc/flutter_bloc.dart'; 8 | import 'package:kanban_taskmanager/presentation/kanban_board/bloc/kanban_state.dart'; 9 | 10 | class KanbanBloc extends Cubit { 11 | KanbanBloc(this.useCaseType) : super(const KanbanState(loading: true)); 12 | 13 | final KanbanUseCaseType useCaseType; 14 | 15 | getSections() async { 16 | final result = await useCaseType.getSections(); 17 | result.fold((error) { 18 | emit(state.copyWith(loading: false, message: error.message, error: true)); 19 | }, (success) { 20 | getTasks(sections: success); 21 | }); 22 | } 23 | 24 | getTasks({required List
sections}) async { 25 | final result = await useCaseType.getTasks(); 26 | result.fold((error) { 27 | emit(state.copyWith(loading: false, message: error.message, error: true)); 28 | }, (successTasks) { 29 | generateSectionMap(sections: sections, tasks: successTasks); 30 | }); 31 | } 32 | 33 | Future updateTask({required TodoTask task}) async { 34 | final result = await useCaseType.updateTask(task: task); 35 | if (result.isLeft()) { 36 | return Future.value(false); 37 | } else { 38 | return Future.value(true); 39 | } 40 | } 41 | 42 | generateSectionMap( 43 | {required List
sections, required List tasks}) { 44 | HashMap> kanbanList = HashMap(); 45 | for (var section in sections) { 46 | List filteredTasks = tasks.where( 47 | (taskElement) { 48 | return (taskElement.sectionId == section.id); 49 | }, 50 | ).toList(); 51 | filteredTasks.sort((a, b) => (a.order ?? 0).compareTo((b.order ?? 0))); 52 | kanbanList.putIfAbsent( 53 | section.id ?? "", 54 | () => filteredTasks, 55 | ); 56 | } 57 | emit(state.copyWith( 58 | loading: false, 59 | kanbanList: kanbanList, 60 | sections: sections, 61 | tasks: tasks, 62 | error: false)); 63 | } 64 | 65 | updateList( 66 | {required String targetSection, 67 | required int targetOrder, 68 | required TodoTask droppedTask}) async { 69 | HashMap> kanbanTasks = state.kanbanList ?? HashMap(); 70 | TodoTask updatedTask = 71 | droppedTask.copyWith(order: targetOrder + 1, sectionId: targetSection); 72 | kanbanTasks[targetSection]?.insert(targetOrder, updatedTask); 73 | //bool isAdded = await updateTask(task: updatedTask); 74 | //if (!isAdded) return; 75 | if (targetSection == droppedTask.sectionId) { 76 | kanbanTasks[targetSection]?.remove(droppedTask); 77 | } else { 78 | kanbanTasks[droppedTask.sectionId]?.remove(droppedTask); 79 | } 80 | emit(state.copyWith( 81 | kanbanList: kanbanTasks, randomUpdate: Random().nextInt(10))); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /lib/presentation/kanban_board/bloc/kanban_state.dart: -------------------------------------------------------------------------------- 1 | import 'dart:collection'; 2 | 3 | import 'package:azl_domain/model/sections/section.dart'; 4 | import 'package:azl_domain/model/tasks/task.dart'; 5 | import 'package:equatable/equatable.dart'; 6 | 7 | class KanbanState extends Equatable { 8 | const KanbanState( 9 | {this.message, 10 | this.sections, 11 | this.loading, 12 | this.error, 13 | this.tasks, 14 | this.kanbanList, 15 | this.randomUpdate}); 16 | 17 | final String? message; 18 | final HashMap>? kanbanList; 19 | final List
? sections; 20 | final List? tasks; 21 | final bool? loading; 22 | final bool? error; 23 | final int? randomUpdate; 24 | 25 | @override 26 | List get props => 27 | [message, sections, tasks, loading, error, kanbanList, randomUpdate]; 28 | 29 | KanbanState copyWith( 30 | {String? message, 31 | HashMap>? kanbanList, 32 | List
? sections, 33 | List? tasks, 34 | bool? loading, 35 | bool? error, 36 | int? randomUpdate}) { 37 | return KanbanState( 38 | message: message ?? this.message, 39 | kanbanList: kanbanList ?? this.kanbanList, 40 | sections: sections ?? this.sections, 41 | tasks: tasks ?? this.tasks, 42 | loading: loading ?? this.loading, 43 | error: error ?? this.error, 44 | randomUpdate: randomUpdate ?? this.randomUpdate); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lib/presentation/kanban_board/kanban_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_domain/di/domain_injection.dart'; 2 | import 'package:azl_domain/model/sections/section.dart'; 3 | import 'package:azl_domain/model/tasks/task.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter/scheduler.dart'; 6 | import 'package:flutter_bloc/flutter_bloc.dart'; 7 | import 'package:kanban_taskmanager/presentation/kanban_board/bloc/kanban_bloc.dart'; 8 | import 'package:kanban_taskmanager/presentation/kanban_board/bloc/kanban_state.dart'; 9 | import 'package:kanban_taskmanager/presentation/kanban_board/widgets/kanban_drag_target.dart'; 10 | import 'package:kanban_taskmanager/presentation/kanban_board/widgets/kanban_draggable.dart'; 11 | 12 | class KanbanScreen extends StatelessWidget { 13 | const KanbanScreen({super.key}); 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | return BlocProvider( 18 | create: (context) { 19 | KanbanBloc bloc = KanbanBloc(DomainInjection.getIt()); 20 | SchedulerBinding.instance.addPostFrameCallback((_) { 21 | bloc.getSections(); 22 | }); 23 | return bloc; 24 | }, 25 | child: const KanbanPage(), 26 | ); 27 | } 28 | } 29 | 30 | class KanbanPage extends StatelessWidget { 31 | const KanbanPage({super.key}); 32 | 33 | @override 34 | Widget build(BuildContext context) { 35 | return Scaffold( 36 | appBar: AppBar( 37 | title: const Text("Users List"), 38 | ), 39 | body: BlocBuilder(builder: (context, state) { 40 | if (state.loading ?? false) { 41 | return const Center( 42 | child: CircularProgressIndicator(), 43 | ); 44 | } 45 | if (state.error ?? false) { 46 | return Center( 47 | child: Text( 48 | state.message ?? "", 49 | textAlign: TextAlign.center, 50 | ), 51 | ); 52 | } 53 | return ListView.builder( 54 | itemCount: state.sections?.length ?? 0, 55 | scrollDirection: Axis.horizontal, 56 | itemBuilder: (context, sectionIndex) { 57 | Section? sectionListItem = state.sections?[sectionIndex]; 58 | return Padding( 59 | padding: const EdgeInsets.all(8.0), 60 | child: Container( 61 | decoration: BoxDecoration( 62 | color: Colors.grey[200], // Light gray color 63 | borderRadius: BorderRadius.circular( 64 | 10.0), // Border radius for rounded corners 65 | ), 66 | width: 200, 67 | child: Column( 68 | crossAxisAlignment: CrossAxisAlignment.stretch, 69 | children: [ 70 | Card( 71 | elevation: 5.0, 72 | color: Colors.grey, 73 | shape: RoundedRectangleBorder( 74 | borderRadius: BorderRadius.circular(5.0)), 75 | clipBehavior: Clip.antiAlias, 76 | child: Padding( 77 | padding: const EdgeInsets.all(16.0), 78 | child: Column( 79 | children: [ 80 | Text(sectionListItem?.name ?? ""), 81 | ], 82 | ), 83 | ), 84 | ), 85 | KanbanDragTarget( 86 | targetSection: sectionListItem?.id ?? "", 87 | targetOrder: 0), 88 | Expanded( 89 | child: ListView.builder( 90 | itemCount: 91 | state.kanbanList?[sectionListItem?.id]?.length ?? 0, 92 | scrollDirection: Axis.vertical, 93 | itemBuilder: (context, taskIndex) { 94 | TodoTask? taskListItem = state 95 | .kanbanList?[sectionListItem?.id]?[taskIndex]; 96 | return Column( 97 | crossAxisAlignment: CrossAxisAlignment.stretch, 98 | children: [ 99 | KanbanDraggable(draggableTask: taskListItem), 100 | KanbanDragTarget( 101 | targetSection: sectionListItem?.id ?? "", 102 | targetOrder: taskIndex + 1), 103 | ], 104 | ); 105 | }, 106 | ), 107 | ) 108 | ], 109 | ), 110 | ), 111 | ); 112 | }, 113 | ); 114 | }), 115 | ); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /lib/presentation/kanban_board/widgets/kanban_drag_target.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_domain/model/tasks/task.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_bloc/flutter_bloc.dart'; 4 | import 'package:kanban_taskmanager/presentation/kanban_board/bloc/kanban_bloc.dart'; 5 | 6 | class KanbanDragTarget extends StatelessWidget { 7 | const KanbanDragTarget( 8 | {super.key, required this.targetSection, required this.targetOrder}); 9 | 10 | final String targetSection; 11 | final int targetOrder; 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return DragTarget( 16 | builder: (context, candidateData, rejectedData) { 17 | if (candidateData.isEmpty) { 18 | return const Divider( 19 | thickness: 1, // Line thickness in pixels 20 | color: Colors.grey, // Line color 21 | indent: 20.0, // Indentation from the left side 22 | endIndent: 10.0, // Indentation from the right side 23 | ); 24 | } else { 25 | return Container( 26 | color: Colors.green, 27 | height: 50, 28 | child: const Center(child: Text('Dropping...')), 29 | ); 30 | } 31 | }, 32 | onAcceptWithDetails: (details) { 33 | context.read().updateList( 34 | targetSection: targetSection, 35 | targetOrder: targetOrder, 36 | droppedTask: details.data); 37 | }, 38 | onWillAcceptWithDetails: (details) { 39 | return true; 40 | }, 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/presentation/kanban_board/widgets/kanban_draggable.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_domain/model/tasks/task.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class KanbanDraggable extends StatelessWidget { 5 | const KanbanDraggable({super.key, required this.draggableTask}); 6 | 7 | final TodoTask? draggableTask; 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return Draggable( 12 | data: draggableTask, 13 | childWhenDragging: const SizedBox( 14 | height: 50, 15 | child: Center(child: Text('Dragging...')), 16 | ), 17 | feedback: Card( 18 | elevation: 5.0, 19 | shape: 20 | RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.0)), 21 | clipBehavior: Clip.antiAlias, 22 | margin: const EdgeInsets.all(10.0), 23 | child: Padding( 24 | padding: const EdgeInsets.all(16.0), 25 | child: Column( 26 | children: [ 27 | Text(draggableTask?.content ?? ""), 28 | ], 29 | ), 30 | ), 31 | ), 32 | child: Card( 33 | elevation: 5.0, 34 | shape: 35 | RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.0)), 36 | clipBehavior: Clip.antiAlias, 37 | margin: const EdgeInsets.all(10.0), 38 | child: Padding( 39 | padding: const EdgeInsets.all(16.0), 40 | child: Column( 41 | children: [ 42 | Text(draggableTask?.content ?? ""), 43 | ], 44 | ), 45 | ), 46 | ), 47 | onDragUpdate: (details) {}, 48 | ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /lib/presentation/splash/splash_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:kanban_taskmanager/router/navigation_controller.dart'; 3 | import 'package:kanban_taskmanager/router/routes.dart'; 4 | import 'package:kanban_taskmanager/util/util.dart'; 5 | 6 | class SplashScreen extends StatelessWidget with ResponsiveMixin { 7 | const SplashScreen({super.key}); 8 | 9 | callSplashDelay() async { 10 | Future.delayed( 11 | const Duration(seconds: 3), 12 | () { 13 | NavigationController.push(Routes.home.routeName, replace: true); 14 | }, 15 | ); 16 | } 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | initResponsive(context); 21 | callSplashDelay(); 22 | return Builder(builder: (context) { 23 | return Center( 24 | child: SizedBox( 25 | width: 124.w, 26 | height: 124.w, 27 | child: const Text("KanBan Tracker"), 28 | ), 29 | ); 30 | }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/router/gen_route.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:kanban_taskmanager/presentation/kanban_board/kanban_screen.dart'; 3 | import 'package:kanban_taskmanager/presentation/splash/splash_page.dart'; 4 | import 'package:kanban_taskmanager/router/routes.dart'; 5 | 6 | Route? generateRoute(RouteSettings settings) { 7 | final namedRoute = settings.name == '/' 8 | ? Routes.root 9 | : Routes.values.firstWhere((element) { 10 | if (settings.name != null) { 11 | return settings.name! == '/${element.appRoute.name}'; 12 | } 13 | return false; 14 | }, orElse: () => Routes.unknown); 15 | debugPrint( 16 | '\n=============== (Origin: ${settings.name}) Navigating to: ${namedRoute.toString()}\n with args: ${settings.arguments}'); 17 | switch (namedRoute.appRoute) { 18 | case AppRoute.unknown: 19 | return _errorRoute(); 20 | case AppRoute.home: 21 | return _buildRoute(settings: settings, screen: const KanbanScreen()); 22 | case AppRoute.root: 23 | return _buildRoute(settings: settings, screen: const SplashScreen()); 24 | } 25 | } 26 | 27 | Route? _errorRoute() { 28 | return MaterialPageRoute(builder: (_) { 29 | return Scaffold( 30 | appBar: AppBar( 31 | title: const Text('Error'), 32 | ), 33 | body: const Center( 34 | child: Text('ERROR'), 35 | ), 36 | ); 37 | }); 38 | } 39 | 40 | Route? _buildRoute( 41 | {required RouteSettings settings, 42 | required Widget screen, 43 | bool fullscreenDialog = false}) { 44 | return CustomMaterialPageRoute( 45 | settings: settings, 46 | fullscreenDialog: fullscreenDialog, 47 | builder: (context) { 48 | return Material(child: screen); 49 | }, 50 | ); 51 | } 52 | 53 | class CustomMaterialPageRoute extends MaterialPageRoute { 54 | @override 55 | @protected 56 | bool get hasScopedWillPopCallback { 57 | return false; 58 | } 59 | 60 | CustomMaterialPageRoute({ 61 | required WidgetBuilder builder, 62 | required RouteSettings settings, 63 | bool maintainState = true, 64 | bool fullscreenDialog = false, 65 | }) : super( 66 | builder: builder, 67 | settings: settings, 68 | maintainState: maintainState, 69 | fullscreenDialog: fullscreenDialog, 70 | ); 71 | } 72 | -------------------------------------------------------------------------------- /lib/router/named_route.dart: -------------------------------------------------------------------------------- 1 | import 'package:kanban_taskmanager/router/routes.dart'; 2 | 3 | class NamedRoute { 4 | final AppRoute appRoute; 5 | final String? overrideRouteName; 6 | 7 | String get routeName => '/${overrideRouteName ?? appRoute.name}'; 8 | 9 | NamedRoute({ 10 | required this.appRoute, 11 | this.overrideRouteName, 12 | }); 13 | 14 | @override 15 | String toString() { 16 | return 'NamedRoute{route: $appRoute, overrideRouteName: $overrideRouteName}'; 17 | } 18 | } -------------------------------------------------------------------------------- /lib/router/navigation_controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class NavigationController { 4 | static final globalNavigatorKey = GlobalKey(); 5 | 6 | /// Returns value from pop if exists. 7 | /// [clean] is true to remove all back stacks after pushing 8 | /// [replace] is true to replace the current route by new route 9 | /// 10 | static Future? push( 11 | String route, { 12 | dynamic arguments, 13 | bool replace = false, 14 | bool clean = false, 15 | }) async { 16 | if (clean) { 17 | return globalNavigatorKey.currentState?.pushNamedAndRemoveUntil( 18 | route, 19 | (_) => false, 20 | arguments: arguments, 21 | ); 22 | } 23 | 24 | if (replace) { 25 | return globalNavigatorKey.currentState?.pushReplacementNamed( 26 | route, 27 | arguments: arguments, 28 | ); 29 | } 30 | 31 | return globalNavigatorKey.currentState?.pushNamed( 32 | route, 33 | arguments: arguments, 34 | ); 35 | } 36 | 37 | static void pop({T? result}){ 38 | globalNavigatorKey.currentState?.pop(result); 39 | } 40 | } -------------------------------------------------------------------------------- /lib/router/routes.dart: -------------------------------------------------------------------------------- 1 | import 'named_route.dart'; 2 | 3 | enum AppRoute { 4 | unknown, 5 | root, 6 | home, 7 | } 8 | 9 | class Routes { 10 | static NamedRoute get root => NamedRoute(appRoute: AppRoute.root); 11 | 12 | static NamedRoute get unknown => NamedRoute(appRoute: AppRoute.unknown); 13 | 14 | static NamedRoute get home => NamedRoute(appRoute: AppRoute.home); 15 | 16 | static List values = [unknown, root, home]; 17 | } 18 | -------------------------------------------------------------------------------- /lib/util/app_global.dart: -------------------------------------------------------------------------------- 1 | library order_app.globals; 2 | import 'package:flutter/material.dart'; 3 | 4 | RouteObserver> navigationObserver = RouteObserver>(); 5 | 6 | ThemeData them = ThemeData( 7 | primarySwatch: Colors.green, 8 | // fontFamily: "Exo2", 9 | pageTransitionsTheme: _buildPageTransitionsTheme() 10 | ); 11 | 12 | /// Custom page transitions theme 13 | PageTransitionsTheme _buildPageTransitionsTheme() { 14 | return const PageTransitionsTheme( 15 | builders: { 16 | TargetPlatform.android: CupertinoPageTransitionsBuilder(), 17 | TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), 18 | }, 19 | ); 20 | } -------------------------------------------------------------------------------- /lib/util/app_mixin.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 3 | 4 | mixin ResponsiveMixin { 5 | void initResponsive(BuildContext context) { 6 | ScreenUtil.init(context, designSize: const Size(375, 812)); 7 | } 8 | } 9 | 10 | mixin AfterLayoutMixin on State { 11 | @override 12 | void initState() { 13 | super.initState(); 14 | WidgetsBinding 15 | .instance 16 | .addPostFrameCallback((_) => afterFirstLayout(context)); 17 | } 18 | Future afterFirstLayout(BuildContext context); 19 | } 20 | -------------------------------------------------------------------------------- /lib/util/app_router.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:kanban_taskmanager/router/navigation_controller.dart'; 3 | import 'package:kanban_taskmanager/router/routes.dart'; 4 | 5 | extension AppRouter on State { 6 | void transitionToHomePage() { 7 | NavigationController.push(Routes.home.routeName, replace: true); 8 | } 9 | 10 | void pop() { 11 | Navigator.pop(context); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/util/assets/app_color.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class AppColor { 4 | static const Color primaryColor = Color(0xFF201A55); 5 | static const Color secondaryColor = Color(0xFF194781); 6 | static const Color buttonOutline = Color(0xFF6D7195); 7 | static const Color black = Color(0xff231F20); 8 | static const Color white = Colors.white; 9 | static const Color transparent = Colors.transparent; 10 | static const Color darkGray = Color(0xff979797); 11 | static const Color mediumGray = Color(0xffCBD3D5); 12 | static const Color lightGray = Color(0xffE2E2E0); 13 | static const Color lightGray1 = Color(0xffCCCCCC); 14 | static const Color blue = Color(0xFF194781); 15 | static const Color darkBlue = Color(0xff113562); 16 | static const Color highDarkBlue = Color(0xff1d2936); 17 | static const Color violet = Color(0xff22117F); 18 | static const Color lightViolet = Color(0xff4D427C); 19 | static const Color lightBlue = Color(0xffCEDDFE); 20 | static const Color yellow = Color(0xffFFE200); 21 | static const Color darkYellow = Color(0xffE29C00); 22 | static const Color green = Color(0xff49A15A); 23 | 24 | static const Color red = Color(0xffF23B14); 25 | static const Color mainGreen = Color(0xff20C3AF); 26 | static const Color textBlack = Color(0xff525464); 27 | static const Color textLightBlack = Color(0xff838391); 28 | static const Color offWhite = Color(0xffF7F7F7); 29 | static const Color pinkLight = Color(0xffFFB19D); 30 | static const Color active = Color(0xff22A45D); 31 | 32 | static const Gradient backgroundGradient = LinearGradient( 33 | stops: [0, 0.9, 1], 34 | colors: [ 35 | darkBlue, 36 | highDarkBlue, 37 | black, 38 | ], 39 | begin: Alignment.topCenter, 40 | end: Alignment.bottomCenter, 41 | ); 42 | } 43 | -------------------------------------------------------------------------------- /lib/util/assets/app_locale.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:azl_data/datasource/translations/translation_datasource.dart'; 3 | class AppLocales { 4 | static const defaultLanguage = 5 | AppLanguage(LocaleTexts.selectLanguage, Locale('en', 'US')); 6 | static const en = AppLanguage(LocaleTexts.en, Locale('en', 'US')); 7 | static const hi = AppLanguage(LocaleTexts.hi, Locale('hi', 'IN')); 8 | 9 | static const path = 'assets/locales'; 10 | 11 | static const List languages = [defaultLanguage, en, hi]; 12 | } 13 | 14 | class AppLanguage { 15 | final String languageText; 16 | final Locale language; 17 | 18 | const AppLanguage(this.languageText, this.language); 19 | 20 | @override 21 | String toString() { 22 | return languageText; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /lib/util/assets/app_text.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 3 | import 'app_color.dart'; 4 | 5 | enum FontFamilyType { 6 | exo, 7 | } 8 | 9 | /*extension FontFamilyExtension on FontFamilyType { 10 | String? name() { 11 | switch (this) { 12 | case FontFamilyType.exo: 13 | return "Exo2"; 14 | } 15 | } 16 | }*/ 17 | 18 | enum FontWeightType { regular, medium, semiBold, bold } 19 | 20 | extension FontWeightTypeExtension on FontWeightType { 21 | FontWeight type() { 22 | switch (this) { 23 | case FontWeightType.regular: 24 | return FontWeight.w400; 25 | case FontWeightType.medium: 26 | return FontWeight.w500; 27 | case FontWeightType.semiBold: 28 | return FontWeight.w600; 29 | case FontWeightType.bold: 30 | return FontWeight.w700; 31 | } 32 | } 33 | } 34 | 35 | class AppText extends StatelessWidget { 36 | final TextStyle? textStyle; 37 | final String text; 38 | final TextAlign? textAlign; 39 | final TextOverflow? overflow; 40 | final int? maxLines; 41 | final bool scalable; 42 | final String? configKey; 43 | 44 | const AppText._(this.text, 45 | {Key? key, 46 | this.textStyle, 47 | this.textAlign, 48 | this.overflow, 49 | this.maxLines, 50 | this.configKey, 51 | this.scalable = true}) 52 | : super(key: key); 53 | 54 | factory AppText.primary(String text, 55 | {Color? color = AppColor.black, 56 | FontWeightType? fontWeight = FontWeightType.regular, 57 | bool scalable = true, 58 | String? configKey, 59 | TextAlign? textAlign, 60 | int? maxLines, 61 | double? fontSize = 15.0, 62 | FontFamilyType? fontFamily = FontFamilyType.exo, 63 | TextDecoration decoration = TextDecoration.none}) { 64 | return AppText._( 65 | text, 66 | textStyle: TextStyle( 67 | fontWeight: fontWeight?.type(), 68 | color: color, 69 | fontSize: fontSize?.sp, 70 | // fontFamily: fontFamily?.name(), 71 | decoration: decoration), 72 | scalable: scalable, 73 | configKey: configKey, 74 | textAlign: textAlign, 75 | maxLines: maxLines, 76 | overflow: maxLines != null ? TextOverflow.ellipsis : null, 77 | ); 78 | } 79 | 80 | factory AppText.body(String text, 81 | {Color? color = AppColor.textLightBlack, 82 | FontWeightType? fontWeight = FontWeightType.regular, 83 | bool scalable = true, 84 | String? configKey, 85 | TextAlign? textAlign, 86 | int? maxLines, 87 | double? fontSize = 16.0, 88 | FontFamilyType? fontFamily = FontFamilyType.exo}) { 89 | return AppText._( 90 | text, 91 | textStyle: TextStyle( 92 | fontWeight: fontWeight?.type(), 93 | color: color, 94 | fontSize: fontSize?.sp, 95 | // fontFamily: fontFamily?.name() 96 | ), 97 | scalable: scalable, 98 | configKey: configKey, 99 | textAlign: textAlign, 100 | maxLines: maxLines, 101 | overflow: maxLines != null ? TextOverflow.ellipsis : null, 102 | ); 103 | } 104 | 105 | factory AppText.itemTitleSmall(String text, 106 | {Color? color = AppColor.black, 107 | FontWeightType? fontWeight = FontWeightType.semiBold, 108 | bool scalable = true, 109 | String? configKey, 110 | TextAlign? textAlign, 111 | int? maxLines, 112 | double? fontSize = 16.0, 113 | FontFamilyType? fontFamily = FontFamilyType.exo}) { 114 | return AppText._( 115 | text, 116 | textStyle: TextStyle( 117 | fontWeight: fontWeight?.type(), 118 | color: color, 119 | fontSize: fontSize?.sp, 120 | // fontFamily: fontFamily?.name() 121 | ), 122 | scalable: scalable, 123 | configKey: configKey, 124 | textAlign: textAlign, 125 | maxLines: maxLines, 126 | overflow: maxLines != null ? TextOverflow.ellipsis : null, 127 | ); 128 | } 129 | 130 | factory AppText.itemTitleLarge(String text, 131 | {Color? color = AppColor.black, 132 | FontWeightType? fontWeight = FontWeightType.semiBold, 133 | bool scalable = true, 134 | String? configKey, 135 | TextAlign? textAlign, 136 | int? maxLines, 137 | double? fontSize = 18.0, 138 | FontFamilyType? fontFamily = FontFamilyType.exo}) { 139 | return AppText._( 140 | text, 141 | textStyle: TextStyle( 142 | fontWeight: fontWeight?.type(), 143 | color: color, 144 | fontSize: fontSize?.sp, 145 | // fontFamily: fontFamily?.name() 146 | ), 147 | scalable: scalable, 148 | configKey: configKey, 149 | textAlign: textAlign, 150 | maxLines: maxLines, 151 | overflow: maxLines != null ? TextOverflow.ellipsis : null, 152 | ); 153 | } 154 | 155 | factory AppText.primaryButtonText(String text, 156 | {Color? color = AppColor.textLightBlack, 157 | FontWeightType? fontWeight = FontWeightType.semiBold, 158 | bool scalable = true, 159 | String? configKey, 160 | TextAlign? textAlign, 161 | int? maxLines, 162 | double? fontSize = 14.0, 163 | FontFamilyType? fontFamily = FontFamilyType.exo}) { 164 | return AppText._( 165 | text, 166 | textStyle: TextStyle( 167 | fontWeight: fontWeight?.type(), 168 | color: color, 169 | fontSize: fontSize?.sp, 170 | // fontFamily: fontFamily?.name() 171 | ), 172 | scalable: scalable, 173 | configKey: configKey, 174 | textAlign: textAlign, 175 | maxLines: maxLines, 176 | overflow: maxLines != null ? TextOverflow.ellipsis : null, 177 | ); 178 | } 179 | 180 | factory AppText.regular(String text, 181 | {Color? color = AppColor.textLightBlack, 182 | FontWeightType? fontWeight = FontWeightType.regular, 183 | bool scalable = true, 184 | String? configKey, 185 | TextAlign? textAlign, 186 | int? maxLines, 187 | double? fontSize = 14.0, 188 | FontFamilyType? fontFamily = FontFamilyType.exo}) { 189 | return AppText._( 190 | text, 191 | textStyle: TextStyle( 192 | fontWeight: fontWeight?.type(), 193 | color: color, 194 | fontSize: fontSize?.sp, 195 | // fontFamily: fontFamily?.name() 196 | ), 197 | scalable: scalable, 198 | configKey: configKey, 199 | textAlign: textAlign, 200 | maxLines: maxLines, 201 | overflow: maxLines != null ? TextOverflow.ellipsis : null, 202 | ); 203 | } 204 | 205 | factory AppText.currency(String text, 206 | {Color? color = AppColor.active, 207 | FontWeightType? fontWeight = FontWeightType.semiBold, 208 | bool scalable = true, 209 | String? configKey, 210 | TextAlign? textAlign, 211 | int? maxLines, 212 | double? fontSize = 16.0, 213 | FontFamilyType? fontFamily = FontFamilyType.exo}) { 214 | return AppText._( 215 | text, 216 | textStyle: TextStyle( 217 | fontWeight: fontWeight?.type(), 218 | color: color, 219 | fontSize: fontSize?.sp, 220 | // fontFamily: fontFamily?.name() 221 | ), 222 | scalable: scalable, 223 | configKey: configKey, 224 | textAlign: textAlign, 225 | maxLines: maxLines, 226 | overflow: maxLines != null ? TextOverflow.ellipsis : null, 227 | ); 228 | } 229 | 230 | factory AppText.small(String text, 231 | {Color? color = AppColor.textLightBlack, 232 | FontWeightType? fontWeight = FontWeightType.regular, 233 | bool scalable = true, 234 | String? configKey, 235 | TextAlign? textAlign, 236 | int? maxLines, 237 | double? fontSize = 12.0, 238 | FontFamilyType? fontFamily = FontFamilyType.exo}) { 239 | return AppText._( 240 | text, 241 | textStyle: TextStyle( 242 | fontWeight: fontWeight?.type(), 243 | color: color, 244 | fontSize: fontSize?.sp, 245 | // fontFamily: fontFamily?.name() 246 | ), 247 | scalable: scalable, 248 | configKey: configKey, 249 | textAlign: textAlign, 250 | maxLines: maxLines, 251 | overflow: maxLines != null ? TextOverflow.ellipsis : null, 252 | ); 253 | } 254 | 255 | factory AppText.h6(String text, 256 | {Color? color = AppColor.textLightBlack, 257 | FontWeightType? fontWeight = FontWeightType.medium, 258 | bool scalable = true, 259 | String? configKey, 260 | TextAlign? textAlign, 261 | int? maxLines, 262 | double? fontSize = 28.0, 263 | FontFamilyType? fontFamily = FontFamilyType.exo}) { 264 | return AppText._( 265 | text, 266 | textStyle: TextStyle( 267 | fontWeight: fontWeight?.type(), 268 | color: color, 269 | fontSize: fontSize?.sp, 270 | // fontFamily: fontFamily?.name() 271 | ), 272 | scalable: scalable, 273 | configKey: configKey, 274 | textAlign: textAlign, 275 | maxLines: maxLines, 276 | overflow: maxLines != null ? TextOverflow.ellipsis : null, 277 | ); 278 | } 279 | 280 | factory AppText.h4(String text, 281 | {Color? color = AppColor.black, 282 | FontWeightType? fontWeight = FontWeightType.semiBold, 283 | bool scalable = true, 284 | String? configKey, 285 | TextAlign? textAlign, 286 | int? maxLines, 287 | double? fontSize = 20.0, 288 | FontFamilyType? fontFamily = FontFamilyType.exo}) { 289 | return AppText._( 290 | text, 291 | textStyle: TextStyle( 292 | fontWeight: fontWeight?.type(), 293 | color: color, 294 | fontSize: fontSize?.sp, 295 | // fontFamily: fontFamily?.name() 296 | ), 297 | scalable: scalable, 298 | configKey: configKey, 299 | textAlign: textAlign, 300 | maxLines: maxLines, 301 | overflow: maxLines != null ? TextOverflow.ellipsis : null, 302 | ); 303 | } 304 | 305 | factory AppText.h3(String text, 306 | {Color? color = AppColor.black, 307 | FontWeightType? fontWeight = FontWeightType.semiBold, 308 | bool scalable = true, 309 | String? configKey, 310 | TextAlign? textAlign, 311 | int? maxLines, 312 | double? fontSize = 24.0, 313 | FontFamilyType? fontFamily = FontFamilyType.exo}) { 314 | return AppText._( 315 | text, 316 | textStyle: TextStyle( 317 | fontWeight: fontWeight?.type(), 318 | color: color, 319 | fontSize: fontSize?.sp, 320 | // fontFamily: fontFamily?.name() 321 | ), 322 | scalable: scalable, 323 | configKey: configKey, 324 | textAlign: textAlign, 325 | maxLines: maxLines, 326 | overflow: maxLines != null ? TextOverflow.ellipsis : null, 327 | ); 328 | } 329 | 330 | @override 331 | Widget build(BuildContext context) { 332 | return Text( 333 | text, 334 | style: textStyle, 335 | textAlign: textAlign, 336 | overflow: overflow, 337 | maxLines: maxLines, 338 | textScaler: scalable ? null : TextScaler.noScaling, 339 | ); 340 | } 341 | } 342 | -------------------------------------------------------------------------------- /lib/util/connectivity_mixin.dart: -------------------------------------------------------------------------------- 1 | /* 2 | import 'package:connectivity_plus/connectivity_plus.dart'; 3 | 4 | mixin ConnectivityMixin { 5 | final connectivity = Connectivity(); 6 | Future isInConnection() async { 7 | var connectivityResult = await connectivity.checkConnectivity(); 8 | return connectivityResult != ConnectivityResult.none; 9 | } 10 | }*/ 11 | -------------------------------------------------------------------------------- /lib/util/constants.dart: -------------------------------------------------------------------------------- 1 | class AppConstants{ 2 | static const addConstantsHere = 'addConstantsHere'; 3 | } -------------------------------------------------------------------------------- /lib/util/navigation/navigation_helper.dart: -------------------------------------------------------------------------------- 1 | import 'package:kanban_taskmanager/router/navigation_controller.dart'; 2 | import 'package:kanban_taskmanager/router/routes.dart'; 3 | 4 | class NavigationHelper { 5 | static void transitionToHome(Map? arguments) { 6 | NavigationController.push( 7 | Routes.home.routeName, 8 | arguments: arguments, 9 | replace: true, 10 | clean: true, 11 | ); 12 | } 13 | 14 | static void transitionToHomeSettingsTab(Map? arguments) { 15 | final data = arguments ?? {}; 16 | data["tab_name"] = "/settings"; 17 | transitionToHome(data); 18 | } 19 | 20 | static void transitionToHomeFaqTab(Map? arguments) { 21 | final data = arguments ?? {}; 22 | data["tab_name"] = "/faq"; 23 | transitionToHome(data); 24 | } 25 | 26 | static void transitionToError(Map? arguments) { 27 | NavigationController.push( 28 | Routes.unknown.routeName, 29 | arguments: arguments, 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/util/util.dart: -------------------------------------------------------------------------------- 1 | export 'package:easy_localization/easy_localization.dart'; 2 | export 'package:flutter_screenutil/flutter_screenutil.dart'; 3 | export 'assets/app_text.dart'; 4 | export 'assets/app_color.dart'; 5 | export 'assets/app_locale.dart'; 6 | export 'app_global.dart'; 7 | export 'app_mixin.dart'; 8 | export 'app_router.dart'; 9 | export 'widget/app_primary_button.dart'; 10 | -------------------------------------------------------------------------------- /lib/util/widget/app_primary_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:kanban_taskmanager/util/util.dart'; 3 | 4 | class AppPrimaryButton extends StatelessWidget { 5 | const AppPrimaryButton( 6 | {super.key, required this.onPressed, required this.title}); 7 | 8 | final VoidCallback onPressed; 9 | final String title; 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return Theme( 14 | data: ThemeData( 15 | colorScheme: const ColorScheme.light(primary: AppColor.active), 16 | ), 17 | child: OutlinedButton( 18 | style: OutlinedButton.styleFrom( 19 | side: BorderSide(width: 1.sp, color: AppColor.active), 20 | padding: EdgeInsets.only(bottom: 1.5.h)), 21 | onPressed: onPressed, 22 | child: AppText.primaryButtonText(title, color: AppColor.active)), 23 | ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: kanban_taskmanager 2 | description: "KanBan Task manager" 3 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 4 | 5 | version: 1.0.0+1 6 | 7 | environment: 8 | sdk: '>=3.4.3 <4.0.0' 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | cupertino_icons: ^1.0.8 14 | flutter_screenutil: ^5.9.3 15 | easy_localization: ^3.0.7 16 | flutter_bloc: ^8.1.5 17 | # get_it: ^7.7.0 18 | # alice: ^0.3.2 19 | azl_domain: 20 | path: domain 21 | environments: 22 | path: environments 23 | 24 | dependency_overrides: 25 | flutter_test: 26 | sdk: flutter 27 | 28 | 29 | dev_dependencies: 30 | flutter_test: 31 | sdk: flutter 32 | build_runner: 33 | flutter_lints: ^4.0.0 34 | test: ^1.25.2 35 | mockito: ^5.4.4 36 | 37 | flutter: 38 | 39 | uses-material-design: true 40 | assets: 41 | # - assets/icons/ 42 | # - assets/fonts/ 43 | # - assets/images/ 44 | - assets/locales/ 45 | # 46 | # fonts: 47 | # - family: Exo2 48 | # fonts: 49 | # - asset: assets/fonts/Exo2-Bold.ttf 50 | # weight: 700 51 | # - asset: assets/fonts/Exo2-SemiBold.ttf 52 | # weight: 600 53 | # - asset: assets/fonts/Exo2-Medium.ttf 54 | # weight: 500 55 | # - asset: assets/fonts/Exo2-Regular.ttf 56 | # weight: 400 -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:azl_domain/di/domain_injection.dart'; 2 | import 'package:azl_domain/usecase/kanban/kanban_usecase_type.dart'; 3 | import 'package:kanban_taskmanager/di/AppConfigure.dart'; 4 | import 'package:kanban_taskmanager/environment/development/development_env.dart'; 5 | import 'package:flutter_test/flutter_test.dart'; 6 | 7 | void main() async { 8 | AppConfigure.configure(DevelopmentEnvironment.development(), 9 | enableMock: true); 10 | KanbanUseCaseType useCaseType = DomainInjection.getIt(); 11 | 12 | test( 13 | "Get Tasks Api Test", 14 | () async { 15 | final result = await useCaseType.getTasks(); 16 | result.fold((errorResponse) { 17 | print(errorResponse.message); 18 | expect(errorResponse.message, isNotNull); 19 | }, (response) { 20 | print(response.length); 21 | expect(response, isNotNull); 22 | }); 23 | }, 24 | ); 25 | } 26 | --------------------------------------------------------------------------------