diff --git a/android/app/build.gradle b/android/app/build.gradle index b0e8782..2822399 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -22,6 +22,9 @@ if (flutterVersionName == null) { } apply plugin: 'com.android.application' +// START: FlutterFire Configuration +apply plugin: 'com.google.gms.google-services' +// END: FlutterFire Configuration apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" @@ -31,7 +34,6 @@ android { ndkVersion flutter.ndkVersion compileOptions { - coreLibraryDesugaringEnabled true sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } @@ -50,7 +52,7 @@ android { applicationId "com.example.habittracker" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. - minSdkVersion flutter.minSdkVersion + minSdkVersion 31 targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName @@ -71,6 +73,6 @@ flutter { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3' + } diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 0000000..0cdddf1 --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,90 @@ +{ + "project_info": { + "project_number": "851745172186", + "project_id": "habittracker-9a354", + "storage_bucket": "habittracker-9a354.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:851745172186:android:c5d3288eb3791b37d553e3", + "android_client_info": { + "package_name": "com.example.habit_tracker" + } + }, + "oauth_client": [ + { + "client_id": "851745172186-7qa2sro8eecd94551lnn5l5hqh0btrol.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.example.habit_tracker", + "certificate_hash": "fc2ca9e85bd95db9cb67598c835ec8ac59f630e7" + } + }, + { + "client_id": "851745172186-guhss3l6u7u06pmqr24627rus4t2nr19.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCTL021AdB9RtSkKstSs-rI7TVNrdzD6rI" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "851745172186-dhon03cfgs557b6bfmjfnb0vvvumpefm.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "851745172186-c8tseejtp6qp62ntnhh109q5vqume7pe.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.example.habitTracker" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:851745172186:android:138cfa04bd50988ad553e3", + "android_client_info": { + "package_name": "com.example.habittracker" + } + }, + "oauth_client": [ + { + "client_id": "851745172186-guhss3l6u7u06pmqr24627rus4t2nr19.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCTL021AdB9RtSkKstSs-rI7TVNrdzD6rI" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "851745172186-dhon03cfgs557b6bfmjfnb0vvvumpefm.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "851745172186-c8tseejtp6qp62ntnhh109q5vqume7pe.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.example.habitTracker" + } + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index a7e967b..20def0d 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ 10.12.0) + - Firebase/CoreOnly (10.12.0): + - FirebaseCore (= 10.12.0) + - firebase_auth (4.7.0): + - Firebase/Auth (= 10.12.0) + - firebase_core + - Flutter + - firebase_core (2.15.0): + - Firebase/CoreOnly (= 10.12.0) + - Flutter + - FirebaseAppCheckInterop (10.12.0) + - FirebaseAuth (10.12.0): + - FirebaseAppCheckInterop (~> 10.0) + - FirebaseCore (~> 10.0) + - GoogleUtilities/AppDelegateSwizzler (~> 7.8) + - GoogleUtilities/Environment (~> 7.8) + - GTMSessionFetcher/Core (< 4.0, >= 2.1) + - FirebaseCore (10.12.0): + - FirebaseCoreInternal (~> 10.0) + - GoogleUtilities/Environment (~> 7.8) + - GoogleUtilities/Logger (~> 7.8) + - FirebaseCoreInternal (10.12.0): + - "GoogleUtilities/NSData+zlib (~> 7.8)" + - Flutter (1.0.0) + - google_sign_in_ios (0.0.1): + - Flutter + - GoogleSignIn (~> 6.2) + - GoogleSignIn (6.2.4): + - AppAuth (~> 1.5) + - GTMAppAuth (~> 1.3) + - GTMSessionFetcher/Core (< 3.0, >= 1.1) + - GoogleUtilities/AppDelegateSwizzler (7.11.1): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Environment (7.11.1): + - PromisesObjC (< 3.0, >= 1.2) + - GoogleUtilities/Logger (7.11.1): + - GoogleUtilities/Environment + - GoogleUtilities/Network (7.11.1): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (7.11.1)" + - GoogleUtilities/Reachability (7.11.1): + - GoogleUtilities/Logger + - GTMAppAuth (1.3.1): + - AppAuth/Core (~> 1.6) + - GTMSessionFetcher/Core (< 3.0, >= 1.5) + - GTMSessionFetcher/Core (2.3.0) + - IosAwnCore (0.7.5-dev.3) + - path_provider_foundation (0.0.1): + - Flutter + - FlutterMacOS + - PromisesObjC (2.2.0) + +DEPENDENCIES: + - awesome_notifications (from `.symlinks/plugins/awesome_notifications/ios`) + - firebase_auth (from `.symlinks/plugins/firebase_auth/ios`) + - firebase_core (from `.symlinks/plugins/firebase_core/ios`) + - Flutter (from `Flutter`) + - google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/ios`) + - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) + +SPEC REPOS: + trunk: + - AppAuth + - Firebase + - FirebaseAppCheckInterop + - FirebaseAuth + - FirebaseCore + - FirebaseCoreInternal + - GoogleSignIn + - GoogleUtilities + - GTMAppAuth + - GTMSessionFetcher + - IosAwnCore + - PromisesObjC + +EXTERNAL SOURCES: + awesome_notifications: + :path: ".symlinks/plugins/awesome_notifications/ios" + firebase_auth: + :path: ".symlinks/plugins/firebase_auth/ios" + firebase_core: + :path: ".symlinks/plugins/firebase_core/ios" + Flutter: + :path: Flutter + google_sign_in_ios: + :path: ".symlinks/plugins/google_sign_in_ios/ios" + path_provider_foundation: + :path: ".symlinks/plugins/path_provider_foundation/darwin" + +SPEC CHECKSUMS: + AppAuth: 3bb1d1cd9340bd09f5ed189fb00b1cc28e1e8570 + awesome_notifications: 1b6393d6ce02878dc50d0ae87baf7bdbc9d802a2 + Firebase: 07150e75d142fb9399f6777fa56a187b17f833a0 + firebase_auth: fdfcf37a6f37b776d56a6b7771df84d0bafdc650 + firebase_core: e477125798fc37cd4ab43ca6a8536bf7e0929c00 + FirebaseAppCheckInterop: f95a4feb9089867aff1a4bdc2ce309137e07736a + FirebaseAuth: a66c1e14ec58f41d154a4b41ce1a23ea00ad4805 + FirebaseCore: f86a1394906b97ac445ae49c92552a9425831bed + FirebaseCoreInternal: 950500ad8a08963657f6d8c67b579740c06d6aa1 + Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 + google_sign_in_ios: 1256ff9d941db546373826966720b0c24804bcdd + GoogleSignIn: 5651ce3a61e56ca864160e79b484cd9ed3f49b7a + GoogleUtilities: 9aa0ad5a7bc171f8bae016300bfcfa3fb8425749 + GTMAppAuth: 0ff230db599948a9ad7470ca667337803b3fc4dd + GTMSessionFetcher: 3a63d75eecd6aa32c2fc79f578064e1214dfdec2 + IosAwnCore: edf31913fd18960ebcde7c05912dc860ca2b63b2 + path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 + PromisesObjC: 09985d6d70fbe7878040aa746d78236e6946d2ef + +PODFILE CHECKSUM: 70d9d25280d0dd177a5f637cdb0f0b0b12c6a189 + +COCOAPODS: 1.12.1 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index dc66bb4..d9cb57e 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -8,12 +8,15 @@ /* 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 */; }; + 483B551CC7BA746BE6343EE0 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 550B00E537747621D8A7A0D8 /* Pods_RunnerTests.framework */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 885C841552C9736658BC244B /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = E5C8AAC441A550DCAC67192C /* GoogleService-Info.plist */; }; + 92746079D2B05279715D60D7 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5690C41E96C3B08C3BCAAEE3 /* Pods_Runner.framework */; }; 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 */; }; - 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -40,12 +43,20 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 05E8AAFB445FDEC635FA2746 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 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 = ""; }; + 2480927E74E75CB46FDE793A /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; 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 = ""; }; + 550B00E537747621D8A7A0D8 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 5690C41E96C3B08C3BCAAEE3 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 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 = ""; }; + 78900FDC7E5282246E12397B /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 8BC91B1C7EDD74C75C136451 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 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; }; @@ -53,8 +64,9 @@ 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 = ""; }; - 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; }; + BC12704B2D48D2BCE7F8F996 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + E5C8AAC441A550DCAC67192C /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; + F938617B16E3C9A47ECF3324 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -62,12 +74,29 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 92746079D2B05279715D60D7 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9C9034310CAFCEE8E5874E0B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 483B551CC7BA746BE6343EE0 /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 331C8082294A63A400263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C807B294A618700263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -79,14 +108,6 @@ name = Flutter; sourceTree = ""; }; - 331C8082294A63A400263BE5 /* RunnerTests */ = { - isa = PBXGroup; - children = ( - 331C807B294A618700263BE5 /* RunnerTests.swift */, - ); - path = RunnerTests; - sourceTree = ""; - }; 97C146E51CF9000F007C117D = { isa = PBXGroup; children = ( @@ -94,6 +115,9 @@ 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, 331C8082294A63A400263BE5 /* RunnerTests */, + A6B548C0E94B548945F2C638 /* Pods */, + BBC7D43ACBA999E002E883C1 /* Frameworks */, + E5C8AAC441A550DCAC67192C /* GoogleService-Info.plist */, ); sourceTree = ""; }; @@ -121,6 +145,29 @@ path = Runner; sourceTree = ""; }; + A6B548C0E94B548945F2C638 /* Pods */ = { + isa = PBXGroup; + children = ( + 05E8AAFB445FDEC635FA2746 /* Pods-Runner.debug.xcconfig */, + BC12704B2D48D2BCE7F8F996 /* Pods-Runner.release.xcconfig */, + 8BC91B1C7EDD74C75C136451 /* Pods-Runner.profile.xcconfig */, + F938617B16E3C9A47ECF3324 /* Pods-RunnerTests.debug.xcconfig */, + 78900FDC7E5282246E12397B /* Pods-RunnerTests.release.xcconfig */, + 2480927E74E75CB46FDE793A /* Pods-RunnerTests.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + BBC7D43ACBA999E002E883C1 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 5690C41E96C3B08C3BCAAEE3 /* Pods_Runner.framework */, + 550B00E537747621D8A7A0D8 /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -128,9 +175,10 @@ isa = PBXNativeTarget; buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( + 7FDE5877B7DAB9ACF32ECA84 /* [CP] Check Pods Manifest.lock */, 331C807D294A63A400263BE5 /* Sources */, - 331C807E294A63A400263BE5 /* Frameworks */, 331C807F294A63A400263BE5 /* Resources */, + 9C9034310CAFCEE8E5874E0B /* Frameworks */, ); buildRules = ( ); @@ -146,12 +194,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + 94CEFF5BAD49FC1974D5243E /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + E9B5769D45838957787BD7E5 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -216,6 +266,7 @@ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + 885C841552C9736658BC244B /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -238,6 +289,50 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 7FDE5877B7DAB9ACF32ECA84 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 94CEFF5BAD49FC1974D5243E /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -253,6 +348,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + E9B5769D45838957787BD7E5 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -377,7 +489,7 @@ }; 331C8088294A63A400263BE5 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = AE0B7B92F70575B8D7E0D07E /* Pods-RunnerTests.debug.xcconfig */; + baseConfigurationReference = F938617B16E3C9A47ECF3324 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -395,7 +507,7 @@ }; 331C8089294A63A400263BE5 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 89B67EB44CE7B6631473024E /* Pods-RunnerTests.release.xcconfig */; + baseConfigurationReference = 78900FDC7E5282246E12397B /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -411,7 +523,7 @@ }; 331C808A294A63A400263BE5 /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 640959BDD8F10B91D80A66BE /* Pods-RunnerTests.profile.xcconfig */; + baseConfigurationReference = 2480927E74E75CB46FDE793A /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata index 1d526a1..21a3cc1 100644 --- a/ios/Runner.xcworkspace/contents.xcworkspacedata +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 70693e4..68214f3 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -8,6 +8,7 @@ import Flutter 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/1024.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png new file mode 100644 index 0000000..0debfd8 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png new file mode 100644 index 0000000..637a299 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png new file mode 100644 index 0000000..6a39487 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png new file mode 100644 index 0000000..78731f0 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png new file mode 100644 index 0000000..789a729 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png new file mode 100644 index 0000000..d914b39 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png new file mode 100644 index 0000000..09d3a53 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png new file mode 100644 index 0000000..f7e8427 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png new file mode 100644 index 0000000..15fe138 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png new file mode 100644 index 0000000..0bc22f2 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png new file mode 100644 index 0000000..8e1cc0b Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json index d36b1fa..73d3b7f 100644 --- a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,122 +1 @@ -{ - "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" - } -} +{"images":[{"size":"60x60","expected-size":"180","filename":"180.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"40x40","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"60x60","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"57x57","expected-size":"57","filename":"57.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"87","filename":"87.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"57x57","expected-size":"114","filename":"114.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"60","filename":"60.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"1024x1024","filename":"1024.png","expected-size":"1024","idiom":"ios-marketing","folder":"Assets.xcassets/AppIcon.appiconset/","scale":"1x"}]} \ No newline at end of file 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 deleted file mode 100644 index dc9ada4..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and /dev/null 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 deleted file mode 100644 index 7353c41..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and /dev/null 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 deleted file mode 100644 index 797d452..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and /dev/null 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 deleted file mode 100644 index 6ed2d93..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and /dev/null 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 deleted file mode 100644 index 4cd7b00..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and /dev/null 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 deleted file mode 100644 index fe73094..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and /dev/null 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 deleted file mode 100644 index 321773c..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and /dev/null 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 deleted file mode 100644 index 797d452..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and /dev/null 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 deleted file mode 100644 index 502f463..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and /dev/null 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 deleted file mode 100644 index 0ec3034..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and /dev/null 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 deleted file mode 100644 index 0ec3034..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and /dev/null 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 deleted file mode 100644 index e9f5fea..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and /dev/null 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 deleted file mode 100644 index 84ac32a..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and /dev/null 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 deleted file mode 100644 index 8953cba..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and /dev/null 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 deleted file mode 100644 index 0467bf1..0000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and /dev/null differ diff --git a/ios/Runner/GoogleService-Info.plist b/ios/Runner/GoogleService-Info.plist new file mode 100644 index 0000000..c29d87f --- /dev/null +++ b/ios/Runner/GoogleService-Info.plist @@ -0,0 +1,36 @@ + + + + + CLIENT_ID + 851745172186-vt9t8ie3hsbf2thh7mq23e7uflgq62a4.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.851745172186-vt9t8ie3hsbf2thh7mq23e7uflgq62a4 + ANDROID_CLIENT_ID + 851745172186-jab47kgoqeo2n184l7404ltr0gf81ufn.apps.googleusercontent.com + API_KEY + AIzaSyBQiHJMTVtUQqiNQxeGZbdeSGMWvDrIFO0 + GCM_SENDER_ID + 851745172186 + PLIST_VERSION + 1 + BUNDLE_ID + com.example.habittracker + PROJECT_ID + habittracker-9a354 + STORAGE_BUCKET + habittracker-9a354.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:851745172186:ios:1e02afd5992d27ded553e3 + + \ No newline at end of file diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 7d33eff..6b7339d 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -2,6 +2,17 @@ + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + com.googleusercontent.apps.851745172186-vt9t8ie3hsbf2thh7mq23e7uflgq62a4 + + + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName diff --git a/ios/firebase_app_id_file.json b/ios/firebase_app_id_file.json new file mode 100644 index 0000000..d0b2acc --- /dev/null +++ b/ios/firebase_app_id_file.json @@ -0,0 +1,7 @@ +{ + "file_generated_by": "FlutterFire CLI", + "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", + "GOOGLE_APP_ID": "1:851745172186:ios:1e02afd5992d27ded553e3", + "FIREBASE_PROJECT_ID": "habittracker-9a354", + "GCM_SENDER_ID": "851745172186" +} \ No newline at end of file diff --git a/lib/authentication_utils/my_button.dart b/lib/authentication_utils/my_button.dart new file mode 100644 index 0000000..c795a4c --- /dev/null +++ b/lib/authentication_utils/my_button.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; + +class Mybutton extends StatelessWidget { + final Function()? onTap; + final String text; + + const Mybutton({super.key, required this.onTap, required this.text}); + + @override + Widget build(BuildContext context) { + return InkWell( + enableFeedback: true, + highlightColor: Colors.grey, + + onTap: onTap, + child: Container( + padding: const EdgeInsets.all(25), + margin: const EdgeInsets.symmetric(horizontal: 25), + decoration: BoxDecoration( + color: Colors.black, + borderRadius: BorderRadius.circular(8), + ), + child: Center( + child: Text( + text, + style: const TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/authentication_utils/my_textfield.dart b/lib/authentication_utils/my_textfield.dart new file mode 100644 index 0000000..55889fd --- /dev/null +++ b/lib/authentication_utils/my_textfield.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; + +class MyTextField extends StatelessWidget { + final controller; + final String hintText; + final bool obscureText; + + const MyTextField({ + super.key, + required this.controller, + required this.hintText, + required this.obscureText, + }); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 25.0), + child: TextField( + controller: controller, + obscureText: obscureText, + decoration: InputDecoration( + enabledBorder: const OutlineInputBorder( + borderSide: BorderSide(color: Colors.white), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.grey.shade400), + ), + fillColor: Colors.grey.shade200, + filled: true, + hintText: hintText, + hintStyle: TextStyle(color: Colors.grey[500])), + ), + ); + } +} \ No newline at end of file diff --git a/lib/authentication_utils/square_tile.dart b/lib/authentication_utils/square_tile.dart new file mode 100644 index 0000000..0a9ab30 --- /dev/null +++ b/lib/authentication_utils/square_tile.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; + +class SquareTile extends StatelessWidget { + final Function()? onTap; + final String imagePath; + const SquareTile({ + super.key, + required this.imagePath,required this.onTap, + }); + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: Container( + padding: EdgeInsets.all(20), + decoration: BoxDecoration( + border: Border.all(color: Colors.white), + borderRadius: BorderRadius.circular(16), + color: Colors.green[50], + ), + child: Image.asset( + imagePath, + height: 40, + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/datetime/time_format.dart b/lib/datetime/time_format.dart new file mode 100644 index 0000000..3f1ffbc --- /dev/null +++ b/lib/datetime/time_format.dart @@ -0,0 +1,43 @@ +String Hour(String time) +{ + int initial = 0; + String hr=""; + int hrs=0; + if(time.substring(time.length-2,time.length)=="PM"){ + initial=12; + } + for(int i=0;i()!.requestPermission(); // init the hive await Hive.initFlutter(); @@ -23,13 +34,15 @@ void main() async { } class MyApp extends StatelessWidget { + static var navigatorKey; + const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, - home: HomePage(), + home: AuthPage(), theme: ThemeData(primarySwatch: Colors.green), ); } diff --git a/lib/pages/auth_page.dart b/lib/pages/auth_page.dart new file mode 100644 index 0000000..a339e3f --- /dev/null +++ b/lib/pages/auth_page.dart @@ -0,0 +1,29 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:habittracker/pages/home_page.dart'; +import 'package:habittracker/pages/login_page.dart'; + +import 'login_or_register.dart'; + +class AuthPage extends StatelessWidget { + const AuthPage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: StreamBuilder( + stream: FirebaseAuth.instance.authStateChanges(), + builder: (context,snapshot) + { + if(snapshot.hasData) + { + return HomePage(); + } + else{ + return LoginOrRegister(); + } + }, + ), + ); + } +} diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index ca9f695..057338e 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -1,12 +1,17 @@ +import 'package:awesome_notifications/awesome_notifications.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; +import 'package:habittracker/datetime/time_format.dart'; import 'package:habittracker/util/monthly_summary.dart'; import 'package:hive/hive.dart'; import 'package:hive_flutter/adapters.dart'; import 'package:hive_flutter/hive_flutter.dart'; -import 'package:hive_flutter/hive_flutter.dart'; +import 'package:schedulers/schedulers.dart'; import '../data/database.dart'; import '../main.dart'; import '../util/dialog_box.dart'; + import '../util/noti.dart'; import '../util/todo_tile.dart'; @@ -21,10 +26,22 @@ class _HomePageState extends State { // reference the hive box final _myBox = Hive.box('mybox'); ToDoDataBase db = ToDoDataBase(); - + final user = FirebaseAuth.instance.currentUser!; @override void initState() { - Noti.initialize(flutterLocalNotificationsPlugin);// if this is the 1st time ever openin the app, then create default data + // if this is the 1st time ever openin the app, then create default data + AwesomeNotifications().isNotificationAllowed().then((isAllowed) { + if (!isAllowed) { + AwesomeNotifications().requestPermissionToSendNotifications(); + } + AwesomeNotifications().setListeners( + onActionReceivedMethod: NotificationController.onActionReceivedMethod, + onNotificationCreatedMethod: NotificationController.onNotificationCreatedMethod, + onNotificationDisplayedMethod: NotificationController.onNotificationDisplayedMethod, + onDismissActionReceivedMethod: NotificationController.onDismissActionReceivedMethod + ); + + }); if (_myBox.get("TODOLIST") == null) { db.createInitialData(); } else { @@ -34,12 +51,21 @@ class _HomePageState extends State { super.initState(); } + void signUserOut(){ + FirebaseAuth.instance.signOut(); + } + // text controller final _controller = TextEditingController(); - TextEditingController _startdatecontroller = TextEditingController(); - TextEditingController _timecontroller = TextEditingController(); - TextEditingController _interval = TextEditingController(); + final TextEditingController _startdatecontroller = TextEditingController(); + final TextEditingController _timecontroller = TextEditingController(); + final TextEditingController _interval = TextEditingController(); + get nameofhabit => _controller.text; // checkbox was tapped + + + + void checkBoxChanged(bool? value, int index) { setState(() { db.toDoList[index][1] = !db.toDoList[index][1]; @@ -47,17 +73,59 @@ class _HomePageState extends State { db.updateDataBase(); } + + + + Future createNewNotification() async { + String localTimeZone = await AwesomeNotifications().getLocalTimeZoneIdentifier(); + String utcTimeZone = await AwesomeNotifications().getLocalTimeZoneIdentifier(); + + await AwesomeNotifications().createNotification( + content: NotificationContent( + id: 10, + channelKey: 'scheduled', + title: _controller.text, + body: "Remainder for $nameofhabit" , + wakeUpScreen: true, + + ), + ); + _controller.clear(); + _timecontroller.clear(); + _startdatecontroller.clear(); + } // save new task void saveNewTask() { setState(() { - db.toDoList.add([_controller.text, false,_startdatecontroller.text,_timecontroller.text]); - _controller.clear(); + db.toDoList.add([ + _controller.text, + false, + _startdatecontroller.text, + _timecontroller.text + + ]); + }); Navigator.of(context).pop(); - Noti.showBigTextNotification(title: _controller.text, body: ".......", fln: flutterLocalNotificationsPlugin); + db.updateDataBase(); + print(_startdatecontroller.text); + print(_timecontroller.text); + int year = int.parse(_startdatecontroller.text.substring(0,4)); + int month = int.parse(_startdatecontroller.text.substring(5,7)); + int date = int.parse(_startdatecontroller.text.substring(8,10)); + int hour = int.parse(Hour(_timecontroller.text)); + int minute = int.parse(Minute(_timecontroller.text)); + final scheduler = TimeScheduler(); + + scheduler.run(() { + createNewNotification(); + }, DateTime(year,month,date,hour,minute)); + } + + // create a new task void createNewTask() { showDialog( @@ -87,38 +155,49 @@ class _HomePageState extends State { Widget build(BuildContext context) { return Container( decoration: BoxDecoration( - gradient: LinearGradient(begin: Alignment.bottomRight,end: Alignment.topLeft,colors: [Colors.green.shade50,Colors.green.shade300]) - ), + gradient: LinearGradient( + begin: Alignment.bottomRight, + end: Alignment.topLeft, + colors: [Colors.green.shade50, Colors.green.shade300])), child: Scaffold( - backgroundColor: Colors.transparent, - appBar: AppBar( - - title: Center(child: Text('Track your Habits')), - elevation: 0, - ), - floatingActionButton: FloatingActionButton( - onPressed: createNewTask, - child: Icon(Icons.add), - ), - body: ListView( - children: [ - MonthlySummary(datasets: db.heatMapDataSet, startDate: _myBox.get("STARTDATE")), - ListView.builder( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemCount: db.toDoList.length, - itemBuilder: (context, index) { - return ToDoTile( - taskName: db.toDoList[index][0], - taskCompleted: db.toDoList[index][1], - onChanged: (value) => checkBoxChanged(value, index), - deleteFunction: (context) => deleteTask(index), - ); - }, - ), - ], - ) - ), + backgroundColor: Colors.transparent, + appBar: AppBar( + leading: IconButton(onPressed: (){},icon: Icon(Icons.account_circle_rounded),), + title: Center(child: Text('Track your Habits')), + actions: [IconButton(onPressed: (signUserOut), icon: Icon(Icons.logout)),], + elevation: 0, + ), + floatingActionButton: FloatingActionButton( + onPressed: createNewTask, + child: Icon(Icons.add), + ), + body: ListView( + children: [ + MonthlySummary( + datasets: db.heatMapDataSet, + startDate: _myBox.get("STARTDATE")), + ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: db.toDoList.length, + itemBuilder: (context, index) { + return ToDoTile( + taskName: db.toDoList[index][0], + taskCompleted: db.toDoList[index][1], + onChanged: (value) => checkBoxChanged(value, index), + deleteFunction: (context) => deleteTask(index), + ); + }, + ), + SizedBox(height: 10,), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text("Logged in as "+user.email!,style: TextStyle(fontSize: 15),), + ],), + SizedBox(height: 20,), + ], + )), ); } -} \ No newline at end of file +} diff --git a/lib/pages/login_or_register.dart b/lib/pages/login_or_register.dart new file mode 100644 index 0000000..2349cc4 --- /dev/null +++ b/lib/pages/login_or_register.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; +import 'package:habittracker/pages/login_page.dart'; +import 'package:habittracker/pages/register_page.dart'; +class LoginOrRegister extends StatefulWidget { + const LoginOrRegister({super.key}); + @override + State createState() => _LoginOrRegisterState(); +} + +class _LoginOrRegisterState extends State { + + bool showLoginPage = true; + void togglepages(){ + setState(() { + showLoginPage = !showLoginPage; + }); + } + @override + Widget build(BuildContext context) { + if(showLoginPage) + { + return LoginPage(onTap: togglepages); + } + else + { + return RegisterPage( + onTap: togglepages, + ); + } + } +} diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart new file mode 100644 index 0000000..73b64d8 --- /dev/null +++ b/lib/pages/login_page.dart @@ -0,0 +1,222 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:habittracker/services/authservice.dart'; +import '../authentication_utils/my_button.dart'; +import '../authentication_utils/my_textfield.dart'; +import '../authentication_utils/square_tile.dart'; + +class LoginPage extends StatefulWidget { + final Function()? onTap; + const LoginPage({super.key, @required this.onTap}); + + @override + State createState() => _LoginPageState(); +} + +class _LoginPageState extends State { + // text editing controllers + final emailnameController = TextEditingController(); + + final passwordController = TextEditingController(); + + // sign user in method + void signUserIn() async { + //show a loading circle + showDialog(context: context, builder: (context) { + return Center(child: CircularProgressIndicator(),); + }); + try { + await FirebaseAuth.instance.signInWithEmailAndPassword( + email: emailnameController.text, password: passwordController.text); + Navigator.pop(context); + } on FirebaseAuthException catch(e) + { + Navigator.pop(context); + if(e.code == "user-not-found"){ + WrongEmailMessage(); + } + else{ + WrongPasswordMessage(); + } + } + + } + + void WrongEmailMessage(){ + showDialog(context: context, builder: (context) { + + return Center( + child: AlertDialog( + backgroundColor: Colors.grey.shade200, + title: Center(child: Text("Incorrect Email")), + ), + ); + }); + } + + void WrongPasswordMessage(){ + showDialog(context: context, builder: (context) + { + return Center( + child: AlertDialog( + backgroundColor: Colors.grey.shade200, + title: Center(child: Text("Incorrect Password")), + ), + ); + }); + } + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.bottomRight, + end: Alignment.topLeft, + colors: [Colors.green.shade50, Colors.green.shade300])), + child: Scaffold( + backgroundColor: Colors.transparent, + body: SafeArea( + child: Center( + child: SingleChildScrollView( + physics: PageScrollPhysics(), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const SizedBox(height: 50), + + // logo + Image.asset("assets/images/Profile.gif",scale: 4,), + + const SizedBox(height: 30), + + // welcome back, you've been missed! + Text( + 'Welcome back you\'ve been missed!', + style: TextStyle( + fontWeight: FontWeight.w600, + color: Colors.grey[700], + fontSize: 16, + ), + ), + + const SizedBox(height: 25), + + // username textfield + MyTextField( + controller: emailnameController, + hintText: 'Username', + obscureText: false, + ), + + const SizedBox(height: 10), + + // password textfield + MyTextField( + controller: passwordController, + hintText: 'Password', + obscureText: true, + ), + + const SizedBox(height: 10), + + // forgot password? + Padding( + padding: const EdgeInsets.symmetric(horizontal: 25.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text( + 'Forgot Password?', + style: TextStyle(color: Colors.grey[600]), + ), + ], + ), + ), + + const SizedBox(height: 25), + + // sign in button + Mybutton( + onTap: signUserIn, + text: "Sign In", + ), + + const SizedBox(height: 50), + + // or continue with + Padding( + padding: const EdgeInsets.symmetric(horizontal: 25.0), + child: Row( + children: [ + Expanded( + child: Divider( + thickness: 0.5, + color: Colors.grey[400], + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0), + child: Text( + 'Or continue with', + style: TextStyle(color: Colors.grey[700]), + ), + ), + Expanded( + child: Divider( + thickness: 0.5, + color: Colors.grey[400], + ), + ), + ], + ), + ), + + const SizedBox(height: 50), + + // google + apple sign in buttons + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // google button + SquareTile(imagePath: 'assets/images/google.png',onTap: () => AuthService().signINWIthGoogle(),), + + SizedBox(width: 25), + + // apple button + SquareTile(imagePath: 'assets/images/apple.png',onTap: () => AuthService().signINWIthGoogle(),) + ], + ), + + const SizedBox(height: 50), + + // not a member? register now + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Not a member?', + style: TextStyle(color: Colors.grey[700]), + ), + const SizedBox(width: 4), + GestureDetector( + onTap: widget.onTap, + child: const Text( + 'Register now', + style: TextStyle( + color: Colors.blue, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ) + ], + ), + ), + ), + ), + ), + ); + } +} diff --git a/lib/pages/register_page.dart b/lib/pages/register_page.dart new file mode 100644 index 0000000..ddf5808 --- /dev/null +++ b/lib/pages/register_page.dart @@ -0,0 +1,243 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import '../authentication_utils/my_button.dart'; +import '../authentication_utils/my_textfield.dart'; +import '../authentication_utils/square_tile.dart'; +import '../services/authservice.dart'; + +class RegisterPage extends StatefulWidget { + final Function()? onTap; + RegisterPage({super.key, @required this.onTap}); + + @override + State createState() => _RegisterPageState(); +} + +class _RegisterPageState extends State { + // text editing controllers + final emailnameController = TextEditingController(); + + final passwordController = TextEditingController(); + + final confirmpasswordController = TextEditingController(); + + // sign user in method + void signUserUp() async { + //show a loading circle + + showDialog( + context: context, + builder: (context) { + return Center( + child: CircularProgressIndicator(), + ); + }); + try { + if (passwordController.text == confirmpasswordController.text) { + await FirebaseAuth.instance.createUserWithEmailAndPassword( + email: emailnameController.text, password: passwordController.text); + Navigator.pop(context); + } + else + { + // Navigator.pop(context); + WrongConfirmPasswordMessage(); + } + + } on FirebaseAuthException catch (e) { + Navigator.pop(context); + if (e.code == "user-not-found") { + WrongEmailMessage(); + } else { + WrongPasswordMessage(); + } + } + } + + void WrongEmailMessage() { + showDialog( + context: context, + builder: (context) { + return Center( + child: AlertDialog( + backgroundColor: Colors.grey.shade200, + title: Center(child: Text("Incorrect Email")), + ), + ); + }); + } + + void WrongConfirmPasswordMessage(){ + showDialog( + context: context, + builder: (context) { + return Center( + child: AlertDialog( + backgroundColor: Colors.grey.shade200, + title: Center(child: Text("Password\'s Mismatch")), + ), + ); + }); + } + + void WrongPasswordMessage() { + showDialog( + context: context, + builder: (context) { + return Center( + child: AlertDialog( + backgroundColor: Colors.grey.shade200, + title: Center(child: Text("Incorrect Password")), + ), + ); + }); + } + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.bottomRight, + end: Alignment.topLeft, + colors: [Colors.green.shade50, Colors.green.shade300])), + child: Scaffold( + backgroundColor: Colors.transparent, + body: SafeArea( + child: Center( + child: SingleChildScrollView( + physics: PageScrollPhysics(), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const SizedBox(height: 40), + + // logo + Image.asset("assets/images/Profile.gif",scale: 4,), + + + const SizedBox(height: 25), + + // welcome back, you've been missed! + Text( + 'Let\'s create your account!', + style: TextStyle( + fontWeight: FontWeight.bold, + color: Colors.grey[700], + fontSize: 16, + ), + ), + + const SizedBox(height: 25), + + // username textfield + MyTextField( + controller: emailnameController, + hintText: 'Username', + obscureText: false, + ), + + const SizedBox(height: 10), + + // password textfield + MyTextField( + controller: passwordController, + hintText: 'Password', + obscureText: true, + ), + + const SizedBox(height: 10), + + // password textfield + MyTextField( + controller: confirmpasswordController, + hintText: 'Confirm Password', + obscureText: true, + ), + + const SizedBox(height: 25), + + // sign in button + Mybutton( + onTap: signUserUp, + text: "Sign Up", + ), + + const SizedBox(height: 30), + + // or continue with + Padding( + padding: const EdgeInsets.symmetric(horizontal: 25.0), + child: Row( + children: [ + Expanded( + child: Divider( + thickness: 0.5, + color: Colors.grey[400], + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0), + child: Text( + 'Or continue with', + style: TextStyle(color: Colors.grey[700]), + ), + ), + Expanded( + child: Divider( + thickness: 0.5, + color: Colors.grey[400], + ), + ), + ], + ), + ), + + const SizedBox(height: 30), + + // google + apple sign in buttons + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // google button + SquareTile(imagePath: 'assets/images/google.png',onTap: () => AuthService().signINWIthGoogle(),), + + SizedBox(width: 25), + + // apple button + SquareTile(imagePath: 'assets/images/apple.png',onTap: () => AuthService().signINWIthGoogle(),) + ], + ), + + const SizedBox(height: 50), + + // not a member? register now + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Already a member?', + style: TextStyle(color: Colors.grey[700]), + ), + const SizedBox(width: 4), + GestureDetector( + onTap: widget.onTap, + child: const Text( + 'Login', + style: TextStyle( + color: Colors.blue, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ) + ], + ), + ), + ), + ), + ), + ); + } +} diff --git a/lib/services/authservice.dart b/lib/services/authservice.dart new file mode 100644 index 0000000..e66cf05 --- /dev/null +++ b/lib/services/authservice.dart @@ -0,0 +1,18 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:google_sign_in/google_sign_in.dart'; + +class AuthService{ + signINWIthGoogle() async{ + final GoogleSignInAccount? guser = await GoogleSignIn().signIn(); + + final GoogleSignInAuthentication gAuth = await guser!.authentication; + + final credential = GoogleAuthProvider.credential( + accessToken: gAuth.accessToken, + idToken: gAuth.idToken, + + ); + + return await FirebaseAuth.instance.signInWithCredential(credential); +} +} \ No newline at end of file diff --git a/lib/util/dialog_box.dart b/lib/util/dialog_box.dart index f2bb922..28e16d2 100644 --- a/lib/util/dialog_box.dart +++ b/lib/util/dialog_box.dart @@ -41,7 +41,7 @@ class _DialogBoxState extends State { controller: widget.controller, decoration: InputDecoration( border: OutlineInputBorder(), - hintText: "Add a new task", + hintText: "Name of new task", ), ), TextField( @@ -58,10 +58,10 @@ class _DialogBoxState extends State { firstDate: DateTime(2022), lastDate: DateTime(2026)); - if(pickeddate != null) - { + if (pickeddate != null) { setState(() { - widget.startdatecontroller.text = DateFormat('dd-MM-yyyy').format(pickeddate); + widget.startdatecontroller.text = + DateFormat('yyyy-MM-dd').format(pickeddate); }); } }, @@ -74,36 +74,38 @@ class _DialogBoxState extends State { hintText: "Enter Time", ), onTap: () async { - TimeOfDay? pickedtime = await showTimePicker(context: context, initialTime: TimeOfDay(hour: 12, minute: 00)); - - if(pickedtime != null) - { - setState(() { - widget.timecontroller.text = pickedtime.format(context).toString(); - - }); - } - }, - ), - TextField( - controller: widget.interval, - decoration: InputDecoration( - icon: Icon(Icons.repeat), - border: OutlineInputBorder(), - hintText: "Repeats after", - ), - onTap: () async { - TimeOfDay? pickedtime = await showTimePicker(context: context, initialTime: TimeOfDay(hour: 12, minute: 00)); + TimeOfDay? pickedtime = await showTimePicker( + context: context, + initialTime: TimeOfDay(hour: 12, minute: 00)); - if(pickedtime != null) - { + if (pickedtime != null) { setState(() { - widget.timecontroller.text = pickedtime.format(context).toString(); - + widget.timecontroller.text = + pickedtime.format(context).toString(); }); } }, ), + // TextField( + // controller: widget.interval, + // decoration: InputDecoration( + // icon: Icon(Icons.repeat), + // border: OutlineInputBorder(), + // hintText: "Repeats after", + // ), + // onTap: () async { + // TimeOfDay? pickedtime = await showTimePicker( + // context: context, + // initialTime: TimeOfDay(hour: 12, minute: 00)); + // + // if (pickedtime != null) { + // setState(() { + // widget.timecontroller.text = + // pickedtime.format(context).toString(); + // }); + // } + // }, + // ), // buttons -> save + cancel Row( diff --git a/lib/util/monthly_summary.dart b/lib/util/monthly_summary.dart index 599f3bc..5ec3a8e 100644 --- a/lib/util/monthly_summary.dart +++ b/lib/util/monthly_summary.dart @@ -15,7 +15,10 @@ class MonthlySummary extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - padding: const EdgeInsets.only(top: 25, bottom: 25,), + padding: const EdgeInsets.only( + top: 25, + bottom: 25, + ), child: HeatMap( margin: EdgeInsets.all(5), borderRadius: 25, @@ -50,4 +53,4 @@ class MonthlySummary extends StatelessWidget { ), ); } -} \ No newline at end of file +} diff --git a/lib/util/noti.dart b/lib/util/noti.dart index d377f14..036c4ea 100644 --- a/lib/util/noti.dart +++ b/lib/util/noti.dart @@ -1,39 +1,34 @@ -import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:awesome_notifications/awesome_notifications.dart'; -import 'package:timezone/timezone.dart' as tz; +import '../main.dart'; -class Noti{ +class NotificationController { - static Future initialize(FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin) async { - var androidInitialize = new AndroidInitializationSettings('mipmap/ic_launcher'); - var iOSInitialize = new DarwinInitializationSettings(); - var initializationsSettings = new InitializationSettings(android: androidInitialize, - iOS: iOSInitialize); - await flutterLocalNotificationsPlugin.initialize(initializationsSettings ); + /// Use this method to detect when a new notification or a schedule is created + @pragma("vm:entry-point") + static Future onNotificationCreatedMethod(ReceivedNotification receivedNotification) async { + // Your code goes here } - static Future showBigTextNotification({var id =0,required String title, required String body, - var payload, required FlutterLocalNotificationsPlugin fln - } ) async { - - AndroidNotificationDetails androidPlatformChannelSpecifics = - AndroidNotificationDetails( - 'you_can_name_it_whatever1', - 'channel_name', - channelDescription: 'your channel description', - - playSound: true, - // sound: RawResourceAndroidNotificationSound('notification'), - importance: Importance.max, - priority: Priority.high, - ); + /// Use this method to detect every time that a new notification is displayed + @pragma("vm:entry-point") + static Future onNotificationDisplayedMethod(ReceivedNotification receivedNotification) async { + // Your code goes here + } - var not= NotificationDetails(android: androidPlatformChannelSpecifics, - iOS: DarwinNotificationDetails() - ); - DateTime scheduledate = DateTime.now().add(Duration(seconds: 5)); - await fln.zonedSchedule(0, title, body, tz.TZDateTime.from(scheduledate, tz.local),not, uiLocalNotificationDateInterpretation:UILocalNotificationDateInterpretation.absoluteTime,payload: payload, - androidAllowWhileIdle: true,androidScheduleMode: AndroidScheduleMode.exact); + /// Use this method to detect if the user dismissed a notification + @pragma("vm:entry-point") + static Future onDismissActionReceivedMethod(ReceivedAction receivedAction) async { + // Your code goes here } + static Future onActionReceivedMethod(ReceivedAction receivedAction) async { + // Your code goes here + // Navigate into pages, avoiding to open the notification details page over another details page already opened + MyApp.navigatorKey.currentState?.pushNamedAndRemoveUntil('/notification-page', + (route) => (route.settings.name != '/notification-page') || route.isFirst, + arguments: receivedAction); + } } + /// Use this method to detect when the user taps on a notification or action button + diff --git a/pubspec.lock b/pubspec.lock index ff92dd4..fc1920d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -9,6 +9,14 @@ packages: url: "https://pub.dev" source: hosted version: "61.0.0" + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + sha256: "5dce45a06d386358334eb1689108db6455d90ceb0d75848d5f4819283d4ee2b8" + url: "https://pub.dev" + source: hosted + version: "1.3.4" analyzer: dependency: transitive description: @@ -33,6 +41,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.11.0" + awesome_notifications: + dependency: "direct main" + description: + name: awesome_notifications + sha256: "6ba98d73553c8a54e7b77f8dd8b95ce9d32a7839ef182b28cf2ad54ec28b1821" + url: "https://pub.dev" + source: hosted + version: "0.7.5-dev.3" boolean_selector: dependency: transitive description: @@ -185,14 +201,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.0" - dbus: - dependency: transitive - description: - name: dbus - sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263" - url: "https://pub.dev" - source: hosted - version: "0.7.8" dropdown_textfield: dependency: "direct main" description: @@ -233,6 +241,54 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.0" + firebase_auth: + dependency: "direct main" + description: + name: firebase_auth + sha256: "87216661b409575ecb1a7849da38604a0abfcb6497146b66d4832cb97a4c9e0f" + url: "https://pub.dev" + source: hosted + version: "4.7.0" + firebase_auth_platform_interface: + dependency: transitive + description: + name: firebase_auth_platform_interface + sha256: "4ab0a8997994db2b76bf0652689d7908ca935a99314857c683251bc23d31c287" + url: "https://pub.dev" + source: hosted + version: "6.16.0" + firebase_auth_web: + dependency: transitive + description: + name: firebase_auth_web + sha256: c74c5753855896b31536b9e151e34bf7eea143f0d9c209947b5f7ddc8e111989 + url: "https://pub.dev" + source: hosted + version: "5.6.0" + firebase_core: + dependency: "direct main" + description: + name: firebase_core + sha256: "2e9324f719e90200dc7d3c4f5d2abc26052f9f2b995d3b6626c47a0dfe1c8192" + url: "https://pub.dev" + source: hosted + version: "2.15.0" + firebase_core_platform_interface: + dependency: transitive + description: + name: firebase_core_platform_interface + sha256: b63e3be6c96ef5c33bdec1aab23c91eb00696f6452f0519401d640938c94cba2 + url: "https://pub.dev" + source: hosted + version: "4.8.0" + firebase_core_web: + dependency: transitive + description: + name: firebase_core_web + sha256: "0fd5c4b228de29b55fac38aed0d9e42514b3d3bd47675de52bf7f8fccaf922fa" + url: "https://pub.dev" + source: hosted + version: "2.6.0" fixnum: dependency: transitive description: @@ -262,30 +318,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.2" - flutter_local_notifications: - dependency: "direct main" - description: - name: flutter_local_notifications - sha256: "3cc40fe8c50ab8383f3e053a499f00f975636622ecdc8e20a77418ece3b1e975" - url: "https://pub.dev" - source: hosted - version: "15.1.0+1" - flutter_local_notifications_linux: - dependency: transitive - description: - name: flutter_local_notifications_linux - sha256: "33f741ef47b5f63cc7f78fe75eeeac7e19f171ff3c3df054d84c1e38bedb6a03" - url: "https://pub.dev" - source: hosted - version: "4.0.0+1" - flutter_local_notifications_platform_interface: - dependency: transitive - description: - name: flutter_local_notifications_platform_interface - sha256: "7cf643d6d5022f3baed0be777b0662cce5919c0a7b86e700299f22dc4ae660ef" - url: "https://pub.dev" - source: hosted - version: "7.0.0+1" flutter_slidable: dependency: "direct main" description: @@ -299,6 +331,11 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" frontend_server_client: dependency: transitive description: @@ -315,6 +352,54 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" + google_identity_services_web: + dependency: transitive + description: + name: google_identity_services_web + sha256: "7940fdc3b1035db4d65d387c1bdd6f9574deaa6777411569c05ecc25672efacd" + url: "https://pub.dev" + source: hosted + version: "0.2.1" + google_sign_in: + dependency: "direct main" + description: + name: google_sign_in + sha256: aab6fdc41374014494f9e9026b9859e7309639d50a0bf4a2a412467a5ae4abc6 + url: "https://pub.dev" + source: hosted + version: "6.1.4" + google_sign_in_android: + dependency: transitive + description: + name: google_sign_in_android + sha256: "8d60a787b29cb7d2bcf29230865f4a91f17323c6ac5b6b9027a6418e48d9ffc3" + url: "https://pub.dev" + source: hosted + version: "6.1.18" + google_sign_in_ios: + dependency: transitive + description: + name: google_sign_in_ios + sha256: "6ec0e13a4c5c646471b9f6a25ceb3ae76d339889d4c0f79b729bf0714215a63e" + url: "https://pub.dev" + source: hosted + version: "5.6.2" + google_sign_in_platform_interface: + dependency: transitive + description: + name: google_sign_in_platform_interface + sha256: e69553c0fc6a76216e9d06a8c3767e291ad9be42171f879aab7ab708569d4393 + url: "https://pub.dev" + source: hosted + version: "2.4.1" + google_sign_in_web: + dependency: transitive + description: + name: google_sign_in_web + sha256: "69b9ce0e760945ff52337921a8b5871592b74c92f85e7632293310701eea68cc" + url: "https://pub.dev" + source: hosted + version: "0.12.0+2" graphs: dependency: transitive description: @@ -347,6 +432,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" + http: + dependency: transitive + description: + name: http + sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + url: "https://pub.dev" + source: hosted + version: "1.1.0" http_multi_server: dependency: transitive description: @@ -507,14 +600,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.7" - petitparser: - dependency: transitive - description: - name: petitparser - sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 - url: "https://pub.dev" - source: hosted - version: "5.4.0" platform: dependency: transitive description: @@ -555,6 +640,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.3" + quiver: + dependency: transitive + description: + name: quiver + sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47 + url: "https://pub.dev" + source: hosted + version: "3.2.1" + schedulers: + dependency: "direct main" + description: + name: schedulers + sha256: "11a3694c700735b85d6955ffebde32fd5e06ed5f52f2679e30973e6437fcc998" + url: "https://pub.dev" + source: hosted + version: "1.0.1" shelf: dependency: transitive description: @@ -712,14 +813,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" - xml: - dependency: transitive - description: - name: xml - sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" - url: "https://pub.dev" - source: hosted - version: "6.3.0" yaml: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index ab30384..1643757 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -41,8 +41,13 @@ dependencies: datetime_picker_formfield_new: dropdown_textfield: ^1.0.8 flutter_heatmap_calendar: ^1.0.5 - flutter_local_notifications: ^15.1.0+1 timezone: ^0.9.2 + awesome_notifications: ^0.7.4+1 + schedulers: ^1.0.1 + firebase_core: ^2.15.0 + firebase_auth: ^4.7.0 + google_sign_in: ^6.1.4 + dev_dependencies: @@ -70,9 +75,9 @@ flutter: uses-material-design: true # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg + assets: + - assets/images/ + # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware