commit e3ea8335d1f7fc4ab970870a93641a1b73c02257 Author: Abdullah Salah Date: Thu Dec 26 09:05:13 2024 +0300 First Commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..29a3a50 --- /dev/null +++ b/.gitignore @@ -0,0 +1,43 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +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 diff --git a/.metadata b/.metadata new file mode 100644 index 0000000..ce66da9 --- /dev/null +++ b/.metadata @@ -0,0 +1,30 @@ +# 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: "4cf269e36de2573851eaef3c763994f8f9be494d" + channel: "stable" + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 4cf269e36de2573851eaef3c763994f8f9be494d + base_revision: 4cf269e36de2573851eaef3c763994f8f9be494d + - platform: android + create_revision: 4cf269e36de2573851eaef3c763994f8f9be494d + base_revision: 4cf269e36de2573851eaef3c763994f8f9be494d + + # 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' diff --git a/README.md b/README.md new file mode 100644 index 0000000..9f7ecd9 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# baligh + +A new Flutter project. diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000..f9b3034 --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1 @@ +include: package:flutter_lints/flutter.yaml diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..55afd91 --- /dev/null +++ b/android/.gitignore @@ -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 diff --git a/android/app/build.gradle b/android/app/build.gradle new file mode 100644 index 0000000..c3b55d1 --- /dev/null +++ b/android/app/build.gradle @@ -0,0 +1,74 @@ +plugins { + id "com.android.application" + // START: FlutterFire Configuration + id 'com.google.gms.google-services' + // END: FlutterFire Configuration + id "kotlin-android" + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id "dev.flutter.flutter-gradle-plugin" +} + +def keystoreProperties = new Properties() +def keystorePropertiesFile = rootProject.file('key.properties') +if (keystorePropertiesFile.exists()) { + keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) +} + +android { + namespace = "iq.go.baligh" + 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 = "iq.go.baligh" + // You can update the following values to match your application needs. + // For more information, see: https://flutter.dev/to/review-gradle-config. + minSdk = 23 + targetSdk = flutter.targetSdkVersion + versionCode = flutter.versionCode + versionName = flutter.versionName + } + + signingConfigs { + debug { + storeFile file('../../debug-keystore.jks') + storePassword 'debug1234' + keyAlias 'debug' + keyPassword 'debug1234' + } + + release { + keyAlias = keystoreProperties['keyAlias'] + keyPassword = keystoreProperties['keyPassword'] + storeFile = keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null + storePassword = keystoreProperties['storePassword'] + } + } + + buildTypes { + debug { + signingConfig = signingConfigs.debug + } + + 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 + signingConfig = signingConfigs.release + } + } +} + +flutter { + source = "../.." +} diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 0000000..62b50d1 --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,29 @@ +{ + "project_info": { + "project_number": "580708075572", + "project_id": "baligh-fbef7", + "storage_bucket": "baligh-fbef7.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:580708075572:android:5ea21c31d74dd8df702261", + "android_client_info": { + "package_name": "iq.go.baligh" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyARwxtYXHm4VrZBrXzKbE7NZd2B_l7xVnY" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..b20afa3 --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/kotlin/com/example/baligh/MainActivity.kt b/android/app/src/main/kotlin/com/example/baligh/MainActivity.kt new file mode 100644 index 0000000..f52ccff --- /dev/null +++ b/android/app/src/main/kotlin/com/example/baligh/MainActivity.kt @@ -0,0 +1,5 @@ +package iq.go.baligh + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() diff --git a/android/app/src/main/res/drawable-v21/launch_background.xml b/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..f74085f --- /dev/null +++ b/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..db77bb4 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..17987b7 Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..09d4391 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..d5f1c8d Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..4d6372e Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/values-night/styles.xml b/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..06952be --- /dev/null +++ b/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..cb1ef88 --- /dev/null +++ b/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 0000000..d2ffbff --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,18 @@ +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 +} diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 0000000..2597170 --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError +android.useAndroidX=true +android.enableJetifier=true diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..7bb2df6 --- /dev/null +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -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 diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000..9759a22 --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1,28 @@ +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.1.0" apply false + // START: FlutterFire Configuration + id "com.google.gms.google-services" version "4.3.15" apply false + // END: FlutterFire Configuration + id "org.jetbrains.kotlin.android" version "1.8.22" apply false +} + +include ":app" diff --git a/assets/fonts/Cairo-Bold.ttf b/assets/fonts/Cairo-Bold.ttf new file mode 100644 index 0000000..098d2fb Binary files /dev/null and b/assets/fonts/Cairo-Bold.ttf differ diff --git a/assets/fonts/Cairo-Light.ttf b/assets/fonts/Cairo-Light.ttf new file mode 100644 index 0000000..3c40958 Binary files /dev/null and b/assets/fonts/Cairo-Light.ttf differ diff --git a/assets/fonts/Cairo-Medium.ttf b/assets/fonts/Cairo-Medium.ttf new file mode 100644 index 0000000..38d2834 Binary files /dev/null and b/assets/fonts/Cairo-Medium.ttf differ diff --git a/assets/fonts/Cairo-Regular.ttf b/assets/fonts/Cairo-Regular.ttf new file mode 100644 index 0000000..fb9e6cc Binary files /dev/null and b/assets/fonts/Cairo-Regular.ttf differ diff --git a/assets/fonts/Cairo-SemiBold.ttf b/assets/fonts/Cairo-SemiBold.ttf new file mode 100644 index 0000000..e2b82ba Binary files /dev/null and b/assets/fonts/Cairo-SemiBold.ttf differ diff --git a/debug-keystore.jks b/debug-keystore.jks new file mode 100644 index 0000000..8e44c3e Binary files /dev/null and b/debug-keystore.jks differ diff --git a/firebase.json b/firebase.json new file mode 100644 index 0000000..0692d69 --- /dev/null +++ b/firebase.json @@ -0,0 +1 @@ +{"flutter":{"platforms":{"android":{"default":{"projectId":"baligh-fbef7","appId":"1:580708075572:android:5ea21c31d74dd8df702261","fileOutput":"android/app/google-services.json"}},"dart":{"lib/firebase_options.dart":{"projectId":"baligh-fbef7","configurations":{"android":"1:580708075572:android:5ea21c31d74dd8df702261","ios":"1:580708075572:ios:943aa5f67d6d3c13702261"}}}}}} \ No newline at end of file diff --git a/ios/.gitignore b/ios/.gitignore new file mode 100644 index 0000000..7a7f987 --- /dev/null +++ b/ios/.gitignore @@ -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 diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..7c56964 --- /dev/null +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 12.0 + + diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..1b3a1de --- /dev/null +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -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 = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 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 = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 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 = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* 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 = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 331C8082294A63A400263BE5 /* RunnerTests */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + 331C8081294A63A400263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 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 = ""; + }; +/* 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 = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* 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.baligh; + 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.baligh.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.baligh.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.baligh.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.baligh; + 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.baligh; + 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 */; +} diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..8e3ca5d --- /dev/null +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..6266644 --- /dev/null +++ b/ios/Runner/AppDelegate.swift @@ -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) + } +} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -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" + } +} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000..dc9ada4 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..7353c41 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..797d452 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..6ed2d93 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..4cd7b00 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..fe73094 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..321773c Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..797d452 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..502f463 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..0ec3034 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..0ec3034 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..e9f5fea Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..84ac32a Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..8953cba Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..0467bf1 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -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" + } +} diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -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. \ No newline at end of file diff --git a/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist new file mode 100644 index 0000000..1f8780c --- /dev/null +++ b/ios/Runner/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Baligh + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + baligh + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + CADisableMinimumFrameDurationOnPhone + + UIApplicationSupportsIndirectInputEvents + + + diff --git a/ios/Runner/Runner-Bridging-Header.h b/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/ios/RunnerTests/RunnerTests.swift b/ios/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..86a7c3b --- /dev/null +++ b/ios/RunnerTests/RunnerTests.swift @@ -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. + } + +} diff --git a/lib/constants/theme.dart b/lib/constants/theme.dart new file mode 100644 index 0000000..784fb6a --- /dev/null +++ b/lib/constants/theme.dart @@ -0,0 +1,66 @@ +import 'package:flutter/material.dart'; + +class MyCustomTheme { + static Color primaryColor = const Color.fromARGB(255, 42, 61, 171); + static Color cardColor = const Color(0xFFECECEC); + static Color textColor = const Color(0xFF181818); + static Color bgColor = const Color(0xFFF8FAFC); + static Color dividerColor = const Color(0xFF4C4C4C); + + static ThemeData theme = ThemeData( + primaryColor: primaryColor, + useMaterial3: true, + cardColor: cardColor, + scaffoldBackgroundColor: bgColor, + dividerColor: dividerColor, + textTheme: TextTheme( + headlineLarge: TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + fontFamily: "Cairo", + color: textColor, + ), + titleLarge: TextStyle( + fontSize: 22, + fontWeight: FontWeight.w500, + fontFamily: "Cairo", + color: textColor, + ), + bodyLarge: TextStyle( + fontSize: 18, + fontWeight: FontWeight.normal, + fontFamily: "Cairo", + color: textColor, + ), + bodyMedium: TextStyle( + fontSize: 16, + fontWeight: FontWeight.normal, + fontFamily: "Cairo", + color: textColor, + ), + bodySmall: TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + fontFamily: "Cairo", + color: textColor, + ), + ), + elevatedButtonTheme: ElevatedButtonThemeData( + style: ButtonStyle( + elevation: const WidgetStatePropertyAll(0), + backgroundColor: WidgetStatePropertyAll(primaryColor), + shape: WidgetStatePropertyAll( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + )), + outlinedButtonTheme: OutlinedButtonThemeData( + style: ButtonStyle( + elevation: const WidgetStatePropertyAll(0), + shape: WidgetStatePropertyAll(RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + )), + )), + ); +} diff --git a/lib/firebase_options.dart b/lib/firebase_options.dart new file mode 100644 index 0000000..6d5cb55 --- /dev/null +++ b/lib/firebase_options.dart @@ -0,0 +1,69 @@ +// File generated by FlutterFire CLI. +// ignore_for_file: type=lint +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' + show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Default [FirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatform, +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for web - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return android; + case TargetPlatform.iOS: + return ios; + case TargetPlatform.macOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for macos - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.windows: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for windows - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } + + static const FirebaseOptions android = FirebaseOptions( + apiKey: 'AIzaSyARwxtYXHm4VrZBrXzKbE7NZd2B_l7xVnY', + appId: '1:580708075572:android:5ea21c31d74dd8df702261', + messagingSenderId: '580708075572', + projectId: 'baligh-fbef7', + storageBucket: 'baligh-fbef7.appspot.com', + ); + + static const FirebaseOptions ios = FirebaseOptions( + apiKey: 'AIzaSyAFcUZ2wYeY6R9o5WaqFzKDcYVUmICjRPE', + appId: '1:580708075572:ios:943aa5f67d6d3c13702261', + messagingSenderId: '580708075572', + projectId: 'baligh-fbef7', + storageBucket: 'baligh-fbef7.appspot.com', + iosBundleId: 'com.example.baligh', + ); + +} \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart new file mode 100644 index 0000000..44b4718 --- /dev/null +++ b/lib/main.dart @@ -0,0 +1,38 @@ +import 'package:baligh/constants/theme.dart'; +import 'package:baligh/screens/home_screen.dart'; +import 'package:baligh/screens/login_screen.dart'; +import 'package:bot_toast/bot_toast.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter/material.dart'; + +import 'firebase_options.dart'; + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + + + runApp(const MainApp()); +} + +class MainApp extends StatelessWidget { + const MainApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'بلغ', + debugShowCheckedModeBanner: false, + theme: MyCustomTheme.theme, + locale: const Locale("ar"), + builder: BotToastInit(), + home: FirebaseAuth.instance.currentUser == null + ? const LoginScreen() + : const HomeScreen(), + ); + } +} diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart new file mode 100644 index 0000000..20f2246 --- /dev/null +++ b/lib/screens/home_screen.dart @@ -0,0 +1,81 @@ +import 'package:baligh/screens/profile_screen.dart'; +import 'package:baligh/widgets/baligh_card.dart'; +import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; + +class HomeScreen extends StatefulWidget { + const HomeScreen({super.key}); + + @override + State createState() => _HomeScreenState(); +} + +class _HomeScreenState extends State { + @override + Widget build(BuildContext context) { + return Directionality( + textDirection: TextDirection.rtl, + child: Scaffold( + appBar: AppBar( + centerTitle: true, + title: Text( + "البلاغات", + style: Theme.of(context).textTheme.headlineLarge, + ), + backgroundColor: Colors.transparent, + actions: [ + Padding( + padding: const EdgeInsets.only(left: 6), + child: IconButton( + onPressed: () { + Navigator.push(context, (MaterialPageRoute(builder: (context) { + return const ProfileScreen(); + }))); + }, + icon: const Icon(FontAwesomeIcons.user), + ), + ), + ], + ), + body: SafeArea( + child: GridView( + padding: const EdgeInsets.all(15), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + mainAxisSpacing: 10, + crossAxisSpacing: 10, + childAspectRatio: 1, + ), + children: [ + BlighCard( + icon: FontAwesomeIcons.unlock, + label: "الابتزاز", + iconColor: Colors.grey[700] ?? Colors.grey, + ), + const BlighCard( + icon: FontAwesomeIcons.pills, + label: "المخدرات", + iconColor: Colors.pink, + ), + const BlighCard( + icon: FontAwesomeIcons.person, + label: "التحرش", + iconColor: Colors.purple, + ), + BlighCard( + icon: FontAwesomeIcons.moneyBill, + label: "الرشوة", + iconColor: Colors.green[700] ?? Colors.green, + ), + BlighCard( + icon: FontAwesomeIcons.handFist, + label: "التعنيف", + iconColor: Colors.yellow[700] ?? Colors.yellow, + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/screens/login_screen.dart b/lib/screens/login_screen.dart new file mode 100644 index 0000000..47e2c22 --- /dev/null +++ b/lib/screens/login_screen.dart @@ -0,0 +1,112 @@ +import 'package:baligh/screens/otp_screen.dart'; +import 'package:baligh/widgets/app_toast.dart'; +import 'package:baligh/widgets/custom_button.dart'; +import 'package:baligh/widgets/custom_text_field.dart'; +import 'package:bot_toast/bot_toast.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; + +class LoginScreen extends StatefulWidget { + const LoginScreen({super.key}); + + @override + State createState() => _LoginScreenState(); +} + +class _LoginScreenState extends State { + TextEditingController phoneNumberController = TextEditingController(); + + bool isLoading = false; + + @override + void dispose() { + phoneNumberController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Directionality( + textDirection: TextDirection.rtl, + child: Scaffold( + body: SafeArea( + child: ListView( + padding: const EdgeInsets.all(15), + children: [ + const SizedBox( + height: 150, + ), + Text( + "تسجيل الدخول", + style: Theme.of(context).textTheme.headlineLarge, + ), + const SizedBox( + height: 50, + ), + CustomTextField( + controller: phoneNumberController, + labelText: "رقم الهاتف", + inputType: TextInputType.phone), + const SizedBox( + height: 15, + ), + CustomButton( + label: "تسجيل الدخول", + isElevated: true, + onPressed: handleLogIn, + isLoading: isLoading, + ), + ], + ), + ), + ), + ); + } + + Future handleLogIn() async { + if (phoneNumberController.text.isEmpty) { + BotToast.showCustomText(toastBuilder: (_) { + return const AppToast(text: "يجب ملئ جميع الحقول"); + }); + } + + setState(() { + isLoading = true; + }); + + try { + await FirebaseAuth.instance.verifyPhoneNumber( + phoneNumber: "+964${phoneNumberController.text.trim()}", + verificationCompleted: (PhoneAuthCredential credential) {}, + verificationFailed: (FirebaseAuthException e) { + setState(() { + isLoading = false; + }); + BotToast.showCustomText(toastBuilder: (_) { + return const AppToast(text: "حدث خطأ ما"); + }); + }, + codeSent: (String verificationId, int? resendToken) { + setState(() { + isLoading = false; + }); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => OtpScreen( + verificationId: verificationId, + )), + ); + }, + codeAutoRetrievalTimeout: (String verificationId) {}, + ); + } catch (e) { + setState(() { + isLoading = false; + }); + BotToast.showCustomText(toastBuilder: (_) { + return const AppToast(text: "حدث خطأ ما"); + }); + } + } +} diff --git a/lib/screens/otp_screen.dart b/lib/screens/otp_screen.dart new file mode 100644 index 0000000..d12f54c --- /dev/null +++ b/lib/screens/otp_screen.dart @@ -0,0 +1,140 @@ +import 'package:baligh/screens/home_screen.dart'; +import 'package:baligh/screens/register_screen.dart'; +import 'package:baligh/widgets/app_toast.dart'; +import 'package:baligh/widgets/custom_button.dart'; +import 'package:bot_toast/bot_toast.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:pinput/pinput.dart'; + +class OtpScreen extends StatefulWidget { + const OtpScreen({ + super.key, + required this.verificationId, + }); + + final String verificationId; + + @override + State createState() => _OtpScreenState(); +} + +class _OtpScreenState extends State { + TextEditingController otpController = TextEditingController(); + + bool isLoading = false; + + @override + void dispose() { + otpController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Directionality( + textDirection: TextDirection.rtl, + child: Scaffold( + appBar: AppBar(), + body: ListView( + padding: const EdgeInsets.all(15), + children: [ + const SizedBox( + height: 80, + ), + Text( + "تأكيد رقم الهاتف", + style: Theme.of(context).textTheme.headlineLarge, + ), + const SizedBox( + height: 10, + ), + Text( + "قمنا بإرسال رمز التحقق اليك ادخل رمز التحقق لتأكيد رقم هاتفك", + style: Theme.of(context).textTheme.bodyMedium, + ), + const SizedBox( + height: 50, + ), + Directionality( + textDirection: TextDirection.ltr, + child: Pinput( + controller: otpController, + length: 6, + autofocus: true, + defaultPinTheme: PinTheme( + width: 56, + height: 56, + textStyle: Theme.of(context) + .textTheme + .bodyLarge + ?.copyWith(fontSize: 20), + decoration: BoxDecoration( + color: const Color(0xFFECECEC), + borderRadius: BorderRadius.circular(10), + ), + ), + separatorBuilder: (index) => const SizedBox(width: 5), + ), + ), + const SizedBox( + height: 20, + ), + CustomButton( + label: "تأكيد رثم الهاتف", + isElevated: true, + onPressed: handleSendOtp, + isLoading: isLoading, + ), + ], + ), + )); + } + + Future handleSendOtp() async { + if (otpController.text.isEmpty) { + BotToast.showCustomText(toastBuilder: (_) { + return const AppToast(text: "يجب ملئ جميع الحقول"); + }); + } + + setState(() { + isLoading = true; + }); + + try { + // Create a PhoneAuthCredential with the code + PhoneAuthCredential credential = PhoneAuthProvider.credential( + verificationId: widget.verificationId, + smsCode: otpController.text.trim()); + + // Sign the user in (or link) with the credential + UserCredential userCredential = + await FirebaseAuth.instance.signInWithCredential(credential); + + setState(() { + isLoading = false; + }); + + if (!mounted) return; + if (userCredential.additionalUserInfo?.isNewUser != true) { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => const HomeScreen()), + ); + } else { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => const RegisterScreen()), + ); + } + } catch (e) { + setState(() { + isLoading = false; + }); + BotToast.showCustomText(toastBuilder: (_) { + return const AppToast(text: "حدث خطأ ما"); + }); + } + } +} diff --git a/lib/screens/profile_screen.dart b/lib/screens/profile_screen.dart new file mode 100644 index 0000000..55ec33b --- /dev/null +++ b/lib/screens/profile_screen.dart @@ -0,0 +1,144 @@ +import 'package:baligh/screens/login_screen.dart'; +import 'package:baligh/widgets/app_toast.dart'; +import 'package:baligh/widgets/custom_button.dart'; +import 'package:bot_toast/bot_toast.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; + +enum ProfileState { loading, error, loaded } + +class ProfileScreen extends StatefulWidget { + const ProfileScreen({super.key}); + + @override + State createState() => _ProfileScreenState(); +} + +class _ProfileScreenState extends State { + ProfileState _profileState = ProfileState.loading; + Map? _userData; + + bool isLogOutLoading = false; + + @override + void initState() { + super.initState(); + _loadUserData(); + } + + @override + Widget build(BuildContext context) { + return Directionality( + textDirection: TextDirection.rtl, + child: Scaffold( + appBar: AppBar( + centerTitle: true, + title: Text( + "المعلومات الشخصية", + style: Theme.of(context).textTheme.headlineLarge, + ), + backgroundColor: Colors.transparent, + ), + body: SafeArea( + child: Padding( + padding: const EdgeInsets.all(15), + child: _buildContent(), + ), + ), + ), + ); + } + + Future _loadUserData() async { + setState(() { + _profileState = ProfileState.loading; + }); + try { + final user = FirebaseAuth.instance.currentUser; + if (user == null) { + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (context) => const LoginScreen()), + (x) => false); + } + + // get user data from firestore in a coolection called 'users' + final userData = await FirebaseFirestore.instance + .collection('users') + .doc(user!.uid) + .get(); + + setState(() { + _userData = userData.data(); + _profileState = ProfileState.loaded; + }); + } catch (e) { + setState(() { + _profileState = ProfileState.error; + }); + } + } + + Future logOut() async { + setState(() { + isLogOutLoading = true; + }); + try { + await FirebaseAuth.instance.signOut(); + + setState(() { + isLogOutLoading = false; + }); + + if (!mounted) return; + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (context) => const LoginScreen()), + (x) => false); + } catch (e) { + setState(() { + isLogOutLoading = false; + }); + BotToast.showCustomText(toastBuilder: (_) { + return const AppToast(text: "حدث خطأ ما"); + }); + } + } + + Widget _buildContent() { + switch (_profileState) { + case ProfileState.loading: + return const CircularProgressIndicator(); + case ProfileState.error: + return const Text("حدث خطأ ما"); + case ProfileState.loaded: + return ListView( + children: [ + Text('الاسم: ${_userData!['name']}'), + const SizedBox(height: 5), + Text('رقم الهاتف: 0${_userData!['phone'].toString().split("+964").last}'), + const SizedBox(height: 5), + Text('العمر: ${_userData!['age']}'), + const SizedBox(height: 5), + Text('رقم البطاقة الوطنية: ${_userData!['nationalIdNumber']}'), + const SizedBox(height: 5), + Text('المدرسة: ${_userData!['schoolName']}'), + const SizedBox(height: 5), + Text('المرحلة الدراسية: ${_userData!['stage']}'), + const SizedBox(height: 5), + Text('العنوان: ${_userData!['address']}'), + const SizedBox(height: 20), + CustomButton( + label: "تسجيل الخروج", + isElevated: true, + onPressed: logOut, + isLoading: isLogOutLoading, + ), + ], + ); + default: + return const SizedBox.shrink(); + } + } +} diff --git a/lib/screens/register_screen.dart b/lib/screens/register_screen.dart new file mode 100644 index 0000000..02cd2cb --- /dev/null +++ b/lib/screens/register_screen.dart @@ -0,0 +1,173 @@ +import 'package:baligh/screens/home_screen.dart'; +import 'package:baligh/widgets/app_toast.dart'; +import 'package:baligh/widgets/custom_button.dart'; +import 'package:baligh/widgets/custom_text_field.dart'; +import 'package:bot_toast/bot_toast.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; + +class RegisterScreen extends StatefulWidget { + const RegisterScreen({super.key}); + + @override + State createState() => _RegisterScreenState(); +} + +class _RegisterScreenState extends State { + TextEditingController fullNameController = TextEditingController(); + TextEditingController ageController = TextEditingController(); + TextEditingController schoolNameController = TextEditingController(); + TextEditingController stageController = TextEditingController(); + TextEditingController addressController = TextEditingController(); + TextEditingController nationalIdNumberController = TextEditingController(); + + bool isLoading = false; + + @override + void dispose() { + fullNameController.dispose(); + ageController.dispose(); + schoolNameController.dispose(); + stageController.dispose(); + addressController.dispose(); + nationalIdNumberController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Directionality( + textDirection: TextDirection.rtl, + child: Scaffold( + appBar: AppBar(), + body: SafeArea( + child: ListView( + padding: const EdgeInsets.all(15), + children: [ + const SizedBox( + height: 30, + ), + Text( + "انشاء حساب", + style: Theme.of(context).textTheme.headlineLarge, + ), + const SizedBox( + height: 30, + ), + CustomTextField( + controller: fullNameController, + labelText: "الاسم الثلاثي", + inputType: TextInputType.text), + const SizedBox( + height: 10, + ), + CustomTextField( + controller: ageController, + labelText: "العمر", + inputType: TextInputType.number), + const SizedBox( + height: 10, + ), + CustomTextField( + controller: schoolNameController, + labelText: "اسم المدرسة", + inputType: TextInputType.text), + const SizedBox( + height: 10, + ), + CustomTextField( + controller: stageController, + labelText: "المرحلة الدراسية", + inputType: TextInputType.text), + const SizedBox( + height: 10, + ), + CustomTextField( + controller: addressController, + labelText: "عنوان السكن", + inputType: TextInputType.text), + const SizedBox( + height: 10, + ), + CustomTextField( + controller: nationalIdNumberController, + labelText: "رقم البطاقة الوطنية الموحدة", + inputType: TextInputType.number), + const SizedBox( + height: 10, + ), + CustomButton( + label: "انشاء حساب", + isElevated: true, + onPressed: handleRegister, + isLoading: isLoading, + ), + ], + ), + ), + ), + ); + } + + Future handleRegister() async { + if (fullNameController.text.trim().isEmpty || + ageController.text.trim().isEmpty || + schoolNameController.text.trim().isEmpty || + stageController.text.trim().isEmpty || + addressController.text.trim().isEmpty || + nationalIdNumberController.text.trim().isEmpty) { + BotToast.showCustomText(toastBuilder: (_) { + return const AppToast(text: "يجب ملئ جميع الحقول"); + }); + } + + setState(() { + isLoading = true; + }); + + try { + final auth = FirebaseAuth.instance; + + await auth.currentUser?.updateDisplayName(fullNameController.text.trim()); + + if (FirebaseAuth.instance.currentUser?.uid == null) { + setState(() { + isLoading = false; + }); + BotToast.showCustomText(toastBuilder: (_) { + return const AppToast(text: "حدث خطأ ما"); + }); + } + + await FirebaseFirestore.instance + .collection('users').doc(FirebaseAuth.instance.currentUser?.uid ?? "").set({ + 'uid': FirebaseAuth.instance.currentUser?.uid ?? "", + 'name': fullNameController.text.trim(), + 'phone': FirebaseAuth.instance.currentUser?.phoneNumber ?? "", + 'age': int.parse(ageController.text.trim()), + 'schoolName': schoolNameController.text.trim(), + 'stage': stageController.text.trim(), + 'address': addressController.text.trim(), + 'nationalIdNumber': int.parse(nationalIdNumberController.text.trim()), + 'createdAt': FieldValue.serverTimestamp(), + }); + + setState(() { + isLoading = false; + }); + if (!mounted) return; + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute(builder: (context) => const HomeScreen()), + (x) => false); + } catch (e) { + setState(() { + isLoading = false; + }); + BotToast.showCustomText(toastBuilder: (_) { + return const AppToast(text: "حدث خطأ ما"); + }); + } + } +} diff --git a/lib/screens/report_screen.dart b/lib/screens/report_screen.dart new file mode 100644 index 0000000..85d7ec0 --- /dev/null +++ b/lib/screens/report_screen.dart @@ -0,0 +1,384 @@ +import 'dart:io'; +import 'dart:math'; + +import 'package:badges/badges.dart' as badges; +import 'package:baligh/screens/success_screen.dart'; +import 'package:baligh/widgets/app_toast.dart'; +import 'package:baligh/widgets/custom_button.dart'; +import 'package:baligh/widgets/custom_text_field.dart'; +import 'package:bot_toast/bot_toast.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:file_picker/file_picker.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:firebase_storage/firebase_storage.dart'; +import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; + +class ReportScreen extends StatefulWidget { + const ReportScreen({ + super.key, + required this.headerText, + }); + + final String headerText; + + @override + State createState() => _ReportScreenState(); +} + +class _ReportScreenState extends State { + TextEditingController descriptionController = TextEditingController(); + + bool isLoading = false; + + bool isExpanded = false; + + List images = []; + List videos = []; + List audios = []; + + String explnationText() { + return widget.headerText == "التحرش" + ? """ +التحرش هو أي تصرف أو قول غير مرغوب فيه يتعلق بالجنس أو الجنسية، ويهدف إلى إزعاج الشخص الآخر أو تهديده. يمكن أن يحدث التحرش في أماكن العمل، المدارس، الأماكن العامة، أو عبر وسائل التواصل الاجتماعي. يمكن أن يكون التحرش لفظيًا (مثل التعليقات الجنسية)، جسديًا (مثل اللمس غير المناسب)، أو بصريًا (مثل عرض صور غير لائقة). + +حقوق المبلغ عن حالة تحرش: + الحماية: على المبلغ أن يشعر بالأمان خلال وبعد تقديم البلاغ. لا يتعرض لأي تهديدات أو انتقادات بسبب تقديمه للبلاغ. + + السرية: يتم التعامل مع المعلومات بسرية، إلا إذا كانت هناك حاجة للكشف عنها في إطار التحقيق أو الإجراءات القانونية. + + التحقق العادل: يتم التحقيق في البلاغ بموضوعية وبدون تحيز. للشخص المبلغ الحق في معرفة نتائج التحقيق. + عدم الانتقام: الشخص الذي يبلغ عن التحرش محميًا من أي شكل من أشكال الانتقام أو التمييز بسبب البلاغ. + +التوجيه والمساعدة: يحق للمبلغ الحصول على استشارات قانونية، نفسية، أو أي نوع من المساعدة يحتاجها خلال هذه العملية. + """ + : widget.headerText == "التعنيف" + ? """ +التعنيف هو مصطلح يشير إلى استخدام القوة أو العنف ضد شخص آخر بشكل يتسبب له في أذى جسدي أو نفسي أو عاطفي. يمكن أن يحدث التعنيف في عدة سياقات، مثل العلاقات الشخصية، الأسرة، مكان العمل، أو المجتمع بشكل عام يتمتع الشخص المبلغ ضد التعنيف بما يلي 1. الحماية: للشخص المعنف الحق في الحصول على حماية فورية من الجاني، سواء عبر الأوامر القانونية مثل أوامر الحماية، أو من خلال الدعم من الشرطة والجهات المعنية. + +2. الأمان: يحق للشخص المعنف العيش في بيئة آمنة خالية من التهديدات والعنف. يمكن أن يتضمن ذلك توفير أماكن إيواء أو دعم لتغيير مكان الإقامة إذا لزم الأمر. + +3. الرعاية الصحية: يجب أن يحصل الشخص المعنف على الرعاية الطبية اللازمة لعلاج الإصابات الجسدية والنفسية الناتجة عن العنف. + +4. الدعم النفسي: يحق للأشخاص المعنفين الحصول على مشورة ودعم نفسي للتعامل مع الصدمات النفسية والعاطفية التي قد يواجهونها. + +5. المشورة القانونية: يجب أن يكون الشخص المعنف قادرًا على الحصول على مشورة قانونية حول حقوقه، الخيارات القانونية المتاحة، وكيفية تقديم الشكاوى. + +6. عدم التمييز: لا يتعرض الشخص المعنف للتمييز أو الانتقاص من حقوقه بسبب تعرضه للعنف، ويجب أن يتم التعامل معه بكرامة واحترام. + +7.الخصوصية: يجب الحفاظ على سرية المعلومات الشخصية للشخص المعنف، وعدم الكشف عنها دون إذنه. + """ + : widget.headerText == "المخدرات" + ? """ + المخدرات هي مواد كيميائية تؤثر على الجهاز العصبي المركزي، وقد تؤدي إلى تغييرات في السلوك، المزاج، والإدراك. الكوكايين، الهيروين، والماريجوانا. + +الأضرار المحتملة للمخدرات: +1. الصحة الجسدية: يمكن أن تؤدي إلى مشكلات صحية خطيرة مثل أمراض القلب، الكبد، والمشاكل التنفسية. +2. الصحة النفسية: قد تسبب اضطرابات مثل الاكتئاب، القلق، أو الاضطرابات النفسية الأخرى. +3. الاعتبارات الاجتماعية: يمكن أن تؤدي إلى مشكلات في العلاقات الشخصية، العمل، والمجتمع بشكل عام. +حقوق الشخص المبلغ عن المخدرات +إذا كنتَ أو كنتِ تبلغون عن مشكلة تتعلق بالمخدرات، لديكَ حقوق يجب أن تُحترم: + +1. الحماية: تكون محميًا من أي شكل من أشكال الانتقام أو الضرر نتيجة تقديم البلاغ. +يمكن أن يشمل ذلك حماية من الجاني أو من أي طرف آخر قد يسعى للإضرار بك. +2. السرية: الحفاظ على سرية هويتك ومعلوماتك الشخصية خلال عملية التحقيق. +لا ينبغي الكشف عن تفاصيل البلاغ دون موافقتك، إلا في حال كانت هناك ضرورة قانونية لذلك. +3. التحقق العادل: يتم التحقيق في البلاغ بموضوعية ونزاهة، مع ضمان أن يتم التعامل مع كل الأطراف بشكل عادل. +4. التوجيه والمساعدة: +الحصول على المشورة القانونية والمساعدة في حال كنت تحتاجين إليها خلال عملية البلاغ. +يمكن أن يتضمن ذلك مشورة حول كيفية حماية نفسك وضمان حقوقك القانونية. +5. عدم التمييز: +لا تتعرض للتمييز أو العقوبات بسبب تقديمك للبلاغ. + يُعامل كل من يقدم البلاغ بكرامة واحترام. + """ + : widget.headerText == "الرشوة" + ? """ +الرشوة هي جريمة تحدث عندما يقدم شخص ما أو يستلم مكافأة أو مالًا بشكل غير قانوني مقابل تأثيره على سلوك أو قرار معين في إطار عمله أو منصبه. تُعتبر الرشوة جريمة جنائية في معظم القوانين حول العالم. + +إذا قام شخص بتقديم بلاغ عن جريمة رشوة، فإن هناك حقوقاً معينة يتمتع بها، +حماية هوية المبلغ: الشخص الذي يقدم البلاغ قد يتمتع بحماية هويته للحفاظ على أمانه وسلامته، خاصة إذا كان هناك خطر من الانتقام. + +1. الحماية من الانتقام: توجد قوانين تحمي المبلغين عن الفساد والرشوة من أي انتقام قد يتعرضون له في مكان العمل أو من قبل المتورطين في الرشوة. + +2. السرية: البلاغات عن الرشوة يتم التعامل معها بسرية تامة، ولا يتم الكشف عن التفاصيل إلا للجهات المختصة. + +3. التعويض: في بعض الحالات، يكون للمبلغ الحق في الحصول على تعويض مالي أو مكافأة إذا ساهم بلاغه في كشف جريمة رشوة أو فساد كبير. + +4. الحماية القانونية: إذا تم تقديم البلاغ بحسن نية وثبتت صحة الاتهامات، فإن المبلغ يتمتع بحماية قانونية من الملاحقة القضائية أو الاتهام الزائف. + """ + : widget.headerText == "الابتزاز" + ? """ +الابتزاز : جريمة تنطوي على تهديد شخص ما بهدف إجباره على تقديم مال أو خدمات أو القيام بشيء ما ضد إرادته. يعتبر الابتزاز من الجرائم الخطيرة التي يعاقب عليها القانون، سواء كان الابتزاز مادياً أو معنوياً. + +الشخص الذي يقدم بلاغًا عن حالة ابتزاز يتمتع بحقوق معينة لحمايته وضمان عدم تعرضه للضرر. : + +1. حماية الهوية: +يتمتع الشخص المبلغ بحقه في الحفاظ على سرية هويته، خاصة في الحالات التي قد يتعرض فيها للخطر أو الانتقام من الجاني. +2. الحماية من الانتقام: +القوانين تحمي المبلغين عن الابتزاز من أي نوع من الانتقام أو الأذى الذي قد يتعرضون له بسبب تقديمهم للبلاغ. . +3. السرية: +، يتم التعامل مع بلاغات الابتزاز بسرية تامة. السلطات تحافظ على سرية المعلومات لضمان حماية المبلغ وسلامة التحقيق. +4. التعويض: + قد يكون للمبلغ الحق في الحصول على تعويض إذا تسبب الابتزاز في خسائر مادية أو معنوية. كما يمكن أن تفرض المحكمة على الجاني دفع تعويضات للضحايا. +5. الحماية القانونية: +الشخص الذي يبلغ عن الابتزاز يكون محمياً قانونيًا إذا تم البلاغ بحسن نية. لا يمكن ملاحقته قانونياً أو توجيه تهم ضده بسبب تقديم البلاغ. +6. المساعدة النفسية والاجتماعية: + تقدم خدمات دعم نفسي واجتماعي للمبلغين عن الابتزاز، خاصة إذا كانت الجريمة قد تسببت في صدمة نفسية أو توتر عاطفي. +8. الإبلاغ عن الابتزاز الرقمي: +في حالة الابتزاز الإلكتروني (مثل التهديد بنشر صور أو معلومات شخصية)، يتمتع المبلغ بحقوق مماثلة ويجب أن تكون السلطات قادرة على تعقب الجناة واتخاذ الإجراءات القانونية ضدهم. + """ + : ""; + } + + @override + void dispose() { + descriptionController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Directionality( + textDirection: TextDirection.rtl, + child: Scaffold( + appBar: AppBar( + centerTitle: true, + title: Text( + widget.headerText, + style: Theme.of(context).textTheme.headlineLarge, + ), + backgroundColor: Colors.transparent, + ), + body: SafeArea( + child: ListView( + padding: const EdgeInsets.all(15), + children: [ + const SizedBox( + height: 50, + ), + ExpansionPanelList( + elevation: 0, + expandedHeaderPadding: EdgeInsets.zero, + expansionCallback: (index, isOpen) { + setState(() { + isExpanded = isOpen; + }); + }, + children: [ + ExpansionPanel( + backgroundColor: Colors.transparent, + isExpanded: isExpanded, + canTapOnHeader: true, + headerBuilder: (context, isOpen) => Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + "شرح توضيحي البلاغ", + style: Theme.of(context).textTheme.bodyLarge, + ), + ], + ), + body: Column( + children: [ + Text( + explnationText(), + style: Theme.of(context).textTheme.bodyMedium, + ), + ], + )), + ], + ), + const SizedBox( + height: 30, + ), + CustomTextField( + controller: descriptionController, + labelText: "قم بوصف الحالة", + inputType: TextInputType.text), + const SizedBox( + height: 15, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + IconButton( + onPressed: handleAddImage, + icon: images.isEmpty + ? Icon(FontAwesomeIcons.image, color: Colors.blue[800]) + : badges.Badge( + badgeContent: Text( + images.length.toString(), + style: Theme.of(context) + .textTheme + .bodySmall + ?.copyWith(color: Colors.white), + ), + child: Icon(FontAwesomeIcons.image, + color: Colors.blue[800]), + ), + ), + IconButton( + onPressed: handleAddVideo, + icon: videos.isEmpty + ? const Icon( + FontAwesomeIcons.video, + color: Colors.red, + ) + : badges.Badge( + badgeContent: Text( + videos.length.toString(), + style: Theme.of(context) + .textTheme + .bodySmall + ?.copyWith(color: Colors.white), + ), + child: const Icon( + FontAwesomeIcons.video, + color: Colors.red, + ), + ), + ), + IconButton( + onPressed: handleAddAudio, + icon: audios.isEmpty + ? Icon( + FontAwesomeIcons.microphone, + color: Colors.purple[300], + ) + : badges.Badge( + badgeContent: Text( + audios.length.toString(), + style: Theme.of(context) + .textTheme + .bodySmall + ?.copyWith(color: Colors.white), + ), + child: Icon( + FontAwesomeIcons.microphone, + color: Colors.purple[300], + ), + ), + ), + ], + ), + const SizedBox( + height: 15, + ), + CustomButton( + label: "ارسال", + isElevated: true, + onPressed: handleSendReport, + isLoading: isLoading, + ), + const SizedBox( + height: 20, + ), + ], + ), + ), + ), + ); + } + + Future handleAddImage() async { + FilePickerResult? result = await FilePicker.platform.pickFiles( + allowMultiple: true, + type: FileType.image, + ); + + if (result != null) { + for (var el in result.files) { + setState(() { + images.add(File(el.path ?? "")); + }); + } + } + } + + Future handleAddVideo() async { + FilePickerResult? result = await FilePicker.platform + .pickFiles(allowMultiple: true, type: FileType.video); + + if (result != null) { + for (var el in result.files) { + setState(() { + videos.add(File(el.path ?? "")); + }); + } + } + } + + Future handleAddAudio() async { + FilePickerResult? result = await FilePicker.platform + .pickFiles(allowMultiple: true, type: FileType.video); + + if (result != null) { + for (var el in result.files) { + setState(() { + audios.add(File(el.path ?? "")); + }); + } + } + } + + Future handleSendReport() async { + setState(() { + isLoading = true; + }); + try { + final storageRef = FirebaseStorage.instance.ref(); + List attachments = []; + + Future uploadImage(List files, String folder) async { + for (var el in files) { + final filePath = + '${el.path.split('.').first}_${Random().nextInt(99999)}.${el.path.split('.').last}'; + + final ref = storageRef.child("$folder/$filePath"); + final uploadTask = ref.putFile(el); // Upload the file + + final snapshot = await uploadTask + .whenComplete(() {}); // Wait for upload completion + + final downloadUrl = + await snapshot.ref.getDownloadURL(); // Get download URL + + attachments.add(downloadUrl); + } + } + + await uploadImage(images, "images"); + await uploadImage(videos, "videos"); + await uploadImage(audios, "audios"); + + DocumentReference userRef = FirebaseFirestore.instance + .collection('users') + .doc(FirebaseAuth.instance.currentUser?.uid); + + await FirebaseFirestore.instance.collection('reports').add({ + 'userRef': userRef, + 'userId': FirebaseAuth.instance.currentUser?.uid, + 'type': widget.headerText, + 'description': descriptionController.text.trim(), + 'attachments': attachments, + 'status': "قيد الانتظار", + 'createdAt': FieldValue.serverTimestamp(), + }); + + setState(() { + isLoading = false; + }); + + if (!mounted) return; + Navigator.push(context, + MaterialPageRoute(builder: (context) => const SuccessScreen())); + } catch (e) { + setState(() { + isLoading = false; + }); + BotToast.showCustomText(toastBuilder: (_) { + return const AppToast(text: "حدث خطأ ما"); + }); + } + } +} diff --git a/lib/screens/success_screen.dart b/lib/screens/success_screen.dart new file mode 100644 index 0000000..6382338 --- /dev/null +++ b/lib/screens/success_screen.dart @@ -0,0 +1,46 @@ +import 'package:baligh/screens/home_screen.dart'; +import 'package:flutter/material.dart'; + +class SuccessScreen extends StatelessWidget { + const SuccessScreen({super.key}); + + @override + Widget build(BuildContext context) { + return Directionality( + textDirection: TextDirection.rtl, + child: Scaffold( + body: SafeArea( + child: ListView( + padding: const EdgeInsets.all(15), + children: [ + const SizedBox(height: 100,), + Icon(Icons.done_outline_rounded, size: 85, color: Colors.blue[600],), + const SizedBox(height: 50,), + Text( + "تم ارسال البلاغ", + style: Theme.of(context).textTheme.titleLarge, + ), + const SizedBox(height: 20,), + Text( + "تم ارسال بلاغك بنجاح و ستتم مراجعته من قبل الجهات المعنية باقرب وقت", + style: Theme.of(context).textTheme.bodyMedium, + ), + const SizedBox(height: 40,), + ElevatedButton( + onPressed: () { + Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => const HomeScreen()), (x) => false); + }, + child: Text( + "العودة الى صفحة البلاغات", + style: Theme.of(context) + .textTheme + .bodyLarge + ?.copyWith(color: Colors.white), + )), + ], + ), + ), + ) + ); + } +} diff --git a/lib/widgets/app_toast.dart b/lib/widgets/app_toast.dart new file mode 100644 index 0000000..a7cbf8f --- /dev/null +++ b/lib/widgets/app_toast.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; + +class AppToast extends StatelessWidget { + const AppToast({ + super.key, + required this.text, + this.bottomPadding, + this.color, + this.textStyle, + }); + + final String text; + final double? bottomPadding; + final Color? color; + final TextStyle? textStyle; + + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsets.only(bottom: bottomPadding ?? 100), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: color ?? Theme.of(context).scaffoldBackgroundColor, + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.4), + offset: const Offset(2, 2), + blurRadius: 5, + spreadRadius: 1 + ) + ] + ), + child: Text( + text, + style: textStyle ?? Theme.of(context).textTheme.bodyMedium, + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/widgets/baligh_card.dart b/lib/widgets/baligh_card.dart new file mode 100644 index 0000000..7074e6e --- /dev/null +++ b/lib/widgets/baligh_card.dart @@ -0,0 +1,73 @@ +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:baligh/screens/report_screen.dart'; +import 'package:flutter/material.dart'; + +class BlighCard extends StatelessWidget { + const BlighCard({ + super.key, + required this.icon, + required this.label, + required this.iconColor, + }); + + final IconData icon; + final String label; + final Color iconColor; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => ReportScreen( + headerText: label, + ))); + }, + child: Column( + children: [ + Expanded( + child: Container( + width: double.infinity, + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Theme.of(context).cardColor, + borderRadius: const BorderRadius.all(Radius.circular(12)), + ), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 10, vertical: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Center( + child: SizedBox( + height: MediaQuery.sizeOf(context).width * 0.2, + child: Icon( + icon, + size: 45, + color: iconColor, + ), + ), + ), + AutoSizeText( + label, + maxLines: 2, + minFontSize: 10, + maxFontSize: 18, + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.bodyLarge, + ), + ], + ), + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/widgets/custom_button.dart b/lib/widgets/custom_button.dart new file mode 100644 index 0000000..e465cf9 --- /dev/null +++ b/lib/widgets/custom_button.dart @@ -0,0 +1,86 @@ +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:baligh/constants/theme.dart'; +import 'package:baligh/widgets/small_spinner.dart'; +import 'package:flutter/material.dart'; + +class CustomButton extends StatelessWidget { + const CustomButton({ + super.key, + required this.onPressed, + required this.label, + required this.isElevated, + this.isLoading = false, + this.textStyle, + this.color, + }); + + final void Function() onPressed; + final String label; + final bool isLoading; + final bool isElevated; + final TextStyle? textStyle; + final Color? color; + + @override + Widget build(BuildContext context) { + return isElevated + ? ElevatedButton( + onPressed: isLoading ? null : onPressed, + style: Theme.of(context).elevatedButtonTheme.style?.copyWith( + backgroundColor: WidgetStatePropertyAll(color ?? MyCustomTheme.primaryColor) + ), + child: isLoading + ? const SmallSpinner() + : Padding( + padding: const EdgeInsets.symmetric(horizontal: 3), + child: Row( + children: [ + Expanded( + child: AutoSizeText( + label, + minFontSize: 8, + maxFontSize: 14, + maxLines: 1, + textAlign: TextAlign.center, + style: textStyle ?? Theme.of(context).textTheme.bodyLarge?.copyWith( + color: MyCustomTheme.bgColor, + ) + ), + ), + ], + ), + ), + ) + : OutlinedButton( + onPressed: isLoading ? null : onPressed, + style: Theme.of(context).elevatedButtonTheme.style?.copyWith( + backgroundColor: WidgetStatePropertyAll(Theme.of(context).scaffoldBackgroundColor), + side: WidgetStatePropertyAll(BorderSide( + width: 1.5, + color: color ?? MyCustomTheme.primaryColor, + )) + ), + child: isLoading + ? SmallSpinner(color: MyCustomTheme.primaryColor,) + : Padding( + padding: const EdgeInsets.symmetric(horizontal: 3), + child: Row( + children: [ + Expanded( + child: AutoSizeText( + label, + minFontSize: 8, + maxFontSize: 14, + maxLines: 1, + textAlign: TextAlign.center, + style: textStyle ?? Theme.of(context).textTheme.bodyLarge?.copyWith( + color: color ?? MyCustomTheme.primaryColor, + ) + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/widgets/custom_text_field.dart b/lib/widgets/custom_text_field.dart new file mode 100644 index 0000000..a247340 --- /dev/null +++ b/lib/widgets/custom_text_field.dart @@ -0,0 +1,77 @@ +import 'package:flutter/material.dart'; + +class CustomTextField extends StatefulWidget { + const CustomTextField({ + super.key, + required this.controller, + required this.labelText, + required this.inputType, + this.errorText, + this.isPassword = false, + this.maxLines = 1, + this.focusNode, + }); + + final TextEditingController controller; + final String labelText; + final TextInputType inputType; + final String? errorText; + final bool isPassword; + final int maxLines; + final FocusNode? focusNode; + + @override + State createState() => _CustomTextFieldState(); +} + +class _CustomTextFieldState extends State { + + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + return TextField( + controller: widget.controller, + focusNode: widget.focusNode, + keyboardType: widget.inputType, + obscureText: widget.isPassword, + enableSuggestions: !widget.isPassword, + autocorrect: false, + maxLines: widget.maxLines, + textDirection: TextDirection.rtl, + style: Theme.of(context).textTheme.bodyMedium, + decoration: InputDecoration( + contentPadding: const EdgeInsets.symmetric(vertical: 5, horizontal: 20), + labelText: widget.labelText, + alignLabelWithHint: true, + labelStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: Theme.of(context).dividerColor), + floatingLabelStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: Theme.of(context).dividerColor), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide(color: Theme.of(context).cardColor, width: 1.5) + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide(color: Theme.of(context).dividerColor, width: 1) + ), + filled: true, + fillColor: Theme.of(context).cardColor, + errorText: widget.errorText, + errorStyle: Theme.of(context).textTheme.bodyMedium?.copyWith( + color: Colors.red + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: const BorderSide(color: Colors.red, width: 1.5) + ), + focusedErrorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: const BorderSide(color: Colors.red, width: 1.5) + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/widgets/small_spinner.dart b/lib/widgets/small_spinner.dart new file mode 100644 index 0000000..0b48ab4 --- /dev/null +++ b/lib/widgets/small_spinner.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; + +class SmallSpinner extends StatelessWidget { + final Color? color; + + const SmallSpinner({super.key, this.color}); + + @override + Widget build(BuildContext context) { + return SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 3, + color: color ?? Colors.white, + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..f8fffa1 --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,442 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + sha256: "5534e701a2c505fed1f0799e652dd6ae23bd4d2c4cf797220e5ced5764a7c1c2" + url: "https://pub.dev" + source: hosted + version: "1.3.44" + async: + dependency: transitive + description: + name: async + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" + source: hosted + version: "2.11.0" + auto_size_text: + dependency: "direct main" + description: + name: auto_size_text + sha256: "3f5261cd3fb5f2a9ab4e2fc3fba84fd9fcaac8821f20a1d4e71f557521b22599" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + badges: + dependency: "direct main" + description: + name: badges + sha256: a7b6bbd60dce418df0db3058b53f9d083c22cdb5132a052145dc267494df0b84 + url: "https://pub.dev" + source: hosted + version: "3.1.2" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + bot_toast: + dependency: "direct main" + description: + name: bot_toast + sha256: "6b93030a99a98335b8827ecd83021e92e885ffc61d261d3825ffdecdd17f3bdf" + url: "https://pub.dev" + source: hosted + version: "4.1.3" + characters: + dependency: transitive + description: + name: characters + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" + source: hosted + version: "1.3.0" + clock: + dependency: transitive + description: + name: clock + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" + source: hosted + version: "1.1.1" + cloud_firestore: + dependency: "direct main" + description: + name: cloud_firestore + sha256: a08d0f4aae40e63e7a57102de890d5d3c93d719ce38985b2a36c2672283af7d2 + url: "https://pub.dev" + source: hosted + version: "5.4.3" + cloud_firestore_platform_interface: + dependency: transitive + description: + name: cloud_firestore_platform_interface + sha256: "884fa34c6be2d9c7c1f4af86f90f36c0a3b3afef585a12b350a5d15368e7ec7a" + url: "https://pub.dev" + source: hosted + version: "6.4.3" + cloud_firestore_web: + dependency: transitive + description: + name: cloud_firestore_web + sha256: "6e621bbcc999f32db0bc6bfcb18d9991617ec20f8d6bf51b6a1571f5c324fafd" + url: "https://pub.dev" + source: hosted + version: "4.3.2" + collection: + dependency: transitive + description: + name: collection + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + url: "https://pub.dev" + source: hosted + version: "1.18.0" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" + url: "https://pub.dev" + source: hosted + version: "0.3.4+2" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" + url: "https://pub.dev" + source: hosted + version: "2.1.3" + file_picker: + dependency: "direct main" + description: + name: file_picker + sha256: "167bb619cdddaa10ef2907609feb8a79c16dfa479d3afaf960f8e223f754bf12" + url: "https://pub.dev" + source: hosted + version: "8.1.2" + firebase_auth: + dependency: "direct main" + description: + name: firebase_auth + sha256: d453acec0d958ba0e25d41a9901b32cb77d1535766903dea7a61b2788c304596 + url: "https://pub.dev" + source: hosted + version: "5.3.1" + firebase_auth_platform_interface: + dependency: transitive + description: + name: firebase_auth_platform_interface + sha256: "78966c2ef774f5bf2a8381a307222867e9ece3509110500f7a138c115926aa65" + url: "https://pub.dev" + source: hosted + version: "7.4.7" + firebase_auth_web: + dependency: transitive + description: + name: firebase_auth_web + sha256: "77ad3b252badedd3f08dfa21a4c7fe244be96c6da3a4067f253b13ea5d32424c" + url: "https://pub.dev" + source: hosted + version: "5.13.2" + firebase_core: + dependency: "direct main" + description: + name: firebase_core + sha256: "51dfe2fbf3a984787a2e7b8592f2f05c986bfedd6fdacea3f9e0a7beb334de96" + url: "https://pub.dev" + source: hosted + version: "3.6.0" + firebase_core_platform_interface: + dependency: transitive + description: + name: firebase_core_platform_interface + sha256: e30da58198a6d4b49d5bce4e852f985c32cb10db329ebef9473db2b9f09ce810 + url: "https://pub.dev" + source: hosted + version: "5.3.0" + firebase_core_web: + dependency: transitive + description: + name: firebase_core_web + sha256: f967a7138f5d2ffb1ce15950e2a382924239eaa521150a8f144af34e68b3b3e5 + url: "https://pub.dev" + source: hosted + version: "2.18.1" + firebase_storage: + dependency: "direct main" + description: + name: firebase_storage + sha256: "8a8a21f3a359129a1257e2e77ece1de9678f40e43876635b3d411388ee388729" + url: "https://pub.dev" + source: hosted + version: "12.3.2" + firebase_storage_platform_interface: + dependency: transitive + description: + name: firebase_storage_platform_interface + sha256: "462621bbdb5ab496518aa0f4785cb6db87763d5f1063aa228e1f65562937af1d" + url: "https://pub.dev" + source: hosted + version: "5.1.31" + firebase_storage_web: + dependency: transitive + description: + name: firebase_storage_web + sha256: "40c52d5585ce63659b4b698fee0d47412ce499392ae3edf69c8e6141c22daf9a" + url: "https://pub.dev" + source: hosted + version: "3.10.2" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: "9ee02950848f61c4129af3d6ec84a1cfc0e47931abc746b03e7a3bc3e8ff6eda" + url: "https://pub.dev" + source: hosted + version: "2.0.22" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + font_awesome_flutter: + dependency: "direct main" + description: + name: font_awesome_flutter + sha256: "275ff26905134bcb59417cf60ad979136f1f8257f2f449914b2c3e05bbb4cd6f" + url: "https://pub.dev" + source: hosted + version: "10.7.0" + http: + dependency: transitive + description: + name: http + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 + url: "https://pub.dev" + source: hosted + version: "1.2.2" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + url: "https://pub.dev" + source: hosted + version: "10.0.5" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + url: "https://pub.dev" + source: hosted + version: "3.0.5" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + url: "https://pub.dev" + source: hosted + version: "3.0.1" + lints: + dependency: transitive + description: + name: lints + sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + matcher: + dependency: transitive + description: + name: matcher + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + url: "https://pub.dev" + source: hosted + version: "0.12.16+1" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + url: "https://pub.dev" + source: hosted + version: "0.11.1" + meta: + dependency: transitive + description: + name: meta + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + url: "https://pub.dev" + source: hosted + version: "1.15.0" + path: + dependency: transitive + description: + name: path + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + url: "https://pub.dev" + source: hosted + version: "1.9.0" + pinput: + dependency: "direct main" + description: + name: pinput + sha256: "7bf9aa7d0eeb3da9f7d49d2087c7bc7d36cd277d2e94cc31c6da52e1ebb048d0" + url: "https://pub.dev" + source: hosted + version: "5.0.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" + source: hosted + version: "1.10.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + url: "https://pub.dev" + source: hosted + version: "1.11.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + url: "https://pub.dev" + source: hosted + version: "2.1.2" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + url: "https://pub.dev" + source: hosted + version: "0.7.2" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + url: "https://pub.dev" + source: hosted + version: "1.3.2" + universal_platform: + dependency: transitive + description: + name: universal_platform + sha256: "64e16458a0ea9b99260ceb5467a214c1f298d647c659af1bff6d3bf82536b1ec" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + url: "https://pub.dev" + source: hosted + version: "14.2.5" + web: + dependency: transitive + description: + name: web + sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062 + url: "https://pub.dev" + source: hosted + version: "1.0.0" + win32: + dependency: transitive + description: + name: win32 + sha256: "68d1e89a91ed61ad9c370f9f8b6effed9ae5e0ede22a270bdfa6daf79fc2290a" + url: "https://pub.dev" + source: hosted + version: "5.5.4" +sdks: + dart: ">=3.5.2 <4.0.0" + flutter: ">=3.22.0" diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..fe27d82 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,51 @@ +name: baligh +description: "A new Flutter project." +publish_to: 'none' +version: 0.1.0 + +environment: + sdk: ^3.5.2 + +dependencies: + flutter: + sdk: flutter + auto_size_text: ^3.0.0 + file_picker: ^8.1.2 + badges: ^3.1.2 + font_awesome_flutter: ^10.7.0 + pinput: ^5.0.0 + firebase_core: ^3.6.0 + firebase_auth: ^5.3.1 + cloud_firestore: ^5.4.3 + bot_toast: ^4.1.3 + firebase_storage: ^12.3.2 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^4.0.0 + +flutter: + uses-material-design: true + + fonts: + - family: Cairo + fonts: + - asset: assets/fonts/Cairo-Light.ttf + weight: 300 + - family: Cairo + fonts: + - asset: assets/fonts/Cairo-Regular.ttf + weight: 400 + - family: Cairo + fonts: + - asset: assets/fonts/Cairo-Medium.ttf + weight: 500 + - family: Cairo + fonts: + - asset: assets/fonts/Cairo-SemiBold.ttf + weight: 600 + - family: Cairo + fonts: + - asset: assets/fonts/Cairo-Bold.ttf + weight: 700 diff --git a/test/widget_test.dart b/test/widget_test.dart new file mode 100644 index 0000000..cc84fb5 --- /dev/null +++ b/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility in the flutter_test package. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:baligh/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/upload-keystore.jks b/upload-keystore.jks new file mode 100644 index 0000000..bf027bf Binary files /dev/null and b/upload-keystore.jks differ