baseproject
							
								
								
									
										45
									
								
								base_project/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,45 @@ | ||||
| # Miscellaneous | ||||
| *.class | ||||
| *.log | ||||
| *.pyc | ||||
| *.swp | ||||
| .DS_Store | ||||
| .atom/ | ||||
| .build/ | ||||
| .buildlog/ | ||||
| .history | ||||
| .svn/ | ||||
| .swiftpm/ | ||||
| migrate_working_dir/ | ||||
| 
 | ||||
| # IntelliJ related | ||||
| *.iml | ||||
| *.ipr | ||||
| *.iws | ||||
| .idea/ | ||||
| 
 | ||||
| # The .vscode folder contains launch configuration and tasks you configure in | ||||
| # VS Code which you may wish to be included in version control, so this line | ||||
| # is commented out by default. | ||||
| #.vscode/ | ||||
| 
 | ||||
| # Flutter/Dart/Pub related | ||||
| **/doc/api/ | ||||
| **/ios/Flutter/.last_build_id | ||||
| .dart_tool/ | ||||
| .flutter-plugins | ||||
| .flutter-plugins-dependencies | ||||
| .pub-cache/ | ||||
| .pub/ | ||||
| /build/ | ||||
| 
 | ||||
| # Symbolication related | ||||
| app.*.symbols | ||||
| 
 | ||||
| # Obfuscation related | ||||
| app.*.map.json | ||||
| 
 | ||||
| # Android Studio will place build artifacts here | ||||
| /android/app/debug | ||||
| /android/app/profile | ||||
| /android/app/release | ||||
							
								
								
									
										45
									
								
								base_project/.metadata
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,45 @@ | ||||
| # This file tracks properties of this Flutter project. | ||||
| # Used by Flutter tool to assess capabilities and perform upgrades etc. | ||||
| # | ||||
| # This file should be version controlled and should not be manually edited. | ||||
| 
 | ||||
| version: | ||||
|   revision: "17025dd88227cd9532c33fa78f5250d548d87e9a" | ||||
|   channel: "stable" | ||||
| 
 | ||||
| project_type: app | ||||
| 
 | ||||
| # Tracks metadata for the flutter migrate command | ||||
| migration: | ||||
|   platforms: | ||||
|     - platform: root | ||||
|       create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a | ||||
|       base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a | ||||
|     - platform: android | ||||
|       create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a | ||||
|       base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a | ||||
|     - platform: ios | ||||
|       create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a | ||||
|       base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a | ||||
|     - platform: linux | ||||
|       create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a | ||||
|       base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a | ||||
|     - platform: macos | ||||
|       create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a | ||||
|       base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a | ||||
|     - platform: web | ||||
|       create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a | ||||
|       base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a | ||||
|     - platform: windows | ||||
|       create_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a | ||||
|       base_revision: 17025dd88227cd9532c33fa78f5250d548d87e9a | ||||
| 
 | ||||
|   # User provided section | ||||
| 
 | ||||
|   # List of Local paths (relative to this file) that should be | ||||
|   # ignored by the migrate tool. | ||||
|   # | ||||
|   # Files that are not part of the templates will be ignored by default. | ||||
|   unmanaged_files: | ||||
|     - 'lib/main.dart' | ||||
|     - 'ios/Runner.xcodeproj/project.pbxproj' | ||||
							
								
								
									
										4
									
								
								base_project/.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,4 @@ | ||||
| { | ||||
|     "java.compile.nullAnalysis.mode": "automatic", | ||||
|     "java.configuration.updateBuildConfiguration": "interactive" | ||||
| } | ||||
							
								
								
									
										19
									
								
								base_project/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,19 @@ | ||||
| # base_project | ||||
| 
 | ||||
| A new Flutter project. | ||||
| 
 | ||||
| ## Getting Started | ||||
| 
 | ||||
| This project is a starting point for a Flutter application. | ||||
| 
 | ||||
| A few resources to get you started if this is your first Flutter project: | ||||
| 
 | ||||
| - [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) | ||||
| - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) | ||||
| 
 | ||||
| For help getting started with Flutter development, view the | ||||
| [online documentation](https://docs.flutter.dev/), which offers tutorials, | ||||
| samples, guidance on mobile development, and a full API reference. | ||||
| 
 | ||||
| 
 | ||||
| treat updating UI_DEVELOPMENT_GUIDE.md as mandatory after every change. | ||||
							
								
								
									
										28
									
								
								base_project/analysis_options.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,28 @@ | ||||
| # This file configures the analyzer, which statically analyzes Dart code to | ||||
| # check for errors, warnings, and lints. | ||||
| # | ||||
| # The issues identified by the analyzer are surfaced in the UI of Dart-enabled | ||||
| # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be | ||||
| # invoked from the command line by running `flutter analyze`. | ||||
| 
 | ||||
| # The following line activates a set of recommended lints for Flutter apps, | ||||
| # packages, and plugins designed to encourage good coding practices. | ||||
| include: package:flutter_lints/flutter.yaml | ||||
| 
 | ||||
| linter: | ||||
|   # The lint rules applied to this project can be customized in the | ||||
|   # section below to disable rules from the `package:flutter_lints/flutter.yaml` | ||||
|   # included above or to enable additional rules. A list of all available lints | ||||
|   # and their documentation is published at https://dart.dev/lints. | ||||
|   # | ||||
|   # Instead of disabling a lint rule for the entire project in the | ||||
|   # section below, it can also be suppressed for a single line of code | ||||
|   # or a specific dart file by using the `// ignore: name_of_lint` and | ||||
|   # `// ignore_for_file: name_of_lint` syntax on the line or in the file | ||||
|   # producing the lint. | ||||
|   rules: | ||||
|     # avoid_print: false  # Uncomment to disable the `avoid_print` rule | ||||
|     # prefer_single_quotes: true  # Uncomment to enable the `prefer_single_quotes` rule | ||||
| 
 | ||||
| # Additional information about this file can be found at | ||||
| # https://dart.dev/guides/language/analysis-options | ||||
							
								
								
									
										13
									
								
								base_project/android/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,13 @@ | ||||
| gradle-wrapper.jar | ||||
| /.gradle | ||||
| /captures/ | ||||
| /gradlew | ||||
| /gradlew.bat | ||||
| /local.properties | ||||
| GeneratedPluginRegistrant.java | ||||
| 
 | ||||
| # Remember to never publicly share your keystore. | ||||
| # See https://flutter.dev/to/reference-keystore | ||||
| key.properties | ||||
| **/*.keystore | ||||
| **/*.jks | ||||
							
								
								
									
										44
									
								
								base_project/android/app/build.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,44 @@ | ||||
| plugins { | ||||
|     id "com.android.application" | ||||
|     id "kotlin-android" | ||||
|     // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. | ||||
|     id "dev.flutter.flutter-gradle-plugin" | ||||
| } | ||||
| 
 | ||||
| android { | ||||
|     namespace = "com.example.base_project" | ||||
|     compileSdk = flutter.compileSdkVersion | ||||
|     ndkVersion = flutter.ndkVersion | ||||
| 
 | ||||
|     compileOptions { | ||||
|         sourceCompatibility = JavaVersion.VERSION_1_8 | ||||
|         targetCompatibility = JavaVersion.VERSION_1_8 | ||||
|     } | ||||
| 
 | ||||
|     kotlinOptions { | ||||
|         jvmTarget = JavaVersion.VERSION_1_8 | ||||
|     } | ||||
| 
 | ||||
|     defaultConfig { | ||||
|         // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). | ||||
|         applicationId = "com.example.base_project" | ||||
|         // You can update the following values to match your application needs. | ||||
|         // For more information, see: https://flutter.dev/to/review-gradle-config. | ||||
|         minSdk = 24 | ||||
|         targetSdk = flutter.targetSdkVersion | ||||
|         versionCode = flutter.versionCode | ||||
|         versionName = flutter.versionName | ||||
|     } | ||||
| 
 | ||||
|     buildTypes { | ||||
|         release { | ||||
|             // TODO: Add your own signing config for the release build. | ||||
|             // Signing with the debug keys for now, so `flutter run --release` works. | ||||
|             signingConfig = signingConfigs.debug | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| flutter { | ||||
|     source = "../.." | ||||
| } | ||||
							
								
								
									
										7
									
								
								base_project/android/app/src/debug/AndroidManifest.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,7 @@ | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <!-- The INTERNET permission is required for development. Specifically, | ||||
|          the Flutter tool needs it to communicate with the running application | ||||
|          to allow setting breakpoints, to provide hot reload, etc. | ||||
|     --> | ||||
|     <uses-permission android:name="android.permission.INTERNET"/> | ||||
| </manifest> | ||||
							
								
								
									
										49
									
								
								base_project/android/app/src/main/AndroidManifest.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,49 @@ | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
| 
 | ||||
|     <uses-permission android:name="android.permission.INTERNET" /> | ||||
|     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> | ||||
|     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> | ||||
|     <application | ||||
|         android:label="base_project" | ||||
|         android:name="${applicationName}" | ||||
|         android:icon="@mipmap/ic_launcher"> | ||||
|         <activity | ||||
|             android:name=".MainActivity" | ||||
|             android:exported="true" | ||||
|             android:launchMode="singleTop" | ||||
|             android:taskAffinity="" | ||||
|             android:theme="@style/LaunchTheme" | ||||
|             android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" | ||||
|             android:hardwareAccelerated="true" | ||||
|             android:windowSoftInputMode="adjustResize"> | ||||
|             <!-- Specifies an Android theme to apply to this Activity as soon as | ||||
|                  the Android process has started. This theme is visible to the user | ||||
|                  while the Flutter UI initializes. After that, this theme continues | ||||
|                  to determine the Window background behind the Flutter UI. --> | ||||
|             <meta-data | ||||
|                 android:name="io.flutter.embedding.android.NormalTheme" | ||||
|                 android:resource="@style/NormalTheme" | ||||
|             /> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.MAIN" /> | ||||
|                 <category android:name="android.intent.category.LAUNCHER" /> | ||||
|             </intent-filter> | ||||
|         </activity> | ||||
|         <!-- Don't delete the meta-data below. | ||||
|              This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> | ||||
|         <meta-data | ||||
|             android:name="flutterEmbedding" | ||||
|             android:value="2" /> | ||||
|     </application> | ||||
|     <!-- Required to query activities that can process text, see: | ||||
|          https://developer.android.com/training/package-visibility and | ||||
|          https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT. | ||||
| 
 | ||||
|          In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. --> | ||||
|     <queries> | ||||
|         <intent> | ||||
|             <action android:name="android.intent.action.PROCESS_TEXT" /> | ||||
|             <data android:mimeType="text/plain" /> | ||||
|         </intent> | ||||
|     </queries> | ||||
| </manifest> | ||||
| @ -0,0 +1,5 @@ | ||||
| package com.example.base_project | ||||
| 
 | ||||
| import io.flutter.embedding.android.FlutterActivity | ||||
| 
 | ||||
| class MainActivity: FlutterActivity() | ||||
| @ -0,0 +1,12 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <!-- Modify this file to customize your launch splash screen --> | ||||
| <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <item android:drawable="?android:colorBackground" /> | ||||
| 
 | ||||
|     <!-- You can insert your own image assets here --> | ||||
|     <!-- <item> | ||||
|         <bitmap | ||||
|             android:gravity="center" | ||||
|             android:src="@mipmap/launch_image" /> | ||||
|     </item> --> | ||||
| </layer-list> | ||||
| @ -0,0 +1,12 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <!-- Modify this file to customize your launch splash screen --> | ||||
| <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <item android:drawable="@android:color/white" /> | ||||
| 
 | ||||
|     <!-- You can insert your own image assets here --> | ||||
|     <!-- <item> | ||||
|         <bitmap | ||||
|             android:gravity="center" | ||||
|             android:src="@mipmap/launch_image" /> | ||||
|     </item> --> | ||||
| </layer-list> | ||||
| After Width: | Height: | Size: 544 B | 
| After Width: | Height: | Size: 442 B | 
| After Width: | Height: | Size: 721 B | 
| After Width: | Height: | Size: 1.0 KiB | 
| After Width: | Height: | Size: 1.4 KiB | 
| @ -0,0 +1,18 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <resources> | ||||
|     <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on --> | ||||
|     <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar"> | ||||
|         <!-- Show a splash screen on the activity. Automatically removed when | ||||
|              the Flutter engine draws its first frame --> | ||||
|         <item name="android:windowBackground">@drawable/launch_background</item> | ||||
|     </style> | ||||
|     <!-- Theme applied to the Android Window as soon as the process has started. | ||||
|          This theme determines the color of the Android Window while your | ||||
|          Flutter UI initializes, as well as behind your Flutter UI while its | ||||
|          running. | ||||
| 
 | ||||
|          This Theme is only used starting with V2 of Flutter's Android embedding. --> | ||||
|     <style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar"> | ||||
|         <item name="android:windowBackground">?android:colorBackground</item> | ||||
|     </style> | ||||
| </resources> | ||||
							
								
								
									
										18
									
								
								base_project/android/app/src/main/res/values/styles.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,18 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <resources> | ||||
|     <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off --> | ||||
|     <style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar"> | ||||
|         <!-- Show a splash screen on the activity. Automatically removed when | ||||
|              the Flutter engine draws its first frame --> | ||||
|         <item name="android:windowBackground">@drawable/launch_background</item> | ||||
|     </style> | ||||
|     <!-- Theme applied to the Android Window as soon as the process has started. | ||||
|          This theme determines the color of the Android Window while your | ||||
|          Flutter UI initializes, as well as behind your Flutter UI while its | ||||
|          running. | ||||
| 
 | ||||
|          This Theme is only used starting with V2 of Flutter's Android embedding. --> | ||||
|     <style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar"> | ||||
|         <item name="android:windowBackground">?android:colorBackground</item> | ||||
|     </style> | ||||
| </resources> | ||||
							
								
								
									
										7
									
								
								base_project/android/app/src/profile/AndroidManifest.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,7 @@ | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <!-- The INTERNET permission is required for development. Specifically, | ||||
|          the Flutter tool needs it to communicate with the running application | ||||
|          to allow setting breakpoints, to provide hot reload, etc. | ||||
|     --> | ||||
|     <uses-permission android:name="android.permission.INTERNET"/> | ||||
| </manifest> | ||||
							
								
								
									
										21
									
								
								base_project/android/build.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,21 @@ | ||||
| allprojects { | ||||
|     repositories { | ||||
|         google() | ||||
|         mavenCentral() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| rootProject.buildDir = "../build" | ||||
| subprojects { | ||||
|     project.buildDir = "${rootProject.buildDir}/${project.name}" | ||||
| } | ||||
| subprojects { | ||||
|     project.evaluationDependsOn(":app") | ||||
| } | ||||
| 
 | ||||
| tasks.register("clean", Delete) { | ||||
|     delete rootProject.buildDir | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										6
									
								
								base_project/android/gradle.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,6 @@ | ||||
| org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError | ||||
| android.useAndroidX=true | ||||
| android.enableJetifier=true | ||||
| android.nonTransitiveRClass=true | ||||
| android.defaults.buildfeatures.namespaces=false | ||||
| 
 | ||||
							
								
								
									
										5
									
								
								base_project/android/gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,5 @@ | ||||
| distributionBase=GRADLE_USER_HOME | ||||
| distributionPath=wrapper/dists | ||||
| zipStoreBase=GRADLE_USER_HOME | ||||
| zipStorePath=wrapper/dists | ||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip | ||||
							
								
								
									
										25
									
								
								base_project/android/settings.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,25 @@ | ||||
| pluginManagement { | ||||
|     def flutterSdkPath = { | ||||
|         def properties = new Properties() | ||||
|         file("local.properties").withInputStream { properties.load(it) } | ||||
|         def flutterSdkPath = properties.getProperty("flutter.sdk") | ||||
|         assert flutterSdkPath != null, "flutter.sdk not set in local.properties" | ||||
|         return flutterSdkPath | ||||
|     }() | ||||
| 
 | ||||
|     includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") | ||||
| 
 | ||||
|     repositories { | ||||
|         google() | ||||
|         mavenCentral() | ||||
|         gradlePluginPortal() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| plugins { | ||||
|     id "dev.flutter.flutter-plugin-loader" version "1.0.0" | ||||
|     id "com.android.application" version "8.2.1" apply false | ||||
|     id "org.jetbrains.kotlin.android" version "1.8.22" apply false | ||||
| } | ||||
| 
 | ||||
| include ":app" | ||||
							
								
								
									
										6
									
								
								base_project/assets/icon/bubbles.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,6 @@ | ||||
| <svg width="93" height="87" viewBox="0 0 93 87" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||
| <circle cx="33.9429" cy="36.8292" r="6.82918" fill="#AF2D2D"/> | ||||
| <circle cx="79" cy="27" r="13" fill="#AF2D2D"/> | ||||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M32.5511 49.4389C32.4191 48.7782 31.9357 48.2428 31.2918 48.0442C30.5686 47.8212 29.7827 48.0647 29.3124 48.6576L26.6097 52.0648C24.7585 54.3984 21.7904 55.5017 18.8235 55.2372C11.5519 54.5888 4.04597 55.1701 -3.42021 57.1407C-37.9518 66.255 -58.5567 101.637 -49.4425 136.169C-40.3282 170.7 -4.9463 191.305 29.5853 182.191C64.1169 173.077 84.7218 137.695 75.6076 103.163C70.3813 83.3617 56.5177 68.1397 39.13 60.4748C36.2342 59.1983 34.0008 56.6968 33.3809 53.5935L32.5511 49.4389Z" fill="#AF2D2D"/> | ||||
| <circle cx="21.5475" cy="4.5476" r="3.49096" transform="rotate(-22.0902 21.5475 4.5476)" fill="#AF2D2D"/> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 869 B | 
							
								
								
									
										3
									
								
								base_project/assets/icon/close.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,3 @@ | ||||
| <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||
| <path d="M25.8137 9.6379C26.6421 8.8095 26.6421 7.46638 25.8137 6.63797L25.3622 6.18649C24.5338 5.35808 23.1907 5.35808 22.3623 6.18649L16.0002 12.5486L9.63815 6.18649C8.80974 5.35809 7.46662 5.35808 6.63822 6.18649L6.18673 6.63797C5.35833 7.46638 5.35833 8.80949 6.18674 9.6379L12.5488 16L6.18674 22.362C5.35833 23.1904 5.35833 24.5336 6.18674 25.362L6.63822 25.8134C7.46662 26.6419 8.80974 26.6419 9.63814 25.8134L16.0002 19.4514L22.3623 25.8134C23.1907 26.6418 24.5338 26.6419 25.3622 25.8134L25.8137 25.362C26.6421 24.5336 26.6421 23.1904 25.8137 22.362L19.4516 16L25.8137 9.6379Z" fill="white"/> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 704 B | 
							
								
								
									
										3
									
								
								base_project/assets/icon/fail.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,3 @@ | ||||
| <svg width="78" height="78" viewBox="0 0 78 78" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||
| <path fill-rule="evenodd" clip-rule="evenodd" d="M47.8055 67.6794C48.1344 67.4706 48.4933 67.3124 48.8664 67.2006C63.0117 62.9621 73.3199 49.8448 73.3199 34.32C73.3199 15.3656 57.9543 0 38.9999 0C20.0455 0 4.67993 15.3656 4.67993 34.32C4.67993 47.8227 12.4777 59.5042 23.8158 65.1068C23.8286 65.1132 23.8233 65.1326 23.8091 65.1315C23.7999 65.1308 23.793 65.1396 23.7957 65.1483L26.9037 74.9903C27.6946 77.4949 30.6437 78.5705 32.8614 77.1631L47.8055 67.6794Z" fill="#801336"/> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 581 B | 
							
								
								
									
										11
									
								
								base_project/assets/images/bubbles.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,11 @@ | ||||
| <?xml version='1.0' encoding='iso-8859-1'?> | ||||
| <!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools --> | ||||
| <svg fill="#000000" height="800px" width="800px" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 363.188 363.188" xmlns:xlink="http://www.w3.org/1999/xlink" enable-background="new 0 0 363.188 363.188"> | ||||
|   <g> | ||||
|     <path d="m111.667,132.311c-61.574,0-111.667,50.093-111.667,111.666s50.093,111.667 111.667,111.667 111.667-50.094 111.667-111.667-50.094-111.666-111.667-111.666zm0,208.333c-53.303,0-96.667-43.364-96.667-96.667 0-53.302 43.364-96.666 96.667-96.666s96.667,43.364 96.667,96.666c-0.001,53.303-43.365,96.667-96.667,96.667z"/> | ||||
|     <path d="m111.667,173.977c-4.142,0-7.5,3.357-7.5,7.5s3.358,7.5 7.5,7.5c30.327,0 55,24.673 55,55 0,4.143 3.358,7.5 7.5,7.5s7.5-3.357 7.5-7.5c0-38.598-31.402-70-70-70z"/> | ||||
|     <path d="m298.333,69.835c-35.761,0-64.855,29.094-64.855,64.855 0,35.761 29.094,64.854 64.855,64.854s64.855-29.094 64.855-64.854c-5.68434e-14-35.761-29.093-64.855-64.855-64.855zm0,114.71c-27.49,0-49.855-22.364-49.855-49.854s22.365-49.855 49.855-49.855 49.855,22.365 49.855,49.855-22.364,49.854-49.855,49.854z"/> | ||||
|     <path d="m302.012,157.925c-14.84,0-26.913-12.073-26.913-26.913 0-4.143-3.358-7.5-7.5-7.5s-7.5,3.357-7.5,7.5c0,23.111 18.802,41.913 41.913,41.913 4.142,0 7.5-3.357 7.5-7.5s-3.358-7.5-7.5-7.5z"/> | ||||
|     <path d="m123.358,96.568c24.544,0 44.512-19.968 44.512-44.512s-19.968-44.512-44.512-44.512-44.512,19.968-44.512,44.512 19.968,44.512 44.512,44.512zm0-74.024c16.273,3.55271e-15 29.512,13.239 29.512,29.512s-13.239,29.512-29.512,29.512-29.512-13.239-29.512-29.512 13.239-29.512 29.512-29.512z"/> | ||||
|   </g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 1.6 KiB | 
							
								
								
									
										1
									
								
								base_project/assets/images/close.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1 @@ | ||||
| <svg xmlns="http://www.w3.org/2000/svg"  viewBox="0 0 50 50" width="50px" height="50px"><path d="M 7.71875 6.28125 L 6.28125 7.71875 L 23.5625 25 L 6.28125 42.28125 L 7.71875 43.71875 L 25 26.4375 L 42.28125 43.71875 L 43.71875 42.28125 L 26.4375 25 L 43.71875 7.71875 L 42.28125 6.28125 L 25 23.5625 Z"/></svg> | ||||
| After Width: | Height: | Size: 311 B | 
							
								
								
									
										
											BIN
										
									
								
								base_project/assets/images/image_not_found.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 4.2 KiB | 
							
								
								
									
										3
									
								
								base_project/assets/images/img_arrowleft.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,3 @@ | ||||
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||
| <path d="M16.9999 10.9999H9.4099L12.7099 7.70994C12.8982 7.52164 13.004 7.26624 13.004 6.99994C13.004 6.73364 12.8982 6.47825 12.7099 6.28994C12.5216 6.10164 12.2662 5.99585 11.9999 5.99585C11.7336 5.99585 11.4782 6.10164 11.2899 6.28994L6.2899 11.2899C6.19886 11.385 6.12749 11.4972 6.0799 11.6199C5.97988 11.8634 5.97988 12.1365 6.0799 12.3799C6.12749 12.5027 6.19886 12.6148 6.2899 12.7099L11.2899 17.7099C11.3829 17.8037 11.4935 17.8781 11.6153 17.9288C11.7372 17.9796 11.8679 18.0057 11.9999 18.0057C12.1319 18.0057 12.2626 17.9796 12.3845 17.9288C12.5063 17.8781 12.6169 17.8037 12.7099 17.7099C12.8036 17.617 12.878 17.5064 12.9288 17.3845C12.9796 17.2627 13.0057 17.132 13.0057 16.9999C13.0057 16.8679 12.9796 16.7372 12.9288 16.6154C12.878 16.4935 12.8036 16.3829 12.7099 16.2899L9.4099 12.9999H16.9999C17.2651 12.9999 17.5195 12.8946 17.707 12.707C17.8945 12.5195 17.9999 12.2652 17.9999 11.9999C17.9999 11.7347 17.8945 11.4804 17.707 11.2928C17.5195 11.1053 17.2651 10.9999 16.9999 10.9999Z" fill="#262B35"/> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 1.1 KiB | 
| @ -0,0 +1,3 @@ | ||||
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||
| <path d="M16.9999 10.9999H9.4099L12.7099 7.70994C12.8982 7.52164 13.004 7.26624 13.004 6.99994C13.004 6.73364 12.8982 6.47825 12.7099 6.28994C12.5216 6.10164 12.2662 5.99585 11.9999 5.99585C11.7336 5.99585 11.4782 6.10164 11.2899 6.28994L6.2899 11.2899C6.19886 11.385 6.12749 11.4972 6.0799 11.6199C5.97988 11.8634 5.97988 12.1365 6.0799 12.3799C6.12749 12.5027 6.19886 12.6148 6.2899 12.7099L11.2899 17.7099C11.3829 17.8037 11.4935 17.8781 11.6153 17.9288C11.7372 17.9796 11.8679 18.0057 11.9999 18.0057C12.1319 18.0057 12.2626 17.9796 12.3845 17.9288C12.5063 17.8781 12.6169 17.8037 12.7099 17.7099C12.8036 17.617 12.878 17.5064 12.9288 17.3845C12.9796 17.2627 13.0057 17.132 13.0057 16.9999C13.0057 16.8679 12.9796 16.7372 12.9288 16.6154C12.878 16.4935 12.8036 16.3829 12.7099 16.2899L9.4099 12.9999H16.9999C17.2651 12.9999 17.5195 12.8946 17.707 12.707C17.8945 12.5195 17.9999 12.2652 17.9999 11.9999C17.9999 11.7347 17.8945 11.4804 17.707 11.2928C17.5195 11.1053 17.2651 10.9999 16.9999 10.9999Z" fill="#262B35"/> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 1.1 KiB | 
							
								
								
									
										10
									
								
								base_project/assets/images/img_fire.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,10 @@ | ||||
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||
| <g opacity="0.5" clip-path="url(#clip0_521_2417)"> | ||||
| <path d="M13.5 0.670013C13.5 0.670013 14.24 3.32001 14.24 5.47001C14.24 7.53001 12.89 9.20001 10.83 9.20001C8.76 9.20001 7.2 7.53001 7.2 5.47001L7.23 5.11001C5.21 7.51001 4 10.62 4 14C4 18.42 7.58 22 12 22C16.42 22 20 18.42 20 14C20 8.61001 17.41 3.80001 13.5 0.670013ZM11.71 19C9.93 19 8.49 17.6 8.49 15.86C8.49 14.24 9.54 13.1 11.3 12.74C13.07 12.38 14.9 11.53 15.92 10.16C16.31 11.45 16.51 12.81 16.51 14.2C16.51 16.85 14.36 19 11.71 19Z" fill="white"/> | ||||
| </g> | ||||
| <defs> | ||||
| <clipPath id="clip0_521_2417"> | ||||
| <rect width="24" height="24" fill="white"/> | ||||
| </clipPath> | ||||
| </defs> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 718 B | 
							
								
								
									
										3
									
								
								base_project/assets/images/img_menu.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,3 @@ | ||||
| <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||
| <path d="M16.125 9H3.875C3.64294 9 3.42038 9.07902 3.25628 9.21967C3.09219 9.36032 3 9.55109 3 9.75C3 9.94891 3.09219 10.1397 3.25628 10.2803C3.42038 10.421 3.64294 10.5 3.875 10.5H16.125C16.3571 10.5 16.5796 10.421 16.7437 10.2803C16.9078 10.1397 17 9.94891 17 9.75C17 9.55109 16.9078 9.36032 16.7437 9.21967C16.5796 9.07902 16.3571 9 16.125 9Z" fill="#75839D"/> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 467 B | 
							
								
								
									
										10
									
								
								base_project/assets/images/img_overflowmenu_white_a700.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,10 @@ | ||||
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||
| <g opacity="0.5" clip-path="url(#clip0_521_2408)"> | ||||
| <path d="M12 8C13.1 8 14 7.1 14 6C14 4.9 13.1 4 12 4C10.9 4 10 4.9 10 6C10 7.1 10.9 8 12 8ZM12 10C10.9 10 10 10.9 10 12C10 13.1 10.9 14 12 14C13.1 14 14 13.1 14 12C14 10.9 13.1 10 12 10ZM12 16C10.9 16 10 16.9 10 18C10 19.1 10.9 20 12 20C13.1 20 14 19.1 14 18C14 16.9 13.1 16 12 16Z" fill="white"/> | ||||
| </g> | ||||
| <defs> | ||||
| <clipPath id="clip0_521_2408"> | ||||
| <rect width="24" height="24" fill="white"/> | ||||
| </clipPath> | ||||
| </defs> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 559 B | 
							
								
								
									
										10
									
								
								base_project/assets/images/img_search_white_a700_20x20.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,10 @@ | ||||
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||||
| <g clip-path="url(#clip0_521_2411)"> | ||||
| <path d="M12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM13 5.3L14.35 4.35C16.17 4.91 17.72 6.11 18.73 7.69L18.34 9.03L16.99 9.49L13 6.7V5.3ZM9.65 4.35L11 5.3V6.7L7.01 9.49L5.66 9.03L5.27 7.69C6.28 6.12 7.83 4.92 9.65 4.35ZM7.08 17.11L5.94 17.21C4.73 15.81 4 13.99 4 12C4 11.88 4.01 11.77 4.02 11.65L5.02 10.92L6.4 11.4L7.86 15.74L7.08 17.11ZM14.5 19.59C13.71 19.85 12.87 20 12 20C11.13 20 10.29 19.85 9.5 19.59L8.81 18.1L9.45 17H14.56L15.2 18.11L14.5 19.59ZM14.27 15H9.73L8.38 10.98L12 8.44L15.63 10.98L14.27 15ZM18.06 17.21L16.92 17.11L16.13 15.74L17.59 11.4L18.98 10.93L19.98 11.66C19.99 11.77 20 11.88 20 12C20 13.99 19.27 15.81 18.06 17.21Z" fill="white"/> | ||||
| </g> | ||||
| <defs> | ||||
| <clipPath id="clip0_521_2411"> | ||||
| <rect width="24" height="24" fill="white"/> | ||||
| </clipPath> | ||||
| </defs> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 954 B | 
							
								
								
									
										1
									
								
								base_project/assets/images/user-line.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1 @@ | ||||
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M4 22C4 17.5817 7.58172 14 12 14C16.4183 14 20 17.5817 20 22H18C18 18.6863 15.3137 16 12 16C8.68629 16 6 18.6863 6 22H4ZM12 13C8.685 13 6 10.315 6 7C6 3.685 8.685 1 12 1C15.315 1 18 3.685 18 7C18 10.315 15.315 13 12 13ZM12 11C14.21 11 16 9.21 16 7C16 4.79 14.21 3 12 3C9.79 3 8 4.79 8 7C8 9.21 9.79 11 12 11Z"></path></svg> | ||||
| After Width: | Height: | Size: 412 B | 
							
								
								
									
										3
									
								
								base_project/devtools_options.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,3 @@ | ||||
| description: This file stores settings for Dart & Flutter DevTools. | ||||
| documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states | ||||
| extensions: | ||||
							
								
								
									
										34
									
								
								base_project/ios/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,34 @@ | ||||
| **/dgph | ||||
| *.mode1v3 | ||||
| *.mode2v3 | ||||
| *.moved-aside | ||||
| *.pbxuser | ||||
| *.perspectivev3 | ||||
| **/*sync/ | ||||
| .sconsign.dblite | ||||
| .tags* | ||||
| **/.vagrant/ | ||||
| **/DerivedData/ | ||||
| Icon? | ||||
| **/Pods/ | ||||
| **/.symlinks/ | ||||
| profile | ||||
| xcuserdata | ||||
| **/.generated/ | ||||
| Flutter/App.framework | ||||
| Flutter/Flutter.framework | ||||
| Flutter/Flutter.podspec | ||||
| Flutter/Generated.xcconfig | ||||
| Flutter/ephemeral/ | ||||
| Flutter/app.flx | ||||
| Flutter/app.zip | ||||
| Flutter/flutter_assets/ | ||||
| Flutter/flutter_export_environment.sh | ||||
| ServiceDefinitions.json | ||||
| Runner/GeneratedPluginRegistrant.* | ||||
| 
 | ||||
| # Exceptions to above rules. | ||||
| !default.mode1v3 | ||||
| !default.mode2v3 | ||||
| !default.pbxuser | ||||
| !default.perspectivev3 | ||||
							
								
								
									
										26
									
								
								base_project/ios/Flutter/AppFrameworkInfo.plist
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,26 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||
| <plist version="1.0"> | ||||
| <dict> | ||||
|   <key>CFBundleDevelopmentRegion</key> | ||||
|   <string>en</string> | ||||
|   <key>CFBundleExecutable</key> | ||||
|   <string>App</string> | ||||
|   <key>CFBundleIdentifier</key> | ||||
|   <string>io.flutter.flutter.app</string> | ||||
|   <key>CFBundleInfoDictionaryVersion</key> | ||||
|   <string>6.0</string> | ||||
|   <key>CFBundleName</key> | ||||
|   <string>App</string> | ||||
|   <key>CFBundlePackageType</key> | ||||
|   <string>FMWK</string> | ||||
|   <key>CFBundleShortVersionString</key> | ||||
|   <string>1.0</string> | ||||
|   <key>CFBundleSignature</key> | ||||
|   <string>????</string> | ||||
|   <key>CFBundleVersion</key> | ||||
|   <string>1.0</string> | ||||
|   <key>MinimumOSVersion</key> | ||||
|   <string>12.0</string> | ||||
| </dict> | ||||
| </plist> | ||||
							
								
								
									
										2
									
								
								base_project/ios/Flutter/Debug.xcconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,2 @@ | ||||
| #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" | ||||
| #include "Generated.xcconfig" | ||||
							
								
								
									
										2
									
								
								base_project/ios/Flutter/Release.xcconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,2 @@ | ||||
| #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" | ||||
| #include "Generated.xcconfig" | ||||
							
								
								
									
										41
									
								
								base_project/ios/Podfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,41 @@ | ||||
| # Uncomment this line to define a global platform for your project | ||||
| # platform :ios, '12.0' | ||||
| 
 | ||||
| # CocoaPods analytics sends network stats synchronously affecting flutter build latency. | ||||
| ENV['COCOAPODS_DISABLE_STATS'] = 'true' | ||||
| 
 | ||||
| project 'Runner', { | ||||
|   'Debug' => :debug, | ||||
|   'Profile' => :release, | ||||
|   'Release' => :release, | ||||
| } | ||||
| 
 | ||||
| def flutter_root | ||||
|   generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) | ||||
|   unless File.exist?(generated_xcode_build_settings_path) | ||||
|     raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" | ||||
|   end | ||||
| 
 | ||||
|   File.foreach(generated_xcode_build_settings_path) do |line| | ||||
|     matches = line.match(/FLUTTER_ROOT\=(.*)/) | ||||
|     return matches[1].strip if matches | ||||
|   end | ||||
|   raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" | ||||
| end | ||||
| 
 | ||||
| require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) | ||||
| 
 | ||||
| flutter_ios_podfile_setup | ||||
| 
 | ||||
| target 'Runner' do | ||||
|   flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) | ||||
|   target 'RunnerTests' do | ||||
|     inherit! :search_paths | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| post_install do |installer| | ||||
|   installer.pods_project.targets.each do |target| | ||||
|     flutter_additional_ios_build_settings(target) | ||||
|   end | ||||
| end | ||||
							
								
								
									
										616
									
								
								base_project/ios/Runner.xcodeproj/project.pbxproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,616 @@ | ||||
| // !$*UTF8*$! | ||||
| { | ||||
| 	archiveVersion = 1; | ||||
| 	classes = { | ||||
| 	}; | ||||
| 	objectVersion = 54; | ||||
| 	objects = { | ||||
| 
 | ||||
| /* Begin PBXBuildFile section */ | ||||
| 		1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; | ||||
| 		331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; | ||||
| 		3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; | ||||
| 		74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; | ||||
| 		97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; | ||||
| 		97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; | ||||
| 		97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; | ||||
| /* End PBXBuildFile section */ | ||||
| 
 | ||||
| /* Begin PBXContainerItemProxy section */ | ||||
| 		331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { | ||||
| 			isa = PBXContainerItemProxy; | ||||
| 			containerPortal = 97C146E61CF9000F007C117D /* Project object */; | ||||
| 			proxyType = 1; | ||||
| 			remoteGlobalIDString = 97C146ED1CF9000F007C117D; | ||||
| 			remoteInfo = Runner; | ||||
| 		}; | ||||
| /* End PBXContainerItemProxy section */ | ||||
| 
 | ||||
| /* Begin PBXCopyFilesBuildPhase section */ | ||||
| 		9705A1C41CF9048500538489 /* Embed Frameworks */ = { | ||||
| 			isa = PBXCopyFilesBuildPhase; | ||||
| 			buildActionMask = 2147483647; | ||||
| 			dstPath = ""; | ||||
| 			dstSubfolderSpec = 10; | ||||
| 			files = ( | ||||
| 			); | ||||
| 			name = "Embed Frameworks"; | ||||
| 			runOnlyForDeploymentPostprocessing = 0; | ||||
| 		}; | ||||
| /* End PBXCopyFilesBuildPhase section */ | ||||
| 
 | ||||
| /* Begin PBXFileReference section */ | ||||
| 		1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; | ||||
| 		1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; | ||||
| 		331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; }; | ||||
| 		331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; | ||||
| 		3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; | ||||
| 		74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; | ||||
| 		74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; | ||||
| 		7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; | ||||
| 		9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; }; | ||||
| 		9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; | ||||
| 		97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; | ||||
| 		97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; | ||||
| 		97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; | ||||
| 		97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; | ||||
| 		97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; | ||||
| /* End PBXFileReference section */ | ||||
| 
 | ||||
| /* Begin PBXFrameworksBuildPhase section */ | ||||
| 		97C146EB1CF9000F007C117D /* Frameworks */ = { | ||||
| 			isa = PBXFrameworksBuildPhase; | ||||
| 			buildActionMask = 2147483647; | ||||
| 			files = ( | ||||
| 			); | ||||
| 			runOnlyForDeploymentPostprocessing = 0; | ||||
| 		}; | ||||
| /* End PBXFrameworksBuildPhase section */ | ||||
| 
 | ||||
| /* Begin PBXGroup section */ | ||||
| 		331C8082294A63A400263BE5 /* RunnerTests */ = { | ||||
| 			isa = PBXGroup; | ||||
| 			children = ( | ||||
| 				331C807B294A618700263BE5 /* RunnerTests.swift */, | ||||
| 			); | ||||
| 			path = RunnerTests; | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| 		9740EEB11CF90186004384FC /* Flutter */ = { | ||||
| 			isa = PBXGroup; | ||||
| 			children = ( | ||||
| 				3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, | ||||
| 				9740EEB21CF90195004384FC /* Debug.xcconfig */, | ||||
| 				7AFA3C8E1D35360C0083082E /* Release.xcconfig */, | ||||
| 				9740EEB31CF90195004384FC /* Generated.xcconfig */, | ||||
| 			); | ||||
| 			name = Flutter; | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| 		97C146E51CF9000F007C117D = { | ||||
| 			isa = PBXGroup; | ||||
| 			children = ( | ||||
| 				9740EEB11CF90186004384FC /* Flutter */, | ||||
| 				97C146F01CF9000F007C117D /* Runner */, | ||||
| 				97C146EF1CF9000F007C117D /* Products */, | ||||
| 				331C8082294A63A400263BE5 /* RunnerTests */, | ||||
| 			); | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| 		97C146EF1CF9000F007C117D /* Products */ = { | ||||
| 			isa = PBXGroup; | ||||
| 			children = ( | ||||
| 				97C146EE1CF9000F007C117D /* Runner.app */, | ||||
| 				331C8081294A63A400263BE5 /* RunnerTests.xctest */, | ||||
| 			); | ||||
| 			name = Products; | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| 		97C146F01CF9000F007C117D /* Runner */ = { | ||||
| 			isa = PBXGroup; | ||||
| 			children = ( | ||||
| 				97C146FA1CF9000F007C117D /* Main.storyboard */, | ||||
| 				97C146FD1CF9000F007C117D /* Assets.xcassets */, | ||||
| 				97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, | ||||
| 				97C147021CF9000F007C117D /* Info.plist */, | ||||
| 				1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, | ||||
| 				1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, | ||||
| 				74858FAE1ED2DC5600515810 /* AppDelegate.swift */, | ||||
| 				74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, | ||||
| 			); | ||||
| 			path = Runner; | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| /* End PBXGroup section */ | ||||
| 
 | ||||
| /* Begin PBXNativeTarget section */ | ||||
| 		331C8080294A63A400263BE5 /* RunnerTests */ = { | ||||
| 			isa = PBXNativeTarget; | ||||
| 			buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; | ||||
| 			buildPhases = ( | ||||
| 				331C807D294A63A400263BE5 /* Sources */, | ||||
| 				331C807F294A63A400263BE5 /* Resources */, | ||||
| 			); | ||||
| 			buildRules = ( | ||||
| 			); | ||||
| 			dependencies = ( | ||||
| 				331C8086294A63A400263BE5 /* PBXTargetDependency */, | ||||
| 			); | ||||
| 			name = RunnerTests; | ||||
| 			productName = RunnerTests; | ||||
| 			productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; | ||||
| 			productType = "com.apple.product-type.bundle.unit-test"; | ||||
| 		}; | ||||
| 		97C146ED1CF9000F007C117D /* Runner */ = { | ||||
| 			isa = PBXNativeTarget; | ||||
| 			buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; | ||||
| 			buildPhases = ( | ||||
| 				9740EEB61CF901F6004384FC /* Run Script */, | ||||
| 				97C146EA1CF9000F007C117D /* Sources */, | ||||
| 				97C146EB1CF9000F007C117D /* Frameworks */, | ||||
| 				97C146EC1CF9000F007C117D /* Resources */, | ||||
| 				9705A1C41CF9048500538489 /* Embed Frameworks */, | ||||
| 				3B06AD1E1E4923F5004D2608 /* Thin Binary */, | ||||
| 			); | ||||
| 			buildRules = ( | ||||
| 			); | ||||
| 			dependencies = ( | ||||
| 			); | ||||
| 			name = Runner; | ||||
| 			productName = Runner; | ||||
| 			productReference = 97C146EE1CF9000F007C117D /* Runner.app */; | ||||
| 			productType = "com.apple.product-type.application"; | ||||
| 		}; | ||||
| /* End PBXNativeTarget section */ | ||||
| 
 | ||||
| /* Begin PBXProject section */ | ||||
| 		97C146E61CF9000F007C117D /* Project object */ = { | ||||
| 			isa = PBXProject; | ||||
| 			attributes = { | ||||
| 				BuildIndependentTargetsInParallel = YES; | ||||
| 				LastUpgradeCheck = 1510; | ||||
| 				ORGANIZATIONNAME = ""; | ||||
| 				TargetAttributes = { | ||||
| 					331C8080294A63A400263BE5 = { | ||||
| 						CreatedOnToolsVersion = 14.0; | ||||
| 						TestTargetID = 97C146ED1CF9000F007C117D; | ||||
| 					}; | ||||
| 					97C146ED1CF9000F007C117D = { | ||||
| 						CreatedOnToolsVersion = 7.3.1; | ||||
| 						LastSwiftMigration = 1100; | ||||
| 					}; | ||||
| 				}; | ||||
| 			}; | ||||
| 			buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; | ||||
| 			compatibilityVersion = "Xcode 9.3"; | ||||
| 			developmentRegion = en; | ||||
| 			hasScannedForEncodings = 0; | ||||
| 			knownRegions = ( | ||||
| 				en, | ||||
| 				Base, | ||||
| 			); | ||||
| 			mainGroup = 97C146E51CF9000F007C117D; | ||||
| 			productRefGroup = 97C146EF1CF9000F007C117D /* Products */; | ||||
| 			projectDirPath = ""; | ||||
| 			projectRoot = ""; | ||||
| 			targets = ( | ||||
| 				97C146ED1CF9000F007C117D /* Runner */, | ||||
| 				331C8080294A63A400263BE5 /* RunnerTests */, | ||||
| 			); | ||||
| 		}; | ||||
| /* End PBXProject section */ | ||||
| 
 | ||||
| /* Begin PBXResourcesBuildPhase section */ | ||||
| 		331C807F294A63A400263BE5 /* Resources */ = { | ||||
| 			isa = PBXResourcesBuildPhase; | ||||
| 			buildActionMask = 2147483647; | ||||
| 			files = ( | ||||
| 			); | ||||
| 			runOnlyForDeploymentPostprocessing = 0; | ||||
| 		}; | ||||
| 		97C146EC1CF9000F007C117D /* Resources */ = { | ||||
| 			isa = PBXResourcesBuildPhase; | ||||
| 			buildActionMask = 2147483647; | ||||
| 			files = ( | ||||
| 				97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, | ||||
| 				3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, | ||||
| 				97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, | ||||
| 				97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, | ||||
| 			); | ||||
| 			runOnlyForDeploymentPostprocessing = 0; | ||||
| 		}; | ||||
| /* End PBXResourcesBuildPhase section */ | ||||
| 
 | ||||
| /* Begin PBXShellScriptBuildPhase section */ | ||||
| 		3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { | ||||
| 			isa = PBXShellScriptBuildPhase; | ||||
| 			alwaysOutOfDate = 1; | ||||
| 			buildActionMask = 2147483647; | ||||
| 			files = ( | ||||
| 			); | ||||
| 			inputPaths = ( | ||||
| 				"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", | ||||
| 			); | ||||
| 			name = "Thin Binary"; | ||||
| 			outputPaths = ( | ||||
| 			); | ||||
| 			runOnlyForDeploymentPostprocessing = 0; | ||||
| 			shellPath = /bin/sh; | ||||
| 			shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; | ||||
| 		}; | ||||
| 		9740EEB61CF901F6004384FC /* Run Script */ = { | ||||
| 			isa = PBXShellScriptBuildPhase; | ||||
| 			alwaysOutOfDate = 1; | ||||
| 			buildActionMask = 2147483647; | ||||
| 			files = ( | ||||
| 			); | ||||
| 			inputPaths = ( | ||||
| 			); | ||||
| 			name = "Run Script"; | ||||
| 			outputPaths = ( | ||||
| 			); | ||||
| 			runOnlyForDeploymentPostprocessing = 0; | ||||
| 			shellPath = /bin/sh; | ||||
| 			shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; | ||||
| 		}; | ||||
| /* End PBXShellScriptBuildPhase section */ | ||||
| 
 | ||||
| /* Begin PBXSourcesBuildPhase section */ | ||||
| 		331C807D294A63A400263BE5 /* Sources */ = { | ||||
| 			isa = PBXSourcesBuildPhase; | ||||
| 			buildActionMask = 2147483647; | ||||
| 			files = ( | ||||
| 				331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, | ||||
| 			); | ||||
| 			runOnlyForDeploymentPostprocessing = 0; | ||||
| 		}; | ||||
| 		97C146EA1CF9000F007C117D /* Sources */ = { | ||||
| 			isa = PBXSourcesBuildPhase; | ||||
| 			buildActionMask = 2147483647; | ||||
| 			files = ( | ||||
| 				74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, | ||||
| 				1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, | ||||
| 			); | ||||
| 			runOnlyForDeploymentPostprocessing = 0; | ||||
| 		}; | ||||
| /* End PBXSourcesBuildPhase section */ | ||||
| 
 | ||||
| /* Begin PBXTargetDependency section */ | ||||
| 		331C8086294A63A400263BE5 /* PBXTargetDependency */ = { | ||||
| 			isa = PBXTargetDependency; | ||||
| 			target = 97C146ED1CF9000F007C117D /* Runner */; | ||||
| 			targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; | ||||
| 		}; | ||||
| /* End PBXTargetDependency section */ | ||||
| 
 | ||||
| /* Begin PBXVariantGroup section */ | ||||
| 		97C146FA1CF9000F007C117D /* Main.storyboard */ = { | ||||
| 			isa = PBXVariantGroup; | ||||
| 			children = ( | ||||
| 				97C146FB1CF9000F007C117D /* Base */, | ||||
| 			); | ||||
| 			name = Main.storyboard; | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| 		97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { | ||||
| 			isa = PBXVariantGroup; | ||||
| 			children = ( | ||||
| 				97C147001CF9000F007C117D /* Base */, | ||||
| 			); | ||||
| 			name = LaunchScreen.storyboard; | ||||
| 			sourceTree = "<group>"; | ||||
| 		}; | ||||
| /* End PBXVariantGroup section */ | ||||
| 
 | ||||
| /* Begin XCBuildConfiguration section */ | ||||
| 		249021D3217E4FDB00AE95B9 /* Profile */ = { | ||||
| 			isa = XCBuildConfiguration; | ||||
| 			buildSettings = { | ||||
| 				ALWAYS_SEARCH_USER_PATHS = NO; | ||||
| 				ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; | ||||
| 				CLANG_ANALYZER_NONNULL = YES; | ||||
| 				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; | ||||
| 				CLANG_CXX_LIBRARY = "libc++"; | ||||
| 				CLANG_ENABLE_MODULES = YES; | ||||
| 				CLANG_ENABLE_OBJC_ARC = YES; | ||||
| 				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; | ||||
| 				CLANG_WARN_BOOL_CONVERSION = YES; | ||||
| 				CLANG_WARN_COMMA = YES; | ||||
| 				CLANG_WARN_CONSTANT_CONVERSION = YES; | ||||
| 				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; | ||||
| 				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; | ||||
| 				CLANG_WARN_EMPTY_BODY = YES; | ||||
| 				CLANG_WARN_ENUM_CONVERSION = YES; | ||||
| 				CLANG_WARN_INFINITE_RECURSION = YES; | ||||
| 				CLANG_WARN_INT_CONVERSION = YES; | ||||
| 				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; | ||||
| 				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; | ||||
| 				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; | ||||
| 				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; | ||||
| 				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; | ||||
| 				CLANG_WARN_STRICT_PROTOTYPES = YES; | ||||
| 				CLANG_WARN_SUSPICIOUS_MOVE = YES; | ||||
| 				CLANG_WARN_UNREACHABLE_CODE = YES; | ||||
| 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; | ||||
| 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; | ||||
| 				COPY_PHASE_STRIP = NO; | ||||
| 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; | ||||
| 				ENABLE_NS_ASSERTIONS = NO; | ||||
| 				ENABLE_STRICT_OBJC_MSGSEND = YES; | ||||
| 				ENABLE_USER_SCRIPT_SANDBOXING = NO; | ||||
| 				GCC_C_LANGUAGE_STANDARD = gnu99; | ||||
| 				GCC_NO_COMMON_BLOCKS = YES; | ||||
| 				GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | ||||
| 				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | ||||
| 				GCC_WARN_UNDECLARED_SELECTOR = YES; | ||||
| 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | ||||
| 				GCC_WARN_UNUSED_FUNCTION = YES; | ||||
| 				GCC_WARN_UNUSED_VARIABLE = YES; | ||||
| 				IPHONEOS_DEPLOYMENT_TARGET = 12.0; | ||||
| 				MTL_ENABLE_DEBUG_INFO = NO; | ||||
| 				SDKROOT = iphoneos; | ||||
| 				SUPPORTED_PLATFORMS = iphoneos; | ||||
| 				TARGETED_DEVICE_FAMILY = "1,2"; | ||||
| 				VALIDATE_PRODUCT = YES; | ||||
| 			}; | ||||
| 			name = Profile; | ||||
| 		}; | ||||
| 		249021D4217E4FDB00AE95B9 /* Profile */ = { | ||||
| 			isa = XCBuildConfiguration; | ||||
| 			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; | ||||
| 			buildSettings = { | ||||
| 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | ||||
| 				CLANG_ENABLE_MODULES = YES; | ||||
| 				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | ||||
| 				ENABLE_BITCODE = NO; | ||||
| 				INFOPLIST_FILE = Runner/Info.plist; | ||||
| 				LD_RUNPATH_SEARCH_PATHS = ( | ||||
| 					"$(inherited)", | ||||
| 					"@executable_path/Frameworks", | ||||
| 				); | ||||
| 				PRODUCT_BUNDLE_IDENTIFIER = com.example.baseProject; | ||||
| 				PRODUCT_NAME = "$(TARGET_NAME)"; | ||||
| 				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | ||||
| 				SWIFT_VERSION = 5.0; | ||||
| 				VERSIONING_SYSTEM = "apple-generic"; | ||||
| 			}; | ||||
| 			name = Profile; | ||||
| 		}; | ||||
| 		331C8088294A63A400263BE5 /* Debug */ = { | ||||
| 			isa = XCBuildConfiguration; | ||||
| 			buildSettings = { | ||||
| 				BUNDLE_LOADER = "$(TEST_HOST)"; | ||||
| 				CODE_SIGN_STYLE = Automatic; | ||||
| 				CURRENT_PROJECT_VERSION = 1; | ||||
| 				GENERATE_INFOPLIST_FILE = YES; | ||||
| 				MARKETING_VERSION = 1.0; | ||||
| 				PRODUCT_BUNDLE_IDENTIFIER = com.example.baseProject.RunnerTests; | ||||
| 				PRODUCT_NAME = "$(TARGET_NAME)"; | ||||
| 				SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; | ||||
| 				SWIFT_OPTIMIZATION_LEVEL = "-Onone"; | ||||
| 				SWIFT_VERSION = 5.0; | ||||
| 				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; | ||||
| 			}; | ||||
| 			name = Debug; | ||||
| 		}; | ||||
| 		331C8089294A63A400263BE5 /* Release */ = { | ||||
| 			isa = XCBuildConfiguration; | ||||
| 			buildSettings = { | ||||
| 				BUNDLE_LOADER = "$(TEST_HOST)"; | ||||
| 				CODE_SIGN_STYLE = Automatic; | ||||
| 				CURRENT_PROJECT_VERSION = 1; | ||||
| 				GENERATE_INFOPLIST_FILE = YES; | ||||
| 				MARKETING_VERSION = 1.0; | ||||
| 				PRODUCT_BUNDLE_IDENTIFIER = com.example.baseProject.RunnerTests; | ||||
| 				PRODUCT_NAME = "$(TARGET_NAME)"; | ||||
| 				SWIFT_VERSION = 5.0; | ||||
| 				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; | ||||
| 			}; | ||||
| 			name = Release; | ||||
| 		}; | ||||
| 		331C808A294A63A400263BE5 /* Profile */ = { | ||||
| 			isa = XCBuildConfiguration; | ||||
| 			buildSettings = { | ||||
| 				BUNDLE_LOADER = "$(TEST_HOST)"; | ||||
| 				CODE_SIGN_STYLE = Automatic; | ||||
| 				CURRENT_PROJECT_VERSION = 1; | ||||
| 				GENERATE_INFOPLIST_FILE = YES; | ||||
| 				MARKETING_VERSION = 1.0; | ||||
| 				PRODUCT_BUNDLE_IDENTIFIER = com.example.baseProject.RunnerTests; | ||||
| 				PRODUCT_NAME = "$(TARGET_NAME)"; | ||||
| 				SWIFT_VERSION = 5.0; | ||||
| 				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; | ||||
| 			}; | ||||
| 			name = Profile; | ||||
| 		}; | ||||
| 		97C147031CF9000F007C117D /* Debug */ = { | ||||
| 			isa = XCBuildConfiguration; | ||||
| 			buildSettings = { | ||||
| 				ALWAYS_SEARCH_USER_PATHS = NO; | ||||
| 				ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; | ||||
| 				CLANG_ANALYZER_NONNULL = YES; | ||||
| 				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; | ||||
| 				CLANG_CXX_LIBRARY = "libc++"; | ||||
| 				CLANG_ENABLE_MODULES = YES; | ||||
| 				CLANG_ENABLE_OBJC_ARC = YES; | ||||
| 				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; | ||||
| 				CLANG_WARN_BOOL_CONVERSION = YES; | ||||
| 				CLANG_WARN_COMMA = YES; | ||||
| 				CLANG_WARN_CONSTANT_CONVERSION = YES; | ||||
| 				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; | ||||
| 				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; | ||||
| 				CLANG_WARN_EMPTY_BODY = YES; | ||||
| 				CLANG_WARN_ENUM_CONVERSION = YES; | ||||
| 				CLANG_WARN_INFINITE_RECURSION = YES; | ||||
| 				CLANG_WARN_INT_CONVERSION = YES; | ||||
| 				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; | ||||
| 				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; | ||||
| 				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; | ||||
| 				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; | ||||
| 				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; | ||||
| 				CLANG_WARN_STRICT_PROTOTYPES = YES; | ||||
| 				CLANG_WARN_SUSPICIOUS_MOVE = YES; | ||||
| 				CLANG_WARN_UNREACHABLE_CODE = YES; | ||||
| 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; | ||||
| 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; | ||||
| 				COPY_PHASE_STRIP = NO; | ||||
| 				DEBUG_INFORMATION_FORMAT = dwarf; | ||||
| 				ENABLE_STRICT_OBJC_MSGSEND = YES; | ||||
| 				ENABLE_TESTABILITY = YES; | ||||
| 				ENABLE_USER_SCRIPT_SANDBOXING = NO; | ||||
| 				GCC_C_LANGUAGE_STANDARD = gnu99; | ||||
| 				GCC_DYNAMIC_NO_PIC = NO; | ||||
| 				GCC_NO_COMMON_BLOCKS = YES; | ||||
| 				GCC_OPTIMIZATION_LEVEL = 0; | ||||
| 				GCC_PREPROCESSOR_DEFINITIONS = ( | ||||
| 					"DEBUG=1", | ||||
| 					"$(inherited)", | ||||
| 				); | ||||
| 				GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | ||||
| 				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | ||||
| 				GCC_WARN_UNDECLARED_SELECTOR = YES; | ||||
| 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | ||||
| 				GCC_WARN_UNUSED_FUNCTION = YES; | ||||
| 				GCC_WARN_UNUSED_VARIABLE = YES; | ||||
| 				IPHONEOS_DEPLOYMENT_TARGET = 12.0; | ||||
| 				MTL_ENABLE_DEBUG_INFO = YES; | ||||
| 				ONLY_ACTIVE_ARCH = YES; | ||||
| 				SDKROOT = iphoneos; | ||||
| 				TARGETED_DEVICE_FAMILY = "1,2"; | ||||
| 			}; | ||||
| 			name = Debug; | ||||
| 		}; | ||||
| 		97C147041CF9000F007C117D /* Release */ = { | ||||
| 			isa = XCBuildConfiguration; | ||||
| 			buildSettings = { | ||||
| 				ALWAYS_SEARCH_USER_PATHS = NO; | ||||
| 				ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; | ||||
| 				CLANG_ANALYZER_NONNULL = YES; | ||||
| 				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; | ||||
| 				CLANG_CXX_LIBRARY = "libc++"; | ||||
| 				CLANG_ENABLE_MODULES = YES; | ||||
| 				CLANG_ENABLE_OBJC_ARC = YES; | ||||
| 				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; | ||||
| 				CLANG_WARN_BOOL_CONVERSION = YES; | ||||
| 				CLANG_WARN_COMMA = YES; | ||||
| 				CLANG_WARN_CONSTANT_CONVERSION = YES; | ||||
| 				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; | ||||
| 				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; | ||||
| 				CLANG_WARN_EMPTY_BODY = YES; | ||||
| 				CLANG_WARN_ENUM_CONVERSION = YES; | ||||
| 				CLANG_WARN_INFINITE_RECURSION = YES; | ||||
| 				CLANG_WARN_INT_CONVERSION = YES; | ||||
| 				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; | ||||
| 				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; | ||||
| 				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; | ||||
| 				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; | ||||
| 				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; | ||||
| 				CLANG_WARN_STRICT_PROTOTYPES = YES; | ||||
| 				CLANG_WARN_SUSPICIOUS_MOVE = YES; | ||||
| 				CLANG_WARN_UNREACHABLE_CODE = YES; | ||||
| 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; | ||||
| 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; | ||||
| 				COPY_PHASE_STRIP = NO; | ||||
| 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; | ||||
| 				ENABLE_NS_ASSERTIONS = NO; | ||||
| 				ENABLE_STRICT_OBJC_MSGSEND = YES; | ||||
| 				ENABLE_USER_SCRIPT_SANDBOXING = NO; | ||||
| 				GCC_C_LANGUAGE_STANDARD = gnu99; | ||||
| 				GCC_NO_COMMON_BLOCKS = YES; | ||||
| 				GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | ||||
| 				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | ||||
| 				GCC_WARN_UNDECLARED_SELECTOR = YES; | ||||
| 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | ||||
| 				GCC_WARN_UNUSED_FUNCTION = YES; | ||||
| 				GCC_WARN_UNUSED_VARIABLE = YES; | ||||
| 				IPHONEOS_DEPLOYMENT_TARGET = 12.0; | ||||
| 				MTL_ENABLE_DEBUG_INFO = NO; | ||||
| 				SDKROOT = iphoneos; | ||||
| 				SUPPORTED_PLATFORMS = iphoneos; | ||||
| 				SWIFT_COMPILATION_MODE = wholemodule; | ||||
| 				SWIFT_OPTIMIZATION_LEVEL = "-O"; | ||||
| 				TARGETED_DEVICE_FAMILY = "1,2"; | ||||
| 				VALIDATE_PRODUCT = YES; | ||||
| 			}; | ||||
| 			name = Release; | ||||
| 		}; | ||||
| 		97C147061CF9000F007C117D /* Debug */ = { | ||||
| 			isa = XCBuildConfiguration; | ||||
| 			baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; | ||||
| 			buildSettings = { | ||||
| 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | ||||
| 				CLANG_ENABLE_MODULES = YES; | ||||
| 				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | ||||
| 				ENABLE_BITCODE = NO; | ||||
| 				INFOPLIST_FILE = Runner/Info.plist; | ||||
| 				LD_RUNPATH_SEARCH_PATHS = ( | ||||
| 					"$(inherited)", | ||||
| 					"@executable_path/Frameworks", | ||||
| 				); | ||||
| 				PRODUCT_BUNDLE_IDENTIFIER = com.example.baseProject; | ||||
| 				PRODUCT_NAME = "$(TARGET_NAME)"; | ||||
| 				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | ||||
| 				SWIFT_OPTIMIZATION_LEVEL = "-Onone"; | ||||
| 				SWIFT_VERSION = 5.0; | ||||
| 				VERSIONING_SYSTEM = "apple-generic"; | ||||
| 			}; | ||||
| 			name = Debug; | ||||
| 		}; | ||||
| 		97C147071CF9000F007C117D /* Release */ = { | ||||
| 			isa = XCBuildConfiguration; | ||||
| 			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; | ||||
| 			buildSettings = { | ||||
| 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | ||||
| 				CLANG_ENABLE_MODULES = YES; | ||||
| 				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; | ||||
| 				ENABLE_BITCODE = NO; | ||||
| 				INFOPLIST_FILE = Runner/Info.plist; | ||||
| 				LD_RUNPATH_SEARCH_PATHS = ( | ||||
| 					"$(inherited)", | ||||
| 					"@executable_path/Frameworks", | ||||
| 				); | ||||
| 				PRODUCT_BUNDLE_IDENTIFIER = com.example.baseProject; | ||||
| 				PRODUCT_NAME = "$(TARGET_NAME)"; | ||||
| 				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; | ||||
| 				SWIFT_VERSION = 5.0; | ||||
| 				VERSIONING_SYSTEM = "apple-generic"; | ||||
| 			}; | ||||
| 			name = Release; | ||||
| 		}; | ||||
| /* End XCBuildConfiguration section */ | ||||
| 
 | ||||
| /* Begin XCConfigurationList section */ | ||||
| 		331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { | ||||
| 			isa = XCConfigurationList; | ||||
| 			buildConfigurations = ( | ||||
| 				331C8088294A63A400263BE5 /* Debug */, | ||||
| 				331C8089294A63A400263BE5 /* Release */, | ||||
| 				331C808A294A63A400263BE5 /* Profile */, | ||||
| 			); | ||||
| 			defaultConfigurationIsVisible = 0; | ||||
| 			defaultConfigurationName = Release; | ||||
| 		}; | ||||
| 		97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { | ||||
| 			isa = XCConfigurationList; | ||||
| 			buildConfigurations = ( | ||||
| 				97C147031CF9000F007C117D /* Debug */, | ||||
| 				97C147041CF9000F007C117D /* Release */, | ||||
| 				249021D3217E4FDB00AE95B9 /* Profile */, | ||||
| 			); | ||||
| 			defaultConfigurationIsVisible = 0; | ||||
| 			defaultConfigurationName = Release; | ||||
| 		}; | ||||
| 		97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { | ||||
| 			isa = XCConfigurationList; | ||||
| 			buildConfigurations = ( | ||||
| 				97C147061CF9000F007C117D /* Debug */, | ||||
| 				97C147071CF9000F007C117D /* Release */, | ||||
| 				249021D4217E4FDB00AE95B9 /* Profile */, | ||||
| 			); | ||||
| 			defaultConfigurationIsVisible = 0; | ||||
| 			defaultConfigurationName = Release; | ||||
| 		}; | ||||
| /* End XCConfigurationList section */ | ||||
| 	}; | ||||
| 	rootObject = 97C146E61CF9000F007C117D /* Project object */; | ||||
| } | ||||
							
								
								
									
										7
									
								
								base_project/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,7 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Workspace | ||||
|    version = "1.0"> | ||||
|    <FileRef | ||||
|       location = "self:"> | ||||
|    </FileRef> | ||||
| </Workspace> | ||||
| @ -0,0 +1,8 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||
| <plist version="1.0"> | ||||
| <dict> | ||||
| 	<key>IDEDidComputeMac32BitWarning</key> | ||||
| 	<true/> | ||||
| </dict> | ||||
| </plist> | ||||
| @ -0,0 +1,8 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||
| <plist version="1.0"> | ||||
| <dict> | ||||
| 	<key>PreviewsEnabled</key> | ||||
| 	<false/> | ||||
| </dict> | ||||
| </plist> | ||||
| @ -0,0 +1,101 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Scheme | ||||
|    LastUpgradeVersion = "1510" | ||||
|    version = "1.3"> | ||||
|    <BuildAction | ||||
|       parallelizeBuildables = "YES" | ||||
|       buildImplicitDependencies = "YES"> | ||||
|       <BuildActionEntries> | ||||
|          <BuildActionEntry | ||||
|             buildForTesting = "YES" | ||||
|             buildForRunning = "YES" | ||||
|             buildForProfiling = "YES" | ||||
|             buildForArchiving = "YES" | ||||
|             buildForAnalyzing = "YES"> | ||||
|             <BuildableReference | ||||
|                BuildableIdentifier = "primary" | ||||
|                BlueprintIdentifier = "97C146ED1CF9000F007C117D" | ||||
|                BuildableName = "Runner.app" | ||||
|                BlueprintName = "Runner" | ||||
|                ReferencedContainer = "container:Runner.xcodeproj"> | ||||
|             </BuildableReference> | ||||
|          </BuildActionEntry> | ||||
|       </BuildActionEntries> | ||||
|    </BuildAction> | ||||
|    <TestAction | ||||
|       buildConfiguration = "Debug" | ||||
|       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||||
|       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||||
|       customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit" | ||||
|       shouldUseLaunchSchemeArgsEnv = "YES"> | ||||
|       <MacroExpansion> | ||||
|          <BuildableReference | ||||
|             BuildableIdentifier = "primary" | ||||
|             BlueprintIdentifier = "97C146ED1CF9000F007C117D" | ||||
|             BuildableName = "Runner.app" | ||||
|             BlueprintName = "Runner" | ||||
|             ReferencedContainer = "container:Runner.xcodeproj"> | ||||
|          </BuildableReference> | ||||
|       </MacroExpansion> | ||||
|       <Testables> | ||||
|          <TestableReference | ||||
|             skipped = "NO" | ||||
|             parallelizable = "YES"> | ||||
|             <BuildableReference | ||||
|                BuildableIdentifier = "primary" | ||||
|                BlueprintIdentifier = "331C8080294A63A400263BE5" | ||||
|                BuildableName = "RunnerTests.xctest" | ||||
|                BlueprintName = "RunnerTests" | ||||
|                ReferencedContainer = "container:Runner.xcodeproj"> | ||||
|             </BuildableReference> | ||||
|          </TestableReference> | ||||
|       </Testables> | ||||
|    </TestAction> | ||||
|    <LaunchAction | ||||
|       buildConfiguration = "Debug" | ||||
|       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||||
|       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||||
|       customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit" | ||||
|       launchStyle = "0" | ||||
|       useCustomWorkingDirectory = "NO" | ||||
|       ignoresPersistentStateOnLaunch = "NO" | ||||
|       debugDocumentVersioning = "YES" | ||||
|       debugServiceExtension = "internal" | ||||
|       enableGPUValidationMode = "1" | ||||
|       allowLocationSimulation = "YES"> | ||||
|       <BuildableProductRunnable | ||||
|          runnableDebuggingMode = "0"> | ||||
|          <BuildableReference | ||||
|             BuildableIdentifier = "primary" | ||||
|             BlueprintIdentifier = "97C146ED1CF9000F007C117D" | ||||
|             BuildableName = "Runner.app" | ||||
|             BlueprintName = "Runner" | ||||
|             ReferencedContainer = "container:Runner.xcodeproj"> | ||||
|          </BuildableReference> | ||||
|       </BuildableProductRunnable> | ||||
|    </LaunchAction> | ||||
|    <ProfileAction | ||||
|       buildConfiguration = "Profile" | ||||
|       shouldUseLaunchSchemeArgsEnv = "YES" | ||||
|       savedToolIdentifier = "" | ||||
|       useCustomWorkingDirectory = "NO" | ||||
|       debugDocumentVersioning = "YES"> | ||||
|       <BuildableProductRunnable | ||||
|          runnableDebuggingMode = "0"> | ||||
|          <BuildableReference | ||||
|             BuildableIdentifier = "primary" | ||||
|             BlueprintIdentifier = "97C146ED1CF9000F007C117D" | ||||
|             BuildableName = "Runner.app" | ||||
|             BlueprintName = "Runner" | ||||
|             ReferencedContainer = "container:Runner.xcodeproj"> | ||||
|          </BuildableReference> | ||||
|       </BuildableProductRunnable> | ||||
|    </ProfileAction> | ||||
|    <AnalyzeAction | ||||
|       buildConfiguration = "Debug"> | ||||
|    </AnalyzeAction> | ||||
|    <ArchiveAction | ||||
|       buildConfiguration = "Release" | ||||
|       revealArchiveInOrganizer = "YES"> | ||||
|    </ArchiveAction> | ||||
| </Scheme> | ||||
							
								
								
									
										7
									
								
								base_project/ios/Runner.xcworkspace/contents.xcworkspacedata
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,7 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Workspace | ||||
|    version = "1.0"> | ||||
|    <FileRef | ||||
|       location = "group:Runner.xcodeproj"> | ||||
|    </FileRef> | ||||
| </Workspace> | ||||
| @ -0,0 +1,8 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||
| <plist version="1.0"> | ||||
| <dict> | ||||
| 	<key>IDEDidComputeMac32BitWarning</key> | ||||
| 	<true/> | ||||
| </dict> | ||||
| </plist> | ||||
| @ -0,0 +1,8 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||
| <plist version="1.0"> | ||||
| <dict> | ||||
| 	<key>PreviewsEnabled</key> | ||||
| 	<false/> | ||||
| </dict> | ||||
| </plist> | ||||
							
								
								
									
										13
									
								
								base_project/ios/Runner/AppDelegate.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,13 @@ | ||||
| import Flutter | ||||
| import UIKit | ||||
| 
 | ||||
| @main | ||||
| @objc class AppDelegate: FlutterAppDelegate { | ||||
|   override func application( | ||||
|     _ application: UIApplication, | ||||
|     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? | ||||
|   ) -> Bool { | ||||
|     GeneratedPluginRegistrant.register(with: self) | ||||
|     return super.application(application, didFinishLaunchingWithOptions: launchOptions) | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,122 @@ | ||||
| { | ||||
|   "images" : [ | ||||
|     { | ||||
|       "size" : "20x20", | ||||
|       "idiom" : "iphone", | ||||
|       "filename" : "Icon-App-20x20@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "20x20", | ||||
|       "idiom" : "iphone", | ||||
|       "filename" : "Icon-App-20x20@3x.png", | ||||
|       "scale" : "3x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "29x29", | ||||
|       "idiom" : "iphone", | ||||
|       "filename" : "Icon-App-29x29@1x.png", | ||||
|       "scale" : "1x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "29x29", | ||||
|       "idiom" : "iphone", | ||||
|       "filename" : "Icon-App-29x29@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "29x29", | ||||
|       "idiom" : "iphone", | ||||
|       "filename" : "Icon-App-29x29@3x.png", | ||||
|       "scale" : "3x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "40x40", | ||||
|       "idiom" : "iphone", | ||||
|       "filename" : "Icon-App-40x40@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "40x40", | ||||
|       "idiom" : "iphone", | ||||
|       "filename" : "Icon-App-40x40@3x.png", | ||||
|       "scale" : "3x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "60x60", | ||||
|       "idiom" : "iphone", | ||||
|       "filename" : "Icon-App-60x60@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "60x60", | ||||
|       "idiom" : "iphone", | ||||
|       "filename" : "Icon-App-60x60@3x.png", | ||||
|       "scale" : "3x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "20x20", | ||||
|       "idiom" : "ipad", | ||||
|       "filename" : "Icon-App-20x20@1x.png", | ||||
|       "scale" : "1x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "20x20", | ||||
|       "idiom" : "ipad", | ||||
|       "filename" : "Icon-App-20x20@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "29x29", | ||||
|       "idiom" : "ipad", | ||||
|       "filename" : "Icon-App-29x29@1x.png", | ||||
|       "scale" : "1x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "29x29", | ||||
|       "idiom" : "ipad", | ||||
|       "filename" : "Icon-App-29x29@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "40x40", | ||||
|       "idiom" : "ipad", | ||||
|       "filename" : "Icon-App-40x40@1x.png", | ||||
|       "scale" : "1x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "40x40", | ||||
|       "idiom" : "ipad", | ||||
|       "filename" : "Icon-App-40x40@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "76x76", | ||||
|       "idiom" : "ipad", | ||||
|       "filename" : "Icon-App-76x76@1x.png", | ||||
|       "scale" : "1x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "76x76", | ||||
|       "idiom" : "ipad", | ||||
|       "filename" : "Icon-App-76x76@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "83.5x83.5", | ||||
|       "idiom" : "ipad", | ||||
|       "filename" : "Icon-App-83.5x83.5@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "size" : "1024x1024", | ||||
|       "idiom" : "ios-marketing", | ||||
|       "filename" : "Icon-App-1024x1024@1x.png", | ||||
|       "scale" : "1x" | ||||
|     } | ||||
|   ], | ||||
|   "info" : { | ||||
|     "version" : 1, | ||||
|     "author" : "xcode" | ||||
|   } | ||||
| } | ||||
| After Width: | Height: | Size: 11 KiB | 
| After Width: | Height: | Size: 295 B | 
| After Width: | Height: | Size: 406 B | 
| After Width: | Height: | Size: 450 B | 
| After Width: | Height: | Size: 282 B | 
| After Width: | Height: | Size: 462 B | 
| After Width: | Height: | Size: 704 B | 
| After Width: | Height: | Size: 406 B | 
| After Width: | Height: | Size: 586 B | 
| After Width: | Height: | Size: 862 B | 
| After Width: | Height: | Size: 862 B | 
| After Width: | Height: | Size: 1.6 KiB | 
| After Width: | Height: | Size: 762 B | 
| After Width: | Height: | Size: 1.2 KiB | 
| After Width: | Height: | Size: 1.4 KiB | 
							
								
								
									
										23
									
								
								base_project/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,23 @@ | ||||
| { | ||||
|   "images" : [ | ||||
|     { | ||||
|       "idiom" : "universal", | ||||
|       "filename" : "LaunchImage.png", | ||||
|       "scale" : "1x" | ||||
|     }, | ||||
|     { | ||||
|       "idiom" : "universal", | ||||
|       "filename" : "LaunchImage@2x.png", | ||||
|       "scale" : "2x" | ||||
|     }, | ||||
|     { | ||||
|       "idiom" : "universal", | ||||
|       "filename" : "LaunchImage@3x.png", | ||||
|       "scale" : "3x" | ||||
|     } | ||||
|   ], | ||||
|   "info" : { | ||||
|     "version" : 1, | ||||
|     "author" : "xcode" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										
											BIN
										
									
								
								base_project/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 68 B | 
							
								
								
									
										
											BIN
										
									
								
								base_project/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 68 B | 
							
								
								
									
										
											BIN
										
									
								
								base_project/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 68 B | 
							
								
								
									
										5
									
								
								base_project/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,5 @@ | ||||
| # Launch Screen Assets | ||||
| 
 | ||||
| You can customize the launch screen with your own desired assets by replacing the image files in this directory. | ||||
| 
 | ||||
| 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. | ||||
							
								
								
									
										37
									
								
								base_project/ios/Runner/Base.lproj/LaunchScreen.storyboard
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,37 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM"> | ||||
|     <dependencies> | ||||
|         <deployment identifier="iOS"/> | ||||
|         <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/> | ||||
|     </dependencies> | ||||
|     <scenes> | ||||
|         <!--View Controller--> | ||||
|         <scene sceneID="EHf-IW-A2E"> | ||||
|             <objects> | ||||
|                 <viewController id="01J-lp-oVM" sceneMemberID="viewController"> | ||||
|                     <layoutGuides> | ||||
|                         <viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/> | ||||
|                         <viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/> | ||||
|                     </layoutGuides> | ||||
|                     <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3"> | ||||
|                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | ||||
|                         <subviews> | ||||
|                             <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4"> | ||||
|                             </imageView> | ||||
|                         </subviews> | ||||
|                         <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> | ||||
|                         <constraints> | ||||
|                             <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/> | ||||
|                             <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/> | ||||
|                         </constraints> | ||||
|                     </view> | ||||
|                 </viewController> | ||||
|                 <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/> | ||||
|             </objects> | ||||
|             <point key="canvasLocation" x="53" y="375"/> | ||||
|         </scene> | ||||
|     </scenes> | ||||
|     <resources> | ||||
|         <image name="LaunchImage" width="168" height="185"/> | ||||
|     </resources> | ||||
| </document> | ||||
							
								
								
									
										26
									
								
								base_project/ios/Runner/Base.lproj/Main.storyboard
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,26 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r"> | ||||
|     <dependencies> | ||||
|         <deployment identifier="iOS"/> | ||||
|         <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/> | ||||
|     </dependencies> | ||||
|     <scenes> | ||||
|         <!--Flutter View Controller--> | ||||
|         <scene sceneID="tne-QT-ifu"> | ||||
|             <objects> | ||||
|                 <viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController"> | ||||
|                     <layoutGuides> | ||||
|                         <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/> | ||||
|                         <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/> | ||||
|                     </layoutGuides> | ||||
|                     <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC"> | ||||
|                         <rect key="frame" x="0.0" y="0.0" width="600" height="600"/> | ||||
|                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | ||||
|                         <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> | ||||
|                     </view> | ||||
|                 </viewController> | ||||
|                 <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/> | ||||
|             </objects> | ||||
|         </scene> | ||||
|     </scenes> | ||||
| </document> | ||||
							
								
								
									
										49
									
								
								base_project/ios/Runner/Info.plist
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,49 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||
| <plist version="1.0"> | ||||
| <dict> | ||||
| 	<key>CFBundleDevelopmentRegion</key> | ||||
| 	<string>$(DEVELOPMENT_LANGUAGE)</string> | ||||
| 	<key>CFBundleDisplayName</key> | ||||
| 	<string>Base Project</string> | ||||
| 	<key>CFBundleExecutable</key> | ||||
| 	<string>$(EXECUTABLE_NAME)</string> | ||||
| 	<key>CFBundleIdentifier</key> | ||||
| 	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> | ||||
| 	<key>CFBundleInfoDictionaryVersion</key> | ||||
| 	<string>6.0</string> | ||||
| 	<key>CFBundleName</key> | ||||
| 	<string>base_project</string> | ||||
| 	<key>CFBundlePackageType</key> | ||||
| 	<string>APPL</string> | ||||
| 	<key>CFBundleShortVersionString</key> | ||||
| 	<string>$(FLUTTER_BUILD_NAME)</string> | ||||
| 	<key>CFBundleSignature</key> | ||||
| 	<string>????</string> | ||||
| 	<key>CFBundleVersion</key> | ||||
| 	<string>$(FLUTTER_BUILD_NUMBER)</string> | ||||
| 	<key>LSRequiresIPhoneOS</key> | ||||
| 	<true/> | ||||
| 	<key>UILaunchStoryboardName</key> | ||||
| 	<string>LaunchScreen</string> | ||||
| 	<key>UIMainStoryboardFile</key> | ||||
| 	<string>Main</string> | ||||
| 	<key>UISupportedInterfaceOrientations</key> | ||||
| 	<array> | ||||
| 		<string>UIInterfaceOrientationPortrait</string> | ||||
| 		<string>UIInterfaceOrientationLandscapeLeft</string> | ||||
| 		<string>UIInterfaceOrientationLandscapeRight</string> | ||||
| 	</array> | ||||
| 	<key>UISupportedInterfaceOrientations~ipad</key> | ||||
| 	<array> | ||||
| 		<string>UIInterfaceOrientationPortrait</string> | ||||
| 		<string>UIInterfaceOrientationPortraitUpsideDown</string> | ||||
| 		<string>UIInterfaceOrientationLandscapeLeft</string> | ||||
| 		<string>UIInterfaceOrientationLandscapeRight</string> | ||||
| 	</array> | ||||
| 	<key>CADisableMinimumFrameDurationOnPhone</key> | ||||
| 	<true/> | ||||
| 	<key>UIApplicationSupportsIndirectInputEvents</key> | ||||
| 	<true/> | ||||
| </dict> | ||||
| </plist> | ||||
							
								
								
									
										1
									
								
								base_project/ios/Runner/Runner-Bridging-Header.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1 @@ | ||||
| #import "GeneratedPluginRegistrant.h" | ||||
							
								
								
									
										12
									
								
								base_project/ios/RunnerTests/RunnerTests.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,12 @@ | ||||
| import Flutter | ||||
| import UIKit | ||||
| import XCTest | ||||
| 
 | ||||
| class RunnerTests: XCTestCase { | ||||
| 
 | ||||
|   func testExample() { | ||||
|     // If you add code to the Runner application, consider adding tests here. | ||||
|     // See https://developer.apple.com/documentation/xctest for more information about using XCTest. | ||||
|   } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										45
									
								
								base_project/lib/Reuseable/reusable_date_picker_field.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,45 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:intl/intl.dart'; | ||||
| 
 | ||||
| class ReusableDatePickerField extends StatelessWidget { | ||||
|   final String label; | ||||
|   final String? initialDate; | ||||
|   final TextEditingController controller; | ||||
|   final Function(String?)? onSaved; | ||||
| 
 | ||||
|   const ReusableDatePickerField({ | ||||
|     super.key, | ||||
|     required this.label, | ||||
|     required this.controller, | ||||
|     this.initialDate, | ||||
|     required this.onSaved, | ||||
|   }); | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return TextFormField( | ||||
|       initialValue: initialDate, | ||||
|       controller: controller, | ||||
|       decoration: InputDecoration( | ||||
|         labelText: label, | ||||
|         border: const OutlineInputBorder(), | ||||
|         contentPadding: | ||||
|             const EdgeInsets.symmetric(vertical: 16.0, horizontal: 12.0), | ||||
|         suffixIcon: const Icon(Icons.calendar_today), | ||||
|       ), | ||||
|       readOnly: true, | ||||
|       onTap: () async { | ||||
|         DateTime? selectedDate = await showDatePicker( | ||||
|           context: context, | ||||
|           initialDate: DateTime.now(), | ||||
|           firstDate: DateTime(2000), | ||||
|           lastDate: DateTime(2101), | ||||
|         ); | ||||
|         controller.text = selectedDate != null | ||||
|             ? DateFormat('yyyy-MM-dd').format(selectedDate!) | ||||
|             : ''; | ||||
|       }, | ||||
|       onSaved: onSaved, | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,74 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:intl/intl.dart'; | ||||
| 
 | ||||
| class ReusableDateTimePickerField extends StatelessWidget { | ||||
|   final String label; | ||||
|   final String? initialDateTime; | ||||
|   final TextEditingController controller; | ||||
|   final Function(String?)? onSaved; | ||||
| 
 | ||||
|   const ReusableDateTimePickerField({super.key,  | ||||
|     required this.label, | ||||
|     required this.controller, | ||||
|     this.initialDateTime, | ||||
|     required this.onSaved, | ||||
|   }); | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return Padding( | ||||
|       padding: const EdgeInsets.symmetric(vertical: 8.0), | ||||
|       child: TextFormField( | ||||
|         initialValue: initialDateTime, | ||||
|         controller: controller, | ||||
|         decoration: InputDecoration( | ||||
|           labelText: label, | ||||
|           border: const OutlineInputBorder(), | ||||
|           contentPadding: | ||||
|               const EdgeInsets.symmetric(vertical: 16.0, horizontal: 12.0), | ||||
|           suffixIcon: const Icon(Icons.event), | ||||
|         ), | ||||
|         readOnly: true, | ||||
|         onTap: () async { | ||||
|           DateTime? selectedDateTime = await showDateTimePicker( | ||||
|             context: context, | ||||
|             initialDateTime: DateTime.now(), | ||||
|           ); | ||||
|           if (selectedDateTime != null) { | ||||
|             controller.text = | ||||
|                 DateFormat('yyyy-MM-dd HH:mm').format(selectedDateTime); | ||||
|           } | ||||
|         }, | ||||
|         onSaved: onSaved, | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   Future<DateTime?> showDateTimePicker({ | ||||
|     required BuildContext context, | ||||
|     required DateTime initialDateTime, | ||||
|   }) async { | ||||
|     // Custom date-time picker implementation or package usage | ||||
|     // This is a placeholder for demonstration purposes. | ||||
|     return await showDatePicker( | ||||
|       context: context, | ||||
|       initialDate: initialDateTime, | ||||
|       firstDate: DateTime(2000), | ||||
|       lastDate: DateTime(2101), | ||||
|     ).then((date) { | ||||
|       if (date != null) { | ||||
|         return showTimePicker( | ||||
|           context: context, | ||||
|           initialTime: TimeOfDay.fromDateTime(initialDateTime), | ||||
|         ).then((time) { | ||||
|           if (time != null) { | ||||
|             return DateTime( | ||||
|                 date.year, date.month, date.day, time.hour, time.minute); | ||||
|           } | ||||
|           return date; | ||||
|         }); | ||||
|       } | ||||
|       return null; | ||||
|     }); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										74
									
								
								base_project/lib/Reuseable/reusable_dropdown_field.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,74 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| 
 | ||||
| class ReusableDropdownField extends StatelessWidget { | ||||
|   final String label; | ||||
|   final List<Map<String, dynamic>> options; | ||||
|   final String? value; | ||||
|   final String valueField; // ID key (dynamic) | ||||
|   final String uiField; // Name key (dynamic) | ||||
|   final void Function(String?)? onChanged; | ||||
|   final void Function(String?)? onSaved; | ||||
| 
 | ||||
|   const ReusableDropdownField({ | ||||
|     super.key, | ||||
|     required this.label, | ||||
|     required this.options, | ||||
|     required this.valueField, // Dynamic ID field | ||||
|     required this.uiField, // Dynamic Name field | ||||
|     this.value, | ||||
|     this.onChanged, | ||||
|     this.onSaved, | ||||
|   }); | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return Padding( | ||||
|       padding: const EdgeInsets.symmetric(vertical: 8.0), | ||||
|       child: DropdownButtonFormField<String>( | ||||
|         decoration: InputDecoration( | ||||
|           labelText: label, | ||||
|           labelStyle: const TextStyle(color: Colors.deepPurple), | ||||
|           contentPadding: | ||||
|               const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0), | ||||
|           border: OutlineInputBorder( | ||||
|             borderRadius: BorderRadius.circular(8.0), | ||||
|             borderSide: const BorderSide(color: Colors.deepPurple, width: 2), | ||||
|           ), | ||||
|           enabledBorder: OutlineInputBorder( | ||||
|             borderRadius: BorderRadius.circular(8.0), | ||||
|             borderSide: const BorderSide(color: Colors.deepPurple, width: 2), | ||||
|           ), | ||||
|           focusedBorder: OutlineInputBorder( | ||||
|             borderRadius: BorderRadius.circular(8.0), | ||||
|             borderSide: | ||||
|                 const BorderSide(color: Colors.deepPurpleAccent, width: 2), | ||||
|           ), | ||||
|         ), | ||||
|         value: (value != null && value!.isNotEmpty) ? value : null, | ||||
|         items: [ | ||||
|           const DropdownMenuItem<String>( | ||||
|             value: '', | ||||
|             child: Text('Select an option'), | ||||
|           ), | ||||
|           ...options.map<DropdownMenuItem<String>>( | ||||
|             (item) => DropdownMenuItem<String>( | ||||
|               value: item[valueField].toString(), | ||||
|               child: Text( | ||||
|                 item[uiField].toString(), | ||||
|                 style: const TextStyle(fontSize: 16), | ||||
|               ), | ||||
|             ), | ||||
|           ), | ||||
|         ], | ||||
|         onChanged: onChanged, | ||||
|         onSaved: onSaved, | ||||
|         validator: (value) { | ||||
|           if (value == null || value.isEmpty) { | ||||
|             return 'Please select a $label'; | ||||
|           } | ||||
|           return null; | ||||
|         }, | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										77
									
								
								base_project/lib/Reuseable/reusable_text_field.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,77 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:flutter/services.dart'; | ||||
| 
 | ||||
| class ReusableTextField extends StatelessWidget { | ||||
|   final String label; | ||||
|   final TextEditingController? controller; | ||||
|   final TextInputType keyboardType; | ||||
|   final bool obscureText; | ||||
|   final int maxLines; | ||||
|   final List<TextInputFormatter>? inputFormatters; | ||||
|   final FormFieldValidator<String>? validator; | ||||
|   final Function(DateTime?)? onDateTimeSelected; // Callback for DateTime picker | ||||
|   final Function(String?)? onSaved; | ||||
|   final Function(String?)? onChanged; | ||||
| 
 | ||||
|   final String? initialValue; | ||||
| 
 | ||||
|   const ReusableTextField({ | ||||
|     super.key, | ||||
|     required this.label, | ||||
|     this.controller, | ||||
|     this.keyboardType = TextInputType.text, | ||||
|     this.obscureText = false, | ||||
|     this.maxLines = 1, | ||||
|     this.inputFormatters, | ||||
|     this.validator, | ||||
|     this.onDateTimeSelected, | ||||
|     this.onSaved, | ||||
|     this.onChanged, | ||||
|     this.initialValue, // Added callback for DateTime picker | ||||
|   }); | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return Padding( | ||||
|       padding: const EdgeInsets.symmetric(vertical: 8.0), | ||||
|       child: TextFormField( | ||||
|         initialValue: initialValue, | ||||
|         onSaved: onSaved, | ||||
|         onChanged: onChanged, | ||||
|         controller: controller, | ||||
|         keyboardType: keyboardType, | ||||
|         obscureText: obscureText, | ||||
|         maxLines: maxLines, | ||||
|         inputFormatters: inputFormatters, | ||||
|         validator: validator, | ||||
|         onTap: () async { | ||||
|           if (keyboardType == TextInputType.datetime && | ||||
|               onDateTimeSelected != null) { | ||||
|             DateTime? dateTime = await showDatePicker( | ||||
|               context: context, | ||||
|               initialDate: DateTime.now(), | ||||
|               firstDate: DateTime(2000), | ||||
|               lastDate: DateTime(2100), | ||||
|             ); | ||||
| // Agar user cancel kare, to current date set ho jaye | ||||
|             dateTime ??= DateTime.now(); | ||||
| 
 | ||||
|             TimeOfDay? timeOfDay = await showTimePicker( | ||||
|               context: context, | ||||
|               initialTime: TimeOfDay.now(), | ||||
|             ); | ||||
|             if (timeOfDay != null) { | ||||
|               dateTime = DateTime(dateTime.year, dateTime.month, dateTime.day, | ||||
|                   timeOfDay.hour, timeOfDay.minute); | ||||
|               onDateTimeSelected!(dateTime); | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         decoration: InputDecoration( | ||||
|           labelText: label, | ||||
|           border: const OutlineInputBorder(), | ||||
|         ), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										69
									
								
								base_project/lib/commans/widgets/custom_textform_field.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,69 @@ | ||||
| import 'package:base_project/resources/app_colors.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:flutter/services.dart'; | ||||
| 
 | ||||
| class MyCustomTextFormField extends StatelessWidget { | ||||
|   final String label; | ||||
|   final Widget? prefixIcon; | ||||
|   final Widget? suffixIcon; | ||||
|   final String? initialValue; | ||||
|   final bool? obscureText; | ||||
|   final TextEditingController controller; | ||||
|   final String? Function(String?)? validator; | ||||
|   final void Function(String)? onChanged; | ||||
|   final TextInputType? keyboardType; | ||||
|   final List<TextInputFormatter>? inputFormatters; | ||||
|   final int? maxLines; | ||||
|   final void Function()? onSuffixIconPressed; | ||||
|    | ||||
| 
 | ||||
|   const MyCustomTextFormField({ | ||||
|     super.key, | ||||
|     required this.label, | ||||
|     this.prefixIcon, | ||||
|     this.suffixIcon, | ||||
|      | ||||
|     this.initialValue, | ||||
|     required this.controller, | ||||
|     this.validator, | ||||
|     this.onChanged, | ||||
|     this.keyboardType, | ||||
|     this.inputFormatters, | ||||
|     this.maxLines = 1, this.obscureText, this.onSuffixIconPressed, | ||||
|   }); | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return TextFormField( | ||||
|       controller: controller, | ||||
|       initialValue: initialValue, | ||||
|       validator: validator, | ||||
|       onChanged: onChanged, | ||||
|       cursorColor: AppColors.primary, | ||||
|       keyboardType: keyboardType, | ||||
|       inputFormatters: inputFormatters, | ||||
|       maxLines: maxLines, | ||||
|       obscureText: obscureText ?? false, | ||||
|       decoration: InputDecoration( | ||||
|         labelText: label, | ||||
|         labelStyle: const TextStyle(color: AppColors.primary), | ||||
|         prefixIcon: prefixIcon, | ||||
|         suffixIcon: suffixIcon, | ||||
|         filled: true, | ||||
|         fillColor: Colors.white, | ||||
|         border: InputBorder.none, // No border | ||||
|         contentPadding: | ||||
|             const EdgeInsets.symmetric(vertical: 15.0, horizontal: 12.0), | ||||
|         // For rounded corners | ||||
|         enabledBorder: OutlineInputBorder( | ||||
|           borderRadius: BorderRadius.circular(8.0), | ||||
|           borderSide: BorderSide.none, | ||||
|         ), | ||||
|         focusedBorder: OutlineInputBorder( | ||||
|           borderRadius: BorderRadius.circular(8.0), | ||||
|           borderSide: BorderSide.none, | ||||
|         ), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										25
									
								
								base_project/lib/commans/widgets/custome_drawe_item.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,25 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| 
 | ||||
| class DrawerItem extends StatelessWidget { | ||||
|   final IconData icon; | ||||
|   final String title; | ||||
|   final VoidCallback onTap; | ||||
|   final Color color; | ||||
| 
 | ||||
|   const DrawerItem({ | ||||
|     super.key, | ||||
|     required this.icon, | ||||
|     required this.title, | ||||
|     required this.onTap, | ||||
|     this.color = Colors.blue, // Default color if none is provided | ||||
|   }); | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return ListTile( | ||||
|       leading: Icon(icon, color: color), | ||||
|       title: Text(title), | ||||
|       onTap: onTap, | ||||
|     ); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										327
									
								
								base_project/lib/commans/widgets/custome_drawer.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,327 @@ | ||||
| import '../../Entity/angulardata/Test_visa/Test_visaView/Test_visa_entity_list_screen.dart'; | ||||
| import '../../Entity/angulardata/Test_visa/Test_visa_viewModel/Test_visa_view_model_screen.dart'; | ||||
| 
 | ||||
| import '../../Entity/angulardata/Basicp/BasicpView/Basicp_entity_list_screen.dart'; | ||||
| import '../../Entity/angulardata/Basicp/Basicp_viewModel/Basicp_view_model_screen.dart'; | ||||
| 
 | ||||
| import '../../Entity/angulardatatype/Ad8/Ad8View/Ad8_entity_list_screen.dart'; | ||||
| import '../../Entity/angulardatatype/Ad8/Ad8_viewModel/Ad8_view_model_screen.dart'; | ||||
| 
 | ||||
| import '../../Entity/angulardatatype/Ad7/Ad7View/Ad7_entity_list_screen.dart'; | ||||
| import '../../Entity/angulardatatype/Ad7/Ad7_viewModel/Ad7_view_model_screen.dart'; | ||||
| 
 | ||||
| import '../../Entity/angulardatatype/Adv5/Adv5View/Adv5_entity_list_screen.dart'; | ||||
| import '../../Entity/angulardatatype/Adv5/Adv5_viewModel/Adv5_view_model_screen.dart'; | ||||
| 
 | ||||
| import '../../Entity/angulardatatype/Adv4/Adv4View/Adv4_entity_list_screen.dart'; | ||||
| import '../../Entity/angulardatatype/Adv4/Adv4_viewModel/Adv4_view_model_screen.dart'; | ||||
| 
 | ||||
| import '../../Entity/angulardatatype/Adv3/Adv3View/Adv3_entity_list_screen.dart'; | ||||
| import '../../Entity/angulardatatype/Adv3/Adv3_viewModel/Adv3_view_model_screen.dart'; | ||||
| 
 | ||||
| import '../../Entity/angulardatatype/Dv2/Dv2View/Dv2_entity_list_screen.dart'; | ||||
| import '../../Entity/angulardatatype/Dv2/Dv2_viewModel/Dv2_view_model_screen.dart'; | ||||
| 
 | ||||
| import '../../Entity/angulardatatype/Adv1/Adv1View/Adv1_entity_list_screen.dart'; | ||||
| import '../../Entity/angulardatatype/Adv1/Adv1_viewModel/Adv1_view_model_screen.dart'; | ||||
| 
 | ||||
| import '../../Entity/angulardatatype/Basicp3/Basicp3View/Basicp3_entity_list_screen.dart'; | ||||
| import '../../Entity/angulardatatype/Basicp3/Basicp3_viewModel/Basicp3_view_model_screen.dart'; | ||||
| 
 | ||||
| import '../../Entity/angulardatatype/Basicp2/Basicp2View/Basicp2_entity_list_screen.dart'; | ||||
| import '../../Entity/angulardatatype/Basicp2/Basicp2_viewModel/Basicp2_view_model_screen.dart'; | ||||
| 
 | ||||
| import '../../Entity/angulardatatype/Basicp1/Basicp1View/Basicp1_entity_list_screen.dart'; | ||||
| import '../../Entity/angulardatatype/Basicp1/Basicp1_viewModel/Basicp1_view_model_screen.dart'; | ||||
| 
 | ||||
| import 'package:base_project/utils/image_constant.dart'; | ||||
| import 'package:base_project/commans/widgets/custome_drawe_item.dart'; | ||||
| import 'package:base_project/resources/app_colors.dart'; | ||||
| import 'package:base_project/routes/route_names.dart'; | ||||
| import 'package:base_project/utils/managers/user_manager.dart'; | ||||
| import 'package:base_project/view_model/profile/profile_view_model.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:flutter_svg/svg.dart'; | ||||
| import 'package:provider/provider.dart'; | ||||
| 
 | ||||
| class MyCustomDrawer extends StatelessWidget { | ||||
|   const MyCustomDrawer({super.key}); | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     final email = UserManager().email; | ||||
|     final userName = UserManager().userName; | ||||
|     final provider = Provider.of<ProfileViewModel>(context, listen: false); | ||||
|     return Drawer( | ||||
|       child: ListView( | ||||
|         padding: EdgeInsets.zero, | ||||
|         children: <Widget>[ | ||||
|           UserAccountsDrawerHeader( | ||||
|             decoration: const BoxDecoration( | ||||
|               color: AppColors.primary, | ||||
|             ), | ||||
|             currentAccountPicture: CircleAvatar( | ||||
|               radius: 60, | ||||
|               backgroundColor: AppColors.primary.withOpacity(0.3), | ||||
|               backgroundImage: provider.profileImageBytes != null | ||||
|                   ? MemoryImage(provider.profileImageBytes!) | ||||
|                   : null, | ||||
|               child: provider.profileImageBytes != null | ||||
|                   ? null // Use backgroundImage for the actual image, so child should be null | ||||
|                   : SvgPicture.asset( | ||||
|                       ImageConstant.userProfileImg, // Placeholder SVG asset | ||||
| 
 | ||||
| // AppImages.userProfileImg, // Placeholder SVG asset | ||||
|                       width: 60, // Adjust to fit the CircleAvatar | ||||
|                       height: 60, | ||||
|                     ), | ||||
|             ), | ||||
|             accountName: Text("Hello, $userName"), | ||||
|             accountEmail: Text(email.toString()), | ||||
|           ), | ||||
|           DrawerItem( | ||||
|             color: AppColors.primary, | ||||
|             icon: Icons.person, | ||||
|             title: 'Profile', | ||||
|             onTap: () { | ||||
|               Navigator.pushNamed(context, RouteNames.profileView); | ||||
|             }, | ||||
|           ), | ||||
|           DrawerItem( | ||||
|             color: AppColors.primary, | ||||
|             icon: Icons.system_security_update, | ||||
|             title: 'System Parameters', | ||||
|             onTap: () { | ||||
| // Add navigation or other logic here | ||||
|               Navigator.pushNamed(context, RouteNames.systemParamsView); | ||||
|             }, | ||||
|           ), | ||||
|           DrawerItem( | ||||
|             color: AppColors.primary, | ||||
|             icon: Icons.password, | ||||
|             title: 'change password', | ||||
|             onTap: () { | ||||
|               Navigator.pushNamed(context, RouteNames.changePasswordView); | ||||
|             }, | ||||
|           ), | ||||
| 
 | ||||
| // NEW MENU | ||||
| 
 | ||||
|           DrawerItem( | ||||
|             color: AppColors.primary, | ||||
|             icon: Icons.chat_bubble, | ||||
|             title: 'Test_visa', | ||||
|             onTap: () { | ||||
|               Navigator.push( | ||||
|                 context, | ||||
|                 MaterialPageRoute( | ||||
|                   builder: (context) => ChangeNotifierProvider( | ||||
|                     create: (context) => Test_visaViewModelScreen(), | ||||
|                     child: test_visa_entity_list_screen(), | ||||
|                   ), | ||||
|                 ), | ||||
|               ); | ||||
|             }, | ||||
|           ), | ||||
| 
 | ||||
|           DrawerItem( | ||||
|             color: AppColors.primary, | ||||
|             icon: Icons.chat_bubble, | ||||
|             title: 'Basicp', | ||||
|             onTap: () { | ||||
|               Navigator.push( | ||||
|                 context, | ||||
|                 MaterialPageRoute( | ||||
|                   builder: (context) => ChangeNotifierProvider( | ||||
|                     create: (context) => BasicpViewModelScreen(), | ||||
|                     child: basicp_entity_list_screen(), | ||||
|                   ), | ||||
|                 ), | ||||
|               ); | ||||
|             }, | ||||
|           ), | ||||
| 
 | ||||
|           DrawerItem( | ||||
|             color: AppColors.primary, | ||||
|             icon: Icons.chat_bubble, | ||||
|             title: 'Ad8', | ||||
|             onTap: () { | ||||
|               Navigator.push( | ||||
|                 context, | ||||
|                 MaterialPageRoute( | ||||
|                   builder: (context) => ChangeNotifierProvider( | ||||
|                     create: (context) => Ad8ViewModelScreen(), | ||||
|                     child: ad8_entity_list_screen(), | ||||
|                   ), | ||||
|                 ), | ||||
|               ); | ||||
|             }, | ||||
|           ), | ||||
| 
 | ||||
|           DrawerItem( | ||||
|             color: AppColors.primary, | ||||
|             icon: Icons.chat_bubble, | ||||
|             title: 'Ad7', | ||||
|             onTap: () { | ||||
|               Navigator.push( | ||||
|                 context, | ||||
|                 MaterialPageRoute( | ||||
|                   builder: (context) => ChangeNotifierProvider( | ||||
|                     create: (context) => Ad7ViewModelScreen(), | ||||
|                     child: ad7_entity_list_screen(), | ||||
|                   ), | ||||
|                 ), | ||||
|               ); | ||||
|             }, | ||||
|           ), | ||||
| 
 | ||||
|           DrawerItem( | ||||
|             color: AppColors.primary, | ||||
|             icon: Icons.chat_bubble, | ||||
|             title: 'Adv5', | ||||
|             onTap: () { | ||||
|               Navigator.push( | ||||
|                 context, | ||||
|                 MaterialPageRoute( | ||||
|                   builder: (context) => ChangeNotifierProvider( | ||||
|                     create: (context) => Adv5ViewModelScreen(), | ||||
|                     child: adv5_entity_list_screen(), | ||||
|                   ), | ||||
|                 ), | ||||
|               ); | ||||
|             }, | ||||
|           ), | ||||
| 
 | ||||
|           DrawerItem( | ||||
|             color: AppColors.primary, | ||||
|             icon: Icons.chat_bubble, | ||||
|             title: 'Adv4', | ||||
|             onTap: () { | ||||
|               Navigator.push( | ||||
|                 context, | ||||
|                 MaterialPageRoute( | ||||
|                   builder: (context) => ChangeNotifierProvider( | ||||
|                     create: (context) => Adv4ViewModelScreen(), | ||||
|                     child: adv4_entity_list_screen(), | ||||
|                   ), | ||||
|                 ), | ||||
|               ); | ||||
|             }, | ||||
|           ), | ||||
| 
 | ||||
|           DrawerItem( | ||||
|             color: AppColors.primary, | ||||
|             icon: Icons.chat_bubble, | ||||
|             title: 'Adv3', | ||||
|             onTap: () { | ||||
|               Navigator.push( | ||||
|                 context, | ||||
|                 MaterialPageRoute( | ||||
|                   builder: (context) => ChangeNotifierProvider( | ||||
|                     create: (context) => Adv3ViewModelScreen(), | ||||
|                     child: adv3_entity_list_screen(), | ||||
|                   ), | ||||
|                 ), | ||||
|               ); | ||||
|             }, | ||||
|           ), | ||||
| 
 | ||||
|           DrawerItem( | ||||
|             color: AppColors.primary, | ||||
|             icon: Icons.chat_bubble, | ||||
|             title: 'Dv2', | ||||
|             onTap: () { | ||||
|               Navigator.push( | ||||
|                 context, | ||||
|                 MaterialPageRoute( | ||||
|                   builder: (context) => ChangeNotifierProvider( | ||||
|                     create: (context) => Dv2ViewModelScreen(), | ||||
|                     child: dv2_entity_list_screen(), | ||||
|                   ), | ||||
|                 ), | ||||
|               ); | ||||
|             }, | ||||
|           ), | ||||
| 
 | ||||
|           DrawerItem( | ||||
|             color: AppColors.primary, | ||||
|             icon: Icons.chat_bubble, | ||||
|             title: 'Adv1', | ||||
|             onTap: () { | ||||
|               Navigator.push( | ||||
|                 context, | ||||
|                 MaterialPageRoute( | ||||
|                   builder: (context) => ChangeNotifierProvider( | ||||
|                     create: (context) => Adv1ViewModelScreen(), | ||||
|                     child: adv1_entity_list_screen(), | ||||
|                   ), | ||||
|                 ), | ||||
|               ); | ||||
|             }, | ||||
|           ), | ||||
| 
 | ||||
|           DrawerItem( | ||||
|             color: AppColors.primary, | ||||
|             icon: Icons.chat_bubble, | ||||
|             title: 'Basicp3', | ||||
|             onTap: () { | ||||
|               Navigator.push( | ||||
|                 context, | ||||
|                 MaterialPageRoute( | ||||
|                   builder: (context) => ChangeNotifierProvider( | ||||
|                     create: (context) => Basicp3ViewModelScreen(), | ||||
|                     child: basicp3_entity_list_screen(), | ||||
|                   ), | ||||
|                 ), | ||||
|               ); | ||||
|             }, | ||||
|           ), | ||||
| 
 | ||||
|           DrawerItem( | ||||
|             color: AppColors.primary, | ||||
|             icon: Icons.chat_bubble, | ||||
|             title: 'Basicp2', | ||||
|             onTap: () { | ||||
|               Navigator.push( | ||||
|                 context, | ||||
|                 MaterialPageRoute( | ||||
|                   builder: (context) => ChangeNotifierProvider( | ||||
|                     create: (context) => Basicp2ViewModelScreen(), | ||||
|                     child: basicp2_entity_list_screen(), | ||||
|                   ), | ||||
|                 ), | ||||
|               ); | ||||
|             }, | ||||
|           ), | ||||
| 
 | ||||
|           DrawerItem( | ||||
|             color: AppColors.primary, | ||||
|             icon: Icons.chat_bubble, | ||||
|             title: 'Basicp1', | ||||
|             onTap: () { | ||||
|               Navigator.push( | ||||
|                 context, | ||||
|                 MaterialPageRoute( | ||||
|                   builder: (context) => ChangeNotifierProvider( | ||||
|                     create: (context) => Basicp1ViewModelScreen(), | ||||
|                     child: basicp_entity_list_screen(), | ||||
|                   ), | ||||
|                 ), | ||||
|               ); | ||||
|             }, | ||||
|           ), | ||||
| 
 | ||||
|           DrawerItem( | ||||
|             icon: Icons.logout, | ||||
|             color: Colors.red, | ||||
|             title: 'Logout', | ||||
|             onTap: () async { | ||||
|               await UserManager().clearUser(); | ||||
|               Navigator.pushReplacementNamed(context, RouteNames.splashView); | ||||
|             }, | ||||
|           ), | ||||
|         ], | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,38 @@ | ||||
| import 'package:base_project/resources/app_colors.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
| 
 | ||||
| class MyCustomElevatedButton extends StatelessWidget { | ||||
|   final Color? backgroundColor; | ||||
|   final Widget child; | ||||
|   final bool isLoading; | ||||
|   final VoidCallback onPressed; | ||||
| 
 | ||||
|   const MyCustomElevatedButton({ | ||||
|     super.key, | ||||
|      this.backgroundColor = AppColors.primary, | ||||
|     required this.child, | ||||
|     required this.onPressed, | ||||
|     this.isLoading = false, | ||||
|   }); | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return ElevatedButton( | ||||
|       onPressed: isLoading ? null : onPressed, | ||||
|       style: ElevatedButton.styleFrom( | ||||
|         backgroundColor: backgroundColor, | ||||
|         minimumSize: const Size(double.infinity, 50), // Full width, height of 50 | ||||
|         shape: RoundedRectangleBorder( | ||||
|           borderRadius: BorderRadius.circular(8), // Rounded corners | ||||
|         ), | ||||
|       ), | ||||
|       child: isLoading | ||||
|           ? const Center( | ||||
|               child: CircularProgressIndicator( | ||||
|                 strokeWidth: 2.0, // Adjust thickness if needed | ||||
|               ), | ||||
|             ) | ||||
|           : child, | ||||
|     ); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										6
									
								
								base_project/lib/core/app_export.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,6 @@ | ||||
| export '/core/utils/size_utils.dart'; | ||||
| export '/routes/app_routes.dart'; | ||||
| export '/theme/app_decoration.dart'; | ||||
| export '/theme/custom_text_style.dart'; | ||||
| export '/theme/theme_helper.dart'; | ||||
| export '/widgets/custom_image_view.dart'; | ||||
							
								
								
									
										229
									
								
								base_project/lib/core/constants/ui_constants.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,229 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| 
 | ||||
| class UIConstants { | ||||
|   // Spacing | ||||
|   static const double spacing4 = 4.0; | ||||
|   static const double spacing6 = 6.0; | ||||
| 
 | ||||
|   static const double spacing8 = 8.0; | ||||
|   static const double spacing12 = 12.0; | ||||
|   static const double spacing14 = 14.0; | ||||
| 
 | ||||
|   static const double spacing16 = 16.0; | ||||
|   static const double spacing18 = 18.0; | ||||
| 
 | ||||
|   static const double spacing20 = 20.0; | ||||
|   static const double spacing24 = 24.0; | ||||
|   static const double spacing32 = 32.0; | ||||
|   static const double spacing40 = 40.0; | ||||
|   static const double spacing48 = 48.0; | ||||
|   static const double spacing56 = 56.0; | ||||
|   static const double spacing64 = 64.0; | ||||
|   static const double spacing72 = 72.0; | ||||
|   static const double spacing80 = 80.0; | ||||
|   static const double spacing96 = 96.0; | ||||
| 
 | ||||
|   // Border Radius | ||||
|   static const double radius4 = 4.0; | ||||
|   static const double radius8 = 8.0; | ||||
|   static const double radius12 = 12.0; | ||||
|   static const double radius16 = 16.0; | ||||
|   static const double radius20 = 20.0; | ||||
|   static const double radius24 = 24.0; | ||||
|   static const double radius32 = 32.0; | ||||
|   static const double radius40 = 40.0; | ||||
|   static const double radiusFull = 999.0; | ||||
| 
 | ||||
|   // Elevation | ||||
|   static const double elevation0 = 0.0; | ||||
|   static const double elevation1 = 1.0; | ||||
|   static const double elevation2 = 2.0; | ||||
|   static const double elevation4 = 4.0; | ||||
|   static const double elevation8 = 8.0; | ||||
|   static const double elevation16 = 16.0; | ||||
|   static const double elevation24 = 24.0; | ||||
| 
 | ||||
|   // Animation Durations | ||||
|   static const Duration durationFast = Duration(milliseconds: 150); | ||||
|   static const Duration durationNormal = Duration(milliseconds: 300); | ||||
|   static const Duration durationSlow = Duration(milliseconds: 500); | ||||
|   static const Duration durationVerySlow = Duration(milliseconds: 800); | ||||
| 
 | ||||
|   // Animation Curves | ||||
|   static const Curve curveFast = Curves.easeInOut; | ||||
|   static const Curve curveNormal = Curves.easeInOutCubic; | ||||
|   static const Curve curveSlow = Curves.easeInOutQuart; | ||||
|   static const Curve curveBounce = Curves.bounceOut; | ||||
|   static const Curve curveElastic = Curves.elasticOut; | ||||
| 
 | ||||
|   // Screen Breakpoints | ||||
|   static const double mobileBreakpoint = 600.0; | ||||
|   static const double tabletBreakpoint = 900.0; | ||||
|   static const double desktopBreakpoint = 1200.0; | ||||
| 
 | ||||
|   // Input Field Heights | ||||
|   static const double inputHeightSmall = 40.0; | ||||
|   static const double inputHeightMedium = 48.0; | ||||
|   static const double inputHeightLarge = 56.0; | ||||
| 
 | ||||
|   // Button Heights | ||||
|   static const double buttonHeightSmall = 36.0; | ||||
|   static const double buttonHeightMedium = 48.0; | ||||
|   static const double buttonHeightLarge = 56.0; | ||||
| 
 | ||||
|   // Icon Sizes | ||||
|   static const double iconSizeSmall = 16.0; | ||||
|   static const double iconSizeMedium = 24.0; | ||||
|   static const double iconSizeLarge = 32.0; | ||||
|   static const double iconSizeXLarge = 48.0; | ||||
| 
 | ||||
|   // Logo Sizes | ||||
|   static const double logoSizeSmall = 32.0; | ||||
|   static const double logoSizeMedium = 48.0; | ||||
|   static const double logoSizeLarge = 64.0; | ||||
|   static const double logoSizeXLarge = 96.0; | ||||
| 
 | ||||
|   // Card Padding | ||||
|   static const EdgeInsets cardPaddingSmall = EdgeInsets.all(spacing12); | ||||
|   static const EdgeInsets cardPaddingMedium = EdgeInsets.all(spacing16); | ||||
|   static const EdgeInsets cardPaddingLarge = EdgeInsets.all(spacing24); | ||||
| 
 | ||||
|   // Screen Padding | ||||
|   static const EdgeInsets screenPaddingSmall = EdgeInsets.all(spacing16); | ||||
|   static const EdgeInsets screenPaddingMedium = EdgeInsets.all(spacing24); | ||||
|   static const EdgeInsets screenPaddingLarge = EdgeInsets.all(spacing32); | ||||
| 
 | ||||
|   // Horizontal Padding | ||||
|   static const EdgeInsets horizontalPaddingSmall = | ||||
|       EdgeInsets.symmetric(horizontal: spacing16); | ||||
|   static const EdgeInsets horizontalPaddingMedium = | ||||
|       EdgeInsets.symmetric(horizontal: spacing24); | ||||
|   static const EdgeInsets horizontalPaddingLarge = | ||||
|       EdgeInsets.symmetric(horizontal: spacing32); | ||||
| 
 | ||||
|   // Vertical Padding | ||||
|   static const EdgeInsets verticalPaddingSmall = | ||||
|       EdgeInsets.symmetric(vertical: spacing16); | ||||
|   static const EdgeInsets verticalPaddingMedium = | ||||
|       EdgeInsets.symmetric(vertical: spacing24); | ||||
|   static const EdgeInsets verticalPaddingLarge = | ||||
|       EdgeInsets.symmetric(vertical: spacing32); | ||||
| 
 | ||||
|   // Responsive Helpers | ||||
|   static bool isMobile(BuildContext context) { | ||||
|     return MediaQuery.of(context).size.width < mobileBreakpoint; | ||||
|   } | ||||
| 
 | ||||
|   static bool isTablet(BuildContext context) { | ||||
|     final width = MediaQuery.of(context).size.width; | ||||
|     return width >= mobileBreakpoint && width < tabletBreakpoint; | ||||
|   } | ||||
| 
 | ||||
|   static bool isDesktop(BuildContext context) { | ||||
|     return MediaQuery.of(context).size.width >= desktopBreakpoint; | ||||
|   } | ||||
| 
 | ||||
|   static double getResponsiveValue( | ||||
|     BuildContext context, { | ||||
|     required double mobile, | ||||
|     required double tablet, | ||||
|     required double desktop, | ||||
|   }) { | ||||
|     if (isMobile(context)) return mobile; | ||||
|     if (isTablet(context)) return tablet; | ||||
|     return desktop; | ||||
|   } | ||||
| 
 | ||||
|   static int getResponsiveInt( | ||||
|     BuildContext context, { | ||||
|     required int mobile, | ||||
|     required int tablet, | ||||
|     required int desktop, | ||||
|   }) { | ||||
|     if (isMobile(context)) return mobile; | ||||
|     if (isTablet(context)) return tablet; | ||||
|     return desktop; | ||||
|   } | ||||
| 
 | ||||
|   static EdgeInsets getResponsivePadding( | ||||
|     BuildContext context, { | ||||
|     required EdgeInsets mobile, | ||||
|     required EdgeInsets tablet, | ||||
|     required EdgeInsets desktop, | ||||
|   }) { | ||||
|     if (isMobile(context)) return mobile; | ||||
|     if (isTablet(context)) return tablet; | ||||
|     return desktop; | ||||
|   } | ||||
| 
 | ||||
|   static double getResponsiveSpacing( | ||||
|     BuildContext context, { | ||||
|     required double mobile, | ||||
|     required double tablet, | ||||
|     required double desktop, | ||||
|   }) { | ||||
|     if (isMobile(context)) return mobile; | ||||
|     if (isTablet(context)) return tablet; | ||||
|     return desktop; | ||||
|   } | ||||
| 
 | ||||
|   // Animation Helpers | ||||
|   static Widget fadeIn({ | ||||
|     required Widget child, | ||||
|     Duration duration = durationNormal, | ||||
|     Curve curve = curveNormal, | ||||
|   }) { | ||||
|     return TweenAnimationBuilder<double>( | ||||
|       duration: duration, | ||||
|       curve: curve, | ||||
|       tween: Tween(begin: 0.0, end: 1.0), | ||||
|       builder: (context, value, child) { | ||||
|         return Opacity( | ||||
|           opacity: value, | ||||
|           child: child, | ||||
|         ); | ||||
|       }, | ||||
|       child: child, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   static Widget slideInUp({ | ||||
|     required Widget child, | ||||
|     Duration duration = durationNormal, | ||||
|     Curve curve = curveNormal, | ||||
|     double offset = 50.0, | ||||
|   }) { | ||||
|     return TweenAnimationBuilder<Offset>( | ||||
|       duration: duration, | ||||
|       curve: curve, | ||||
|       tween: Tween(begin: Offset(0, offset), end: Offset.zero), | ||||
|       builder: (context, value, child) { | ||||
|         return Transform.translate( | ||||
|           offset: value, | ||||
|           child: child, | ||||
|         ); | ||||
|       }, | ||||
|       child: child, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   static Widget scaleIn({ | ||||
|     required Widget child, | ||||
|     Duration duration = durationNormal, | ||||
|     Curve curve = curveNormal, | ||||
|     double beginScale = 0.8, | ||||
|   }) { | ||||
|     return TweenAnimationBuilder<double>( | ||||
|       duration: duration, | ||||
|       curve: curve, | ||||
|       tween: Tween(begin: beginScale, end: 1.0), | ||||
|       builder: (context, value, child) { | ||||
|         return Transform.scale( | ||||
|           scale: value, | ||||
|           child: child, | ||||
|         ); | ||||
|       }, | ||||
|       child: child, | ||||
|     ); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										81
									
								
								base_project/lib/core/network/network_info.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,81 @@ | ||||
| // import 'package:flutter/material.dart'; | ||||
| // import 'package:connectivity_plus/connectivity_plus.dart'; | ||||
| 
 | ||||
| // // For checking internet connectivity | ||||
| // abstract class NetworkInfoI { | ||||
| //   Future<bool> isConnected(); | ||||
| 
 | ||||
| //   Future<ConnectivityResult> get connectivityResult; | ||||
| 
 | ||||
| //   Stream<ConnectivityResult> get onConnectivityChanged; | ||||
| // } | ||||
| 
 | ||||
| // class NetworkInfo implements NetworkInfoI { | ||||
| //   Connectivity connectivity; | ||||
| 
 | ||||
| //   static final NetworkInfo _networkInfo = NetworkInfo._internal(Connectivity()); | ||||
| 
 | ||||
| //   factory NetworkInfo() { | ||||
| //     return _networkInfo; | ||||
| //   } | ||||
| 
 | ||||
| //   NetworkInfo._internal(this.connectivity) { | ||||
| //     connectivity = this.connectivity; | ||||
| //   } | ||||
| 
 | ||||
| //   ///checks internet is connected or not | ||||
| //   ///returns [true] if internet is connected | ||||
| //   ///else it will return [false] | ||||
| //   @override | ||||
| //   Future<bool> isConnected() async { | ||||
| //     final result = await connectivity.checkConnectivity(); | ||||
| //     if (result != ConnectivityResult.none) { | ||||
| //       return true; | ||||
| //     } | ||||
| //     return false; | ||||
| //   } | ||||
| 
 | ||||
| //   // to check type of internet connectivity | ||||
| //   @override | ||||
| //   Future<ConnectivityResult> get connectivityResult async { | ||||
| //     return connectivity.checkConnectivity(); | ||||
| //   } | ||||
| 
 | ||||
| //   //check the type on internet connection on changed of internet connection | ||||
| //   @override | ||||
| //   Stream<ConnectivityResult> get onConnectivityChanged => | ||||
| //       connectivity.onConnectivityChanged; | ||||
| // } | ||||
| 
 | ||||
| // abstract class Failure {} | ||||
| 
 | ||||
| // // General failures | ||||
| // class ServerFailure extends Failure {} | ||||
| 
 | ||||
| // class CacheFailure extends Failure {} | ||||
| 
 | ||||
| // class NetworkFailure extends Failure {} | ||||
| 
 | ||||
| // class ServerException implements Exception {} | ||||
| 
 | ||||
| // class CacheException implements Exception {} | ||||
| 
 | ||||
| // class NetworkException implements Exception {} | ||||
| 
 | ||||
| // ///can be used for throwing [NoInternetException] | ||||
| // class NoInternetException implements Exception { | ||||
| //   late String _message; | ||||
| 
 | ||||
| //   NoInternetException([String message = 'NoInternetException Occurred']) { | ||||
| //     if (globalMessengerKey.currentState != null) { | ||||
| //       globalMessengerKey.currentState! | ||||
| //           .showSnackBar(SnackBar(content: Text(message))); | ||||
| //     } | ||||
| //     this._message = message; | ||||
| //   } | ||||
| 
 | ||||
| //   @override | ||||
| //   String toString() { | ||||
| //     return _message; | ||||
| //   } | ||||
| // } | ||||
							
								
								
									
										266
									
								
								base_project/lib/core/providers/dynamic_theme_provider.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,266 @@ | ||||
| import 'dart:typed_data'; | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:flutter/foundation.dart'; | ||||
| import '../theme/dynamic_color_scheme.dart'; | ||||
| import 'package:flutter/foundation.dart' show compute; | ||||
| 
 | ||||
| class DynamicThemeProvider extends ChangeNotifier { | ||||
|   ColorScheme? _dynamicColorScheme; | ||||
|   List<Color> _logoColors = []; | ||||
|   bool _isUsingDynamicTheme = false; | ||||
|   bool _isLoading = false; | ||||
| 
 | ||||
|   // Manual override | ||||
|   bool _useManualOverride = false; | ||||
|   Color? _manualPrimary; | ||||
|   Color? _manualSecondary; | ||||
|   Color? _manualTertiary; | ||||
| 
 | ||||
|   // Getters | ||||
|   ColorScheme? get dynamicColorScheme => _dynamicColorScheme; | ||||
|   List<Color> get logoColors => _logoColors; | ||||
|   bool get isUsingDynamicTheme => _isUsingDynamicTheme; | ||||
|   bool get isLoading => _isLoading; | ||||
|   bool get useManualOverride => _useManualOverride; | ||||
|   Color? get manualPrimary => _manualPrimary; | ||||
|   Color? get manualSecondary => _manualSecondary; | ||||
|   Color? get manualTertiary => _manualTertiary; | ||||
| 
 | ||||
|   // Set loading state | ||||
|   set isLoading(bool value) { | ||||
|     _isLoading = value; | ||||
|     notifyListeners(); | ||||
|   } | ||||
| 
 | ||||
|   // Generate dynamic theme from logo | ||||
|   Future<void> generateThemeFromLogo(Uint8List logoBytes) async { | ||||
|     try { | ||||
|       print("DynamicThemeProvider.generateThemeFromLogo called"); | ||||
|       print("Logo bytes length: ${logoBytes.length}"); | ||||
| 
 | ||||
|       isLoading = true; | ||||
| 
 | ||||
|       // Extract colors with lightweight, downscaled palette to avoid jank | ||||
|       print("Extracting colors from logo (lite in main isolate)..."); | ||||
|       final colors = | ||||
|           await DynamicColorScheme.extractColorsFromBytesLite(logoBytes); | ||||
| 
 | ||||
|       print("Colors extracted: ${colors.length}"); | ||||
|       _logoColors = colors; | ||||
| 
 | ||||
|       // Generate light theme | ||||
|       print("Generating light theme..."); | ||||
|       final lightTheme = | ||||
|           DynamicColorScheme.generateDynamicColorScheme(colors, isDark: false); | ||||
| 
 | ||||
|       // Generate dark theme | ||||
|       print("Generating dark theme..."); | ||||
|       final darkTheme = | ||||
|           DynamicColorScheme.generateDynamicColorScheme(colors, isDark: true); | ||||
| 
 | ||||
|       // Store the dynamic color scheme | ||||
|       _dynamicColorScheme = lightTheme; | ||||
|       _isUsingDynamicTheme = true; | ||||
| 
 | ||||
|       print('Dynamic theme generated with ${colors.length} colors'); | ||||
|       print('Primary: ${colors.isNotEmpty ? colors[0] : 'N/A'}'); | ||||
|       print('Secondary: ${colors.length > 1 ? colors[1] : 'N/A'}'); | ||||
|       print('Tertiary: ${colors.length > 2 ? colors[2] : 'N/A'}'); | ||||
|       print('_isUsingDynamicTheme set to: $_isUsingDynamicTheme'); | ||||
| 
 | ||||
|       isLoading = false; | ||||
|       print("Notifying listeners..."); | ||||
|       notifyListeners(); | ||||
|       print("Listeners notified!"); | ||||
|     } catch (e) { | ||||
|       print('Error generating dynamic theme: $e'); | ||||
|       isLoading = false; | ||||
|       // Fallback to default theme | ||||
|       _isUsingDynamicTheme = false; | ||||
|       _dynamicColorScheme = null; | ||||
|       notifyListeners(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Get current color scheme (dynamic or default) | ||||
|   ColorScheme getCurrentColorScheme(bool isDark) { | ||||
|     // Manual overrides take highest precedence | ||||
|     if (_useManualOverride && (_manualPrimary != null)) { | ||||
|       final base = [ | ||||
|         _manualPrimary!, | ||||
|         _manualSecondary ?? _manualPrimary!, | ||||
|         _manualTertiary ?? (_manualSecondary ?? _manualPrimary!) | ||||
|       ]; | ||||
|       return DynamicColorScheme.generateDynamicColorScheme(base, | ||||
|           isDark: isDark); | ||||
|     } | ||||
| 
 | ||||
|     if (_isUsingDynamicTheme && _dynamicColorScheme != null) { | ||||
|       // Return dynamic theme with appropriate brightness | ||||
|       if (isDark) { | ||||
|         return DynamicColorScheme.generateDynamicColorScheme(_logoColors, | ||||
|             isDark: true); | ||||
|       } else { | ||||
|         return _dynamicColorScheme!; | ||||
|       } | ||||
|     } else { | ||||
|       // Return default theme | ||||
|       return DynamicColorScheme.generateDynamicColorScheme([], isDark: isDark); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Get gradient colors for UI elements | ||||
|   List<Color> getGradientColors() { | ||||
|     if (_useManualOverride && _manualPrimary != null) { | ||||
|       return DynamicColorScheme.generateGradientColors([ | ||||
|         _manualPrimary!, | ||||
|         _manualSecondary ?? _manualPrimary!, | ||||
|         _manualTertiary ?? (_manualSecondary ?? _manualPrimary!) | ||||
|       ]); | ||||
|     } | ||||
|     if (_isUsingDynamicTheme && _logoColors.isNotEmpty) { | ||||
|       return DynamicColorScheme.generateGradientColors(_logoColors); | ||||
|     } else { | ||||
|       return DynamicColorScheme.generateGradientColors([]); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Get accent colors for semantic elements | ||||
|   Map<String, Color> getAccentColors() { | ||||
|     if (_useManualOverride && _manualPrimary != null) { | ||||
|       return DynamicColorScheme.generateAccentColors([ | ||||
|         _manualPrimary!, | ||||
|         _manualSecondary ?? _manualPrimary!, | ||||
|         _manualTertiary ?? (_manualSecondary ?? _manualPrimary!) | ||||
|       ]); | ||||
|     } | ||||
|     if (_isUsingDynamicTheme && _logoColors.isNotEmpty) { | ||||
|       return DynamicColorScheme.generateAccentColors(_logoColors); | ||||
|     } else { | ||||
|       return DynamicColorScheme.generateAccentColors([]); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Reset to default theme | ||||
|   void resetToDefaultTheme() { | ||||
|     _isUsingDynamicTheme = false; | ||||
|     _dynamicColorScheme = null; | ||||
|     _logoColors = []; | ||||
|     _useManualOverride = false; | ||||
|     _manualPrimary = null; | ||||
|     _manualSecondary = null; | ||||
|     _manualTertiary = null; | ||||
|     notifyListeners(); | ||||
|   } | ||||
| 
 | ||||
|   // Enable manual override with provided colors (hex or Color) | ||||
|   void enableManualOverride( | ||||
|       {Color? primary, Color? secondary, Color? tertiary}) { | ||||
|     _useManualOverride = true; | ||||
|     if (primary != null) _manualPrimary = primary; | ||||
|     if (secondary != null) _manualSecondary = secondary; | ||||
|     if (tertiary != null) _manualTertiary = tertiary; | ||||
|     notifyListeners(); | ||||
|   } | ||||
| 
 | ||||
|   // Disable manual override | ||||
|   void disableManualOverride() { | ||||
|     _useManualOverride = false; | ||||
|     notifyListeners(); | ||||
|   } | ||||
| 
 | ||||
|   // Update manual colors | ||||
|   void setManualColors({Color? primary, Color? secondary, Color? tertiary}) { | ||||
|     if (primary != null) _manualPrimary = primary; | ||||
|     if (secondary != null) _manualSecondary = secondary; | ||||
|     if (tertiary != null) _manualTertiary = tertiary; | ||||
|     // Ensure override is on when user sets colors | ||||
|     _useManualOverride = true; | ||||
|     notifyListeners(); | ||||
|   } | ||||
| 
 | ||||
|   // Check if logo has specific color characteristics | ||||
|   bool hasWarmColors() { | ||||
|     if (_logoColors.isEmpty) return false; | ||||
| 
 | ||||
|     for (final color in _logoColors) { | ||||
|       final hsl = HSLColor.fromColor(color); | ||||
|       // Warm colors: red, orange, yellow (0-60 degrees) | ||||
|       if (hsl.hue >= 0 && hsl.hue <= 60) { | ||||
|         return true; | ||||
|       } | ||||
|     } | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   bool hasCoolColors() { | ||||
|     if (_logoColors.isEmpty) return false; | ||||
| 
 | ||||
|     for (final color in _logoColors) { | ||||
|       final hsl = HSLColor.fromColor(color); | ||||
|       // Cool colors: blue, green, purple (120-300 degrees) | ||||
|       if (hsl.hue >= 120 && hsl.hue <= 300) { | ||||
|         return true; | ||||
|       } | ||||
|     } | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   bool hasNeutralColors() { | ||||
|     if (_logoColors.isEmpty) return false; | ||||
| 
 | ||||
|     for (final color in _logoColors) { | ||||
|       final hsl = HSLColor.fromColor(color); | ||||
|       // Neutral colors: low saturation | ||||
|       if (hsl.saturation < 0.3) { | ||||
|         return true; | ||||
|       } | ||||
|     } | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   // Get theme description | ||||
|   String getThemeDescription() { | ||||
|     if (!_isUsingDynamicTheme) { | ||||
|       return 'Default Theme'; | ||||
|     } | ||||
| 
 | ||||
|     List<String> characteristics = []; | ||||
| 
 | ||||
|     if (hasWarmColors()) characteristics.add('Warm'); | ||||
|     if (hasCoolColors()) characteristics.add('Cool'); | ||||
|     if (hasNeutralColors()) characteristics.add('Neutral'); | ||||
| 
 | ||||
|     if (characteristics.isEmpty) { | ||||
|       characteristics.add('Dynamic'); | ||||
|     } | ||||
| 
 | ||||
|     return '${characteristics.join(', ')} Theme'; | ||||
|   } | ||||
| 
 | ||||
|   // Get color palette info | ||||
|   Map<String, dynamic> getColorPaletteInfo() { | ||||
|     if (_logoColors.isEmpty) { | ||||
|       return { | ||||
|         'primary': null, | ||||
|         'secondary': null, | ||||
|         'tertiary': null, | ||||
|         'totalColors': 0, | ||||
|         'description': 'No logo colors available', | ||||
|       }; | ||||
|     } | ||||
| 
 | ||||
|     return { | ||||
|       'primary': _logoColors.isNotEmpty ? _logoColors[0] : null, | ||||
|       'secondary': _logoColors.length > 1 ? _logoColors[1] : null, | ||||
|       'tertiary': _logoColors.length > 2 ? _logoColors[2] : null, | ||||
|       'totalColors': _logoColors.length, | ||||
|       'description': 'Generated from uploaded logo', | ||||
|       'characteristics': { | ||||
|         'warm': hasWarmColors(), | ||||
|         'cool': hasCoolColors(), | ||||
|         'neutral': hasNeutralColors(), | ||||
|       }, | ||||
|     }; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										20
									
								
								base_project/lib/core/providers/theme_provider.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,20 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:flutter/foundation.dart'; | ||||
| 
 | ||||
| class ThemeProvider extends ChangeNotifier { | ||||
|   bool _isDarkMode = false; | ||||
| 
 | ||||
|   bool get isDarkMode => _isDarkMode; | ||||
| 
 | ||||
|   void toggleTheme() { | ||||
|     _isDarkMode = !_isDarkMode; | ||||
|     notifyListeners(); | ||||
|   } | ||||
| 
 | ||||
|   void setTheme(bool isDark) { | ||||
|     if (_isDarkMode != isDark) { | ||||
|       _isDarkMode = isDark; | ||||
|       notifyListeners(); | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										624
									
								
								base_project/lib/core/theme/app_theme.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,624 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:provider/provider.dart'; | ||||
| 
 | ||||
| import '../providers/dynamic_theme_provider.dart'; | ||||
| import '../providers/theme_provider.dart'; | ||||
| 
 | ||||
| class AppTheme { | ||||
|   static ThemeData getLightTheme(BuildContext context) { | ||||
|     final dynamicThemeProvider = | ||||
|         Provider.of<DynamicThemeProvider>(context, listen: false); | ||||
|     final themeProvider = Provider.of<ThemeProvider>(context, listen: false); | ||||
| 
 | ||||
|     // Get color scheme (dynamic or default) | ||||
|     final colorScheme = dynamicThemeProvider.getCurrentColorScheme(false); | ||||
| 
 | ||||
|     return ThemeData( | ||||
|       useMaterial3: true, | ||||
|       brightness: Brightness.light, | ||||
|       colorScheme: colorScheme, | ||||
|       textTheme: _getTextTheme(colorScheme), | ||||
|       appBarTheme: _getAppBarTheme(colorScheme), | ||||
|       cardTheme: _getCardTheme(colorScheme), | ||||
|       elevatedButtonTheme: _getElevatedButtonTheme(colorScheme), | ||||
|       outlinedButtonTheme: _getOutlinedButtonTheme(colorScheme), | ||||
|       textButtonTheme: _getTextButtonTheme(colorScheme), | ||||
|       inputDecorationTheme: _getInputDecorationTheme(colorScheme), | ||||
|       bottomNavigationBarTheme: _getBottomNavigationBarTheme(colorScheme), | ||||
|       floatingActionButtonTheme: _getFloatingActionButtonTheme(colorScheme), | ||||
|       dividerTheme: _getDividerTheme(colorScheme), | ||||
|       iconTheme: _getIconTheme(colorScheme), | ||||
|       chipTheme: _getChipTheme(colorScheme), | ||||
|       switchTheme: _getSwitchTheme(colorScheme), | ||||
|       checkboxTheme: _getCheckboxTheme(colorScheme), | ||||
|       radioTheme: _getRadioTheme(colorScheme), | ||||
|       sliderTheme: _getSliderTheme(colorScheme), | ||||
|       progressIndicatorTheme: _getProgressIndicatorTheme(colorScheme), | ||||
|       snackBarTheme: _getSnackBarTheme(colorScheme), | ||||
|       dialogTheme: _getDialogTheme(colorScheme), | ||||
|       bottomSheetTheme: _getBottomSheetTheme(colorScheme), | ||||
|       tooltipTheme: _getTooltipTheme(colorScheme), | ||||
|       popupMenuTheme: _getPopupMenuTheme(colorScheme), | ||||
|       drawerTheme: _getDrawerTheme(colorScheme), | ||||
|       listTileTheme: _getListTileTheme(colorScheme), | ||||
|       tabBarTheme: _getTabBarTheme(colorScheme), | ||||
|       dataTableTheme: _getDataTableTheme(colorScheme), | ||||
|       expansionTileTheme: _getExpansionTileTheme(colorScheme), | ||||
|       timePickerTheme: _getTimePickerTheme(colorScheme), | ||||
|       datePickerTheme: _getDatePickerTheme(colorScheme), | ||||
|       pageTransitionsTheme: _getPageTransitionsTheme(), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   static ThemeData getDarkTheme(BuildContext context) { | ||||
|     final dynamicThemeProvider = | ||||
|         Provider.of<DynamicThemeProvider>(context, listen: false); | ||||
|     final themeProvider = Provider.of<ThemeProvider>(context, listen: false); | ||||
| 
 | ||||
|     // Get color scheme (dynamic or default) | ||||
|     final colorScheme = dynamicThemeProvider.getCurrentColorScheme(true); | ||||
| 
 | ||||
|     return ThemeData( | ||||
|       useMaterial3: true, | ||||
|       brightness: Brightness.dark, | ||||
|       colorScheme: colorScheme, | ||||
|       textTheme: _getTextTheme(colorScheme), | ||||
|       appBarTheme: _getAppBarTheme(colorScheme), | ||||
|       cardTheme: _getCardTheme(colorScheme), | ||||
|       elevatedButtonTheme: _getElevatedButtonTheme(colorScheme), | ||||
|       outlinedButtonTheme: _getOutlinedButtonTheme(colorScheme), | ||||
|       textButtonTheme: _getTextButtonTheme(colorScheme), | ||||
|       inputDecorationTheme: _getInputDecorationTheme(colorScheme), | ||||
|       bottomNavigationBarTheme: _getBottomNavigationBarTheme(colorScheme), | ||||
|       floatingActionButtonTheme: _getFloatingActionButtonTheme(colorScheme), | ||||
|       dividerTheme: _getDividerTheme(colorScheme), | ||||
|       iconTheme: _getIconTheme(colorScheme), | ||||
|       chipTheme: _getChipTheme(colorScheme), | ||||
|       switchTheme: _getSwitchTheme(colorScheme), | ||||
|       checkboxTheme: _getCheckboxTheme(colorScheme), | ||||
|       radioTheme: _getRadioTheme(colorScheme), | ||||
|       sliderTheme: _getSliderTheme(colorScheme), | ||||
|       progressIndicatorTheme: _getProgressIndicatorTheme(colorScheme), | ||||
|       snackBarTheme: _getSnackBarTheme(colorScheme), | ||||
|       dialogTheme: _getDialogTheme(colorScheme), | ||||
|       bottomSheetTheme: _getBottomSheetTheme(colorScheme), | ||||
|       tooltipTheme: _getTooltipTheme(colorScheme), | ||||
|       popupMenuTheme: _getPopupMenuTheme(colorScheme), | ||||
|       drawerTheme: _getDrawerTheme(colorScheme), | ||||
|       listTileTheme: _getListTileTheme(colorScheme), | ||||
|       tabBarTheme: _getTabBarTheme(colorScheme), | ||||
|       dataTableTheme: _getDataTableTheme(colorScheme), | ||||
|       expansionTileTheme: _getExpansionTileTheme(colorScheme), | ||||
|       timePickerTheme: _getTimePickerTheme(colorScheme), | ||||
|       datePickerTheme: _getDatePickerTheme(colorScheme), | ||||
|       pageTransitionsTheme: _getPageTransitionsTheme(), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Get theme based on current mode | ||||
| 
 | ||||
|   // Get theme based on current mode | ||||
|   static ThemeData getTheme(BuildContext context) { | ||||
|     final themeProvider = Provider.of<ThemeProvider>(context, listen: false); | ||||
|     final dynamicThemeProvider = | ||||
|         Provider.of<DynamicThemeProvider>(context, listen: false); | ||||
| 
 | ||||
|     // Force rebuild when dynamic theme changes | ||||
|     dynamicThemeProvider.isUsingDynamicTheme; | ||||
| 
 | ||||
|     return themeProvider.isDarkMode | ||||
|         ? getDarkTheme(context) | ||||
|         : getLightTheme(context); | ||||
|   } | ||||
| 
 | ||||
|   // Text Theme | ||||
|   static TextTheme _getTextTheme(ColorScheme colorScheme) { | ||||
|     return TextTheme( | ||||
|       displayLarge: TextStyle( | ||||
|         fontSize: 57, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         color: colorScheme.onSurface, | ||||
|         letterSpacing: -0.25, | ||||
|       ), | ||||
|       displayMedium: TextStyle( | ||||
|         fontSize: 45, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         color: colorScheme.onSurface, | ||||
|         letterSpacing: 0, | ||||
|       ), | ||||
|       displaySmall: TextStyle( | ||||
|         fontSize: 36, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         color: colorScheme.onSurface, | ||||
|         letterSpacing: 0, | ||||
|       ), | ||||
|       headlineLarge: TextStyle( | ||||
|         fontSize: 32, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         color: colorScheme.onSurface, | ||||
|         letterSpacing: 0, | ||||
|       ), | ||||
|       headlineMedium: TextStyle( | ||||
|         fontSize: 28, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         color: colorScheme.onSurface, | ||||
|         letterSpacing: 0, | ||||
|       ), | ||||
|       headlineSmall: TextStyle( | ||||
|         fontSize: 24, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         color: colorScheme.onSurface, | ||||
|         letterSpacing: 0, | ||||
|       ), | ||||
|       titleLarge: TextStyle( | ||||
|         fontSize: 22, | ||||
|         fontWeight: FontWeight.w500, | ||||
|         color: colorScheme.onSurface, | ||||
|         letterSpacing: 0, | ||||
|       ), | ||||
|       titleMedium: TextStyle( | ||||
|         fontSize: 16, | ||||
|         fontWeight: FontWeight.w500, | ||||
|         color: colorScheme.onSurface, | ||||
|         letterSpacing: 0.15, | ||||
|       ), | ||||
|       titleSmall: TextStyle( | ||||
|         fontSize: 14, | ||||
|         fontWeight: FontWeight.w500, | ||||
|         color: colorScheme.onSurface, | ||||
|         letterSpacing: 0.1, | ||||
|       ), | ||||
|       bodyLarge: TextStyle( | ||||
|         fontSize: 16, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         color: colorScheme.onSurface, | ||||
|         letterSpacing: 0.5, | ||||
|       ), | ||||
|       bodyMedium: TextStyle( | ||||
|         fontSize: 14, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         color: colorScheme.onSurface, | ||||
|         letterSpacing: 0.25, | ||||
|       ), | ||||
|       bodySmall: TextStyle( | ||||
|         fontSize: 12, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         color: colorScheme.onSurface, | ||||
|         letterSpacing: 0.4, | ||||
|       ), | ||||
|       labelLarge: TextStyle( | ||||
|         fontSize: 14, | ||||
|         fontWeight: FontWeight.w500, | ||||
|         color: colorScheme.onSurface, | ||||
|         letterSpacing: 0.1, | ||||
|       ), | ||||
|       labelMedium: TextStyle( | ||||
|         fontSize: 12, | ||||
|         fontWeight: FontWeight.w500, | ||||
|         color: colorScheme.onSurface, | ||||
|         letterSpacing: 0.5, | ||||
|       ), | ||||
|       labelSmall: TextStyle( | ||||
|         fontSize: 11, | ||||
|         fontWeight: FontWeight.w500, | ||||
|         color: colorScheme.onSurface, | ||||
|         letterSpacing: 0.5, | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // AppBar Theme | ||||
|   static AppBarTheme _getAppBarTheme(ColorScheme colorScheme) { | ||||
|     return AppBarTheme( | ||||
|       backgroundColor: colorScheme.surface, | ||||
|       foregroundColor: colorScheme.onSurface, | ||||
|       elevation: 0, | ||||
|       centerTitle: true, | ||||
|       titleTextStyle: TextStyle( | ||||
|         color: colorScheme.onSurface, | ||||
|         fontSize: 20, | ||||
|         fontWeight: FontWeight.w600, | ||||
|       ), | ||||
|       iconTheme: IconThemeData( | ||||
|         color: colorScheme.onSurface, | ||||
|         size: 24, | ||||
|       ), | ||||
|       actionsIconTheme: IconThemeData( | ||||
|         color: colorScheme.onSurface, | ||||
|         size: 24, | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Card Theme | ||||
|   static CardThemeData _getCardTheme(ColorScheme colorScheme) { | ||||
|     return CardThemeData( | ||||
|       color: colorScheme.surface, | ||||
|       elevation: 2, | ||||
|       shadowColor: colorScheme.shadow, | ||||
|       shape: RoundedRectangleBorder( | ||||
|         borderRadius: BorderRadius.circular(16), | ||||
|       ), | ||||
|       margin: const EdgeInsets.all(8), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Elevated Button Theme | ||||
|   static ElevatedButtonThemeData _getElevatedButtonTheme( | ||||
|       ColorScheme colorScheme) { | ||||
|     return ElevatedButtonThemeData( | ||||
|       style: ElevatedButton.styleFrom( | ||||
|         backgroundColor: colorScheme.primary, | ||||
|         foregroundColor: colorScheme.onPrimary, | ||||
|         elevation: 2, | ||||
|         shadowColor: colorScheme.shadow, | ||||
|         shape: RoundedRectangleBorder( | ||||
|           borderRadius: BorderRadius.circular(12), | ||||
|         ), | ||||
|         padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), | ||||
|         textStyle: const TextStyle( | ||||
|           fontSize: 16, | ||||
|           fontWeight: FontWeight.w600, | ||||
|         ), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Outlined Button Theme | ||||
|   static OutlinedButtonThemeData _getOutlinedButtonTheme( | ||||
|       ColorScheme colorScheme) { | ||||
|     return OutlinedButtonThemeData( | ||||
|       style: OutlinedButton.styleFrom( | ||||
|         foregroundColor: colorScheme.primary, | ||||
|         side: BorderSide(color: colorScheme.outline, width: 1), | ||||
|         shape: RoundedRectangleBorder( | ||||
|           borderRadius: BorderRadius.circular(12), | ||||
|         ), | ||||
|         padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), | ||||
|         textStyle: const TextStyle( | ||||
|           fontSize: 16, | ||||
|           fontWeight: FontWeight.w600, | ||||
|         ), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Text Button Theme | ||||
|   static TextButtonThemeData _getTextButtonTheme(ColorScheme colorScheme) { | ||||
|     return TextButtonThemeData( | ||||
|       style: TextButton.styleFrom( | ||||
|         foregroundColor: colorScheme.primary, | ||||
|         shape: RoundedRectangleBorder( | ||||
|           borderRadius: BorderRadius.circular(12), | ||||
|         ), | ||||
|         padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), | ||||
|         textStyle: const TextStyle( | ||||
|           fontSize: 16, | ||||
|           fontWeight: FontWeight.w600, | ||||
|         ), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Input Decoration Theme | ||||
|   static InputDecorationTheme _getInputDecorationTheme( | ||||
|       ColorScheme colorScheme) { | ||||
|     return InputDecorationTheme( | ||||
|       filled: true, | ||||
|       fillColor: colorScheme.surfaceVariant, | ||||
|       border: OutlineInputBorder( | ||||
|         borderRadius: BorderRadius.circular(12), | ||||
|         borderSide: BorderSide(color: colorScheme.outline), | ||||
|       ), | ||||
|       enabledBorder: OutlineInputBorder( | ||||
|         borderRadius: BorderRadius.circular(12), | ||||
|         borderSide: BorderSide(color: colorScheme.outline), | ||||
|       ), | ||||
|       focusedBorder: OutlineInputBorder( | ||||
|         borderRadius: BorderRadius.circular(12), | ||||
|         borderSide: BorderSide(color: colorScheme.primary, width: 2), | ||||
|       ), | ||||
|       errorBorder: OutlineInputBorder( | ||||
|         borderRadius: BorderRadius.circular(12), | ||||
|         borderSide: BorderSide(color: colorScheme.error), | ||||
|       ), | ||||
|       focusedErrorBorder: OutlineInputBorder( | ||||
|         borderRadius: BorderRadius.circular(12), | ||||
|         borderSide: BorderSide(color: colorScheme.error, width: 2), | ||||
|       ), | ||||
|       contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16), | ||||
|       labelStyle: TextStyle( | ||||
|         color: colorScheme.onSurfaceVariant, | ||||
|         fontSize: 16, | ||||
|       ), | ||||
|       hintStyle: TextStyle( | ||||
|         color: colorScheme.onSurfaceVariant, | ||||
|         fontSize: 16, | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Bottom Navigation Bar Theme | ||||
|   static BottomNavigationBarThemeData _getBottomNavigationBarTheme( | ||||
|       ColorScheme colorScheme) { | ||||
|     return BottomNavigationBarThemeData( | ||||
|       backgroundColor: colorScheme.surface, | ||||
|       selectedItemColor: colorScheme.primary, | ||||
|       unselectedItemColor: colorScheme.onSurfaceVariant, | ||||
|       type: BottomNavigationBarType.fixed, | ||||
|       elevation: 8, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Floating Action Button Theme | ||||
|   static FloatingActionButtonThemeData _getFloatingActionButtonTheme( | ||||
|       ColorScheme colorScheme) { | ||||
|     return FloatingActionButtonThemeData( | ||||
|       backgroundColor: colorScheme.primary, | ||||
|       foregroundColor: colorScheme.onPrimary, | ||||
|       elevation: 6, | ||||
|       shape: RoundedRectangleBorder( | ||||
|         borderRadius: BorderRadius.circular(16), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Divider Theme | ||||
|   static DividerThemeData _getDividerTheme(ColorScheme colorScheme) { | ||||
|     return DividerThemeData( | ||||
|       color: colorScheme.outlineVariant, | ||||
|       thickness: 1, | ||||
|       space: 1, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Icon Theme | ||||
|   static IconThemeData _getIconTheme(ColorScheme colorScheme) { | ||||
|     return IconThemeData( | ||||
|       color: colorScheme.onSurface, | ||||
|       size: 24, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Chip Theme | ||||
|   static ChipThemeData _getChipTheme(ColorScheme colorScheme) { | ||||
|     return ChipThemeData( | ||||
|       backgroundColor: colorScheme.surfaceVariant, | ||||
|       selectedColor: colorScheme.primaryContainer, | ||||
|       labelStyle: TextStyle( | ||||
|         color: colorScheme.onSurface, | ||||
|         fontSize: 14, | ||||
|       ), | ||||
|       shape: RoundedRectangleBorder( | ||||
|         borderRadius: BorderRadius.circular(20), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Switch Theme | ||||
|   // Switch Theme | ||||
|   static SwitchThemeData _getSwitchTheme(ColorScheme colorScheme) { | ||||
|     return SwitchThemeData( | ||||
|       thumbColor: MaterialStateProperty.all<Color?>(colorScheme.primary), | ||||
|       trackColor: MaterialStateProperty.all<Color?>(colorScheme.surfaceVariant), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Checkbox Theme | ||||
|   // Checkbox Theme | ||||
|   static CheckboxThemeData _getCheckboxTheme(ColorScheme colorScheme) { | ||||
|     return CheckboxThemeData( | ||||
|       fillColor: MaterialStateProperty.resolveWith<Color?>((states) { | ||||
|         if (states.contains(MaterialState.selected)) { | ||||
|           return colorScheme.primary; | ||||
|         } | ||||
|         return colorScheme.surfaceVariant; | ||||
|       }), | ||||
|       checkColor: MaterialStateProperty.all<Color?>(colorScheme.onPrimary), | ||||
|       shape: RoundedRectangleBorder( | ||||
|         borderRadius: BorderRadius.circular(4), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Radio Theme | ||||
|   static RadioThemeData _getRadioTheme(ColorScheme colorScheme) { | ||||
|     return RadioThemeData( | ||||
|       fillColor: MaterialStateProperty.resolveWith<Color?>((states) { | ||||
|         if (states.contains(MaterialState.selected)) { | ||||
|           return colorScheme.primary; | ||||
|         } | ||||
|         return colorScheme.surfaceVariant; | ||||
|       }), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Slider Theme | ||||
|   static SliderThemeData _getSliderTheme(ColorScheme colorScheme) { | ||||
|     return SliderThemeData( | ||||
|       activeTrackColor: colorScheme.primary, | ||||
|       inactiveTrackColor: colorScheme.surfaceVariant, | ||||
|       thumbColor: colorScheme.primary, | ||||
|       overlayColor: colorScheme.primary.withOpacity(0.2), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Progress Indicator Theme | ||||
|   static ProgressIndicatorThemeData _getProgressIndicatorTheme( | ||||
|       ColorScheme colorScheme) { | ||||
|     return ProgressIndicatorThemeData( | ||||
|       color: colorScheme.primary, | ||||
|       linearTrackColor: colorScheme.surfaceVariant, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // SnackBar Theme | ||||
|   static SnackBarThemeData _getSnackBarTheme(ColorScheme colorScheme) { | ||||
|     return SnackBarThemeData( | ||||
|       backgroundColor: colorScheme.surface, | ||||
|       shape: RoundedRectangleBorder( | ||||
|         borderRadius: BorderRadius.circular(12), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Dialog Theme | ||||
| 
 | ||||
|   static DialogThemeData _getDialogTheme(ColorScheme colorScheme) { | ||||
|     return DialogThemeData( | ||||
|       backgroundColor: colorScheme.surface, | ||||
|       elevation: 24, | ||||
|       shape: RoundedRectangleBorder( | ||||
|         borderRadius: BorderRadius.circular(16), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Bottom Sheet Theme | ||||
|   static BottomSheetThemeData _getBottomSheetTheme(ColorScheme colorScheme) { | ||||
|     return BottomSheetThemeData( | ||||
|       backgroundColor: colorScheme.surface, | ||||
|       shape: const RoundedRectangleBorder( | ||||
|         borderRadius: BorderRadius.vertical(top: Radius.circular(16)), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Tooltip Theme | ||||
|   static TooltipThemeData _getTooltipTheme(ColorScheme colorScheme) { | ||||
|     return TooltipThemeData( | ||||
|       decoration: BoxDecoration( | ||||
|         color: colorScheme.surface, | ||||
|         borderRadius: BorderRadius.circular(8), | ||||
|       ), | ||||
|       textStyle: TextStyle( | ||||
|         color: colorScheme.onSurface, | ||||
|         fontSize: 14, | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Popup Menu Theme | ||||
|   static PopupMenuThemeData _getPopupMenuTheme(ColorScheme colorScheme) { | ||||
|     return PopupMenuThemeData( | ||||
|       color: colorScheme.surface, | ||||
|       shape: RoundedRectangleBorder( | ||||
|         borderRadius: BorderRadius.circular(12), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Drawer Theme | ||||
|   static DrawerThemeData _getDrawerTheme(ColorScheme colorScheme) { | ||||
|     return DrawerThemeData( | ||||
|       backgroundColor: colorScheme.surface, | ||||
|       elevation: 16, | ||||
|       shape: const RoundedRectangleBorder( | ||||
|         borderRadius: BorderRadius.horizontal(right: Radius.circular(16)), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // List Tile Theme | ||||
|   static ListTileThemeData _getListTileTheme(ColorScheme colorScheme) { | ||||
|     return ListTileThemeData( | ||||
|       tileColor: colorScheme.surface, | ||||
|       textColor: colorScheme.onSurface, | ||||
|       iconColor: colorScheme.onSurfaceVariant, | ||||
|       // shape: RoundedRectangleBorder( | ||||
|       //   borderRadius: BorderRadius.circular(12), | ||||
|       // ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Tab Bar Theme | ||||
|   // Tab Bar Theme | ||||
|   static TabBarThemeData _getTabBarTheme(ColorScheme colorScheme) { | ||||
|     return TabBarThemeData( | ||||
|       labelColor: colorScheme.primary, | ||||
|       unselectedLabelColor: colorScheme.onSurfaceVariant, | ||||
|       indicatorColor: colorScheme.primary, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Data Table Theme | ||||
|   static DataTableThemeData _getDataTableTheme(ColorScheme colorScheme) { | ||||
|     return DataTableThemeData( | ||||
|       dataTextStyle: TextStyle( | ||||
|         color: colorScheme.onSurface, | ||||
|         fontSize: 14, | ||||
|       ), | ||||
|       headingTextStyle: TextStyle( | ||||
|         color: colorScheme.onSurface, | ||||
|         fontSize: 14, | ||||
|         fontWeight: FontWeight.w600, | ||||
|       ), | ||||
|       dividerThickness: 1, | ||||
|       dataRowColor: MaterialStateProperty.all<Color?>(colorScheme.surface), | ||||
|       headingRowColor: | ||||
|           MaterialStateProperty.all<Color?>(colorScheme.surfaceVariant), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Expansion Tile Theme | ||||
|   static ExpansionTileThemeData _getExpansionTileTheme( | ||||
|       ColorScheme colorScheme) { | ||||
|     return ExpansionTileThemeData( | ||||
|       backgroundColor: colorScheme.surface, | ||||
|       collapsedBackgroundColor: colorScheme.surfaceVariant, | ||||
|       textColor: colorScheme.onSurface, | ||||
|       collapsedTextColor: colorScheme.onSurfaceVariant, | ||||
|       iconColor: colorScheme.primary, | ||||
|       collapsedIconColor: colorScheme.onSurfaceVariant, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Time Picker Theme | ||||
|   static TimePickerThemeData _getTimePickerTheme(ColorScheme colorScheme) { | ||||
|     return TimePickerThemeData( | ||||
|       backgroundColor: colorScheme.surface, | ||||
|       hourMinuteTextColor: colorScheme.onSurface, | ||||
|       hourMinuteColor: colorScheme.surfaceVariant, | ||||
|       dayPeriodTextColor: colorScheme.onSurface, | ||||
|       dayPeriodColor: colorScheme.surfaceVariant, | ||||
|       dialHandColor: colorScheme.primary, | ||||
|       dialBackgroundColor: colorScheme.surfaceVariant, | ||||
|       dialTextColor: colorScheme.onSurface, | ||||
|       entryModeIconColor: colorScheme.onSurfaceVariant, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Date Picker Theme | ||||
|   static DatePickerThemeData _getDatePickerTheme(ColorScheme colorScheme) { | ||||
|     return DatePickerThemeData( | ||||
|       backgroundColor: colorScheme.surface, | ||||
|       headerBackgroundColor: colorScheme.primary, | ||||
|       headerForegroundColor: colorScheme.onPrimary, | ||||
|       dayForegroundColor: | ||||
|           MaterialStateProperty.all<Color?>(colorScheme.onSurface), | ||||
|       dayBackgroundColor: | ||||
|           MaterialStateProperty.all<Color?>(colorScheme.surface), | ||||
|       todayForegroundColor: | ||||
|           MaterialStateProperty.all<Color?>(colorScheme.primary), | ||||
|       todayBackgroundColor: | ||||
|           MaterialStateProperty.all<Color?>(colorScheme.primaryContainer), | ||||
|       yearForegroundColor: | ||||
|           MaterialStateProperty.all<Color?>(colorScheme.onSurface), | ||||
|       yearBackgroundColor: | ||||
|           MaterialStateProperty.all<Color?>(colorScheme.surface), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Page Transitions Theme | ||||
|   static PageTransitionsTheme _getPageTransitionsTheme() { | ||||
|     return const PageTransitionsTheme( | ||||
|       builders: { | ||||
|         TargetPlatform.android: CupertinoPageTransitionsBuilder(), | ||||
|         TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), | ||||
|         TargetPlatform.windows: CupertinoPageTransitionsBuilder(), | ||||
|         TargetPlatform.macOS: CupertinoPageTransitionsBuilder(), | ||||
|         TargetPlatform.linux: CupertinoPageTransitionsBuilder(), | ||||
|       }, | ||||
|     ); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										126
									
								
								base_project/lib/core/theme/color_scheme.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,126 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| 
 | ||||
| class AppColorScheme { | ||||
|   // Primary Colors - Modern Blue | ||||
|   static const Color _primaryLight = Color(0xFF2563EB); | ||||
|   static const Color _primaryDark = Color(0xFF3B82F6); | ||||
| 
 | ||||
|   // Secondary Colors - Purple | ||||
|   static const Color _secondaryLight = Color(0xFF7C3AED); | ||||
|   static const Color _secondaryDark = Color(0xFF8B5CF6); | ||||
| 
 | ||||
|   // Tertiary Colors - Teal | ||||
|   static const Color _tertiaryLight = Color(0xFF0D9488); | ||||
|   static const Color _tertiaryDark = Color(0xFF14B8A6); | ||||
| 
 | ||||
|   // Light Color Scheme | ||||
|   static const ColorScheme lightColorScheme = ColorScheme( | ||||
|     brightness: Brightness.light, | ||||
|     primary: _primaryLight, | ||||
|     onPrimary: Color(0xFFFFFFFF), | ||||
|     primaryContainer: Color(0xFFDBEAFE), | ||||
|     onPrimaryContainer: Color(0xFF001E3C), | ||||
|     secondary: _secondaryLight, | ||||
|     onSecondary: Color(0xFFFFFFFF), | ||||
|     secondaryContainer: Color(0xFFEDE9FE), | ||||
|     onSecondaryContainer: Color(0xFF21005D), | ||||
|     tertiary: _tertiaryLight, | ||||
|     onTertiary: Color(0xFFFFFFFF), | ||||
|     tertiaryContainer: Color(0xFFCCFBF1), | ||||
|     onTertiaryContainer: Color(0xFF00201C), | ||||
|     error: Color(0xFFDC2626), | ||||
|     onError: Color(0xFFFFFFFF), | ||||
|     errorContainer: Color(0xFFFEE2E2), | ||||
|     onErrorContainer: Color(0xFF7F1D1D), | ||||
|     background: Color(0xFFFAFAFA), | ||||
|     onBackground: Color(0xFF1A1A1A), | ||||
|     surface: Color(0xFFFFFFFF), | ||||
|     onSurface: Color(0xFF1A1A1A), | ||||
|     surfaceVariant: Color(0xFFF3F4F6), | ||||
|     onSurfaceVariant: Color(0xFF6B7280), | ||||
|     outline: Color(0xFFD1D5DB), | ||||
|     outlineVariant: Color(0xFFE5E7EB), | ||||
|     shadow: Color(0xFF000000), | ||||
|     scrim: Color(0xFF000000), | ||||
|     inverseSurface: Color(0xFF1F2937), | ||||
|     onInverseSurface: Color(0xFFF9FAFB), | ||||
|     inversePrimary: Color(0xFF93C5FD), | ||||
|     surfaceTint: _primaryLight, | ||||
|   ); | ||||
| 
 | ||||
|   // Dark Color Scheme | ||||
|   static const ColorScheme darkColorScheme = ColorScheme( | ||||
|     brightness: Brightness.dark, | ||||
|     primary: _primaryDark, | ||||
|     onPrimary: Color(0xFF000000), | ||||
|     primaryContainer: Color(0xFF1E3A8A), | ||||
|     onPrimaryContainer: Color(0xFFDBEAFE), | ||||
|     secondary: _secondaryDark, | ||||
|     onSecondary: Color(0xFF000000), | ||||
|     secondaryContainer: Color(0xFF4C1D95), | ||||
|     onSecondaryContainer: Color(0xFFEDE9FE), | ||||
|     tertiary: _tertiaryDark, | ||||
|     onTertiary: Color(0xFF000000), | ||||
|     tertiaryContainer: Color(0xFF0F766E), | ||||
|     onTertiaryContainer: Color(0xFFCCFBF1), | ||||
|     error: Color(0xFFEF4444), | ||||
|     onError: Color(0xFF000000), | ||||
|     errorContainer: Color(0xFF7F1D1D), | ||||
|     onErrorContainer: Color(0xFFFEE2E2), | ||||
|     background: Color(0xFF0F172A), | ||||
|     onBackground: Color(0xFFF8FAFC), | ||||
|     surface: Color(0xFF1E293B), | ||||
|     onSurface: Color(0xFFF8FAFC), | ||||
|     surfaceVariant: Color(0xFF334155), | ||||
|     onSurfaceVariant: Color(0xFFCBD5E1), | ||||
|     outline: Color(0xFF64748B), | ||||
|     outlineVariant: Color(0xFF475569), | ||||
|     shadow: Color(0xFF000000), | ||||
|     scrim: Color(0xFF000000), | ||||
|     inverseSurface: Color(0xFFF8FAFC), | ||||
|     onInverseSurface: Color(0xFF1E293B), | ||||
|     inversePrimary: Color(0xFF1E40AF), | ||||
|     surfaceTint: _primaryDark, | ||||
|   ); | ||||
| 
 | ||||
|   // Additional Custom Colors | ||||
|   static const Color success = Color(0xFF10B981); | ||||
|   static const Color warning = Color(0xFFF59E0B); | ||||
|   static const Color info = Color(0xFF3B82F6); | ||||
| 
 | ||||
|   // Convenience getters for commonly used colors | ||||
|   static Color get primary => _primaryLight; | ||||
|   static Color get secondary => _secondaryLight; | ||||
|   static Color get tertiary => _tertiaryLight; | ||||
|   static Color get error => Color(0xFFDC2626); | ||||
| 
 | ||||
|   // Gradient Colors | ||||
|   static const List<Color> primaryGradient = [ | ||||
|     Color(0xFF2563EB), | ||||
|     Color(0xFF1D4ED8), | ||||
|     Color(0xFF1E40AF), | ||||
|   ]; | ||||
| 
 | ||||
|   static const List<Color> secondaryGradient = [ | ||||
|     Color(0xFF7C3AED), | ||||
|     Color(0xFF6D28D9), | ||||
|     Color(0xFF5B21B6), | ||||
|   ]; | ||||
| 
 | ||||
|   static const List<Color> successGradient = [ | ||||
|     Color(0xFF10B981), | ||||
|     Color(0xFF059669), | ||||
|     Color(0xFF047857), | ||||
|   ]; | ||||
| 
 | ||||
|   static const List<Color> errorGradient = [ | ||||
|     Color(0xFFEF4444), | ||||
|     Color(0xFFDC2626), | ||||
|     Color(0xFFB91C1C), | ||||
|   ]; | ||||
| 
 | ||||
|   // Get color scheme based on brightness | ||||
|   static ColorScheme getColorScheme(Brightness brightness) { | ||||
|     return brightness == Brightness.dark ? darkColorScheme : lightColorScheme; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										355
									
								
								base_project/lib/core/theme/dynamic_color_scheme.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,355 @@ | ||||
| import 'dart:typed_data'; | ||||
| import 'dart:ui' as ui; | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:flutter/services.dart'; | ||||
| import 'package:palette_generator/palette_generator.dart'; | ||||
| 
 | ||||
| class DynamicColorScheme { | ||||
|   static const Color _defaultPrimary = Color(0xFF3C82FF); // lighter blue | ||||
|   static const Color _defaultSecondary = Color(0xFF7C3AED); | ||||
|   static const Color _defaultTertiary = Color(0xFF0D9488); | ||||
|   static const Color _defaultSurface = Color(0xFFFFFFFF); | ||||
|   static const Color _defaultBackground = Color(0xFFFAFAFA); | ||||
| 
 | ||||
|   // Extract dominant colors from logo image | ||||
|   static Future<List<Color>> extractColorsFromImage( | ||||
|       Uint8List imageBytes) async { | ||||
|     try { | ||||
|       // Convert bytes to image | ||||
|       final codec = await ui.instantiateImageCodec(imageBytes); | ||||
|       final frame = await codec.getNextFrame(); | ||||
|       final image = frame.image; | ||||
| 
 | ||||
|       // Generate palette from image | ||||
|       final paletteGenerator = await PaletteGenerator.fromImage(image); | ||||
| 
 | ||||
|       List<Color> colors = []; | ||||
| 
 | ||||
|       // Add dominant colors | ||||
|       if (paletteGenerator.dominantColor != null) { | ||||
|         colors.add(paletteGenerator.dominantColor!.color); | ||||
|       } | ||||
| 
 | ||||
|       // Add vibrant colors | ||||
|       if (paletteGenerator.vibrantColor != null) { | ||||
|         colors.add(paletteGenerator.vibrantColor!.color); | ||||
|       } | ||||
| 
 | ||||
|       // Add muted colors | ||||
|       if (paletteGenerator.mutedColor != null) { | ||||
|         colors.add(paletteGenerator.mutedColor!.color); | ||||
|       } | ||||
| 
 | ||||
|       // Add light vibrant colors | ||||
|       if (paletteGenerator.lightVibrantColor != null) { | ||||
|         colors.add(paletteGenerator.lightVibrantColor!.color); | ||||
|       } | ||||
| 
 | ||||
|       // Add dark vibrant colors | ||||
|       if (paletteGenerator.darkVibrantColor != null) { | ||||
|         colors.add(paletteGenerator.darkVibrantColor!.color); | ||||
|       } | ||||
| 
 | ||||
|       // Ensure we have at least 3 colors | ||||
|       while (colors.length < 3) { | ||||
|         colors.add(_generateComplementaryColor( | ||||
|             colors.isNotEmpty ? colors.first : _defaultPrimary)); | ||||
|       } | ||||
| 
 | ||||
|       return colors.take(5).toList(); // Return top 5 colors | ||||
|     } catch (e) { | ||||
|       print('Error extracting colors: $e'); | ||||
|       return [_defaultPrimary, _defaultSecondary, _defaultTertiary]; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Lightweight extraction using ImageProvider with downscaling to reduce jank | ||||
|   static Future<List<Color>> extractColorsFromBytesLite( | ||||
|       Uint8List imageBytes) async { | ||||
|     try { | ||||
|       final provider = MemoryImage(imageBytes); | ||||
|       // Downscale to limit processing cost | ||||
|       final resized = ResizeImage(provider, width: 256, height: 256); | ||||
| 
 | ||||
|       final paletteGenerator = | ||||
|           await PaletteGenerator.fromImageProvider(resized); | ||||
|       final List<Color> colors = []; | ||||
| 
 | ||||
|       if (paletteGenerator.dominantColor != null) { | ||||
|         colors.add(paletteGenerator.dominantColor!.color); | ||||
|       } | ||||
|       if (paletteGenerator.vibrantColor != null) { | ||||
|         colors.add(paletteGenerator.vibrantColor!.color); | ||||
|       } | ||||
|       if (paletteGenerator.mutedColor != null) { | ||||
|         colors.add(paletteGenerator.mutedColor!.color); | ||||
|       } | ||||
|       if (paletteGenerator.lightVibrantColor != null) { | ||||
|         colors.add(paletteGenerator.lightVibrantColor!.color); | ||||
|       } | ||||
|       if (paletteGenerator.darkVibrantColor != null) { | ||||
|         colors.add(paletteGenerator.darkVibrantColor!.color); | ||||
|       } | ||||
| 
 | ||||
|       while (colors.length < 3) { | ||||
|         colors.add(_generateComplementaryColor( | ||||
|             colors.isNotEmpty ? colors.first : _defaultPrimary)); | ||||
|       } | ||||
| 
 | ||||
|       return colors.take(5).toList(); | ||||
|     } catch (e) { | ||||
|       print('Error extracting colors (lite): $e'); | ||||
|       return [_defaultPrimary, _defaultSecondary, _defaultTertiary]; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Generate complementary color | ||||
|   static Color _generateComplementaryColor(Color baseColor) { | ||||
|     final hsl = HSLColor.fromColor(baseColor); | ||||
|     return hsl.withHue((hsl.hue + 180) % 360).toColor(); | ||||
|   } | ||||
| 
 | ||||
|   // Generate dynamic color scheme from logo colors | ||||
|   static ColorScheme generateDynamicColorScheme(List<Color> logoColors, | ||||
|       {bool isDark = false}) { | ||||
|     if (logoColors.isEmpty) { | ||||
|       return _getDefaultColorScheme(isDark); | ||||
|     } | ||||
| 
 | ||||
|     try { | ||||
|       // Extract primary, secondary, and tertiary colors | ||||
|       final primary = logoColors[0]; | ||||
|       final secondary = logoColors.length > 1 | ||||
|           ? logoColors[1] | ||||
|           : _generateComplementaryColor(primary); | ||||
|       final tertiary = logoColors.length > 2 | ||||
|           ? logoColors[2] | ||||
|           : _generateComplementaryColor(secondary); | ||||
| 
 | ||||
|       // Generate surface and background colors | ||||
|       final surface = | ||||
|           isDark ? _darkenColor(primary, 0.95) : _lightenColor(primary, 0.95); | ||||
|       final background = | ||||
|           isDark ? _darkenColor(primary, 0.98) : _lightenColor(primary, 0.98); | ||||
| 
 | ||||
|       // Generate on-surface and on-background colors | ||||
|       final onSurface = isDark ? Colors.white : Colors.black; | ||||
|       final onBackground = isDark ? Colors.white : Colors.black; | ||||
| 
 | ||||
|       // Generate outline and outline variant | ||||
|       final outline = | ||||
|           isDark ? _lightenColor(primary, 0.3) : _darkenColor(primary, 0.3); | ||||
|       final outlineVariant = | ||||
|           isDark ? _lightenColor(primary, 0.2) : _darkenColor(primary, 0.2); | ||||
| 
 | ||||
|       // Generate surface variant | ||||
|       final surfaceVariant = | ||||
|           isDark ? _darkenColor(primary, 0.9) : _lightenColor(primary, 0.9); | ||||
| 
 | ||||
|       // Generate error, warning, success, info colors | ||||
|       final error = isDark ? Color(0xFFF87171) : Color(0xFFEF4444); | ||||
|       final warning = isDark ? Color(0xFFFBBF24) : Color(0xFFF59E0B); | ||||
|       final success = isDark ? Color(0xFF34D399) : Color(0xFF10B981); | ||||
|       final info = isDark ? Color(0xFF60A5FA) : Color(0xFF3B82F6); | ||||
| 
 | ||||
|       return ColorScheme( | ||||
|         brightness: isDark ? Brightness.dark : Brightness.light, | ||||
|         primary: primary, | ||||
|         onPrimary: _getContrastColor(primary), | ||||
|         primaryContainer: _generateContainerColor(primary, isDark), | ||||
|         onPrimaryContainer: | ||||
|             _getContrastColor(_generateContainerColor(primary, isDark)), | ||||
|         secondary: secondary, | ||||
|         onSecondary: _getContrastColor(secondary), | ||||
|         secondaryContainer: _generateContainerColor(secondary, isDark), | ||||
|         onSecondaryContainer: | ||||
|             _getContrastColor(_generateContainerColor(secondary, isDark)), | ||||
|         tertiary: tertiary, | ||||
|         onTertiary: _getContrastColor(tertiary), | ||||
|         tertiaryContainer: _generateContainerColor(tertiary, isDark), | ||||
|         onTertiaryContainer: | ||||
|             _getContrastColor(_generateContainerColor(tertiary, isDark)), | ||||
|         surface: surface, | ||||
|         onSurface: onSurface, | ||||
|         surfaceVariant: surfaceVariant, | ||||
|         onSurfaceVariant: _getContrastColor(surfaceVariant), | ||||
|         background: background, | ||||
|         onBackground: onBackground, | ||||
|         outline: outline, | ||||
|         outlineVariant: outlineVariant, | ||||
|         error: error, | ||||
|         onError: _getContrastColor(error), | ||||
|         errorContainer: _generateContainerColor(error, isDark), | ||||
|         onErrorContainer: | ||||
|             _getContrastColor(_generateContainerColor(error, isDark)), | ||||
|         shadow: isDark ? Colors.black : Colors.black12, | ||||
|         scrim: isDark ? Colors.black54 : Colors.black26, | ||||
|         inverseSurface: isDark ? background : surface, | ||||
|         onInverseSurface: isDark ? onBackground : onSurface, | ||||
|         inversePrimary: | ||||
|             isDark ? _lightenColor(primary, 0.8) : _darkenColor(primary, 0.8), | ||||
|       ); | ||||
|     } catch (e) { | ||||
|       print('Error generating dynamic color scheme: $e'); | ||||
|       return _getDefaultColorScheme(isDark); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Get default color scheme | ||||
|   static ColorScheme _getDefaultColorScheme(bool isDark) { | ||||
|     if (isDark) { | ||||
|       return const ColorScheme.dark( | ||||
|         primary: Color(0xFF3B82F6), | ||||
|         secondary: Color(0xFF8B5CF6), | ||||
|         tertiary: Color(0xFF14B8A6), | ||||
|       ); | ||||
|     } else { | ||||
|       return const ColorScheme.light( | ||||
|         primary: Color(0xFF2563EB), | ||||
|         secondary: Color(0xFF7C3AED), | ||||
|         tertiary: Color(0xFF0D9488), | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Generate container color | ||||
|   static Color _generateContainerColor(Color baseColor, bool isDark) { | ||||
|     if (isDark) { | ||||
|       return _lightenColor(baseColor, 0.2); | ||||
|     } else { | ||||
|       return _darkenColor(baseColor, 0.9); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Lighten color | ||||
|   static Color _lightenColor(Color color, double amount) { | ||||
|     final hsl = HSLColor.fromColor(color); | ||||
|     return hsl | ||||
|         .withLightness((hsl.lightness + amount).clamp(0.0, 1.0)) | ||||
|         .toColor(); | ||||
|   } | ||||
| 
 | ||||
|   // Darken color | ||||
|   static Color _darkenColor(Color color, double amount) { | ||||
|     final hsl = HSLColor.fromColor(color); | ||||
|     return hsl | ||||
|         .withLightness((hsl.lightness - amount).clamp(0.0, 1.0)) | ||||
|         .toColor(); | ||||
|   } | ||||
| 
 | ||||
|   // Get contrast color (black or white) | ||||
|   static Color _getContrastColor(Color backgroundColor) { | ||||
|     final luminance = backgroundColor.computeLuminance(); | ||||
|     return luminance > 0.5 ? Colors.black : Colors.white; | ||||
|   } | ||||
| 
 | ||||
|   // Generate gradient colors from logo | ||||
|   static List<Color> generateGradientColors(List<Color> logoColors) { | ||||
|     if (logoColors.isEmpty) { | ||||
|       return [_defaultPrimary, _defaultSecondary, _defaultTertiary]; | ||||
|     } | ||||
| 
 | ||||
|     List<Color> gradientColors = []; | ||||
| 
 | ||||
|     // Add primary colors | ||||
|     gradientColors.addAll(logoColors.take(3)); | ||||
| 
 | ||||
|     // Generate complementary colors if needed | ||||
|     while (gradientColors.length < 3) { | ||||
|       final lastColor = gradientColors.last; | ||||
|       gradientColors.add(_generateComplementaryColor(lastColor)); | ||||
|     } | ||||
| 
 | ||||
|     return gradientColors; | ||||
|   } | ||||
| 
 | ||||
|   // Generate accent colors for specific UI elements | ||||
|   static Map<String, Color> generateAccentColors(List<Color> logoColors) { | ||||
|     if (logoColors.isEmpty) { | ||||
|       return { | ||||
|         'success': const Color(0xFF10B981), | ||||
|         'warning': const Color(0xFFF59E0B), | ||||
|         'error': const Color(0xFFEF4444), | ||||
|         'info': const Color(0xFF3B82F6), | ||||
|       }; | ||||
|     } | ||||
| 
 | ||||
|     final primary = logoColors[0]; | ||||
| 
 | ||||
|     return { | ||||
|       'success': _adjustColorForSuccess(primary), | ||||
|       'warning': _adjustColorForWarning(primary), | ||||
|       'error': _adjustColorForError(primary), | ||||
|       'info': _adjustColorForInfo(primary), | ||||
|     }; | ||||
|   } | ||||
| 
 | ||||
|   // Adjust colors for semantic meanings | ||||
|   static Color _adjustColorForSuccess(Color baseColor) { | ||||
|     final hsl = HSLColor.fromColor(baseColor); | ||||
|     return hsl.withHue(120).withSaturation(0.8).withLightness(0.5).toColor(); | ||||
|   } | ||||
| 
 | ||||
|   static Color _adjustColorForWarning(Color baseColor) { | ||||
|     final hsl = HSLColor.fromColor(baseColor); | ||||
|     return hsl.withHue(45).withSaturation(0.9).withLightness(0.6).toColor(); | ||||
|   } | ||||
| 
 | ||||
|   static Color _adjustColorForError(Color baseColor) { | ||||
|     final hsl = HSLColor.fromColor(baseColor); | ||||
|     return hsl.withHue(0).withSaturation(0.8).withLightness(0.5).toColor(); | ||||
|   } | ||||
| 
 | ||||
|   static Color _adjustColorForInfo(Color baseColor) { | ||||
|     final hsl = HSLColor.fromColor(baseColor); | ||||
|     return hsl.withHue(210).withSaturation(0.8).withLightness(0.5).toColor(); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Top-level helper to run in an isolate: returns list of color values (ints) | ||||
| Future<List<int>> extractColorValuesFromImageBytes(Uint8List imageBytes) async { | ||||
|   try { | ||||
|     // Convert bytes to image | ||||
|     final codec = await ui.instantiateImageCodec(imageBytes); | ||||
|     final frame = await codec.getNextFrame(); | ||||
|     final image = frame.image; | ||||
| 
 | ||||
|     // Generate palette from image | ||||
|     final paletteGenerator = await PaletteGenerator.fromImage(image); | ||||
| 
 | ||||
|     final List<int> values = []; | ||||
|     if (paletteGenerator.dominantColor != null) { | ||||
|       values.add(paletteGenerator.dominantColor!.color.value); | ||||
|     } | ||||
|     if (paletteGenerator.vibrantColor != null) { | ||||
|       values.add(paletteGenerator.vibrantColor!.color.value); | ||||
|     } | ||||
|     if (paletteGenerator.mutedColor != null) { | ||||
|       values.add(paletteGenerator.mutedColor!.color.value); | ||||
|     } | ||||
|     if (paletteGenerator.lightVibrantColor != null) { | ||||
|       values.add(paletteGenerator.lightVibrantColor!.color.value); | ||||
|     } | ||||
|     if (paletteGenerator.darkVibrantColor != null) { | ||||
|       values.add(paletteGenerator.darkVibrantColor!.color.value); | ||||
|     } | ||||
| 
 | ||||
|     while (values.length < 3) { | ||||
|       // Fallback complementary color generation using default primary | ||||
|       values.add(DynamicColorScheme._generateComplementaryColor( | ||||
|         values.isNotEmpty | ||||
|             ? Color(values.first) | ||||
|             : DynamicColorScheme._defaultPrimary, | ||||
|       ).value); | ||||
|     } | ||||
| 
 | ||||
|     return values.take(5).toList(); | ||||
|   } catch (e) { | ||||
|     // Fallback to defaults | ||||
|     return [ | ||||
|       DynamicColorScheme._defaultPrimary.value, | ||||
|       DynamicColorScheme._defaultSecondary.value, | ||||
|       DynamicColorScheme._defaultTertiary.value, | ||||
|     ]; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										277
									
								
								base_project/lib/core/theme/text_theme.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,277 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:google_fonts/google_fonts.dart'; | ||||
| 
 | ||||
| class AppTextTheme { | ||||
|   // Font Family | ||||
|   static const String _fontFamily = 'Inter'; | ||||
| 
 | ||||
|   // Light Text Theme | ||||
|   static TextTheme get lightTextTheme { | ||||
|     return GoogleFonts.interTextTheme().copyWith( | ||||
|       displayLarge: GoogleFonts.inter( | ||||
|         fontSize: 57, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         letterSpacing: -0.25, | ||||
|         height: 1.12, | ||||
|         color: const Color(0xFF1A1A1A), | ||||
|       ), | ||||
|       displayMedium: GoogleFonts.inter( | ||||
|         fontSize: 45, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         letterSpacing: 0, | ||||
|         height: 1.16, | ||||
|         color: const Color(0xFF1A1A1A), | ||||
|       ), | ||||
|       displaySmall: GoogleFonts.inter( | ||||
|         fontSize: 36, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         letterSpacing: 0, | ||||
|         height: 1.22, | ||||
|         color: const Color(0xFF1A1A1A), | ||||
|       ), | ||||
|       headlineLarge: GoogleFonts.inter( | ||||
|         fontSize: 32, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0, | ||||
|         height: 1.25, | ||||
|         color: const Color(0xFF1A1A1A), | ||||
|       ), | ||||
|       headlineMedium: GoogleFonts.inter( | ||||
|         fontSize: 28, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0, | ||||
|         height: 1.29, | ||||
|         color: const Color(0xFF1A1A1A), | ||||
|       ), | ||||
|       headlineSmall: GoogleFonts.inter( | ||||
|         fontSize: 24, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0, | ||||
|         height: 1.33, | ||||
|         color: const Color(0xFF1A1A1A), | ||||
|       ), | ||||
|       titleLarge: GoogleFonts.inter( | ||||
|         fontSize: 22, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0, | ||||
|         height: 1.27, | ||||
|         color: const Color(0xFF1A1A1A), | ||||
|       ), | ||||
|       titleMedium: GoogleFonts.inter( | ||||
|         fontSize: 16, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0.15, | ||||
|         height: 1.5, | ||||
|         color: const Color(0xFF1A1A1A), | ||||
|       ), | ||||
|       titleSmall: GoogleFonts.inter( | ||||
|         fontSize: 14, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0.1, | ||||
|         height: 1.43, | ||||
|         color: const Color(0xFF1A1A1A), | ||||
|       ), | ||||
|       labelLarge: GoogleFonts.inter( | ||||
|         fontSize: 14, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0.1, | ||||
|         height: 1.43, | ||||
|         color: const Color(0xFF1A1A1A), | ||||
|       ), | ||||
|       labelMedium: GoogleFonts.inter( | ||||
|         fontSize: 12, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0.5, | ||||
|         height: 1.33, | ||||
|         color: const Color(0xFF1A1A1A), | ||||
|       ), | ||||
|       labelSmall: GoogleFonts.inter( | ||||
|         fontSize: 11, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0.5, | ||||
|         height: 1.45, | ||||
|         color: const Color(0xFF1A1A1A), | ||||
|       ), | ||||
|       bodyLarge: GoogleFonts.inter( | ||||
|         fontSize: 16, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         letterSpacing: 0.5, | ||||
|         height: 1.5, | ||||
|         color: const Color(0xFF1A1A1A), | ||||
|       ), | ||||
|       bodyMedium: GoogleFonts.inter( | ||||
|         fontSize: 14, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         letterSpacing: 0.25, | ||||
|         height: 1.43, | ||||
|         color: const Color(0xFF1A1A1A), | ||||
|       ), | ||||
|       bodySmall: GoogleFonts.inter( | ||||
|         fontSize: 12, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         letterSpacing: 0.4, | ||||
|         height: 1.33, | ||||
|         color: const Color(0xFF6B7280), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Dark Text Theme | ||||
|   static TextTheme get darkTextTheme { | ||||
|     return GoogleFonts.interTextTheme().copyWith( | ||||
|       displayLarge: GoogleFonts.inter( | ||||
|         fontSize: 57, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         letterSpacing: -0.25, | ||||
|         height: 1.12, | ||||
|         color: const Color(0xFFF8FAFC), | ||||
|       ), | ||||
|       displayMedium: GoogleFonts.inter( | ||||
|         fontSize: 45, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         letterSpacing: 0, | ||||
|         height: 1.16, | ||||
|         color: const Color(0xFFF8FAFC), | ||||
|       ), | ||||
|       displaySmall: GoogleFonts.inter( | ||||
|         fontSize: 36, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         letterSpacing: 0, | ||||
|         height: 1.22, | ||||
|         color: const Color(0xFFF8FAFC), | ||||
|       ), | ||||
|       headlineLarge: GoogleFonts.inter( | ||||
|         fontSize: 32, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0, | ||||
|         height: 1.25, | ||||
|         color: const Color(0xFFF8FAFC), | ||||
|       ), | ||||
|       headlineMedium: GoogleFonts.inter( | ||||
|         fontSize: 28, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0, | ||||
|         height: 1.29, | ||||
|         color: const Color(0xFFF8FAFC), | ||||
|       ), | ||||
|       headlineSmall: GoogleFonts.inter( | ||||
|         fontSize: 24, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0, | ||||
|         height: 1.33, | ||||
|         color: const Color(0xFFF8FAFC), | ||||
|       ), | ||||
|       titleLarge: GoogleFonts.inter( | ||||
|         fontSize: 22, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0, | ||||
|         height: 1.27, | ||||
|         color: const Color(0xFFF8FAFC), | ||||
|       ), | ||||
|       titleMedium: GoogleFonts.inter( | ||||
|         fontSize: 16, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0.15, | ||||
|         height: 1.5, | ||||
|         color: const Color(0xFFF8FAFC), | ||||
|       ), | ||||
|       titleSmall: GoogleFonts.inter( | ||||
|         fontSize: 14, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0.1, | ||||
|         height: 1.43, | ||||
|         color: const Color(0xFFF8FAFC), | ||||
|       ), | ||||
|       labelLarge: GoogleFonts.inter( | ||||
|         fontSize: 14, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0.1, | ||||
|         height: 1.43, | ||||
|         color: const Color(0xFFF8FAFC), | ||||
|       ), | ||||
|       labelMedium: GoogleFonts.inter( | ||||
|         fontSize: 12, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0.5, | ||||
|         height: 1.33, | ||||
|         color: const Color(0xFFF8FAFC), | ||||
|       ), | ||||
|       labelSmall: GoogleFonts.inter( | ||||
|         fontSize: 11, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0.5, | ||||
|         height: 1.45, | ||||
|         color: const Color(0xFFF8FAFC), | ||||
|       ), | ||||
|       bodyLarge: GoogleFonts.inter( | ||||
|         fontSize: 16, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         letterSpacing: 0.5, | ||||
|         height: 1.5, | ||||
|         color: const Color(0xFFF8FAFC), | ||||
|       ), | ||||
|       bodyMedium: GoogleFonts.inter( | ||||
|         fontSize: 14, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         letterSpacing: 0.25, | ||||
|         height: 1.43, | ||||
|         color: const Color(0xFFF8FAFC), | ||||
|       ), | ||||
|       bodySmall: GoogleFonts.inter( | ||||
|         fontSize: 12, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         letterSpacing: 0.4, | ||||
|         height: 1.33, | ||||
|         color: const Color(0xFFCBD5E1), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Custom Text Styles for specific use cases | ||||
|   static TextStyle get heroTitle => GoogleFonts.inter( | ||||
|         fontSize: 48, | ||||
|         fontWeight: FontWeight.w700, | ||||
|         letterSpacing: -0.5, | ||||
|         height: 1.1, | ||||
|       ); | ||||
| 
 | ||||
|   static TextStyle get sectionTitle => GoogleFonts.inter( | ||||
|         fontSize: 20, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0, | ||||
|         height: 1.4, | ||||
|       ); | ||||
| 
 | ||||
|   static TextStyle get cardTitle => GoogleFonts.inter( | ||||
|         fontSize: 18, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0, | ||||
|         height: 1.33, | ||||
|       ); | ||||
| 
 | ||||
|   static TextStyle get buttonText => GoogleFonts.inter( | ||||
|         fontSize: 16, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 0.1, | ||||
|         height: 1.5, | ||||
|       ); | ||||
| 
 | ||||
|   static TextStyle get caption => GoogleFonts.inter( | ||||
|         fontSize: 12, | ||||
|         fontWeight: FontWeight.w400, | ||||
|         letterSpacing: 0.4, | ||||
|         height: 1.33, | ||||
|       ); | ||||
| 
 | ||||
|   static TextStyle get overline => GoogleFonts.inter( | ||||
|         fontSize: 10, | ||||
|         fontWeight: FontWeight.w600, | ||||
|         letterSpacing: 1.5, | ||||
|         height: 1.6, | ||||
|       ); | ||||
| 
 | ||||
|   // Get text theme based on brightness | ||||
|   static TextTheme getTextTheme(Brightness brightness) { | ||||
|     return brightness == Brightness.dark ? darkTextTheme : lightTextTheme; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										16
									
								
								base_project/lib/core/utils/date_time_utils.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,16 @@ | ||||
| import 'package:intl/date_symbol_data_local.dart'; | ||||
| import 'package:intl/intl.dart'; | ||||
| 
 | ||||
| const String dateTimeFormatPattern = 'dd/MM/yyyy'; | ||||
| 
 | ||||
| extension DateTimeExtension on DateTime { | ||||
|   String format({ | ||||
|     String pattern = dateTimeFormatPattern, | ||||
|     String? locale, | ||||
|   }) { | ||||
|     if (locale != null && locale.isNotEmpty) { | ||||
|       initializeDateFormatting(locale); | ||||
|     } | ||||
|     return DateFormat(pattern, locale).format(this); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										93
									
								
								base_project/lib/core/utils/size_utils.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,93 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| // These are the Viewport values of your Figma Design. | ||||
| 
 | ||||
| // These are used in the code as a reference to create your UI Responsively. | ||||
| const num FIGMA_DESIGN_WIDTH = 428; | ||||
| const num FIGMA_DESIGN_HEIGHT = 926; | ||||
| const num FIGMA_DESIGN_STATUS_BAR = 0; | ||||
| 
 | ||||
| extension ResponsiveExtension on num { | ||||
|   double get _width => SizeUtils.width; | ||||
|   double get _height => SizeUtils.height; | ||||
|   double get h => ((this * _width) / FIGMA_DESIGN_WIDTH); | ||||
|   double get v => | ||||
|       (this * _height) / (FIGMA_DESIGN_HEIGHT - FIGMA_DESIGN_STATUS_BAR); | ||||
|   double get adaptSize { | ||||
|     var height = v; | ||||
|     var width = h; | ||||
|     return height < width ? height.toDoubleValue() : width.toDoubleValue(); | ||||
|   } | ||||
| 
 | ||||
|   double get fSize => adaptSize; | ||||
| } | ||||
| 
 | ||||
| extension FormatExtension on double { | ||||
|   double toDoubleValue({int fractionDigits = 2}) { | ||||
|     return double.parse(toStringAsFixed(fractionDigits)); | ||||
|   } | ||||
| 
 | ||||
|   double isNonZero({num defaultValue = 0.0}) { | ||||
|     return this > 0 ? this : defaultValue.toDouble(); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| enum DeviceType { mobile, tablet, desktop } | ||||
| 
 | ||||
| typedef ResponsiveBuild = Widget Function( | ||||
|     BuildContext context, Orientation orientation, DeviceType deviceType); | ||||
| 
 | ||||
| class Sizer extends StatelessWidget { | ||||
|   const Sizer({super.key, required this.builder}); | ||||
| 
 | ||||
|   /// Builds the widget whenever the orientation changes. | ||||
|   final ResponsiveBuild builder; | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return LayoutBuilder(builder: (context, constraints) { | ||||
|       return OrientationBuilder(builder: (context, orientation) { | ||||
|         SizeUtils.setScreenSize(constraints, orientation); | ||||
|         return builder(context, orientation, SizeUtils.deviceType); | ||||
|       }); | ||||
|     }); | ||||
|   } | ||||
| } | ||||
| // ignore_for_file: must_be_immutable | ||||
| 
 | ||||
| // ignore_for_file: must_be_immutable | ||||
| class SizeUtils { | ||||
|   /// Device's BoxConstraints | ||||
|   static late BoxConstraints boxConstraints; | ||||
| 
 | ||||
|   /// Device's Orientation | ||||
|   static late Orientation orientation; | ||||
| 
 | ||||
|   /// Type of Device | ||||
|   /// | ||||
|   /// This can either be mobile or tablet | ||||
|   static late DeviceType deviceType; | ||||
| 
 | ||||
|   /// Device's Height | ||||
|   static late double height; | ||||
| 
 | ||||
|   /// Device's Width | ||||
|   static late double width; | ||||
| 
 | ||||
|   static void setScreenSize( | ||||
|     BoxConstraints constraints, | ||||
|     Orientation currentOrientation, | ||||
|   ) { | ||||
|     boxConstraints = constraints; | ||||
|     orientation = currentOrientation; | ||||
|     if (orientation == Orientation.portrait) { | ||||
|       width = | ||||
|           boxConstraints.maxWidth.isNonZero(defaultValue: FIGMA_DESIGN_WIDTH); | ||||
|       height = boxConstraints.maxHeight.isNonZero(); | ||||
|     } else { | ||||
|       width = | ||||
|           boxConstraints.maxHeight.isNonZero(defaultValue: FIGMA_DESIGN_WIDTH); | ||||
|       height = boxConstraints.maxWidth.isNonZero(); | ||||
|     } | ||||
|     deviceType = DeviceType.mobile; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										13
									
								
								base_project/lib/core/utils/validation_functions.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,13 @@ | ||||
| bool isValidEmail(String? inputString, {bool isRequired = false}) { | ||||
|   bool isInputStringValid = false; | ||||
|   if (!isRequired && (inputString == null ? true : inputString.isEmpty)) { | ||||
|     isInputStringValid = true; | ||||
|   } | ||||
|   if (inputString != null && inputString.isNotEmpty) { | ||||
|     const pattern = | ||||
|         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,}))$'; | ||||
|     final regExp = RegExp(pattern); | ||||
|     isInputStringValid = regExp.hasMatch(inputString); | ||||
|   } | ||||
|   return isInputStringValid; | ||||
| } | ||||
							
								
								
									
										81
									
								
								base_project/lib/data/exceptions/app_exceptions.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,81 @@ | ||||
| class AppExceptions implements Exception { | ||||
|   final String? _message; | ||||
|   final String? _prefix; | ||||
| 
 | ||||
|   AppExceptions([this._message, this._prefix]); | ||||
| 
 | ||||
|   @override | ||||
|   String toString() { | ||||
|     return "${_prefix ?? ''}${_message ?? 'An unknown error occurred'}"; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // Network error when data fetch fails | ||||
| class FetchDataException extends AppExceptions { | ||||
|   FetchDataException([String? message]) | ||||
|       : super(message ?? "Network Error: Failed to communicate with the server. Please check your internet connection and try again.",  | ||||
|               "Error During Communication: "); | ||||
| } | ||||
| 
 | ||||
| // Error for invalid or malformed requests | ||||
| class BadRequestException extends AppExceptions { | ||||
|   BadRequestException([String? message]) | ||||
|       : super(message ?? "Client Error: The request sent to the server was malformed or contained invalid parameters.",  | ||||
|               "Invalid Request: "); | ||||
| } | ||||
| 
 | ||||
| // Error for unauthorized access | ||||
| class UnauthorizedException extends AppExceptions { | ||||
|   UnauthorizedException([String? message]) | ||||
|       : super(message ?? "Authorization Error: You are not authorized to perform this action. Please log in with appropriate credentials.",  | ||||
|               "Unauthorized: "); | ||||
| } | ||||
| 
 | ||||
| // Error when a resource is not found | ||||
| class NotFoundException extends AppExceptions { | ||||
|   NotFoundException([String? message]) | ||||
|       : super(message ?? "Resource Not Found: The requested resource could not be found on the server. It may have been moved or deleted.",  | ||||
|               "Not Found: "); | ||||
| } | ||||
| 
 | ||||
| // Error for server-side issues | ||||
| class InternalServerErrorException extends AppExceptions { | ||||
|   InternalServerErrorException([String? message]) | ||||
|       : super(message ?? "Server Error: An unexpected error occurred on the server. Please try again later or contact support.",  | ||||
|               "Internal Server Error: "); | ||||
| } | ||||
| 
 | ||||
| // Error when user input is invalid | ||||
| class InvalidInputException extends AppExceptions { | ||||
|   InvalidInputException([String? message]) | ||||
|       : super(message ?? "Validation Error: The provided input does not match the required format. Please correct the errors and try again.",  | ||||
|               "Invalid Input: "); | ||||
| } | ||||
| 
 | ||||
| // Error when a request times out | ||||
| class TimeoutException extends AppExceptions { | ||||
|   TimeoutException([String? message]) | ||||
|       : super(message ?? "Request Timeout: The server took too long to respond. Please check your connection and try again.",  | ||||
|               "Timeout: "); | ||||
| } | ||||
| 
 | ||||
| // Error when a request conflicts with the current state | ||||
| class ConflictException extends AppExceptions { | ||||
|   ConflictException([String? message]) | ||||
|       : super(message ?? "Conflict Error: The request could not be processed because of a conflict with the current state of the resource.",  | ||||
|               "Conflict: "); | ||||
| } | ||||
| 
 | ||||
| // Error when the service is unavailable | ||||
| class ServiceUnavailableException extends AppExceptions { | ||||
|   ServiceUnavailableException([String? message]) | ||||
|       : super(message ?? "Service Unavailable: The server is currently unable to handle the request. Please try again later.",  | ||||
|               "Service Unavailable: "); | ||||
| } | ||||
| 
 | ||||
| // Error when access to a resource is forbidden | ||||
| class ForbiddenException extends AppExceptions { | ||||
|   ForbiddenException([String? message]) | ||||
|       : super(message ?? "Forbidden: You do not have the necessary permissions to access this resource.",  | ||||
|               "Forbidden: "); | ||||
| } | ||||
							
								
								
									
										7
									
								
								base_project/lib/data/network/base_network_service.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,7 @@ | ||||
| abstract class BaseNetworkService { | ||||
|   Future<dynamic> getGetApiResponse(String? url); | ||||
|   Future<dynamic> getPostApiResponse(String? url, dynamic body); | ||||
|   Future<dynamic> getPutApiResponse(String? url, dynamic body); | ||||
| 
 | ||||
|   Future<dynamic> getDeleteApiResponse(String? url); | ||||
| } | ||||