├── .gitignore ├── .metadata ├── LICENSE ├── README.md ├── android ├── .gitignore ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── chatify_app │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable-v21 │ │ │ └── launch_background.xml │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── values-night │ │ │ └── styles.xml │ │ │ └── values │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── assets ├── images │ └── logo.png └── preview │ ├── preview_2.png │ └── preview_4.png ├── ios ├── .gitignore ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings ├── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ └── Runner-Bridging-Header.h └── build │ └── Pods.build │ └── Release-iphonesimulator │ ├── BoringSSL-GRPC.build │ └── dgph │ ├── DKImagePickerController-DKImagePickerController.build │ └── dgph │ ├── DKImagePickerController.build │ └── dgph │ ├── DKPhotoGallery-DKPhotoGallery.build │ └── dgph │ ├── DKPhotoGallery.build │ └── dgph │ ├── Firebase.build │ └── dgph │ ├── FirebaseAnalytics.build │ └── dgph │ ├── FirebaseAuth.build │ └── dgph │ ├── FirebaseCore.build │ └── dgph │ ├── FirebaseCoreDiagnostics.build │ └── dgph │ ├── FirebaseFirestore.build │ └── dgph │ ├── FirebaseInstallations.build │ └── dgph │ ├── FirebaseStorage.build │ └── dgph │ ├── Flutter.build │ └── dgph │ ├── GTMSessionFetcher.build │ └── dgph │ ├── GoogleAppMeasurement.build │ └── dgph │ ├── GoogleDataTransport.build │ └── dgph │ ├── GoogleUtilities.build │ └── dgph │ ├── Pods-Runner.build │ └── dgph │ ├── PromisesObjC.build │ └── dgph │ ├── SDWebImage.build │ └── dgph │ ├── SwiftyGif.build │ └── dgph │ ├── abseil.build │ └── dgph │ ├── cloud_firestore.build │ └── dgph │ ├── file_picker.build │ └── dgph │ ├── firebase_analytics.build │ └── dgph │ ├── firebase_auth.build │ └── dgph │ ├── firebase_core.build │ └── dgph │ ├── firebase_storage.build │ └── dgph │ ├── flutter_keyboard_visibility.build │ └── dgph │ ├── gRPC-C++-gRPCCertificates-Cpp.build │ └── dgph │ ├── gRPC-C++.build │ └── dgph │ ├── gRPC-Core.build │ └── dgph │ ├── leveldb-library.build │ └── dgph │ └── nanopb.build │ └── dgph ├── lib ├── main.dart ├── models │ ├── chat.dart │ ├── chat_message.dart │ └── chat_user.dart ├── pages │ ├── chat_page.dart │ ├── chats_page.dart │ ├── home_page.dart │ ├── login_page.dart │ ├── register_page.dart │ ├── splash_page.dart │ └── users_page.dart ├── providers │ ├── authentication_provider.dart │ ├── chat_page_provider.dart │ ├── chats_page_provider.dart │ └── users_page_provider.dart ├── services │ ├── cloud_storage_service.dart │ ├── database_service.dart │ ├── media_service.dart │ └── navigation_service.dart └── widgets │ ├── custom_input_fields.dart │ ├── custom_list_view_tiles.dart │ ├── message_bubbles.dart │ ├── rounded_button.dart │ ├── rounded_image.dart │ └── top_bar.dart ├── pubspec.lock ├── pubspec.yaml └── web ├── favicon.png ├── icons ├── Icon-192.png └── Icon-512.png ├── index.html └── manifest.json /.gitignore: -------------------------------------------------------------------------------- 1 | #Firebase 2 | GoogleService-Info.plist 3 | google-services.json 4 | 5 | # Miscellaneous 6 | *.class 7 | *.log 8 | *.pyc 9 | *.swp 10 | .DS_Store 11 | .atom/ 12 | .buildlog/ 13 | .history 14 | .svn/ 15 | 16 | # IntelliJ related 17 | *.iml 18 | *.ipr 19 | *.iws 20 | .idea/ 21 | 22 | # The .vscode folder contains launch configuration and tasks you configure in 23 | # VS Code which you may wish to be included in version control, so this line 24 | # is commented out by default. 25 | #.vscode/ 26 | 27 | # Flutter/Dart/Pub related 28 | **/doc/api/ 29 | **/ios/Flutter/.last_build_id 30 | .dart_tool/ 31 | .flutter-plugins 32 | .flutter-plugins-dependencies 33 | .packages 34 | .pub-cache/ 35 | .pub/ 36 | /build/ 37 | 38 | # Web related 39 | lib/generated_plugin_registrant.dart 40 | 41 | # Symbolication related 42 | app.*.symbols 43 | 44 | # Obfuscation related 45 | app.*.map.json 46 | 47 | # Android Studio will place build artifacts here 48 | /android/app/debug 49 | /android/app/profile 50 | /android/app/release 51 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: f4abaa0735eba4dfd8f33f73363911d63931fe03 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Hussain Mustafa 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Chatify Flutter Application 2 | 3 |

Chatify Flutter & Firebase Powered Chat Application

4 |
5 | Awesome Badge 6 | Star Badge 7 | Join Community Badge 8 |
9 | 10 |
11 | 12 | Flutter Flutter allows you to build beautiful native apps on iOS and Android Platforms from a single codebase. The main goal of this repository is to find free open source apps and start contributing to it. Feel free to [contribute](https://github.com/tortuvshin/open-source-flutter-apps/graphs/contributors) to the list, any suggestions are always welcomed! 13 | 14 |
15 | feed example 16 | feed example 17 |
18 |

19 | 20 | ### Discord 21 | 22 | 23 | feed example 24 | 25 | 26 | ## License 27 | 28 | [![CC0](http://mirrors.creativecommons.org/presskit/buttons/88x31/svg/cc-zero.svg)](https://creativecommons.org/publicdomain/zero/1.0/) -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.google.gms.google-services' 25 | apply plugin: 'com.android.application' 26 | apply plugin: 'kotlin-android' 27 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 28 | 29 | android { 30 | compileSdkVersion 30 31 | 32 | sourceSets { 33 | main.java.srcDirs += 'src/main/kotlin' 34 | } 35 | 36 | defaultConfig { 37 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 38 | applicationId "com.example.chatify_app" 39 | minSdkVersion 21 40 | targetSdkVersion 30 41 | versionCode flutterVersionCode.toInteger() 42 | versionName flutterVersionName 43 | } 44 | 45 | buildTypes { 46 | release { 47 | // TODO: Add your own signing config for the release build. 48 | // Signing with the debug keys for now, so `flutter run --release` works. 49 | signingConfig signingConfigs.debug 50 | } 51 | } 52 | } 53 | 54 | flutter { 55 | source '../..' 56 | } 57 | 58 | dependencies { 59 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 60 | } 61 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 13 | 17 | 21 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 37 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/chatify_app/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.chatify_app 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.google.gms:google-services:4.3.10' 10 | classpath 'com.android.tools.build:gradle:4.1.0' 11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | google() 18 | jcenter() 19 | } 20 | } 21 | 22 | rootProject.buildDir = '../build' 23 | subprojects { 24 | project.buildDir = "${rootProject.buildDir}/${project.name}" 25 | project.evaluationDependsOn(':app') 26 | } 27 | 28 | task clean(type: Delete) { 29 | delete rootProject.buildDir 30 | } 31 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip 7 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/assets/images/logo.png -------------------------------------------------------------------------------- /assets/preview/preview_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/assets/preview/preview_2.png -------------------------------------------------------------------------------- /assets/preview/preview_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/assets/preview/preview_4.png -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/ephemeral/ 22 | Flutter/app.flx 23 | Flutter/app.zip 24 | Flutter/flutter_assets/ 25 | Flutter/flutter_export_environment.sh 26 | ServiceDefinitions.json 27 | Runner/GeneratedPluginRegistrant.* 28 | 29 | # Exceptions to above rules. 30 | !default.mode1v3 31 | !default.mode2v3 32 | !default.pbxuser 33 | !default.perspectivev3 34 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 10.0 25 | 26 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | #platform :ios, '10.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - abseil/algorithm (0.20200225.0): 3 | - abseil/algorithm/algorithm (= 0.20200225.0) 4 | - abseil/algorithm/container (= 0.20200225.0) 5 | - abseil/algorithm/algorithm (0.20200225.0): 6 | - abseil/base/config 7 | - abseil/algorithm/container (0.20200225.0): 8 | - abseil/algorithm/algorithm 9 | - abseil/base/core_headers 10 | - abseil/meta/type_traits 11 | - abseil/base (0.20200225.0): 12 | - abseil/base/atomic_hook (= 0.20200225.0) 13 | - abseil/base/base (= 0.20200225.0) 14 | - abseil/base/base_internal (= 0.20200225.0) 15 | - abseil/base/bits (= 0.20200225.0) 16 | - abseil/base/config (= 0.20200225.0) 17 | - abseil/base/core_headers (= 0.20200225.0) 18 | - abseil/base/dynamic_annotations (= 0.20200225.0) 19 | - abseil/base/endian (= 0.20200225.0) 20 | - abseil/base/errno_saver (= 0.20200225.0) 21 | - abseil/base/exponential_biased (= 0.20200225.0) 22 | - abseil/base/log_severity (= 0.20200225.0) 23 | - abseil/base/malloc_internal (= 0.20200225.0) 24 | - abseil/base/periodic_sampler (= 0.20200225.0) 25 | - abseil/base/pretty_function (= 0.20200225.0) 26 | - abseil/base/raw_logging_internal (= 0.20200225.0) 27 | - abseil/base/spinlock_wait (= 0.20200225.0) 28 | - abseil/base/throw_delegate (= 0.20200225.0) 29 | - abseil/base/atomic_hook (0.20200225.0): 30 | - abseil/base/config 31 | - abseil/base/core_headers 32 | - abseil/base/base (0.20200225.0): 33 | - abseil/base/atomic_hook 34 | - abseil/base/base_internal 35 | - abseil/base/config 36 | - abseil/base/core_headers 37 | - abseil/base/dynamic_annotations 38 | - abseil/base/log_severity 39 | - abseil/base/raw_logging_internal 40 | - abseil/base/spinlock_wait 41 | - abseil/meta/type_traits 42 | - abseil/base/base_internal (0.20200225.0): 43 | - abseil/base/config 44 | - abseil/meta/type_traits 45 | - abseil/base/bits (0.20200225.0): 46 | - abseil/base/config 47 | - abseil/base/core_headers 48 | - abseil/base/config (0.20200225.0) 49 | - abseil/base/core_headers (0.20200225.0): 50 | - abseil/base/config 51 | - abseil/base/dynamic_annotations (0.20200225.0) 52 | - abseil/base/endian (0.20200225.0): 53 | - abseil/base/config 54 | - abseil/base/core_headers 55 | - abseil/base/errno_saver (0.20200225.0): 56 | - abseil/base/config 57 | - abseil/base/exponential_biased (0.20200225.0): 58 | - abseil/base/config 59 | - abseil/base/core_headers 60 | - abseil/base/log_severity (0.20200225.0): 61 | - abseil/base/config 62 | - abseil/base/core_headers 63 | - abseil/base/malloc_internal (0.20200225.0): 64 | - abseil/base/base 65 | - abseil/base/base_internal 66 | - abseil/base/config 67 | - abseil/base/core_headers 68 | - abseil/base/dynamic_annotations 69 | - abseil/base/raw_logging_internal 70 | - abseil/base/periodic_sampler (0.20200225.0): 71 | - abseil/base/core_headers 72 | - abseil/base/exponential_biased 73 | - abseil/base/pretty_function (0.20200225.0) 74 | - abseil/base/raw_logging_internal (0.20200225.0): 75 | - abseil/base/atomic_hook 76 | - abseil/base/config 77 | - abseil/base/core_headers 78 | - abseil/base/log_severity 79 | - abseil/base/spinlock_wait (0.20200225.0): 80 | - abseil/base/base_internal 81 | - abseil/base/core_headers 82 | - abseil/base/errno_saver 83 | - abseil/base/throw_delegate (0.20200225.0): 84 | - abseil/base/config 85 | - abseil/base/raw_logging_internal 86 | - abseil/container/common (0.20200225.0): 87 | - abseil/meta/type_traits 88 | - abseil/types/optional 89 | - abseil/container/compressed_tuple (0.20200225.0): 90 | - abseil/utility/utility 91 | - abseil/container/container_memory (0.20200225.0): 92 | - abseil/memory/memory 93 | - abseil/utility/utility 94 | - abseil/container/fixed_array (0.20200225.0): 95 | - abseil/algorithm/algorithm 96 | - abseil/base/core_headers 97 | - abseil/base/dynamic_annotations 98 | - abseil/base/throw_delegate 99 | - abseil/container/compressed_tuple 100 | - abseil/memory/memory 101 | - abseil/container/flat_hash_map (0.20200225.0): 102 | - abseil/algorithm/container 103 | - abseil/container/container_memory 104 | - abseil/container/hash_function_defaults 105 | - abseil/container/raw_hash_map 106 | - abseil/memory/memory 107 | - abseil/container/hash_function_defaults (0.20200225.0): 108 | - abseil/base/config 109 | - abseil/hash/hash 110 | - abseil/strings/strings 111 | - abseil/container/hash_policy_traits (0.20200225.0): 112 | - abseil/meta/type_traits 113 | - abseil/container/hashtable_debug_hooks (0.20200225.0): 114 | - abseil/base/config 115 | - abseil/container/hashtablez_sampler (0.20200225.0): 116 | - abseil/base/base 117 | - abseil/base/core_headers 118 | - abseil/base/exponential_biased 119 | - abseil/container/have_sse 120 | - abseil/debugging/stacktrace 121 | - abseil/memory/memory 122 | - abseil/synchronization/synchronization 123 | - abseil/utility/utility 124 | - abseil/container/have_sse (0.20200225.0) 125 | - abseil/container/inlined_vector (0.20200225.0): 126 | - abseil/algorithm/algorithm 127 | - abseil/base/core_headers 128 | - abseil/base/throw_delegate 129 | - abseil/container/inlined_vector_internal 130 | - abseil/memory/memory 131 | - abseil/container/inlined_vector_internal (0.20200225.0): 132 | - abseil/base/core_headers 133 | - abseil/container/compressed_tuple 134 | - abseil/memory/memory 135 | - abseil/meta/type_traits 136 | - abseil/types/span 137 | - abseil/container/layout (0.20200225.0): 138 | - abseil/base/core_headers 139 | - abseil/meta/type_traits 140 | - abseil/strings/strings 141 | - abseil/types/span 142 | - abseil/utility/utility 143 | - abseil/container/raw_hash_map (0.20200225.0): 144 | - abseil/base/throw_delegate 145 | - abseil/container/container_memory 146 | - abseil/container/raw_hash_set 147 | - abseil/container/raw_hash_set (0.20200225.0): 148 | - abseil/base/bits 149 | - abseil/base/config 150 | - abseil/base/core_headers 151 | - abseil/base/endian 152 | - abseil/container/common 153 | - abseil/container/compressed_tuple 154 | - abseil/container/container_memory 155 | - abseil/container/hash_policy_traits 156 | - abseil/container/hashtable_debug_hooks 157 | - abseil/container/hashtablez_sampler 158 | - abseil/container/have_sse 159 | - abseil/container/layout 160 | - abseil/memory/memory 161 | - abseil/meta/type_traits 162 | - abseil/utility/utility 163 | - abseil/debugging/debugging_internal (0.20200225.0): 164 | - abseil/base/config 165 | - abseil/base/core_headers 166 | - abseil/base/dynamic_annotations 167 | - abseil/base/errno_saver 168 | - abseil/base/raw_logging_internal 169 | - abseil/debugging/demangle_internal (0.20200225.0): 170 | - abseil/base/base 171 | - abseil/base/config 172 | - abseil/base/core_headers 173 | - abseil/debugging/stacktrace (0.20200225.0): 174 | - abseil/base/config 175 | - abseil/base/core_headers 176 | - abseil/debugging/debugging_internal 177 | - abseil/debugging/symbolize (0.20200225.0): 178 | - abseil/base/base 179 | - abseil/base/config 180 | - abseil/base/core_headers 181 | - abseil/base/dynamic_annotations 182 | - abseil/base/malloc_internal 183 | - abseil/base/raw_logging_internal 184 | - abseil/debugging/debugging_internal 185 | - abseil/debugging/demangle_internal 186 | - abseil/hash/city (0.20200225.0): 187 | - abseil/base/config 188 | - abseil/base/core_headers 189 | - abseil/base/endian 190 | - abseil/hash/hash (0.20200225.0): 191 | - abseil/base/core_headers 192 | - abseil/base/endian 193 | - abseil/container/fixed_array 194 | - abseil/hash/city 195 | - abseil/meta/type_traits 196 | - abseil/numeric/int128 197 | - abseil/strings/strings 198 | - abseil/types/optional 199 | - abseil/types/variant 200 | - abseil/utility/utility 201 | - abseil/memory (0.20200225.0): 202 | - abseil/memory/memory (= 0.20200225.0) 203 | - abseil/memory/memory (0.20200225.0): 204 | - abseil/base/core_headers 205 | - abseil/meta/type_traits 206 | - abseil/meta (0.20200225.0): 207 | - abseil/meta/type_traits (= 0.20200225.0) 208 | - abseil/meta/type_traits (0.20200225.0): 209 | - abseil/base/config 210 | - abseil/numeric/int128 (0.20200225.0): 211 | - abseil/base/config 212 | - abseil/base/core_headers 213 | - abseil/strings/internal (0.20200225.0): 214 | - abseil/base/config 215 | - abseil/base/core_headers 216 | - abseil/base/endian 217 | - abseil/base/raw_logging_internal 218 | - abseil/meta/type_traits 219 | - abseil/strings/str_format (0.20200225.0): 220 | - abseil/strings/str_format_internal 221 | - abseil/strings/str_format_internal (0.20200225.0): 222 | - abseil/base/config 223 | - abseil/base/core_headers 224 | - abseil/meta/type_traits 225 | - abseil/numeric/int128 226 | - abseil/strings/strings 227 | - abseil/types/span 228 | - abseil/strings/strings (0.20200225.0): 229 | - abseil/base/base 230 | - abseil/base/bits 231 | - abseil/base/config 232 | - abseil/base/core_headers 233 | - abseil/base/endian 234 | - abseil/base/raw_logging_internal 235 | - abseil/base/throw_delegate 236 | - abseil/memory/memory 237 | - abseil/meta/type_traits 238 | - abseil/numeric/int128 239 | - abseil/strings/internal 240 | - abseil/synchronization/graphcycles_internal (0.20200225.0): 241 | - abseil/base/base 242 | - abseil/base/base_internal 243 | - abseil/base/config 244 | - abseil/base/core_headers 245 | - abseil/base/malloc_internal 246 | - abseil/base/raw_logging_internal 247 | - abseil/synchronization/kernel_timeout_internal (0.20200225.0): 248 | - abseil/base/core_headers 249 | - abseil/base/raw_logging_internal 250 | - abseil/time/time 251 | - abseil/synchronization/synchronization (0.20200225.0): 252 | - abseil/base/atomic_hook 253 | - abseil/base/base 254 | - abseil/base/base_internal 255 | - abseil/base/config 256 | - abseil/base/core_headers 257 | - abseil/base/dynamic_annotations 258 | - abseil/base/malloc_internal 259 | - abseil/base/raw_logging_internal 260 | - abseil/debugging/stacktrace 261 | - abseil/debugging/symbolize 262 | - abseil/synchronization/graphcycles_internal 263 | - abseil/synchronization/kernel_timeout_internal 264 | - abseil/time/time 265 | - abseil/time (0.20200225.0): 266 | - abseil/time/internal (= 0.20200225.0) 267 | - abseil/time/time (= 0.20200225.0) 268 | - abseil/time/internal (0.20200225.0): 269 | - abseil/time/internal/cctz (= 0.20200225.0) 270 | - abseil/time/internal/cctz (0.20200225.0): 271 | - abseil/time/internal/cctz/civil_time (= 0.20200225.0) 272 | - abseil/time/internal/cctz/time_zone (= 0.20200225.0) 273 | - abseil/time/internal/cctz/civil_time (0.20200225.0): 274 | - abseil/base/config 275 | - abseil/time/internal/cctz/time_zone (0.20200225.0): 276 | - abseil/base/config 277 | - abseil/time/internal/cctz/civil_time 278 | - abseil/time/time (0.20200225.0): 279 | - abseil/base/base 280 | - abseil/base/core_headers 281 | - abseil/base/raw_logging_internal 282 | - abseil/numeric/int128 283 | - abseil/strings/strings 284 | - abseil/time/internal/cctz/civil_time 285 | - abseil/time/internal/cctz/time_zone 286 | - abseil/types (0.20200225.0): 287 | - abseil/types/any (= 0.20200225.0) 288 | - abseil/types/bad_any_cast (= 0.20200225.0) 289 | - abseil/types/bad_any_cast_impl (= 0.20200225.0) 290 | - abseil/types/bad_optional_access (= 0.20200225.0) 291 | - abseil/types/bad_variant_access (= 0.20200225.0) 292 | - abseil/types/compare (= 0.20200225.0) 293 | - abseil/types/optional (= 0.20200225.0) 294 | - abseil/types/span (= 0.20200225.0) 295 | - abseil/types/variant (= 0.20200225.0) 296 | - abseil/types/any (0.20200225.0): 297 | - abseil/base/config 298 | - abseil/base/core_headers 299 | - abseil/meta/type_traits 300 | - abseil/types/bad_any_cast 301 | - abseil/utility/utility 302 | - abseil/types/bad_any_cast (0.20200225.0): 303 | - abseil/base/config 304 | - abseil/types/bad_any_cast_impl 305 | - abseil/types/bad_any_cast_impl (0.20200225.0): 306 | - abseil/base/config 307 | - abseil/base/raw_logging_internal 308 | - abseil/types/bad_optional_access (0.20200225.0): 309 | - abseil/base/config 310 | - abseil/base/raw_logging_internal 311 | - abseil/types/bad_variant_access (0.20200225.0): 312 | - abseil/base/config 313 | - abseil/base/raw_logging_internal 314 | - abseil/types/compare (0.20200225.0): 315 | - abseil/base/core_headers 316 | - abseil/meta/type_traits 317 | - abseil/types/optional (0.20200225.0): 318 | - abseil/base/base_internal 319 | - abseil/base/config 320 | - abseil/base/core_headers 321 | - abseil/memory/memory 322 | - abseil/meta/type_traits 323 | - abseil/types/bad_optional_access 324 | - abseil/utility/utility 325 | - abseil/types/span (0.20200225.0): 326 | - abseil/algorithm/algorithm 327 | - abseil/base/core_headers 328 | - abseil/base/throw_delegate 329 | - abseil/meta/type_traits 330 | - abseil/types/variant (0.20200225.0): 331 | - abseil/base/base_internal 332 | - abseil/base/config 333 | - abseil/base/core_headers 334 | - abseil/meta/type_traits 335 | - abseil/types/bad_variant_access 336 | - abseil/utility/utility 337 | - abseil/utility/utility (0.20200225.0): 338 | - abseil/base/base_internal 339 | - abseil/base/config 340 | - abseil/meta/type_traits 341 | - BoringSSL-GRPC (0.0.7): 342 | - BoringSSL-GRPC/Implementation (= 0.0.7) 343 | - BoringSSL-GRPC/Interface (= 0.0.7) 344 | - BoringSSL-GRPC/Implementation (0.0.7): 345 | - BoringSSL-GRPC/Interface (= 0.0.7) 346 | - BoringSSL-GRPC/Interface (0.0.7) 347 | - cloud_firestore (2.5.1): 348 | - Firebase/Firestore (= 8.6.0) 349 | - firebase_core 350 | - Flutter 351 | - DKImagePickerController/Core (4.3.2): 352 | - DKImagePickerController/ImageDataManager 353 | - DKImagePickerController/Resource 354 | - DKImagePickerController/ImageDataManager (4.3.2) 355 | - DKImagePickerController/PhotoGallery (4.3.2): 356 | - DKImagePickerController/Core 357 | - DKPhotoGallery 358 | - DKImagePickerController/Resource (4.3.2) 359 | - DKPhotoGallery (0.0.17): 360 | - DKPhotoGallery/Core (= 0.0.17) 361 | - DKPhotoGallery/Model (= 0.0.17) 362 | - DKPhotoGallery/Preview (= 0.0.17) 363 | - DKPhotoGallery/Resource (= 0.0.17) 364 | - SDWebImage 365 | - SwiftyGif 366 | - DKPhotoGallery/Core (0.0.17): 367 | - DKPhotoGallery/Model 368 | - DKPhotoGallery/Preview 369 | - SDWebImage 370 | - SwiftyGif 371 | - DKPhotoGallery/Model (0.0.17): 372 | - SDWebImage 373 | - SwiftyGif 374 | - DKPhotoGallery/Preview (0.0.17): 375 | - DKPhotoGallery/Model 376 | - DKPhotoGallery/Resource 377 | - SDWebImage 378 | - SwiftyGif 379 | - DKPhotoGallery/Resource (0.0.17): 380 | - SDWebImage 381 | - SwiftyGif 382 | - file_picker (0.0.1): 383 | - DKImagePickerController/PhotoGallery 384 | - Flutter 385 | - Firebase/Analytics (8.6.0): 386 | - Firebase/Core 387 | - Firebase/Auth (8.6.0): 388 | - Firebase/CoreOnly 389 | - FirebaseAuth (~> 8.6.0) 390 | - Firebase/Core (8.6.0): 391 | - Firebase/CoreOnly 392 | - FirebaseAnalytics (~> 8.6.0) 393 | - Firebase/CoreOnly (8.6.0): 394 | - FirebaseCore (= 8.6.0) 395 | - Firebase/Firestore (8.6.0): 396 | - Firebase/CoreOnly 397 | - FirebaseFirestore (~> 8.6.0) 398 | - Firebase/Storage (8.6.0): 399 | - Firebase/CoreOnly 400 | - FirebaseStorage (~> 8.6.0) 401 | - firebase_analytics (8.3.1): 402 | - Firebase/Analytics (= 8.6.0) 403 | - firebase_core 404 | - Flutter 405 | - firebase_auth (3.1.0): 406 | - Firebase/Auth (= 8.6.0) 407 | - firebase_core 408 | - Flutter 409 | - firebase_core (1.6.0): 410 | - Firebase/CoreOnly (= 8.6.0) 411 | - Flutter 412 | - firebase_storage (10.0.3): 413 | - Firebase/Storage (= 8.6.0) 414 | - firebase_core 415 | - Flutter 416 | - FirebaseAnalytics (8.6.0): 417 | - FirebaseAnalytics/AdIdSupport (= 8.6.0) 418 | - FirebaseCore (~> 8.0) 419 | - FirebaseInstallations (~> 8.0) 420 | - GoogleUtilities/AppDelegateSwizzler (~> 7.4) 421 | - GoogleUtilities/MethodSwizzler (~> 7.4) 422 | - GoogleUtilities/Network (~> 7.4) 423 | - "GoogleUtilities/NSData+zlib (~> 7.4)" 424 | - nanopb (~> 2.30908.0) 425 | - FirebaseAnalytics/AdIdSupport (8.6.0): 426 | - FirebaseCore (~> 8.0) 427 | - FirebaseInstallations (~> 8.0) 428 | - GoogleAppMeasurement (= 8.6.0) 429 | - GoogleUtilities/AppDelegateSwizzler (~> 7.4) 430 | - GoogleUtilities/MethodSwizzler (~> 7.4) 431 | - GoogleUtilities/Network (~> 7.4) 432 | - "GoogleUtilities/NSData+zlib (~> 7.4)" 433 | - nanopb (~> 2.30908.0) 434 | - FirebaseAuth (8.6.0): 435 | - FirebaseCore (~> 8.0) 436 | - GoogleUtilities/AppDelegateSwizzler (~> 7.4) 437 | - GoogleUtilities/Environment (~> 7.4) 438 | - GTMSessionFetcher/Core (~> 1.5) 439 | - FirebaseCore (8.6.0): 440 | - FirebaseCoreDiagnostics (~> 8.0) 441 | - GoogleUtilities/Environment (~> 7.4) 442 | - GoogleUtilities/Logger (~> 7.4) 443 | - FirebaseCoreDiagnostics (8.7.0): 444 | - GoogleDataTransport (~> 9.0) 445 | - GoogleUtilities/Environment (~> 7.4) 446 | - GoogleUtilities/Logger (~> 7.4) 447 | - nanopb (~> 2.30908.0) 448 | - FirebaseFirestore (8.6.0): 449 | - abseil/algorithm (= 0.20200225.0) 450 | - abseil/base (= 0.20200225.0) 451 | - abseil/container/flat_hash_map (= 0.20200225.0) 452 | - abseil/memory (= 0.20200225.0) 453 | - abseil/meta (= 0.20200225.0) 454 | - abseil/strings/strings (= 0.20200225.0) 455 | - abseil/time (= 0.20200225.0) 456 | - abseil/types (= 0.20200225.0) 457 | - FirebaseCore (~> 8.0) 458 | - "gRPC-C++ (~> 1.28.0)" 459 | - leveldb-library (~> 1.22) 460 | - nanopb (~> 2.30908.0) 461 | - FirebaseInstallations (8.7.0): 462 | - FirebaseCore (~> 8.0) 463 | - GoogleUtilities/Environment (~> 7.4) 464 | - GoogleUtilities/UserDefaults (~> 7.4) 465 | - PromisesObjC (< 3.0, >= 1.2) 466 | - FirebaseStorage (8.6.0): 467 | - FirebaseCore (~> 8.0) 468 | - GTMSessionFetcher/Core (~> 1.5) 469 | - Flutter (1.0.0) 470 | - flutter_keyboard_visibility (0.0.1): 471 | - Flutter 472 | - GoogleAppMeasurement (8.6.0): 473 | - GoogleAppMeasurement/AdIdSupport (= 8.6.0) 474 | - GoogleUtilities/AppDelegateSwizzler (~> 7.4) 475 | - GoogleUtilities/MethodSwizzler (~> 7.4) 476 | - GoogleUtilities/Network (~> 7.4) 477 | - "GoogleUtilities/NSData+zlib (~> 7.4)" 478 | - nanopb (~> 2.30908.0) 479 | - GoogleAppMeasurement/AdIdSupport (8.6.0): 480 | - GoogleUtilities/AppDelegateSwizzler (~> 7.4) 481 | - GoogleUtilities/MethodSwizzler (~> 7.4) 482 | - GoogleUtilities/Network (~> 7.4) 483 | - "GoogleUtilities/NSData+zlib (~> 7.4)" 484 | - nanopb (~> 2.30908.0) 485 | - GoogleDataTransport (9.1.0): 486 | - GoogleUtilities/Environment (~> 7.2) 487 | - nanopb (~> 2.30908.0) 488 | - PromisesObjC (< 3.0, >= 1.2) 489 | - GoogleUtilities/AppDelegateSwizzler (7.5.2): 490 | - GoogleUtilities/Environment 491 | - GoogleUtilities/Logger 492 | - GoogleUtilities/Network 493 | - GoogleUtilities/Environment (7.5.2): 494 | - PromisesObjC (< 3.0, >= 1.2) 495 | - GoogleUtilities/Logger (7.5.2): 496 | - GoogleUtilities/Environment 497 | - GoogleUtilities/MethodSwizzler (7.5.2): 498 | - GoogleUtilities/Logger 499 | - GoogleUtilities/Network (7.5.2): 500 | - GoogleUtilities/Logger 501 | - "GoogleUtilities/NSData+zlib" 502 | - GoogleUtilities/Reachability 503 | - "GoogleUtilities/NSData+zlib (7.5.2)" 504 | - GoogleUtilities/Reachability (7.5.2): 505 | - GoogleUtilities/Logger 506 | - GoogleUtilities/UserDefaults (7.5.2): 507 | - GoogleUtilities/Logger 508 | - "gRPC-C++ (1.28.2)": 509 | - "gRPC-C++/Implementation (= 1.28.2)" 510 | - "gRPC-C++/Interface (= 1.28.2)" 511 | - "gRPC-C++/Implementation (1.28.2)": 512 | - abseil/container/inlined_vector (= 0.20200225.0) 513 | - abseil/memory/memory (= 0.20200225.0) 514 | - abseil/strings/str_format (= 0.20200225.0) 515 | - abseil/strings/strings (= 0.20200225.0) 516 | - abseil/types/optional (= 0.20200225.0) 517 | - "gRPC-C++/Interface (= 1.28.2)" 518 | - gRPC-Core (= 1.28.2) 519 | - "gRPC-C++/Interface (1.28.2)" 520 | - gRPC-Core (1.28.2): 521 | - gRPC-Core/Implementation (= 1.28.2) 522 | - gRPC-Core/Interface (= 1.28.2) 523 | - gRPC-Core/Implementation (1.28.2): 524 | - abseil/container/inlined_vector (= 0.20200225.0) 525 | - abseil/memory/memory (= 0.20200225.0) 526 | - abseil/strings/str_format (= 0.20200225.0) 527 | - abseil/strings/strings (= 0.20200225.0) 528 | - abseil/types/optional (= 0.20200225.0) 529 | - BoringSSL-GRPC (= 0.0.7) 530 | - gRPC-Core/Interface (= 1.28.2) 531 | - gRPC-Core/Interface (1.28.2) 532 | - GTMSessionFetcher/Core (1.7.0) 533 | - leveldb-library (1.22.1) 534 | - nanopb (2.30908.0): 535 | - nanopb/decode (= 2.30908.0) 536 | - nanopb/encode (= 2.30908.0) 537 | - nanopb/decode (2.30908.0) 538 | - nanopb/encode (2.30908.0) 539 | - PromisesObjC (2.0.0) 540 | - SDWebImage (5.11.1): 541 | - SDWebImage/Core (= 5.11.1) 542 | - SDWebImage/Core (5.11.1) 543 | - SwiftyGif (5.4.0) 544 | 545 | DEPENDENCIES: 546 | - cloud_firestore (from `.symlinks/plugins/cloud_firestore/ios`) 547 | - file_picker (from `.symlinks/plugins/file_picker/ios`) 548 | - firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`) 549 | - firebase_auth (from `.symlinks/plugins/firebase_auth/ios`) 550 | - firebase_core (from `.symlinks/plugins/firebase_core/ios`) 551 | - firebase_storage (from `.symlinks/plugins/firebase_storage/ios`) 552 | - Flutter (from `Flutter`) 553 | - flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`) 554 | 555 | SPEC REPOS: 556 | trunk: 557 | - abseil 558 | - BoringSSL-GRPC 559 | - DKImagePickerController 560 | - DKPhotoGallery 561 | - Firebase 562 | - FirebaseAnalytics 563 | - FirebaseAuth 564 | - FirebaseCore 565 | - FirebaseCoreDiagnostics 566 | - FirebaseFirestore 567 | - FirebaseInstallations 568 | - FirebaseStorage 569 | - GoogleAppMeasurement 570 | - GoogleDataTransport 571 | - GoogleUtilities 572 | - "gRPC-C++" 573 | - gRPC-Core 574 | - GTMSessionFetcher 575 | - leveldb-library 576 | - nanopb 577 | - PromisesObjC 578 | - SDWebImage 579 | - SwiftyGif 580 | 581 | EXTERNAL SOURCES: 582 | cloud_firestore: 583 | :path: ".symlinks/plugins/cloud_firestore/ios" 584 | file_picker: 585 | :path: ".symlinks/plugins/file_picker/ios" 586 | firebase_analytics: 587 | :path: ".symlinks/plugins/firebase_analytics/ios" 588 | firebase_auth: 589 | :path: ".symlinks/plugins/firebase_auth/ios" 590 | firebase_core: 591 | :path: ".symlinks/plugins/firebase_core/ios" 592 | firebase_storage: 593 | :path: ".symlinks/plugins/firebase_storage/ios" 594 | Flutter: 595 | :path: Flutter 596 | flutter_keyboard_visibility: 597 | :path: ".symlinks/plugins/flutter_keyboard_visibility/ios" 598 | 599 | SPEC CHECKSUMS: 600 | abseil: 6c8eb7892aefa08d929b39f9bb108e5367e3228f 601 | BoringSSL-GRPC: 8edf627ee524575e2f8d19d56f068b448eea3879 602 | cloud_firestore: 3280837bd2fdec18489ef93699527df4af4f177d 603 | DKImagePickerController: b5eb7f7a388e4643264105d648d01f727110fc3d 604 | DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179 605 | file_picker: 3e6c3790de664ccf9b882732d9db5eaf6b8d4eb1 606 | Firebase: 21ac9f28b09a8bdfc005f34c984fca84e7e8786d 607 | firebase_analytics: de68415415782a5ad1d922d5c51789afbb2bb82d 608 | firebase_auth: 2dfa8e886191c24ddcf4da34463d47b72e6d19dc 609 | firebase_core: c21ac09a8d23afd3594b56ed786bad12e5266bba 610 | firebase_storage: 75fc62b16cfbb268ea4e90729be5729e3dc38b1e 611 | FirebaseAnalytics: 8f32ae54ad42754f503354782575c4ddfc1425c3 612 | FirebaseAuth: 223adeeb2262b417532e89bf06a960e3a0a1e9e4 613 | FirebaseCore: 620b677f70f5470a8e59cb77f3ddc666f6f09785 614 | FirebaseCoreDiagnostics: b63732f581a1c6a453ec7241f9ab60b3a5bd3450 615 | FirebaseFirestore: 7b8bd72aff4d3ad91498343e81fdbaa994ce8abe 616 | FirebaseInstallations: ede6fb72bb6337914e5888b399271259d0c4910c 617 | FirebaseStorage: 2765944230981e63f8bd2938d9d5819158b7c34c 618 | Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a 619 | flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069 620 | GoogleAppMeasurement: 2c0c6e2a7ab3fe730ade6379f732bdefb46f50b0 621 | GoogleDataTransport: 85fd18ff3019bb85d3f2c551d04c481dedf71fc9 622 | GoogleUtilities: 8de2a97a17e15b6b98e38e8770e2d129a57c0040 623 | "gRPC-C++": 13d8ccef97d5c3c441b7e3c529ef28ebee86fad2 624 | gRPC-Core: 4afa11bfbedf7cdecd04de535a9e046893404ed5 625 | GTMSessionFetcher: 43748f93435c2aa068b1cbe39655aaf600652e91 626 | leveldb-library: 50c7b45cbd7bf543c81a468fe557a16ae3db8729 627 | nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96 628 | PromisesObjC: 68159ce6952d93e17b2dfe273b8c40907db5ba58 629 | SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d 630 | SwiftyGif: 5d4af95df24caf1c570dbbcb32a3b8a0763bc6d7 631 | 632 | PODFILE CHECKSUM: 9b30da706c782e048277779a01ce55c0622f1606 633 | 634 | COCOAPODS: 1.10.2 635 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 51; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 646F5D4C315B49521EFD061F /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB424645C44E3056495B97E8 /* Pods_Runner.framework */; }; 13 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 14 | 9744C0FA26E55B9B00DC834A /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9744C0F926E55B9B00DC834A /* GoogleService-Info.plist */; }; 15 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 16 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 17 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXCopyFilesBuildPhase section */ 21 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 22 | isa = PBXCopyFilesBuildPhase; 23 | buildActionMask = 2147483647; 24 | dstPath = ""; 25 | dstSubfolderSpec = 10; 26 | files = ( 27 | ); 28 | name = "Embed Frameworks"; 29 | runOnlyForDeploymentPostprocessing = 0; 30 | }; 31 | /* End PBXCopyFilesBuildPhase section */ 32 | 33 | /* Begin PBXFileReference section */ 34 | 035B284C9A8017957699BE8E /* 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 = ""; }; 35 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 36 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 37 | 23A7EF1271EB9DA6ACFA60BA /* 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 = ""; }; 38 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 39 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 40 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 41 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 42 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 43 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 44 | 9744C0F926E55B9B00DC834A /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 45 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 47 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 48 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 49 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 50 | B81DD0A5F7291F56077C71FE /* 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 = ""; }; 51 | CB424645C44E3056495B97E8 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | /* End PBXFileReference section */ 53 | 54 | /* Begin PBXFrameworksBuildPhase section */ 55 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 56 | isa = PBXFrameworksBuildPhase; 57 | buildActionMask = 2147483647; 58 | files = ( 59 | 646F5D4C315B49521EFD061F /* Pods_Runner.framework in Frameworks */, 60 | ); 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | /* End PBXFrameworksBuildPhase section */ 64 | 65 | /* Begin PBXGroup section */ 66 | 67F08A3D8FA7B60FA834C4C7 /* Frameworks */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | CB424645C44E3056495B97E8 /* Pods_Runner.framework */, 70 | ); 71 | name = Frameworks; 72 | sourceTree = ""; 73 | }; 74 | 9740EEB11CF90186004384FC /* Flutter */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 78 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 79 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 80 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 81 | ); 82 | name = Flutter; 83 | sourceTree = ""; 84 | }; 85 | 97C146E51CF9000F007C117D = { 86 | isa = PBXGroup; 87 | children = ( 88 | 9740EEB11CF90186004384FC /* Flutter */, 89 | 97C146F01CF9000F007C117D /* Runner */, 90 | 97C146EF1CF9000F007C117D /* Products */, 91 | F2CA52E7E1442246E2515173 /* Pods */, 92 | 67F08A3D8FA7B60FA834C4C7 /* Frameworks */, 93 | ); 94 | sourceTree = ""; 95 | }; 96 | 97C146EF1CF9000F007C117D /* Products */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | 97C146EE1CF9000F007C117D /* Runner.app */, 100 | ); 101 | name = Products; 102 | sourceTree = ""; 103 | }; 104 | 97C146F01CF9000F007C117D /* Runner */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 9744C0F926E55B9B00DC834A /* GoogleService-Info.plist */, 108 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 109 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 110 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 111 | 97C147021CF9000F007C117D /* Info.plist */, 112 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 113 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 114 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 115 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 116 | ); 117 | path = Runner; 118 | sourceTree = ""; 119 | }; 120 | F2CA52E7E1442246E2515173 /* Pods */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | B81DD0A5F7291F56077C71FE /* Pods-Runner.debug.xcconfig */, 124 | 23A7EF1271EB9DA6ACFA60BA /* Pods-Runner.release.xcconfig */, 125 | 035B284C9A8017957699BE8E /* Pods-Runner.profile.xcconfig */, 126 | ); 127 | path = Pods; 128 | sourceTree = ""; 129 | }; 130 | /* End PBXGroup section */ 131 | 132 | /* Begin PBXNativeTarget section */ 133 | 97C146ED1CF9000F007C117D /* Runner */ = { 134 | isa = PBXNativeTarget; 135 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 136 | buildPhases = ( 137 | 48593859D752F7DF29805BF0 /* [CP] Check Pods Manifest.lock */, 138 | 9740EEB61CF901F6004384FC /* Run Script */, 139 | 97C146EA1CF9000F007C117D /* Sources */, 140 | 97C146EB1CF9000F007C117D /* Frameworks */, 141 | 97C146EC1CF9000F007C117D /* Resources */, 142 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 143 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 144 | 57CDEA424E0A76DB86395DDD /* [CP] Embed Pods Frameworks */, 145 | ); 146 | buildRules = ( 147 | ); 148 | dependencies = ( 149 | ); 150 | name = Runner; 151 | productName = Runner; 152 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 153 | productType = "com.apple.product-type.application"; 154 | }; 155 | /* End PBXNativeTarget section */ 156 | 157 | /* Begin PBXProject section */ 158 | 97C146E61CF9000F007C117D /* Project object */ = { 159 | isa = PBXProject; 160 | attributes = { 161 | LastUpgradeCheck = 1020; 162 | ORGANIZATIONNAME = ""; 163 | TargetAttributes = { 164 | 97C146ED1CF9000F007C117D = { 165 | CreatedOnToolsVersion = 7.3.1; 166 | LastSwiftMigration = 1100; 167 | }; 168 | }; 169 | }; 170 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 171 | compatibilityVersion = "Xcode 9.3"; 172 | developmentRegion = en; 173 | hasScannedForEncodings = 0; 174 | knownRegions = ( 175 | en, 176 | Base, 177 | ); 178 | mainGroup = 97C146E51CF9000F007C117D; 179 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 180 | projectDirPath = ""; 181 | projectRoot = ""; 182 | targets = ( 183 | 97C146ED1CF9000F007C117D /* Runner */, 184 | ); 185 | }; 186 | /* End PBXProject section */ 187 | 188 | /* Begin PBXResourcesBuildPhase section */ 189 | 97C146EC1CF9000F007C117D /* Resources */ = { 190 | isa = PBXResourcesBuildPhase; 191 | buildActionMask = 2147483647; 192 | files = ( 193 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 194 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 195 | 9744C0FA26E55B9B00DC834A /* GoogleService-Info.plist in Resources */, 196 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 197 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 198 | ); 199 | runOnlyForDeploymentPostprocessing = 0; 200 | }; 201 | /* End PBXResourcesBuildPhase section */ 202 | 203 | /* Begin PBXShellScriptBuildPhase section */ 204 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 205 | isa = PBXShellScriptBuildPhase; 206 | buildActionMask = 2147483647; 207 | files = ( 208 | ); 209 | inputPaths = ( 210 | ); 211 | name = "Thin Binary"; 212 | outputPaths = ( 213 | ); 214 | runOnlyForDeploymentPostprocessing = 0; 215 | shellPath = /bin/sh; 216 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 217 | }; 218 | 48593859D752F7DF29805BF0 /* [CP] Check Pods Manifest.lock */ = { 219 | isa = PBXShellScriptBuildPhase; 220 | buildActionMask = 2147483647; 221 | files = ( 222 | ); 223 | inputFileListPaths = ( 224 | ); 225 | inputPaths = ( 226 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 227 | "${PODS_ROOT}/Manifest.lock", 228 | ); 229 | name = "[CP] Check Pods Manifest.lock"; 230 | outputFileListPaths = ( 231 | ); 232 | outputPaths = ( 233 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 234 | ); 235 | runOnlyForDeploymentPostprocessing = 0; 236 | shellPath = /bin/sh; 237 | 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"; 238 | showEnvVarsInLog = 0; 239 | }; 240 | 57CDEA424E0A76DB86395DDD /* [CP] Embed Pods Frameworks */ = { 241 | isa = PBXShellScriptBuildPhase; 242 | buildActionMask = 2147483647; 243 | files = ( 244 | ); 245 | inputFileListPaths = ( 246 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", 247 | ); 248 | name = "[CP] Embed Pods Frameworks"; 249 | outputFileListPaths = ( 250 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", 251 | ); 252 | runOnlyForDeploymentPostprocessing = 0; 253 | shellPath = /bin/sh; 254 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 255 | showEnvVarsInLog = 0; 256 | }; 257 | 9740EEB61CF901F6004384FC /* Run Script */ = { 258 | isa = PBXShellScriptBuildPhase; 259 | buildActionMask = 2147483647; 260 | files = ( 261 | ); 262 | inputPaths = ( 263 | ); 264 | name = "Run Script"; 265 | outputPaths = ( 266 | ); 267 | runOnlyForDeploymentPostprocessing = 0; 268 | shellPath = /bin/sh; 269 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 270 | }; 271 | /* End PBXShellScriptBuildPhase section */ 272 | 273 | /* Begin PBXSourcesBuildPhase section */ 274 | 97C146EA1CF9000F007C117D /* Sources */ = { 275 | isa = PBXSourcesBuildPhase; 276 | buildActionMask = 2147483647; 277 | files = ( 278 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 279 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 280 | ); 281 | runOnlyForDeploymentPostprocessing = 0; 282 | }; 283 | /* End PBXSourcesBuildPhase section */ 284 | 285 | /* Begin PBXVariantGroup section */ 286 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 287 | isa = PBXVariantGroup; 288 | children = ( 289 | 97C146FB1CF9000F007C117D /* Base */, 290 | ); 291 | name = Main.storyboard; 292 | sourceTree = ""; 293 | }; 294 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 295 | isa = PBXVariantGroup; 296 | children = ( 297 | 97C147001CF9000F007C117D /* Base */, 298 | ); 299 | name = LaunchScreen.storyboard; 300 | sourceTree = ""; 301 | }; 302 | /* End PBXVariantGroup section */ 303 | 304 | /* Begin XCBuildConfiguration section */ 305 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 306 | isa = XCBuildConfiguration; 307 | buildSettings = { 308 | ALWAYS_SEARCH_USER_PATHS = NO; 309 | CLANG_ANALYZER_NONNULL = YES; 310 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 311 | CLANG_CXX_LIBRARY = "libc++"; 312 | CLANG_ENABLE_MODULES = YES; 313 | CLANG_ENABLE_OBJC_ARC = YES; 314 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 315 | CLANG_WARN_BOOL_CONVERSION = YES; 316 | CLANG_WARN_COMMA = YES; 317 | CLANG_WARN_CONSTANT_CONVERSION = YES; 318 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 319 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 320 | CLANG_WARN_EMPTY_BODY = YES; 321 | CLANG_WARN_ENUM_CONVERSION = YES; 322 | CLANG_WARN_INFINITE_RECURSION = YES; 323 | CLANG_WARN_INT_CONVERSION = YES; 324 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 325 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 326 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 327 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 328 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 329 | CLANG_WARN_STRICT_PROTOTYPES = YES; 330 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 331 | CLANG_WARN_UNREACHABLE_CODE = YES; 332 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 333 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 334 | COPY_PHASE_STRIP = NO; 335 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 336 | ENABLE_NS_ASSERTIONS = NO; 337 | ENABLE_STRICT_OBJC_MSGSEND = YES; 338 | GCC_C_LANGUAGE_STANDARD = gnu99; 339 | GCC_NO_COMMON_BLOCKS = YES; 340 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 341 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 342 | GCC_WARN_UNDECLARED_SELECTOR = YES; 343 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 344 | GCC_WARN_UNUSED_FUNCTION = YES; 345 | GCC_WARN_UNUSED_VARIABLE = YES; 346 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 347 | MTL_ENABLE_DEBUG_INFO = NO; 348 | SDKROOT = iphoneos; 349 | SUPPORTED_PLATFORMS = iphoneos; 350 | TARGETED_DEVICE_FAMILY = "1,2"; 351 | VALIDATE_PRODUCT = YES; 352 | }; 353 | name = Profile; 354 | }; 355 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 356 | isa = XCBuildConfiguration; 357 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 358 | buildSettings = { 359 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 360 | CLANG_ENABLE_MODULES = YES; 361 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 362 | ENABLE_BITCODE = NO; 363 | INFOPLIST_FILE = Runner/Info.plist; 364 | LD_RUNPATH_SEARCH_PATHS = ( 365 | "$(inherited)", 366 | "@executable_path/Frameworks", 367 | ); 368 | PRODUCT_BUNDLE_IDENTIFIER = com.example.chatifyApp; 369 | PRODUCT_NAME = "$(TARGET_NAME)"; 370 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 371 | SWIFT_VERSION = 5.0; 372 | VERSIONING_SYSTEM = "apple-generic"; 373 | }; 374 | name = Profile; 375 | }; 376 | 97C147031CF9000F007C117D /* Debug */ = { 377 | isa = XCBuildConfiguration; 378 | buildSettings = { 379 | ALWAYS_SEARCH_USER_PATHS = NO; 380 | CLANG_ANALYZER_NONNULL = YES; 381 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 382 | CLANG_CXX_LIBRARY = "libc++"; 383 | CLANG_ENABLE_MODULES = YES; 384 | CLANG_ENABLE_OBJC_ARC = YES; 385 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 386 | CLANG_WARN_BOOL_CONVERSION = YES; 387 | CLANG_WARN_COMMA = YES; 388 | CLANG_WARN_CONSTANT_CONVERSION = YES; 389 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 390 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 391 | CLANG_WARN_EMPTY_BODY = YES; 392 | CLANG_WARN_ENUM_CONVERSION = YES; 393 | CLANG_WARN_INFINITE_RECURSION = YES; 394 | CLANG_WARN_INT_CONVERSION = YES; 395 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 396 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 397 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 398 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 399 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 400 | CLANG_WARN_STRICT_PROTOTYPES = YES; 401 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 402 | CLANG_WARN_UNREACHABLE_CODE = YES; 403 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 404 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 405 | COPY_PHASE_STRIP = NO; 406 | DEBUG_INFORMATION_FORMAT = dwarf; 407 | ENABLE_STRICT_OBJC_MSGSEND = YES; 408 | ENABLE_TESTABILITY = YES; 409 | GCC_C_LANGUAGE_STANDARD = gnu99; 410 | GCC_DYNAMIC_NO_PIC = NO; 411 | GCC_NO_COMMON_BLOCKS = YES; 412 | GCC_OPTIMIZATION_LEVEL = 0; 413 | GCC_PREPROCESSOR_DEFINITIONS = ( 414 | "DEBUG=1", 415 | "$(inherited)", 416 | ); 417 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 418 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 419 | GCC_WARN_UNDECLARED_SELECTOR = YES; 420 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 421 | GCC_WARN_UNUSED_FUNCTION = YES; 422 | GCC_WARN_UNUSED_VARIABLE = YES; 423 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 424 | MTL_ENABLE_DEBUG_INFO = YES; 425 | ONLY_ACTIVE_ARCH = YES; 426 | SDKROOT = iphoneos; 427 | TARGETED_DEVICE_FAMILY = "1,2"; 428 | }; 429 | name = Debug; 430 | }; 431 | 97C147041CF9000F007C117D /* Release */ = { 432 | isa = XCBuildConfiguration; 433 | buildSettings = { 434 | ALWAYS_SEARCH_USER_PATHS = NO; 435 | CLANG_ANALYZER_NONNULL = YES; 436 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 437 | CLANG_CXX_LIBRARY = "libc++"; 438 | CLANG_ENABLE_MODULES = YES; 439 | CLANG_ENABLE_OBJC_ARC = YES; 440 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 441 | CLANG_WARN_BOOL_CONVERSION = YES; 442 | CLANG_WARN_COMMA = YES; 443 | CLANG_WARN_CONSTANT_CONVERSION = YES; 444 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 445 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 446 | CLANG_WARN_EMPTY_BODY = YES; 447 | CLANG_WARN_ENUM_CONVERSION = YES; 448 | CLANG_WARN_INFINITE_RECURSION = YES; 449 | CLANG_WARN_INT_CONVERSION = YES; 450 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 451 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 452 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 453 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 454 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 455 | CLANG_WARN_STRICT_PROTOTYPES = YES; 456 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 457 | CLANG_WARN_UNREACHABLE_CODE = YES; 458 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 459 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 460 | COPY_PHASE_STRIP = NO; 461 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 462 | ENABLE_NS_ASSERTIONS = NO; 463 | ENABLE_STRICT_OBJC_MSGSEND = YES; 464 | GCC_C_LANGUAGE_STANDARD = gnu99; 465 | GCC_NO_COMMON_BLOCKS = YES; 466 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 467 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 468 | GCC_WARN_UNDECLARED_SELECTOR = YES; 469 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 470 | GCC_WARN_UNUSED_FUNCTION = YES; 471 | GCC_WARN_UNUSED_VARIABLE = YES; 472 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 473 | MTL_ENABLE_DEBUG_INFO = NO; 474 | SDKROOT = iphoneos; 475 | SUPPORTED_PLATFORMS = iphoneos; 476 | SWIFT_COMPILATION_MODE = wholemodule; 477 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 478 | TARGETED_DEVICE_FAMILY = "1,2"; 479 | VALIDATE_PRODUCT = YES; 480 | }; 481 | name = Release; 482 | }; 483 | 97C147061CF9000F007C117D /* Debug */ = { 484 | isa = XCBuildConfiguration; 485 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 486 | buildSettings = { 487 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 488 | CLANG_ENABLE_MODULES = YES; 489 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 490 | ENABLE_BITCODE = NO; 491 | INFOPLIST_FILE = Runner/Info.plist; 492 | LD_RUNPATH_SEARCH_PATHS = ( 493 | "$(inherited)", 494 | "@executable_path/Frameworks", 495 | ); 496 | PRODUCT_BUNDLE_IDENTIFIER = com.example.chatifyApp; 497 | PRODUCT_NAME = "$(TARGET_NAME)"; 498 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 499 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 500 | SWIFT_VERSION = 5.0; 501 | VERSIONING_SYSTEM = "apple-generic"; 502 | }; 503 | name = Debug; 504 | }; 505 | 97C147071CF9000F007C117D /* Release */ = { 506 | isa = XCBuildConfiguration; 507 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 508 | buildSettings = { 509 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 510 | CLANG_ENABLE_MODULES = YES; 511 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 512 | ENABLE_BITCODE = NO; 513 | INFOPLIST_FILE = Runner/Info.plist; 514 | LD_RUNPATH_SEARCH_PATHS = ( 515 | "$(inherited)", 516 | "@executable_path/Frameworks", 517 | ); 518 | PRODUCT_BUNDLE_IDENTIFIER = com.example.chatifyApp; 519 | PRODUCT_NAME = "$(TARGET_NAME)"; 520 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 521 | SWIFT_VERSION = 5.0; 522 | VERSIONING_SYSTEM = "apple-generic"; 523 | }; 524 | name = Release; 525 | }; 526 | /* End XCBuildConfiguration section */ 527 | 528 | /* Begin XCConfigurationList section */ 529 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 530 | isa = XCConfigurationList; 531 | buildConfigurations = ( 532 | 97C147031CF9000F007C117D /* Debug */, 533 | 97C147041CF9000F007C117D /* Release */, 534 | 249021D3217E4FDB00AE95B9 /* Profile */, 535 | ); 536 | defaultConfigurationIsVisible = 0; 537 | defaultConfigurationName = Release; 538 | }; 539 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 540 | isa = XCConfigurationList; 541 | buildConfigurations = ( 542 | 97C147061CF9000F007C117D /* Debug */, 543 | 97C147071CF9000F007C117D /* Release */, 544 | 249021D4217E4FDB00AE95B9 /* Profile */, 545 | ); 546 | defaultConfigurationIsVisible = 0; 547 | defaultConfigurationName = Release; 548 | }; 549 | /* End XCConfigurationList section */ 550 | }; 551 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 552 | } 553 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | chatify_app 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | 33 | UISupportedInterfaceOrientations~ipad 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationPortraitUpsideDown 37 | UIInterfaceOrientationLandscapeLeft 38 | UIInterfaceOrientationLandscapeRight 39 | 40 | UIViewControllerBasedStatusBarAppearance 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/BoringSSL-GRPC.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/DKImagePickerController-DKImagePickerController.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/DKImagePickerController.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/DKPhotoGallery-DKPhotoGallery.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/DKPhotoGallery.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/Firebase.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/FirebaseAnalytics.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/FirebaseAuth.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/FirebaseCore.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/FirebaseCoreDiagnostics.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/FirebaseFirestore.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/FirebaseInstallations.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/FirebaseStorage.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/Flutter.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/GTMSessionFetcher.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/GoogleAppMeasurement.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/GoogleDataTransport.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/GoogleUtilities.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/Pods-Runner.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/PromisesObjC.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/SDWebImage.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/SwiftyGif.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/abseil.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/cloud_firestore.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/file_picker.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/firebase_analytics.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/firebase_auth.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/firebase_core.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/firebase_storage.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/flutter_keyboard_visibility.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/gRPC-C++-gRPCCertificates-Cpp.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/gRPC-C++.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/gRPC-Core.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/leveldb-library.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /ios/build/Pods.build/Release-iphonesimulator/nanopb.build/dgph: -------------------------------------------------------------------------------- 1 | DGPH1.04 Jun 8 202114:00:05 /UsershussainDesktop DevelopmentChatify_Source_Code_Udemy chatify_appiosPods -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | //Packages 4 | import 'package:firebase_analytics/firebase_analytics.dart'; 5 | import 'package:provider/provider.dart'; 6 | 7 | //Services 8 | import './services/navigation_service.dart'; 9 | 10 | //Providers 11 | import './providers/authentication_provider.dart'; 12 | 13 | //Pages 14 | import './pages/splash_page.dart'; 15 | import './pages/login_page.dart'; 16 | import './pages/register_page.dart'; 17 | import './pages/home_page.dart'; 18 | 19 | void main() { 20 | runApp( 21 | SplashPage( 22 | key: UniqueKey(), 23 | onInitializationComplete: () { 24 | runApp( 25 | MainApp(), 26 | ); 27 | }, 28 | ), 29 | ); 30 | } 31 | 32 | class MainApp extends StatelessWidget { 33 | @override 34 | Widget build(BuildContext context) { 35 | return MultiProvider( 36 | providers: [ 37 | ChangeNotifierProvider( 38 | create: (BuildContext _context) { 39 | return AuthenticationProvider(); 40 | }, 41 | ) 42 | ], 43 | child: MaterialApp( 44 | title: 'Chatify', 45 | theme: ThemeData( 46 | backgroundColor: Color.fromRGBO(36, 35, 49, 1.0), 47 | scaffoldBackgroundColor: Color.fromRGBO(36, 35, 49, 1.0), 48 | bottomNavigationBarTheme: BottomNavigationBarThemeData( 49 | backgroundColor: Color.fromRGBO(30, 29, 37, 1.0), 50 | ), 51 | ), 52 | navigatorKey: NavigationService.navigatorKey, 53 | initialRoute: '/login', 54 | routes: { 55 | '/login': (BuildContext _context) => LoginPage(), 56 | '/register': (BuildContext _context) => RegisterPage(), 57 | '/home': (BuildContext _context) => HomePage(), 58 | }, 59 | ), 60 | ); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /lib/models/chat.dart: -------------------------------------------------------------------------------- 1 | import '../models/chat_user.dart'; 2 | import '../models/chat_message.dart'; 3 | 4 | class Chat { 5 | final String uid; 6 | final String currentUserUid; 7 | final bool activity; 8 | final bool group; 9 | final List members; 10 | List messages; 11 | 12 | late final List _recepients; 13 | 14 | Chat({ 15 | required this.uid, 16 | required this.currentUserUid, 17 | required this.members, 18 | required this.messages, 19 | required this.activity, 20 | required this.group, 21 | }) { 22 | _recepients = members.where((_i) => _i.uid != currentUserUid).toList(); 23 | } 24 | 25 | List recepients() { 26 | return _recepients; 27 | } 28 | 29 | String title() { 30 | return !group 31 | ? _recepients.first.name 32 | : _recepients.map((_user) => _user.name).join(", "); 33 | } 34 | 35 | String imageURL() { 36 | return !group 37 | ? _recepients.first.imageURL 38 | : "https://e7.pngegg.com/pngimages/380/670/png-clipart-group-chat-logo-blue-area-text-symbol-metroui-apps-live-messenger-alt-2-blue-text.png"; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/models/chat_message.dart: -------------------------------------------------------------------------------- 1 | import 'package:cloud_firestore/cloud_firestore.dart'; 2 | 3 | enum MessageType { 4 | TEXT, 5 | IMAGE, 6 | UNKNOWN, 7 | } 8 | 9 | class ChatMessage { 10 | final String senderID; 11 | final MessageType type; 12 | final String content; 13 | final DateTime sentTime; 14 | 15 | ChatMessage( 16 | {required this.content, 17 | required this.type, 18 | required this.senderID, 19 | required this.sentTime}); 20 | 21 | factory ChatMessage.fromJSON(Map _json) { 22 | MessageType _messageType; 23 | switch (_json["type"]) { 24 | case "text": 25 | _messageType = MessageType.TEXT; 26 | break; 27 | case "image": 28 | _messageType = MessageType.IMAGE; 29 | break; 30 | default: 31 | _messageType = MessageType.UNKNOWN; 32 | } 33 | return ChatMessage( 34 | content: _json["content"], 35 | type: _messageType, 36 | senderID: _json["sender_id"], 37 | sentTime: _json["sent_time"].toDate(), 38 | ); 39 | } 40 | 41 | Map toJson() { 42 | String _messageType; 43 | switch (type) { 44 | case MessageType.TEXT: 45 | _messageType = "text"; 46 | break; 47 | case MessageType.IMAGE: 48 | _messageType = "image"; 49 | break; 50 | default: 51 | _messageType = ""; 52 | } 53 | return { 54 | "content": content, 55 | "type": _messageType, 56 | "sender_id": senderID, 57 | "sent_time": Timestamp.fromDate(sentTime), 58 | }; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /lib/models/chat_user.dart: -------------------------------------------------------------------------------- 1 | class ChatUser { 2 | final String uid; 3 | final String name; 4 | final String email; 5 | final String imageURL; 6 | late DateTime lastActive; 7 | 8 | ChatUser({ 9 | required this.uid, 10 | required this.name, 11 | required this.email, 12 | required this.imageURL, 13 | required this.lastActive, 14 | }); 15 | 16 | factory ChatUser.fromJSON(Map _json) { 17 | return ChatUser( 18 | uid: _json["uid"], 19 | name: _json["name"], 20 | email: _json["email"], 21 | imageURL: _json["image"], 22 | lastActive: _json["last_active"].toDate(), 23 | ); 24 | } 25 | 26 | Map toMap() { 27 | return { 28 | "email": email, 29 | "name": name, 30 | "last_active": lastActive, 31 | "image": imageURL, 32 | }; 33 | } 34 | 35 | String lastDayActive() { 36 | return "${lastActive.month}/${lastActive.day}/${lastActive.year}"; 37 | } 38 | 39 | bool wasRecentlyActive() { 40 | return DateTime.now().difference(lastActive).inHours < 2; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/pages/chat_page.dart: -------------------------------------------------------------------------------- 1 | //Packages 2 | import 'package:flutter/material.dart'; 3 | import 'package:provider/provider.dart'; 4 | 5 | //Widgets 6 | import '../widgets/top_bar.dart'; 7 | import '../widgets/custom_list_view_tiles.dart'; 8 | import '../widgets/custom_input_fields.dart'; 9 | 10 | //Models 11 | import '../models/chat.dart'; 12 | import '../models/chat_message.dart'; 13 | 14 | //Providers 15 | import '../providers/authentication_provider.dart'; 16 | import '../providers/chat_page_provider.dart'; 17 | 18 | class ChatPage extends StatefulWidget { 19 | final Chat chat; 20 | 21 | ChatPage({required this.chat}); 22 | 23 | @override 24 | State createState() { 25 | return _ChatPageState(); 26 | } 27 | } 28 | 29 | class _ChatPageState extends State { 30 | late double _deviceHeight; 31 | late double _deviceWidth; 32 | 33 | late AuthenticationProvider _auth; 34 | late ChatPageProvider _pageProvider; 35 | 36 | late GlobalKey _messageFormState; 37 | late ScrollController _messagesListViewController; 38 | 39 | @override 40 | void initState() { 41 | super.initState(); 42 | _messageFormState = GlobalKey(); 43 | _messagesListViewController = ScrollController(); 44 | } 45 | 46 | @override 47 | Widget build(BuildContext context) { 48 | _deviceHeight = MediaQuery.of(context).size.height; 49 | _deviceWidth = MediaQuery.of(context).size.width; 50 | _auth = Provider.of(context); 51 | return MultiProvider( 52 | providers: [ 53 | ChangeNotifierProvider( 54 | create: (_) => ChatPageProvider( 55 | this.widget.chat.uid, _auth, _messagesListViewController), 56 | ), 57 | ], 58 | child: _buildUI(), 59 | ); 60 | } 61 | 62 | Widget _buildUI() { 63 | return Builder( 64 | builder: (BuildContext _context) { 65 | _pageProvider = _context.watch(); 66 | return Scaffold( 67 | body: SingleChildScrollView( 68 | child: Container( 69 | padding: EdgeInsets.symmetric( 70 | horizontal: _deviceWidth * 0.03, 71 | vertical: _deviceHeight * 0.02, 72 | ), 73 | height: _deviceHeight, 74 | width: _deviceWidth * 0.97, 75 | child: Column( 76 | mainAxisSize: MainAxisSize.max, 77 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 78 | crossAxisAlignment: CrossAxisAlignment.center, 79 | children: [ 80 | TopBar( 81 | this.widget.chat.title(), 82 | fontSize: 10, 83 | primaryAction: IconButton( 84 | icon: Icon( 85 | Icons.delete, 86 | color: Color.fromRGBO(0, 82, 218, 1.0), 87 | ), 88 | onPressed: () { 89 | _pageProvider.deleteChat(); 90 | }, 91 | ), 92 | secondaryAction: IconButton( 93 | icon: Icon( 94 | Icons.arrow_back, 95 | color: Color.fromRGBO(0, 82, 218, 1.0), 96 | ), 97 | onPressed: () { 98 | _pageProvider.goBack(); 99 | }, 100 | ), 101 | ), 102 | _messagesListView(), 103 | _sendMessageForm(), 104 | ], 105 | ), 106 | ), 107 | ), 108 | ); 109 | }, 110 | ); 111 | } 112 | 113 | Widget _messagesListView() { 114 | if (_pageProvider.messages != null) { 115 | if (_pageProvider.messages!.length != 0) { 116 | return Container( 117 | height: _deviceHeight * 0.74, 118 | child: ListView.builder( 119 | controller: _messagesListViewController, 120 | itemCount: _pageProvider.messages!.length, 121 | itemBuilder: (BuildContext _context, int _index) { 122 | ChatMessage _message = _pageProvider.messages![_index]; 123 | bool _isOwnMessage = _message.senderID == _auth.user.uid; 124 | return Container( 125 | child: CustomChatListViewTile( 126 | deviceHeight: _deviceHeight, 127 | width: _deviceWidth * 0.80, 128 | message: _message, 129 | isOwnMessage: _isOwnMessage, 130 | sender: this 131 | .widget 132 | .chat 133 | .members 134 | .where((_m) => _m.uid == _message.senderID) 135 | .first, 136 | ), 137 | ); 138 | }, 139 | ), 140 | ); 141 | } else { 142 | return Align( 143 | alignment: Alignment.center, 144 | child: Text( 145 | "Be the first to say Hi!", 146 | style: TextStyle(color: Colors.white), 147 | ), 148 | ); 149 | } 150 | } else { 151 | return Center( 152 | child: CircularProgressIndicator( 153 | color: Colors.white, 154 | ), 155 | ); 156 | } 157 | } 158 | 159 | Widget _sendMessageForm() { 160 | return Container( 161 | height: _deviceHeight * 0.06, 162 | decoration: BoxDecoration( 163 | color: Color.fromRGBO(30, 29, 37, 1.0), 164 | borderRadius: BorderRadius.circular(100), 165 | ), 166 | margin: EdgeInsets.symmetric( 167 | horizontal: _deviceWidth * 0.04, 168 | vertical: _deviceHeight * 0.03, 169 | ), 170 | child: Form( 171 | key: _messageFormState, 172 | child: Row( 173 | mainAxisSize: MainAxisSize.max, 174 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 175 | crossAxisAlignment: CrossAxisAlignment.center, 176 | children: [ 177 | _messageTextField(), 178 | _sendMessageButton(), 179 | _imageMessageButton(), 180 | ], 181 | ), 182 | ), 183 | ); 184 | } 185 | 186 | Widget _messageTextField() { 187 | return SizedBox( 188 | width: _deviceWidth * 0.65, 189 | child: CustomTextFormField( 190 | onSaved: (_value) { 191 | _pageProvider.message = _value; 192 | }, 193 | regEx: r"^(?!\s*$).+", 194 | hintText: "Type a message", 195 | obscureText: false), 196 | ); 197 | } 198 | 199 | Widget _sendMessageButton() { 200 | double _size = _deviceHeight * 0.04; 201 | return Container( 202 | height: _size, 203 | width: _size, 204 | child: IconButton( 205 | icon: Icon( 206 | Icons.send, 207 | color: Colors.white, 208 | ), 209 | onPressed: () { 210 | if (_messageFormState.currentState!.validate()) { 211 | _messageFormState.currentState!.save(); 212 | _pageProvider.sendTextMessage(); 213 | _messageFormState.currentState!.reset(); 214 | } 215 | }, 216 | ), 217 | ); 218 | } 219 | 220 | Widget _imageMessageButton() { 221 | double _size = _deviceHeight * 0.04; 222 | return Container( 223 | height: _size, 224 | width: _size, 225 | child: FloatingActionButton( 226 | backgroundColor: Color.fromRGBO( 227 | 0, 228 | 82, 229 | 218, 230 | 1.0, 231 | ), 232 | onPressed: () { 233 | _pageProvider.sendImageMessage(); 234 | }, 235 | child: Icon(Icons.camera_enhance), 236 | ), 237 | ); 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /lib/pages/chats_page.dart: -------------------------------------------------------------------------------- 1 | //Packages 2 | import 'package:flutter/material.dart'; 3 | import 'package:provider/provider.dart'; 4 | import 'package:get_it/get_it.dart'; 5 | 6 | //Providers 7 | import '../providers/authentication_provider.dart'; 8 | import '../providers/chats_page_provider.dart'; 9 | 10 | //Services 11 | import '../services/navigation_service.dart'; 12 | 13 | //Pages 14 | import '../pages/chat_page.dart'; 15 | 16 | //Widgets 17 | import '../widgets/top_bar.dart'; 18 | import '../widgets/custom_list_view_tiles.dart'; 19 | 20 | //Models 21 | import '../models/chat.dart'; 22 | import '../models/chat_user.dart'; 23 | import '../models/chat_message.dart'; 24 | 25 | class ChatsPage extends StatefulWidget { 26 | @override 27 | State createState() { 28 | return _ChatsPageState(); 29 | } 30 | } 31 | 32 | class _ChatsPageState extends State { 33 | late double _deviceHeight; 34 | late double _deviceWidth; 35 | 36 | late AuthenticationProvider _auth; 37 | late NavigationService _navigation; 38 | late ChatsPageProvider _pageProvider; 39 | 40 | @override 41 | Widget build(BuildContext context) { 42 | _deviceHeight = MediaQuery.of(context).size.height; 43 | _deviceWidth = MediaQuery.of(context).size.width; 44 | _auth = Provider.of(context); 45 | _navigation = GetIt.instance.get(); 46 | return MultiProvider( 47 | providers: [ 48 | ChangeNotifierProvider( 49 | create: (_) => ChatsPageProvider(_auth), 50 | ), 51 | ], 52 | child: _buildUI(), 53 | ); 54 | } 55 | 56 | Widget _buildUI() { 57 | return Builder( 58 | builder: (BuildContext _context) { 59 | _pageProvider = _context.watch(); 60 | return Container( 61 | padding: EdgeInsets.symmetric( 62 | horizontal: _deviceWidth * 0.03, 63 | vertical: _deviceHeight * 0.02, 64 | ), 65 | height: _deviceHeight * 0.98, 66 | width: _deviceWidth * 0.97, 67 | child: Column( 68 | mainAxisSize: MainAxisSize.max, 69 | mainAxisAlignment: MainAxisAlignment.start, 70 | crossAxisAlignment: CrossAxisAlignment.center, 71 | children: [ 72 | TopBar( 73 | 'Chats', 74 | primaryAction: IconButton( 75 | icon: Icon( 76 | Icons.logout, 77 | color: Color.fromRGBO(0, 82, 218, 1.0), 78 | ), 79 | onPressed: () { 80 | _auth.logout(); 81 | }, 82 | ), 83 | ), 84 | _chatsList(), 85 | ], 86 | ), 87 | ); 88 | }, 89 | ); 90 | } 91 | 92 | Widget _chatsList() { 93 | List? _chats = _pageProvider.chats; 94 | return Expanded( 95 | child: (() { 96 | if (_chats != null) { 97 | if (_chats.length != 0) { 98 | return ListView.builder( 99 | itemCount: _chats.length, 100 | itemBuilder: (BuildContext _context, int _index) { 101 | return _chatTile( 102 | _chats[_index], 103 | ); 104 | }, 105 | ); 106 | } else { 107 | return Center( 108 | child: Text( 109 | "No Chats Found.", 110 | style: TextStyle(color: Colors.white), 111 | ), 112 | ); 113 | } 114 | } else { 115 | return Center( 116 | child: CircularProgressIndicator( 117 | color: Colors.white, 118 | ), 119 | ); 120 | } 121 | })(), 122 | ); 123 | } 124 | 125 | Widget _chatTile(Chat _chat) { 126 | List _recepients = _chat.recepients(); 127 | bool _isActive = _recepients.any((_d) => _d.wasRecentlyActive()); 128 | String _subtitleText = ""; 129 | if (_chat.messages.isNotEmpty) { 130 | _subtitleText = _chat.messages.first.type != MessageType.TEXT 131 | ? "Media Attachment" 132 | : _chat.messages.first.content; 133 | } 134 | return CustomListViewTileWithActivity( 135 | height: _deviceHeight * 0.10, 136 | title: _chat.title(), 137 | subtitle: _subtitleText, 138 | imagePath: _chat.imageURL(), 139 | isActive: _isActive, 140 | isActivity: _chat.activity, 141 | onTap: () { 142 | _navigation.navigateToPage( 143 | ChatPage(chat: _chat), 144 | ); 145 | }, 146 | ); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /lib/pages/home_page.dart: -------------------------------------------------------------------------------- 1 | //Packages 2 | import 'package:flutter/material.dart'; 3 | 4 | //Pages 5 | import '../pages/chats_page.dart'; 6 | import '../pages/users_page.dart'; 7 | 8 | class HomePage extends StatefulWidget { 9 | @override 10 | State createState() { 11 | return _HomePageState(); 12 | } 13 | } 14 | 15 | class _HomePageState extends State { 16 | int _currentPage = 0; 17 | final List _pages = [ 18 | ChatsPage(), 19 | UsersPage(), 20 | ]; 21 | 22 | @override 23 | Widget build(BuildContext context) { 24 | return _buildUI(); 25 | } 26 | 27 | Widget _buildUI() { 28 | return Scaffold( 29 | body: _pages[_currentPage], 30 | bottomNavigationBar: BottomNavigationBar( 31 | currentIndex: _currentPage, 32 | onTap: (_index) { 33 | setState(() { 34 | _currentPage = _index; 35 | }); 36 | }, 37 | items: [ 38 | BottomNavigationBarItem( 39 | label: "Chats", 40 | icon: Icon( 41 | Icons.chat_bubble_sharp, 42 | ), 43 | ), 44 | BottomNavigationBarItem( 45 | label: "Users", 46 | icon: Icon( 47 | Icons.supervised_user_circle_sharp, 48 | ), 49 | ), 50 | ], 51 | ), 52 | ); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /lib/pages/login_page.dart: -------------------------------------------------------------------------------- 1 | //Packages 2 | import 'package:flutter/material.dart'; 3 | import 'package:provider/provider.dart'; 4 | import 'package:get_it/get_it.dart'; 5 | 6 | //Widgets 7 | import '../widgets/custom_input_fields.dart'; 8 | import '../widgets/rounded_button.dart'; 9 | 10 | //Providers 11 | import '../providers/authentication_provider.dart'; 12 | 13 | //Services 14 | import '../services/navigation_service.dart'; 15 | 16 | class LoginPage extends StatefulWidget { 17 | @override 18 | State createState() { 19 | return _LoginPageState(); 20 | } 21 | } 22 | 23 | class _LoginPageState extends State { 24 | late double _deviceHeight; 25 | late double _deviceWidth; 26 | 27 | late AuthenticationProvider _auth; 28 | late NavigationService _navigation; 29 | 30 | final _loginFormKey = GlobalKey(); 31 | 32 | String? _email; 33 | String? _password; 34 | 35 | @override 36 | Widget build(BuildContext context) { 37 | _deviceHeight = MediaQuery.of(context).size.height; 38 | _deviceWidth = MediaQuery.of(context).size.width; 39 | _auth = Provider.of(context); 40 | _navigation = GetIt.instance.get(); 41 | return _buildUI(); 42 | } 43 | 44 | Widget _buildUI() { 45 | return Scaffold( 46 | body: Container( 47 | padding: EdgeInsets.symmetric( 48 | horizontal: _deviceWidth * 0.03, 49 | vertical: _deviceHeight * 0.02, 50 | ), 51 | height: _deviceHeight * 0.98, 52 | width: _deviceWidth * 0.97, 53 | child: Column( 54 | mainAxisSize: MainAxisSize.max, 55 | mainAxisAlignment: MainAxisAlignment.center, 56 | crossAxisAlignment: CrossAxisAlignment.center, 57 | children: [ 58 | _pageTitle(), 59 | SizedBox( 60 | height: _deviceHeight * 0.04, 61 | ), 62 | _loginForm(), 63 | SizedBox( 64 | height: _deviceHeight * 0.05, 65 | ), 66 | _loginButton(), 67 | SizedBox( 68 | height: _deviceHeight * 0.02, 69 | ), 70 | _registerAccountLink(), 71 | ], 72 | ), 73 | ), 74 | ); 75 | } 76 | 77 | Widget _pageTitle() { 78 | return Container( 79 | height: _deviceHeight * 0.10, 80 | child: Text( 81 | 'Chatify', 82 | style: TextStyle( 83 | color: Colors.white, 84 | fontSize: 40, 85 | fontWeight: FontWeight.w600, 86 | ), 87 | ), 88 | ); 89 | } 90 | 91 | Widget _loginForm() { 92 | return Container( 93 | height: _deviceHeight * 0.18, 94 | child: Form( 95 | key: _loginFormKey, 96 | child: Column( 97 | mainAxisSize: MainAxisSize.max, 98 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 99 | crossAxisAlignment: CrossAxisAlignment.center, 100 | children: [ 101 | CustomTextFormField( 102 | onSaved: (_value) { 103 | setState(() { 104 | _email = _value; 105 | }); 106 | }, 107 | regEx: 108 | r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+", 109 | hintText: "Email", 110 | obscureText: false), 111 | CustomTextFormField( 112 | onSaved: (_value) { 113 | setState(() { 114 | _password = _value; 115 | }); 116 | }, 117 | regEx: r".{8,}", 118 | hintText: "Password", 119 | obscureText: true), 120 | ], 121 | ), 122 | ), 123 | ); 124 | } 125 | 126 | Widget _loginButton() { 127 | return RoundedButton( 128 | name: "Login", 129 | height: _deviceHeight * 0.065, 130 | width: _deviceWidth * 0.65, 131 | onPressed: () { 132 | if (_loginFormKey.currentState!.validate()) { 133 | _loginFormKey.currentState!.save(); 134 | _auth.loginUsingEmailAndPassword(_email!, _password!); 135 | } 136 | }, 137 | ); 138 | } 139 | 140 | Widget _registerAccountLink() { 141 | return GestureDetector( 142 | onTap: () => _navigation.navigateToRoute('/register'), 143 | child: Container( 144 | child: Text( 145 | 'Don\'t have an account?', 146 | style: TextStyle( 147 | color: Colors.blueAccent, 148 | ), 149 | ), 150 | ), 151 | ); 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /lib/pages/register_page.dart: -------------------------------------------------------------------------------- 1 | //Packages 2 | import 'package:flutter/material.dart'; 3 | import 'package:file_picker/file_picker.dart'; 4 | import 'package:get_it/get_it.dart'; 5 | import 'package:provider/provider.dart'; 6 | 7 | //Services 8 | import '../services/media_service.dart'; 9 | import '../services/database_service.dart'; 10 | import '../services/cloud_storage_service.dart'; 11 | import '../services/navigation_service.dart'; 12 | 13 | //Widgets 14 | import '../widgets/custom_input_fields.dart'; 15 | import '../widgets/rounded_button.dart'; 16 | import '../widgets/rounded_image.dart'; 17 | 18 | //Providers 19 | import '../providers/authentication_provider.dart'; 20 | 21 | class RegisterPage extends StatefulWidget { 22 | @override 23 | State createState() { 24 | return _RegisterPageState(); 25 | } 26 | } 27 | 28 | class _RegisterPageState extends State { 29 | late double _deviceHeight; 30 | late double _deviceWidth; 31 | 32 | late AuthenticationProvider _auth; 33 | late DatabaseService _db; 34 | late CloudStorageService _cloudStorage; 35 | late NavigationService _navigation; 36 | 37 | String? _email; 38 | String? _password; 39 | String? _name; 40 | PlatformFile? _profileImage; 41 | 42 | final _registerFormKey = GlobalKey(); 43 | 44 | @override 45 | Widget build(BuildContext context) { 46 | _auth = Provider.of(context); 47 | _db = GetIt.instance.get(); 48 | _cloudStorage = GetIt.instance.get(); 49 | _navigation = GetIt.instance.get(); 50 | _deviceHeight = MediaQuery.of(context).size.height; 51 | _deviceWidth = MediaQuery.of(context).size.width; 52 | return _buildUI(); 53 | } 54 | 55 | Widget _buildUI() { 56 | return Scaffold( 57 | resizeToAvoidBottomInset: false, 58 | body: Container( 59 | padding: EdgeInsets.symmetric( 60 | horizontal: _deviceWidth * 0.03, 61 | vertical: _deviceHeight * 0.02, 62 | ), 63 | height: _deviceHeight * 0.98, 64 | width: _deviceWidth * 0.97, 65 | child: Column( 66 | mainAxisSize: MainAxisSize.max, 67 | mainAxisAlignment: MainAxisAlignment.center, 68 | crossAxisAlignment: CrossAxisAlignment.center, 69 | children: [ 70 | _profileImageField(), 71 | SizedBox( 72 | height: _deviceHeight * 0.05, 73 | ), 74 | _registerForm(), 75 | SizedBox( 76 | height: _deviceHeight * 0.05, 77 | ), 78 | _registerButton(), 79 | SizedBox( 80 | height: _deviceHeight * 0.02, 81 | ), 82 | ], 83 | ), 84 | ), 85 | ); 86 | } 87 | 88 | Widget _profileImageField() { 89 | return GestureDetector( 90 | onTap: () { 91 | GetIt.instance.get().pickImageFromLibrary().then( 92 | (_file) { 93 | setState( 94 | () { 95 | _profileImage = _file; 96 | }, 97 | ); 98 | }, 99 | ); 100 | }, 101 | child: () { 102 | if (_profileImage != null) { 103 | return RoundedImageFile( 104 | key: UniqueKey(), 105 | image: _profileImage!, 106 | size: _deviceHeight * 0.15, 107 | ); 108 | } else { 109 | return RoundedImageNetwork( 110 | key: UniqueKey(), 111 | imagePath: "https://i.pravatar.cc/150?img=65", 112 | size: _deviceHeight * 0.15, 113 | ); 114 | } 115 | }(), 116 | ); 117 | } 118 | 119 | Widget _registerForm() { 120 | return Container( 121 | height: _deviceHeight * 0.35, 122 | child: Form( 123 | key: _registerFormKey, 124 | child: Column( 125 | mainAxisSize: MainAxisSize.max, 126 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 127 | crossAxisAlignment: CrossAxisAlignment.center, 128 | children: [ 129 | CustomTextFormField( 130 | onSaved: (_value) { 131 | setState(() { 132 | _name = _value; 133 | }); 134 | }, 135 | regEx: r'.{8,}', 136 | hintText: "Name", 137 | obscureText: false), 138 | CustomTextFormField( 139 | onSaved: (_value) { 140 | setState(() { 141 | _email = _value; 142 | }); 143 | }, 144 | regEx: 145 | r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+", 146 | hintText: "Email", 147 | obscureText: false), 148 | CustomTextFormField( 149 | onSaved: (_value) { 150 | setState(() { 151 | _password = _value; 152 | }); 153 | }, 154 | regEx: r".{8,}", 155 | hintText: "Password", 156 | obscureText: true), 157 | ], 158 | ), 159 | ), 160 | ); 161 | } 162 | 163 | Widget _registerButton() { 164 | return RoundedButton( 165 | name: "Register", 166 | height: _deviceHeight * 0.065, 167 | width: _deviceWidth * 0.65, 168 | onPressed: () async { 169 | if (_registerFormKey.currentState!.validate() && 170 | _profileImage != null) { 171 | _registerFormKey.currentState!.save(); 172 | String? _uid = await _auth.registerUserUsingEmailAndPassword( 173 | _email!, _password!); 174 | String? _imageURL = 175 | await _cloudStorage.saveUserImageToStorage(_uid!, _profileImage!); 176 | await _db.createUser(_uid, _email!, _name!, _imageURL!); 177 | await _auth.logout(); 178 | await _auth.loginUsingEmailAndPassword(_email!, _password!); 179 | } 180 | }, 181 | ); 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /lib/pages/splash_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | //Packages 4 | import 'package:firebase_core/firebase_core.dart'; 5 | import 'package:get_it/get_it.dart'; 6 | 7 | //Services 8 | import '../services/navigation_service.dart'; 9 | import '../services/media_service.dart'; 10 | import '../services/cloud_storage_service.dart'; 11 | import '../services/database_service.dart'; 12 | 13 | class SplashPage extends StatefulWidget { 14 | final VoidCallback onInitializationComplete; 15 | 16 | const SplashPage({ 17 | required Key key, 18 | required this.onInitializationComplete, 19 | }) : super(key: key); 20 | 21 | @override 22 | State createState() { 23 | return _SplashPageState(); 24 | } 25 | } 26 | 27 | class _SplashPageState extends State { 28 | @override 29 | void initState() { 30 | super.initState(); 31 | Future.delayed(Duration(seconds: 1)).then( 32 | (_) { 33 | _setup().then( 34 | (_) => widget.onInitializationComplete(), 35 | ); 36 | }, 37 | ); 38 | } 39 | 40 | @override 41 | Widget build(BuildContext context) { 42 | return MaterialApp( 43 | title: 'Chatify', 44 | theme: ThemeData( 45 | backgroundColor: Color.fromRGBO(36, 35, 49, 1.0), 46 | scaffoldBackgroundColor: Color.fromRGBO(36, 35, 49, 1.0), 47 | ), 48 | home: Scaffold( 49 | body: Center( 50 | child: Container( 51 | height: 200, 52 | width: 200, 53 | decoration: BoxDecoration( 54 | image: DecorationImage( 55 | fit: BoxFit.contain, 56 | image: AssetImage('assets/images/logo.png'), 57 | ), 58 | ), 59 | ), 60 | ), 61 | ), 62 | ); 63 | } 64 | 65 | Future _setup() async { 66 | WidgetsFlutterBinding.ensureInitialized(); 67 | await Firebase.initializeApp(); 68 | _registerServices(); 69 | } 70 | 71 | void _registerServices() { 72 | GetIt.instance.registerSingleton( 73 | NavigationService(), 74 | ); 75 | GetIt.instance.registerSingleton( 76 | MediaService(), 77 | ); 78 | GetIt.instance.registerSingleton( 79 | CloudStorageService(), 80 | ); 81 | GetIt.instance.registerSingleton( 82 | DatabaseService(), 83 | ); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /lib/pages/users_page.dart: -------------------------------------------------------------------------------- 1 | //Packages 2 | import 'package:flutter/material.dart'; 3 | import 'package:provider/provider.dart'; 4 | import 'package:get_it/get_it.dart'; 5 | 6 | //Providers 7 | import '../providers/authentication_provider.dart'; 8 | import '../providers/users_page_provider.dart'; 9 | 10 | //Widgets 11 | import '../widgets/top_bar.dart'; 12 | import '../widgets/custom_input_fields.dart'; 13 | import '../widgets/custom_list_view_tiles.dart'; 14 | import '../widgets/rounded_button.dart'; 15 | 16 | //Models 17 | import '../models/chat_user.dart'; 18 | 19 | class UsersPage extends StatefulWidget { 20 | @override 21 | State createState() { 22 | return _UsersPageState(); 23 | } 24 | } 25 | 26 | class _UsersPageState extends State { 27 | late double _deviceHeight; 28 | late double _deviceWidth; 29 | 30 | late AuthenticationProvider _auth; 31 | late UsersPageProvider _pageProvider; 32 | 33 | final TextEditingController _searchFieldTextEditingController = 34 | TextEditingController(); 35 | 36 | @override 37 | Widget build(BuildContext context) { 38 | _deviceHeight = MediaQuery.of(context).size.height; 39 | _deviceWidth = MediaQuery.of(context).size.width; 40 | _auth = Provider.of(context); 41 | return MultiProvider( 42 | providers: [ 43 | ChangeNotifierProvider( 44 | create: (_) => UsersPageProvider(_auth), 45 | ), 46 | ], 47 | child: _buildUI(), 48 | ); 49 | } 50 | 51 | Widget _buildUI() { 52 | return Builder( 53 | builder: (BuildContext _context) { 54 | _pageProvider = _context.watch(); 55 | return Container( 56 | padding: EdgeInsets.symmetric( 57 | horizontal: _deviceWidth * 0.03, vertical: _deviceHeight * 0.02), 58 | height: _deviceHeight * 0.98, 59 | width: _deviceWidth * 0.97, 60 | child: Column( 61 | mainAxisSize: MainAxisSize.max, 62 | mainAxisAlignment: MainAxisAlignment.start, 63 | crossAxisAlignment: CrossAxisAlignment.center, 64 | children: [ 65 | TopBar( 66 | 'Users', 67 | primaryAction: IconButton( 68 | icon: Icon( 69 | Icons.logout, 70 | color: Color.fromRGBO(0, 82, 218, 1.0), 71 | ), 72 | onPressed: () { 73 | _auth.logout(); 74 | }, 75 | ), 76 | ), 77 | CustomTextField( 78 | onEditingComplete: (_value) { 79 | _pageProvider.getUsers(name: _value); 80 | FocusScope.of(context).unfocus(); 81 | }, 82 | hintText: "Search...", 83 | obscureText: false, 84 | controller: _searchFieldTextEditingController, 85 | icon: Icons.search, 86 | ), 87 | _usersList(), 88 | _createChatButton(), 89 | ], 90 | ), 91 | ); 92 | }, 93 | ); 94 | } 95 | 96 | Widget _usersList() { 97 | List? _users = _pageProvider.users; 98 | return Expanded(child: () { 99 | if (_users != null) { 100 | if (_users.length != 0) { 101 | return ListView.builder( 102 | itemCount: _users.length, 103 | itemBuilder: (BuildContext _context, int _index) { 104 | return CustomListViewTile( 105 | height: _deviceHeight * 0.10, 106 | title: _users[_index].name, 107 | subtitle: "Last Active: ${_users[_index].lastDayActive()}", 108 | imagePath: _users[_index].imageURL, 109 | isActive: _users[_index].wasRecentlyActive(), 110 | isSelected: _pageProvider.selectedUsers.contains( 111 | _users[_index], 112 | ), 113 | onTap: () { 114 | _pageProvider.updateSelectedUsers( 115 | _users[_index], 116 | ); 117 | }, 118 | ); 119 | }, 120 | ); 121 | } else { 122 | return Center( 123 | child: Text( 124 | "No Users Found.", 125 | style: TextStyle( 126 | color: Colors.white, 127 | ), 128 | ), 129 | ); 130 | } 131 | } else { 132 | return Center( 133 | child: CircularProgressIndicator( 134 | color: Colors.white, 135 | ), 136 | ); 137 | } 138 | }()); 139 | } 140 | 141 | Widget _createChatButton() { 142 | return Visibility( 143 | visible: _pageProvider.selectedUsers.isNotEmpty, 144 | child: RoundedButton( 145 | name: _pageProvider.selectedUsers.length == 1 146 | ? "Chat With ${_pageProvider.selectedUsers.first.name}" 147 | : "Create Group Chat", 148 | height: _deviceHeight * 0.08, 149 | width: _deviceWidth * 0.80, 150 | onPressed: () { 151 | _pageProvider.createChat(); 152 | }, 153 | ), 154 | ); 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /lib/providers/authentication_provider.dart: -------------------------------------------------------------------------------- 1 | //Packages 2 | import 'package:chatify_app/models/chat_user.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:firebase_auth/firebase_auth.dart'; 5 | import 'package:get_it/get_it.dart'; 6 | 7 | //Services 8 | import '../services/database_service.dart'; 9 | import '../services/navigation_service.dart'; 10 | 11 | //Models 12 | import '../models/chat_user.dart'; 13 | 14 | class AuthenticationProvider extends ChangeNotifier { 15 | late final FirebaseAuth _auth; 16 | late final NavigationService _navigationService; 17 | late final DatabaseService _databaseService; 18 | 19 | late ChatUser user; 20 | 21 | AuthenticationProvider() { 22 | _auth = FirebaseAuth.instance; 23 | _navigationService = GetIt.instance.get(); 24 | _databaseService = GetIt.instance.get(); 25 | 26 | _auth.authStateChanges().listen((_user) { 27 | if (_user != null) { 28 | _databaseService.updateUserLastSeenTime(_user.uid); 29 | _databaseService.getUser(_user.uid).then( 30 | (_snapshot) { 31 | Map _userData = 32 | _snapshot.data()! as Map; 33 | user = ChatUser.fromJSON( 34 | { 35 | "uid": _user.uid, 36 | "name": _userData["name"], 37 | "email": _userData["email"], 38 | "last_active": _userData["last_active"], 39 | "image": _userData["image"], 40 | }, 41 | ); 42 | _navigationService.removeAndNavigateToRoute('/home'); 43 | }, 44 | ); 45 | } else { 46 | if (_navigationService.getCurrentRoute() != '/login') { 47 | _navigationService.removeAndNavigateToRoute('/login'); 48 | } 49 | } 50 | }); 51 | } 52 | 53 | Future loginUsingEmailAndPassword( 54 | String _email, String _password) async { 55 | try { 56 | await _auth.signInWithEmailAndPassword( 57 | email: _email, password: _password); 58 | } on FirebaseAuthException { 59 | print("Error logging user into Firebase"); 60 | } catch (e) { 61 | print(e); 62 | } 63 | } 64 | 65 | Future registerUserUsingEmailAndPassword( 66 | String _email, String _password) async { 67 | try { 68 | UserCredential _credentials = await _auth.createUserWithEmailAndPassword( 69 | email: _email, password: _password); 70 | return _credentials.user!.uid; 71 | } on FirebaseAuthException { 72 | print("Error registering user."); 73 | } catch (e) { 74 | print(e); 75 | } 76 | } 77 | 78 | Future logout() async { 79 | try { 80 | await _auth.signOut(); 81 | } catch (e) { 82 | print(e); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /lib/providers/chat_page_provider.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | //Packages 4 | import 'package:file_picker/file_picker.dart'; 5 | import 'package:flutter/material.dart'; 6 | import 'package:get_it/get_it.dart'; 7 | import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; 8 | 9 | //Services 10 | import '../services/database_service.dart'; 11 | import '../services/cloud_storage_service.dart'; 12 | import '../services/media_service.dart'; 13 | import '../services/navigation_service.dart'; 14 | 15 | //Providers 16 | import '../providers/authentication_provider.dart'; 17 | 18 | //Models 19 | import '../models/chat_message.dart'; 20 | 21 | class ChatPageProvider extends ChangeNotifier { 22 | late DatabaseService _db; 23 | late CloudStorageService _storage; 24 | late MediaService _media; 25 | late NavigationService _navigation; 26 | 27 | AuthenticationProvider _auth; 28 | ScrollController _messagesListViewController; 29 | 30 | String _chatId; 31 | List? messages; 32 | 33 | late StreamSubscription _messagesStream; 34 | late StreamSubscription _keyboardVisibilityStream; 35 | late KeyboardVisibilityController _keyboardVisibilityController; 36 | 37 | String? _message; 38 | 39 | String get message { 40 | return message; 41 | } 42 | 43 | void set message(String _value) { 44 | _message = _value; 45 | } 46 | 47 | ChatPageProvider(this._chatId, this._auth, this._messagesListViewController) { 48 | _db = GetIt.instance.get(); 49 | _storage = GetIt.instance.get(); 50 | _media = GetIt.instance.get(); 51 | _navigation = GetIt.instance.get(); 52 | _keyboardVisibilityController = KeyboardVisibilityController(); 53 | listenToMessages(); 54 | listenToKeyboardChanges(); 55 | } 56 | 57 | @override 58 | void dispose() { 59 | _messagesStream.cancel(); 60 | super.dispose(); 61 | } 62 | 63 | void listenToMessages() { 64 | try { 65 | _messagesStream = _db.streamMessagesForChat(_chatId).listen( 66 | (_snapshot) { 67 | List _messages = _snapshot.docs.map( 68 | (_m) { 69 | Map _messageData = 70 | _m.data() as Map; 71 | return ChatMessage.fromJSON(_messageData); 72 | }, 73 | ).toList(); 74 | messages = _messages; 75 | notifyListeners(); 76 | WidgetsBinding.instance!.addPostFrameCallback( 77 | (_) { 78 | if (_messagesListViewController.hasClients) { 79 | _messagesListViewController.jumpTo( 80 | _messagesListViewController.position.maxScrollExtent); 81 | } 82 | }, 83 | ); 84 | }, 85 | ); 86 | } catch (e) { 87 | print("Error getting messages."); 88 | print(e); 89 | } 90 | } 91 | 92 | void listenToKeyboardChanges() { 93 | _keyboardVisibilityStream = _keyboardVisibilityController.onChange.listen( 94 | (_event) { 95 | _db.updateChatData(_chatId, {"is_activity": _event}); 96 | }, 97 | ); 98 | } 99 | 100 | void sendTextMessage() { 101 | if (_message != null) { 102 | ChatMessage _messageToSend = ChatMessage( 103 | content: _message!, 104 | type: MessageType.TEXT, 105 | senderID: _auth.user.uid, 106 | sentTime: DateTime.now(), 107 | ); 108 | _db.addMessageToChat(_chatId, _messageToSend); 109 | } 110 | } 111 | 112 | void sendImageMessage() async { 113 | try { 114 | PlatformFile? _file = await _media.pickImageFromLibrary(); 115 | if (_file != null) { 116 | String? _downloadURL = await _storage.saveChatImageToStorage( 117 | _chatId, _auth.user.uid, _file); 118 | ChatMessage _messageToSend = ChatMessage( 119 | content: _downloadURL!, 120 | type: MessageType.IMAGE, 121 | senderID: _auth.user.uid, 122 | sentTime: DateTime.now(), 123 | ); 124 | _db.addMessageToChat(_chatId, _messageToSend); 125 | } 126 | } catch (e) { 127 | print("Error sending image message."); 128 | print(e); 129 | } 130 | } 131 | 132 | void deleteChat() { 133 | goBack(); 134 | _db.deleteChat(_chatId); 135 | } 136 | 137 | void goBack() { 138 | _navigation.goBack(); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /lib/providers/chats_page_provider.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | //Packages 4 | import 'package:flutter/material.dart'; 5 | import 'package:get_it/get_it.dart'; 6 | import 'package:cloud_firestore/cloud_firestore.dart'; 7 | 8 | //Services 9 | import '../services/database_service.dart'; 10 | 11 | //Providers 12 | import '../providers/authentication_provider.dart'; 13 | 14 | //Models 15 | import '../models/chat.dart'; 16 | import '../models/chat_message.dart'; 17 | import '../models/chat_user.dart'; 18 | 19 | class ChatsPageProvider extends ChangeNotifier { 20 | AuthenticationProvider _auth; 21 | 22 | late DatabaseService _db; 23 | 24 | List? chats; 25 | 26 | late StreamSubscription _chatsStream; 27 | 28 | ChatsPageProvider(this._auth) { 29 | _db = GetIt.instance.get(); 30 | getChats(); 31 | } 32 | 33 | @override 34 | void dispose() { 35 | _chatsStream.cancel(); 36 | super.dispose(); 37 | } 38 | 39 | void getChats() async { 40 | try { 41 | _chatsStream = 42 | _db.getChatsForUser(_auth.user.uid).listen((_snapshot) async { 43 | chats = await Future.wait( 44 | _snapshot.docs.map( 45 | (_d) async { 46 | Map _chatData = 47 | _d.data() as Map; 48 | //Get Users In Chat 49 | List _members = []; 50 | for (var _uid in _chatData["members"]) { 51 | DocumentSnapshot _userSnapshot = await _db.getUser(_uid); 52 | Map _userData = 53 | _userSnapshot.data() as Map; 54 | _userData["uid"] = _userSnapshot.id; 55 | _members.add( 56 | ChatUser.fromJSON(_userData), 57 | ); 58 | } 59 | //Get Last Message For Chat 60 | List _messages = []; 61 | QuerySnapshot _chatMessage = 62 | await _db.getLastMessageForChat(_d.id); 63 | if (_chatMessage.docs.isNotEmpty) { 64 | Map _messageData = 65 | _chatMessage.docs.first.data()! as Map; 66 | ChatMessage _message = ChatMessage.fromJSON(_messageData); 67 | _messages.add(_message); 68 | } 69 | //Return Chat Instance 70 | return Chat( 71 | uid: _d.id, 72 | currentUserUid: _auth.user.uid, 73 | members: _members, 74 | messages: _messages, 75 | activity: _chatData["is_activity"], 76 | group: _chatData["is_group"], 77 | ); 78 | }, 79 | ).toList(), 80 | ); 81 | notifyListeners(); 82 | }); 83 | } catch (e) { 84 | print("Error getting chats."); 85 | print(e); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /lib/providers/users_page_provider.dart: -------------------------------------------------------------------------------- 1 | //Packages 2 | import 'package:flutter/material.dart'; 3 | import 'package:cloud_firestore/cloud_firestore.dart'; 4 | import 'package:get_it/get_it.dart'; 5 | 6 | //Services 7 | import '../services/database_service.dart'; 8 | import '../services/navigation_service.dart'; 9 | 10 | //Providers 11 | import '../providers/authentication_provider.dart'; 12 | 13 | //Models 14 | import '../models/chat_user.dart'; 15 | import '../models/chat.dart'; 16 | 17 | //Pages 18 | import '../pages/chat_page.dart'; 19 | 20 | class UsersPageProvider extends ChangeNotifier { 21 | AuthenticationProvider _auth; 22 | 23 | late DatabaseService _database; 24 | late NavigationService _navigation; 25 | 26 | List? users; 27 | late List _selectedUsers; 28 | 29 | List get selectedUsers { 30 | return _selectedUsers; 31 | } 32 | 33 | UsersPageProvider(this._auth) { 34 | _selectedUsers = []; 35 | _database = GetIt.instance.get(); 36 | _navigation = GetIt.instance.get(); 37 | getUsers(); 38 | } 39 | 40 | @override 41 | void dispose() { 42 | super.dispose(); 43 | } 44 | 45 | void getUsers({String? name}) async { 46 | _selectedUsers = []; 47 | try { 48 | _database.getUsers(name: name).then( 49 | (_snapshot) { 50 | users = _snapshot.docs.map( 51 | (_doc) { 52 | Map _data = _doc.data() as Map; 53 | _data["uid"] = _doc.id; 54 | return ChatUser.fromJSON(_data); 55 | }, 56 | ).toList(); 57 | notifyListeners(); 58 | }, 59 | ); 60 | } catch (e) { 61 | print("Error getting users."); 62 | print(e); 63 | } 64 | } 65 | 66 | void updateSelectedUsers(ChatUser _user) { 67 | if (_selectedUsers.contains(_user)) { 68 | _selectedUsers.remove(_user); 69 | } else { 70 | _selectedUsers.add(_user); 71 | } 72 | notifyListeners(); 73 | } 74 | 75 | void createChat() async { 76 | try { 77 | //Create Chat 78 | List _membersIds = 79 | _selectedUsers.map((_user) => _user.uid).toList(); 80 | _membersIds.add(_auth.user.uid); 81 | bool _isGroup = _selectedUsers.length > 1; 82 | DocumentReference? _doc = await _database.createChat( 83 | { 84 | "is_group": _isGroup, 85 | "is_activity": false, 86 | "members": _membersIds, 87 | }, 88 | ); 89 | //Navigate To Chat Page 90 | List _members = []; 91 | for (var _uid in _membersIds) { 92 | DocumentSnapshot _userSnapshot = await _database.getUser(_uid); 93 | Map _userData = 94 | _userSnapshot.data() as Map; 95 | _userData["uid"] = _userSnapshot.id; 96 | _members.add( 97 | ChatUser.fromJSON( 98 | _userData, 99 | ), 100 | ); 101 | } 102 | ChatPage _chatPage = ChatPage( 103 | chat: Chat( 104 | uid: _doc!.id, 105 | currentUserUid: _auth.user.uid, 106 | members: _members, 107 | messages: [], 108 | activity: false, 109 | group: _isGroup), 110 | ); 111 | _selectedUsers = []; 112 | notifyListeners(); 113 | _navigation.navigateToPage(_chatPage); 114 | } catch (e) { 115 | print("Error creating chat."); 116 | print(e); 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /lib/services/cloud_storage_service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | //Packages 4 | import 'package:cloud_firestore/cloud_firestore.dart'; 5 | import 'package:firebase_storage/firebase_storage.dart'; 6 | import 'package:file_picker/file_picker.dart'; 7 | 8 | const String USER_COLLECTION = "Users"; 9 | 10 | class CloudStorageService { 11 | final FirebaseStorage _storage = FirebaseStorage.instance; 12 | 13 | CloudStorageService() {} 14 | 15 | Future saveUserImageToStorage( 16 | String _uid, PlatformFile _file) async { 17 | try { 18 | Reference _ref = 19 | _storage.ref().child('images/users/$_uid/profile.${_file.extension}'); 20 | UploadTask _task = _ref.putFile( 21 | File(_file.path), 22 | ); 23 | return await _task.then( 24 | (_result) => _result.ref.getDownloadURL(), 25 | ); 26 | } catch (e) { 27 | print(e); 28 | } 29 | } 30 | 31 | Future saveChatImageToStorage( 32 | String _chatID, String _userID, PlatformFile _file) async { 33 | try { 34 | Reference _ref = _storage.ref().child( 35 | 'images/chats/$_chatID/${_userID}_${Timestamp.now().millisecondsSinceEpoch}.${_file.extension}'); 36 | UploadTask _task = _ref.putFile( 37 | File(_file.path), 38 | ); 39 | return await _task.then( 40 | (_result) => _result.ref.getDownloadURL(), 41 | ); 42 | } catch (e) { 43 | print(e); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lib/services/database_service.dart: -------------------------------------------------------------------------------- 1 | //Packages 2 | import 'package:cloud_firestore/cloud_firestore.dart'; 3 | 4 | //Models 5 | import '../models/chat_message.dart'; 6 | 7 | const String USER_COLLECTION = "Users"; 8 | const String CHAT_COLLECTION = "Chats"; 9 | const String MESSAGES_COLLECTION = "messages"; 10 | 11 | class DatabaseService { 12 | final FirebaseFirestore _db = FirebaseFirestore.instance; 13 | 14 | DatabaseService() {} 15 | 16 | Future createUser( 17 | String _uid, String _email, String _name, String _imageURL) async { 18 | try { 19 | await _db.collection(USER_COLLECTION).doc(_uid).set( 20 | { 21 | "email": _email, 22 | "image": _imageURL, 23 | "last_active": DateTime.now().toUtc(), 24 | "name": _name, 25 | }, 26 | ); 27 | } catch (e) { 28 | print(e); 29 | } 30 | } 31 | 32 | Future getUser(String _uid) { 33 | return _db.collection(USER_COLLECTION).doc(_uid).get(); 34 | } 35 | 36 | Future getUsers({String? name}) { 37 | Query _query = _db.collection(USER_COLLECTION); 38 | if (name != null) { 39 | _query = _query 40 | .where("name", isGreaterThanOrEqualTo: name) 41 | .where("name", isLessThanOrEqualTo: name + "z"); 42 | } 43 | return _query.get(); 44 | } 45 | 46 | Stream getChatsForUser(String _uid) { 47 | return _db 48 | .collection(CHAT_COLLECTION) 49 | .where('members', arrayContains: _uid) 50 | .snapshots(); 51 | } 52 | 53 | Future getLastMessageForChat(String _chatID) { 54 | return _db 55 | .collection(CHAT_COLLECTION) 56 | .doc(_chatID) 57 | .collection(MESSAGES_COLLECTION) 58 | .orderBy("sent_time", descending: true) 59 | .limit(1) 60 | .get(); 61 | } 62 | 63 | Stream streamMessagesForChat(String _chatID) { 64 | return _db 65 | .collection(CHAT_COLLECTION) 66 | .doc(_chatID) 67 | .collection(MESSAGES_COLLECTION) 68 | .orderBy("sent_time", descending: false) 69 | .snapshots(); 70 | } 71 | 72 | Future addMessageToChat(String _chatID, ChatMessage _message) async { 73 | try { 74 | await _db 75 | .collection(CHAT_COLLECTION) 76 | .doc(_chatID) 77 | .collection(MESSAGES_COLLECTION) 78 | .add( 79 | _message.toJson(), 80 | ); 81 | } catch (e) { 82 | print(e); 83 | } 84 | } 85 | 86 | Future updateChatData( 87 | String _chatID, Map _data) async { 88 | try { 89 | await _db.collection(CHAT_COLLECTION).doc(_chatID).update(_data); 90 | } catch (e) { 91 | print(e); 92 | } 93 | } 94 | 95 | Future updateUserLastSeenTime(String _uid) async { 96 | try { 97 | await _db.collection(USER_COLLECTION).doc(_uid).update( 98 | { 99 | "last_active": DateTime.now().toUtc(), 100 | }, 101 | ); 102 | } catch (e) { 103 | print(e); 104 | } 105 | } 106 | 107 | Future deleteChat(String _chatID) async { 108 | try { 109 | await _db.collection(CHAT_COLLECTION).doc(_chatID).delete(); 110 | } catch (e) { 111 | print(e); 112 | } 113 | } 114 | 115 | Future createChat(Map _data) async { 116 | try { 117 | DocumentReference _chat = 118 | await _db.collection(CHAT_COLLECTION).add(_data); 119 | return _chat; 120 | } catch (e) { 121 | print(e); 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /lib/services/media_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:file_picker/file_picker.dart'; 2 | 3 | class MediaService { 4 | MediaService() {} 5 | 6 | Future pickImageFromLibrary() async { 7 | FilePickerResult? _result = 8 | await FilePicker.platform.pickFiles(type: FileType.image); 9 | if (_result != null) { 10 | return _result.files[0]; 11 | } 12 | return null; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/services/navigation_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class NavigationService { 4 | static GlobalKey navigatorKey = 5 | new GlobalKey(); 6 | 7 | void removeAndNavigateToRoute(String _route) { 8 | navigatorKey.currentState?.popAndPushNamed(_route); 9 | } 10 | 11 | void navigateToRoute(String _route) { 12 | navigatorKey.currentState?.pushNamed(_route); 13 | } 14 | 15 | void navigateToPage(Widget _page) { 16 | navigatorKey.currentState?.push( 17 | MaterialPageRoute( 18 | builder: (BuildContext _context) { 19 | return _page; 20 | }, 21 | ), 22 | ); 23 | } 24 | 25 | String? getCurrentRoute() { 26 | return ModalRoute.of(navigatorKey.currentState!.context)?.settings.name!; 27 | } 28 | 29 | void goBack() { 30 | navigatorKey.currentState?.pop(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/widgets/custom_input_fields.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class CustomTextFormField extends StatelessWidget { 4 | final Function(String) onSaved; 5 | final String regEx; 6 | final String hintText; 7 | final bool obscureText; 8 | 9 | CustomTextFormField( 10 | {required this.onSaved, 11 | required this.regEx, 12 | required this.hintText, 13 | required this.obscureText}); 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | return TextFormField( 18 | onSaved: (_value) => onSaved(_value!), 19 | cursorColor: Colors.white, 20 | style: TextStyle(color: Colors.white), 21 | obscureText: obscureText, 22 | validator: (_value) { 23 | return RegExp(regEx).hasMatch(_value!) ? null : 'Enter a valid value.'; 24 | }, 25 | decoration: InputDecoration( 26 | fillColor: Color.fromRGBO(30, 29, 37, 1.0), 27 | filled: true, 28 | border: OutlineInputBorder( 29 | borderRadius: BorderRadius.circular(10.0), 30 | borderSide: BorderSide.none, 31 | ), 32 | hintText: hintText, 33 | hintStyle: TextStyle(color: Colors.white54), 34 | ), 35 | ); 36 | } 37 | } 38 | 39 | class CustomTextField extends StatelessWidget { 40 | final Function(String) onEditingComplete; 41 | final String hintText; 42 | final bool obscureText; 43 | final TextEditingController controller; 44 | IconData? icon; 45 | 46 | CustomTextField( 47 | {required this.onEditingComplete, 48 | required this.hintText, 49 | required this.obscureText, 50 | required this.controller, 51 | this.icon}); 52 | 53 | @override 54 | Widget build(BuildContext context) { 55 | return TextField( 56 | controller: controller, 57 | onEditingComplete: () => onEditingComplete(controller.value.text), 58 | cursorColor: Colors.white, 59 | style: TextStyle(color: Colors.white), 60 | obscureText: obscureText, 61 | decoration: InputDecoration( 62 | fillColor: Color.fromRGBO(30, 29, 37, 1.0), 63 | filled: true, 64 | border: OutlineInputBorder( 65 | borderRadius: BorderRadius.circular(10.0), 66 | borderSide: BorderSide.none, 67 | ), 68 | hintText: hintText, 69 | hintStyle: TextStyle(color: Colors.white54), 70 | prefixIcon: Icon(icon, color: Colors.white54), 71 | ), 72 | ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /lib/widgets/custom_list_view_tiles.dart: -------------------------------------------------------------------------------- 1 | //Packages 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_spinkit/flutter_spinkit.dart'; 4 | 5 | //Widgets 6 | import '../widgets/rounded_image.dart'; 7 | import '../widgets/message_bubbles.dart'; 8 | 9 | //Models 10 | import '../models/chat_message.dart'; 11 | import '../models/chat_user.dart'; 12 | 13 | class CustomListViewTile extends StatelessWidget { 14 | final double height; 15 | final String title; 16 | final String subtitle; 17 | final String imagePath; 18 | final bool isActive; 19 | final bool isSelected; 20 | final Function onTap; 21 | 22 | CustomListViewTile({ 23 | required this.height, 24 | required this.title, 25 | required this.subtitle, 26 | required this.imagePath, 27 | required this.isActive, 28 | required this.isSelected, 29 | required this.onTap, 30 | }); 31 | 32 | @override 33 | Widget build(BuildContext context) { 34 | return ListTile( 35 | trailing: isSelected ? Icon(Icons.check, color: Colors.white) : null, 36 | onTap: () => onTap(), 37 | minVerticalPadding: height * 0.20, 38 | leading: RoundedImageNetworkWithStatusIndicator( 39 | key: UniqueKey(), 40 | size: height / 2, 41 | imagePath: imagePath, 42 | isActive: isActive, 43 | ), 44 | title: Text( 45 | title, 46 | style: TextStyle( 47 | color: Colors.white, 48 | fontSize: 18, 49 | fontWeight: FontWeight.w500, 50 | ), 51 | ), 52 | subtitle: Text( 53 | subtitle, 54 | style: TextStyle( 55 | color: Colors.white54, 56 | fontSize: 12, 57 | fontWeight: FontWeight.w400, 58 | ), 59 | ), 60 | ); 61 | } 62 | } 63 | 64 | class CustomListViewTileWithActivity extends StatelessWidget { 65 | final double height; 66 | final String title; 67 | final String subtitle; 68 | final String imagePath; 69 | final bool isActive; 70 | final bool isActivity; 71 | final Function onTap; 72 | 73 | CustomListViewTileWithActivity({ 74 | required this.height, 75 | required this.title, 76 | required this.subtitle, 77 | required this.imagePath, 78 | required this.isActive, 79 | required this.isActivity, 80 | required this.onTap, 81 | }); 82 | 83 | @override 84 | Widget build(BuildContext context) { 85 | return ListTile( 86 | onTap: () => onTap(), 87 | minVerticalPadding: height * 0.20, 88 | leading: RoundedImageNetworkWithStatusIndicator( 89 | key: UniqueKey(), 90 | size: height / 2, 91 | imagePath: imagePath, 92 | isActive: isActive, 93 | ), 94 | title: Text( 95 | title, 96 | style: TextStyle( 97 | color: Colors.white, 98 | fontSize: 18, 99 | fontWeight: FontWeight.w500, 100 | ), 101 | ), 102 | subtitle: isActivity 103 | ? Row( 104 | mainAxisSize: MainAxisSize.max, 105 | mainAxisAlignment: MainAxisAlignment.start, 106 | crossAxisAlignment: CrossAxisAlignment.center, 107 | children: [ 108 | SpinKitThreeBounce( 109 | color: Colors.white54, 110 | size: height * 0.10, 111 | ), 112 | ], 113 | ) 114 | : Text( 115 | subtitle, 116 | style: TextStyle( 117 | color: Colors.white54, 118 | fontSize: 12, 119 | fontWeight: FontWeight.w400), 120 | ), 121 | ); 122 | } 123 | } 124 | 125 | class CustomChatListViewTile extends StatelessWidget { 126 | final double width; 127 | final double deviceHeight; 128 | final bool isOwnMessage; 129 | final ChatMessage message; 130 | final ChatUser sender; 131 | 132 | CustomChatListViewTile({ 133 | required this.width, 134 | required this.deviceHeight, 135 | required this.isOwnMessage, 136 | required this.message, 137 | required this.sender, 138 | }); 139 | 140 | @override 141 | Widget build(BuildContext context) { 142 | return Container( 143 | padding: EdgeInsets.only(bottom: 10), 144 | width: width, 145 | child: Row( 146 | mainAxisSize: MainAxisSize.max, 147 | mainAxisAlignment: 148 | isOwnMessage ? MainAxisAlignment.end : MainAxisAlignment.start, 149 | crossAxisAlignment: CrossAxisAlignment.end, 150 | children: [ 151 | !isOwnMessage 152 | ? RoundedImageNetwork( 153 | key: UniqueKey(), 154 | imagePath: sender.imageURL, 155 | size: width * 0.08) 156 | : Container(), 157 | SizedBox( 158 | width: width * 0.05, 159 | ), 160 | message.type == MessageType.TEXT 161 | ? TextMessageBubble( 162 | isOwnMessage: isOwnMessage, 163 | message: message, 164 | height: deviceHeight * 0.06, 165 | width: width, 166 | ) 167 | : ImageMessageBubble( 168 | isOwnMessage: isOwnMessage, 169 | message: message, 170 | height: deviceHeight * 0.30, 171 | width: width * 0.55, 172 | ), 173 | ], 174 | ), 175 | ); 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /lib/widgets/message_bubbles.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | //Packages 4 | import 'package:timeago/timeago.dart' as timeago; 5 | 6 | //Models 7 | import '../models/chat_message.dart'; 8 | 9 | class TextMessageBubble extends StatelessWidget { 10 | final bool isOwnMessage; 11 | final ChatMessage message; 12 | final double height; 13 | final double width; 14 | 15 | TextMessageBubble( 16 | {required this.isOwnMessage, 17 | required this.message, 18 | required this.height, 19 | required this.width}); 20 | 21 | @override 22 | Widget build(BuildContext context) { 23 | List _colorScheme = isOwnMessage 24 | ? [Color.fromRGBO(0, 136, 249, 1.0), Color.fromRGBO(0, 82, 218, 1.0)] 25 | : [ 26 | Color.fromRGBO(51, 49, 68, 1.0), 27 | Color.fromRGBO(51, 49, 68, 1.0), 28 | ]; 29 | return Container( 30 | height: height + (message.content.length / 20 * 6.0), 31 | width: width, 32 | padding: EdgeInsets.symmetric(horizontal: 10), 33 | decoration: BoxDecoration( 34 | borderRadius: BorderRadius.circular(10), 35 | gradient: LinearGradient( 36 | colors: _colorScheme, 37 | stops: [0.30, 0.70], 38 | begin: Alignment.centerLeft, 39 | end: Alignment.centerRight, 40 | ), 41 | ), 42 | child: Column( 43 | mainAxisSize: MainAxisSize.max, 44 | mainAxisAlignment: MainAxisAlignment.spaceAround, 45 | crossAxisAlignment: CrossAxisAlignment.start, 46 | children: [ 47 | Text( 48 | message.content, 49 | style: TextStyle( 50 | color: Colors.white, 51 | ), 52 | ), 53 | Text( 54 | timeago.format(message.sentTime), 55 | style: TextStyle( 56 | color: Colors.white70, 57 | ), 58 | ), 59 | ], 60 | ), 61 | ); 62 | } 63 | } 64 | 65 | class ImageMessageBubble extends StatelessWidget { 66 | final bool isOwnMessage; 67 | final ChatMessage message; 68 | final double height; 69 | final double width; 70 | 71 | ImageMessageBubble( 72 | {required this.isOwnMessage, 73 | required this.message, 74 | required this.height, 75 | required this.width}); 76 | 77 | @override 78 | Widget build(BuildContext context) { 79 | List _colorScheme = isOwnMessage 80 | ? [Color.fromRGBO(0, 136, 249, 1.0), Color.fromRGBO(0, 82, 218, 1.0)] 81 | : [ 82 | Color.fromRGBO(51, 49, 68, 1.0), 83 | Color.fromRGBO(51, 49, 68, 1.0), 84 | ]; 85 | DecorationImage _image = DecorationImage( 86 | image: NetworkImage(message.content), 87 | fit: BoxFit.cover, 88 | ); 89 | return Container( 90 | padding: EdgeInsets.symmetric( 91 | horizontal: width * 0.02, 92 | vertical: height * 0.03, 93 | ), 94 | decoration: BoxDecoration( 95 | borderRadius: BorderRadius.circular(15), 96 | gradient: LinearGradient( 97 | colors: _colorScheme, 98 | stops: [0.30, 0.70], 99 | begin: Alignment.bottomLeft, 100 | end: Alignment.topRight, 101 | ), 102 | ), 103 | child: Column( 104 | mainAxisSize: MainAxisSize.max, 105 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 106 | crossAxisAlignment: CrossAxisAlignment.start, 107 | children: [ 108 | Container( 109 | height: height, 110 | width: width, 111 | decoration: BoxDecoration( 112 | borderRadius: BorderRadius.circular(15), 113 | image: _image, 114 | ), 115 | ), 116 | SizedBox(height: height * 0.02), 117 | Text( 118 | timeago.format(message.sentTime), 119 | style: TextStyle( 120 | color: Colors.white70, 121 | ), 122 | ), 123 | ], 124 | ), 125 | ); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /lib/widgets/rounded_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class RoundedButton extends StatelessWidget { 4 | final String name; 5 | final double height; 6 | final double width; 7 | final Function onPressed; 8 | 9 | const RoundedButton({ 10 | required this.name, 11 | required this.height, 12 | required this.width, 13 | required this.onPressed, 14 | }); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return Container( 19 | height: height, 20 | width: width, 21 | decoration: BoxDecoration( 22 | borderRadius: BorderRadius.circular(height * 0.25), 23 | color: Color.fromRGBO(0, 82, 218, 1.0), 24 | ), 25 | child: TextButton( 26 | onPressed: () => onPressed(), 27 | child: Text( 28 | name, 29 | style: TextStyle(fontSize: 22, color: Colors.white, height: 1.5), 30 | ), 31 | ), 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /lib/widgets/rounded_image.dart: -------------------------------------------------------------------------------- 1 | import 'package:file_picker/file_picker.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class RoundedImageNetwork extends StatelessWidget { 5 | final String imagePath; 6 | final double size; 7 | 8 | RoundedImageNetwork({ 9 | required Key key, 10 | required this.imagePath, 11 | required this.size, 12 | }) : super(key: key); 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | return Container( 17 | height: size, 18 | width: size, 19 | decoration: BoxDecoration( 20 | image: DecorationImage( 21 | fit: BoxFit.cover, 22 | image: NetworkImage(imagePath), 23 | ), 24 | borderRadius: BorderRadius.all( 25 | Radius.circular(size), 26 | ), 27 | color: Colors.black, 28 | ), 29 | ); 30 | } 31 | } 32 | 33 | class RoundedImageFile extends StatelessWidget { 34 | final PlatformFile image; 35 | final double size; 36 | 37 | RoundedImageFile({ 38 | required Key key, 39 | required this.image, 40 | required this.size, 41 | }) : super(key: key); 42 | 43 | @override 44 | Widget build(BuildContext context) { 45 | return Container( 46 | width: size, 47 | height: size, 48 | decoration: BoxDecoration( 49 | image: DecorationImage( 50 | fit: BoxFit.cover, 51 | image: AssetImage(image.path), 52 | ), 53 | borderRadius: BorderRadius.all(Radius.circular(size)), 54 | color: Colors.black, 55 | ), 56 | ); 57 | } 58 | } 59 | 60 | class RoundedImageNetworkWithStatusIndicator extends RoundedImageNetwork { 61 | final bool isActive; 62 | 63 | RoundedImageNetworkWithStatusIndicator({ 64 | required Key key, 65 | required String imagePath, 66 | required double size, 67 | required this.isActive, 68 | }) : super(key: key, imagePath: imagePath, size: size); 69 | 70 | @override 71 | Widget build(BuildContext context) { 72 | return Stack( 73 | clipBehavior: Clip.none, 74 | alignment: Alignment.bottomRight, 75 | children: [ 76 | super.build(context), 77 | Container( 78 | height: size * 0.20, 79 | width: size * 0.20, 80 | decoration: BoxDecoration( 81 | color: isActive ? Colors.green : Colors.red, 82 | borderRadius: BorderRadius.circular(size), 83 | ), 84 | ), 85 | ], 86 | ); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /lib/widgets/top_bar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class TopBar extends StatelessWidget { 4 | String _barTitle; 5 | Widget? primaryAction; 6 | Widget? secondaryAction; 7 | double? fontSize; 8 | 9 | late double _deviceHeight; 10 | late double _deviceWidth; 11 | 12 | TopBar( 13 | this._barTitle, { 14 | this.primaryAction, 15 | this.secondaryAction, 16 | this.fontSize = 35, 17 | }); 18 | 19 | @override 20 | Widget build(BuildContext context) { 21 | _deviceHeight = MediaQuery.of(context).size.height; 22 | _deviceWidth = MediaQuery.of(context).size.width; 23 | return _buildUI(); 24 | } 25 | 26 | Widget _buildUI() { 27 | return Container( 28 | height: _deviceHeight * 0.10, 29 | width: _deviceWidth, 30 | child: Row( 31 | mainAxisSize: MainAxisSize.max, 32 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 33 | crossAxisAlignment: CrossAxisAlignment.center, 34 | children: [ 35 | if (secondaryAction != null) secondaryAction!, 36 | _titleBar(), 37 | if (primaryAction != null) primaryAction!, 38 | ], 39 | ), 40 | ); 41 | } 42 | 43 | Widget _titleBar() { 44 | return Text( 45 | _barTitle, 46 | overflow: TextOverflow.ellipsis, 47 | style: TextStyle( 48 | color: Colors.white, 49 | fontSize: fontSize, 50 | fontWeight: FontWeight.w700, 51 | ), 52 | ); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "2.8.1" 11 | boolean_selector: 12 | dependency: transitive 13 | description: 14 | name: boolean_selector 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "2.1.0" 18 | characters: 19 | dependency: transitive 20 | description: 21 | name: characters 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "1.1.0" 25 | charcode: 26 | dependency: transitive 27 | description: 28 | name: charcode 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "1.3.1" 32 | clock: 33 | dependency: transitive 34 | description: 35 | name: clock 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "1.1.0" 39 | cloud_firestore: 40 | dependency: "direct main" 41 | description: 42 | name: cloud_firestore 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "2.5.1" 46 | cloud_firestore_platform_interface: 47 | dependency: transitive 48 | description: 49 | name: cloud_firestore_platform_interface 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "5.4.1" 53 | cloud_firestore_web: 54 | dependency: transitive 55 | description: 56 | name: cloud_firestore_web 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "2.4.1" 60 | collection: 61 | dependency: transitive 62 | description: 63 | name: collection 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "1.15.0" 67 | cupertino_icons: 68 | dependency: "direct main" 69 | description: 70 | name: cupertino_icons 71 | url: "https://pub.dartlang.org" 72 | source: hosted 73 | version: "1.0.3" 74 | fake_async: 75 | dependency: transitive 76 | description: 77 | name: fake_async 78 | url: "https://pub.dartlang.org" 79 | source: hosted 80 | version: "1.2.0" 81 | ffi: 82 | dependency: transitive 83 | description: 84 | name: ffi 85 | url: "https://pub.dartlang.org" 86 | source: hosted 87 | version: "1.1.2" 88 | file_picker: 89 | dependency: "direct main" 90 | description: 91 | name: file_picker 92 | url: "https://pub.dartlang.org" 93 | source: hosted 94 | version: "4.0.1" 95 | firebase: 96 | dependency: transitive 97 | description: 98 | name: firebase 99 | url: "https://pub.dartlang.org" 100 | source: hosted 101 | version: "9.0.1" 102 | firebase_analytics: 103 | dependency: "direct main" 104 | description: 105 | name: firebase_analytics 106 | url: "https://pub.dartlang.org" 107 | source: hosted 108 | version: "8.3.1" 109 | firebase_analytics_platform_interface: 110 | dependency: transitive 111 | description: 112 | name: firebase_analytics_platform_interface 113 | url: "https://pub.dartlang.org" 114 | source: hosted 115 | version: "2.0.1" 116 | firebase_analytics_web: 117 | dependency: transitive 118 | description: 119 | name: firebase_analytics_web 120 | url: "https://pub.dartlang.org" 121 | source: hosted 122 | version: "0.3.0+1" 123 | firebase_auth: 124 | dependency: "direct main" 125 | description: 126 | name: firebase_auth 127 | url: "https://pub.dartlang.org" 128 | source: hosted 129 | version: "3.1.0" 130 | firebase_auth_platform_interface: 131 | dependency: transitive 132 | description: 133 | name: firebase_auth_platform_interface 134 | url: "https://pub.dartlang.org" 135 | source: hosted 136 | version: "6.1.0" 137 | firebase_auth_web: 138 | dependency: transitive 139 | description: 140 | name: firebase_auth_web 141 | url: "https://pub.dartlang.org" 142 | source: hosted 143 | version: "3.1.0" 144 | firebase_core: 145 | dependency: "direct main" 146 | description: 147 | name: firebase_core 148 | url: "https://pub.dartlang.org" 149 | source: hosted 150 | version: "1.6.0" 151 | firebase_core_platform_interface: 152 | dependency: transitive 153 | description: 154 | name: firebase_core_platform_interface 155 | url: "https://pub.dartlang.org" 156 | source: hosted 157 | version: "4.0.1" 158 | firebase_core_web: 159 | dependency: transitive 160 | description: 161 | name: firebase_core_web 162 | url: "https://pub.dartlang.org" 163 | source: hosted 164 | version: "1.1.0" 165 | firebase_storage: 166 | dependency: "direct main" 167 | description: 168 | name: firebase_storage 169 | url: "https://pub.dartlang.org" 170 | source: hosted 171 | version: "10.0.3" 172 | firebase_storage_platform_interface: 173 | dependency: transitive 174 | description: 175 | name: firebase_storage_platform_interface 176 | url: "https://pub.dartlang.org" 177 | source: hosted 178 | version: "4.0.2" 179 | firebase_storage_web: 180 | dependency: transitive 181 | description: 182 | name: firebase_storage_web 183 | url: "https://pub.dartlang.org" 184 | source: hosted 185 | version: "3.0.2" 186 | flutter: 187 | dependency: "direct main" 188 | description: flutter 189 | source: sdk 190 | version: "0.0.0" 191 | flutter_keyboard_visibility: 192 | dependency: "direct main" 193 | description: 194 | name: flutter_keyboard_visibility 195 | url: "https://pub.dartlang.org" 196 | source: hosted 197 | version: "5.0.3" 198 | flutter_keyboard_visibility_platform_interface: 199 | dependency: transitive 200 | description: 201 | name: flutter_keyboard_visibility_platform_interface 202 | url: "https://pub.dartlang.org" 203 | source: hosted 204 | version: "2.0.0" 205 | flutter_keyboard_visibility_web: 206 | dependency: transitive 207 | description: 208 | name: flutter_keyboard_visibility_web 209 | url: "https://pub.dartlang.org" 210 | source: hosted 211 | version: "2.0.0" 212 | flutter_plugin_android_lifecycle: 213 | dependency: transitive 214 | description: 215 | name: flutter_plugin_android_lifecycle 216 | url: "https://pub.dartlang.org" 217 | source: hosted 218 | version: "2.0.3" 219 | flutter_spinkit: 220 | dependency: "direct main" 221 | description: 222 | name: flutter_spinkit 223 | url: "https://pub.dartlang.org" 224 | source: hosted 225 | version: "5.1.0" 226 | flutter_test: 227 | dependency: "direct dev" 228 | description: flutter 229 | source: sdk 230 | version: "0.0.0" 231 | flutter_web_plugins: 232 | dependency: transitive 233 | description: flutter 234 | source: sdk 235 | version: "0.0.0" 236 | get_it: 237 | dependency: "direct main" 238 | description: 239 | name: get_it 240 | url: "https://pub.dartlang.org" 241 | source: hosted 242 | version: "7.2.0" 243 | http: 244 | dependency: transitive 245 | description: 246 | name: http 247 | url: "https://pub.dartlang.org" 248 | source: hosted 249 | version: "0.13.3" 250 | http_parser: 251 | dependency: transitive 252 | description: 253 | name: http_parser 254 | url: "https://pub.dartlang.org" 255 | source: hosted 256 | version: "4.0.0" 257 | intl: 258 | dependency: transitive 259 | description: 260 | name: intl 261 | url: "https://pub.dartlang.org" 262 | source: hosted 263 | version: "0.17.0" 264 | js: 265 | dependency: transitive 266 | description: 267 | name: js 268 | url: "https://pub.dartlang.org" 269 | source: hosted 270 | version: "0.6.3" 271 | matcher: 272 | dependency: transitive 273 | description: 274 | name: matcher 275 | url: "https://pub.dartlang.org" 276 | source: hosted 277 | version: "0.12.10" 278 | meta: 279 | dependency: transitive 280 | description: 281 | name: meta 282 | url: "https://pub.dartlang.org" 283 | source: hosted 284 | version: "1.7.0" 285 | nested: 286 | dependency: transitive 287 | description: 288 | name: nested 289 | url: "https://pub.dartlang.org" 290 | source: hosted 291 | version: "1.0.0" 292 | path: 293 | dependency: transitive 294 | description: 295 | name: path 296 | url: "https://pub.dartlang.org" 297 | source: hosted 298 | version: "1.8.0" 299 | pedantic: 300 | dependency: transitive 301 | description: 302 | name: pedantic 303 | url: "https://pub.dartlang.org" 304 | source: hosted 305 | version: "1.11.1" 306 | plugin_platform_interface: 307 | dependency: transitive 308 | description: 309 | name: plugin_platform_interface 310 | url: "https://pub.dartlang.org" 311 | source: hosted 312 | version: "2.0.1" 313 | provider: 314 | dependency: "direct main" 315 | description: 316 | name: provider 317 | url: "https://pub.dartlang.org" 318 | source: hosted 319 | version: "6.0.0" 320 | sky_engine: 321 | dependency: transitive 322 | description: flutter 323 | source: sdk 324 | version: "0.0.99" 325 | source_span: 326 | dependency: transitive 327 | description: 328 | name: source_span 329 | url: "https://pub.dartlang.org" 330 | source: hosted 331 | version: "1.8.1" 332 | stack_trace: 333 | dependency: transitive 334 | description: 335 | name: stack_trace 336 | url: "https://pub.dartlang.org" 337 | source: hosted 338 | version: "1.10.0" 339 | stream_channel: 340 | dependency: transitive 341 | description: 342 | name: stream_channel 343 | url: "https://pub.dartlang.org" 344 | source: hosted 345 | version: "2.1.0" 346 | string_scanner: 347 | dependency: transitive 348 | description: 349 | name: string_scanner 350 | url: "https://pub.dartlang.org" 351 | source: hosted 352 | version: "1.1.0" 353 | term_glyph: 354 | dependency: transitive 355 | description: 356 | name: term_glyph 357 | url: "https://pub.dartlang.org" 358 | source: hosted 359 | version: "1.2.0" 360 | test_api: 361 | dependency: transitive 362 | description: 363 | name: test_api 364 | url: "https://pub.dartlang.org" 365 | source: hosted 366 | version: "0.4.2" 367 | timeago: 368 | dependency: "direct main" 369 | description: 370 | name: timeago 371 | url: "https://pub.dartlang.org" 372 | source: hosted 373 | version: "3.1.0" 374 | typed_data: 375 | dependency: transitive 376 | description: 377 | name: typed_data 378 | url: "https://pub.dartlang.org" 379 | source: hosted 380 | version: "1.3.0" 381 | vector_math: 382 | dependency: transitive 383 | description: 384 | name: vector_math 385 | url: "https://pub.dartlang.org" 386 | source: hosted 387 | version: "2.1.0" 388 | sdks: 389 | dart: ">=2.12.0 <3.0.0" 390 | flutter: ">=2.0.0" 391 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: chatify_app 2 | description: A new Flutter project. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: "none" # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 1.0.0+1 19 | 20 | environment: 21 | sdk: ">=2.12.0 <3.0.0" 22 | 23 | dependencies: 24 | flutter: 25 | sdk: flutter 26 | 27 | firebase_core: "1.6.0" 28 | firebase_storage: "10.0.3" 29 | firebase_auth: "3.1.0" 30 | firebase_analytics: "8.3.1" 31 | cloud_firestore: "2.5.1" 32 | provider: "6.0.0" 33 | get_it: "7.2.0" 34 | file_picker: "4.0.1" 35 | flutter_spinkit: "5.1.0" 36 | timeago: "3.1.0" 37 | flutter_keyboard_visibility: "5.0.3" 38 | 39 | # The following adds the Cupertino Icons font to your application. 40 | # Use with the CupertinoIcons class for iOS style icons. 41 | cupertino_icons: ^1.0.2 42 | 43 | dev_dependencies: 44 | flutter_test: 45 | sdk: flutter 46 | 47 | # For information on the generic Dart part of this file, see the 48 | # following page: https://dart.dev/tools/pub/pubspec 49 | 50 | # The following section is specific to Flutter. 51 | flutter: 52 | # The following line ensures that the Material Icons font is 53 | # included with your application, so that you can use the icons in 54 | # the material Icons class. 55 | uses-material-design: true 56 | # To add assets to your application, add an assets section, like this: 57 | assets: 58 | - assets/images/ 59 | # An image asset can refer to one or more resolution-specific "variants", see 60 | # https://flutter.dev/assets-and-images/#resolution-aware. 61 | # For details regarding adding assets from package dependencies, see 62 | # https://flutter.dev/assets-and-images/#from-packages 63 | # To add custom fonts to your application, add a fonts section here, 64 | # in this "flutter" section. Each entry in this list should have a 65 | # "family" key with the font family name, and a "fonts" key with a 66 | # list giving the asset and other descriptors for the font. For 67 | # example: 68 | # fonts: 69 | # - family: Schyler 70 | # fonts: 71 | # - asset: fonts/Schyler-Regular.ttf 72 | # - asset: fonts/Schyler-Italic.ttf 73 | # style: italic 74 | # - family: Trajan Pro 75 | # fonts: 76 | # - asset: fonts/TrajanPro.ttf 77 | # - asset: fonts/TrajanPro_Bold.ttf 78 | # weight: 700 79 | # 80 | # For details regarding fonts from package dependencies, 81 | # see https://flutter.dev/custom-fonts/#from-packages 82 | -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/web/favicon.png -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hussain-mustafa990/chatify_flutter_firebase_chat_application/a0ae04f7780d5c93bfe6b8a53b470890ccd39364/web/icons/Icon-512.png -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | chatify_app 27 | 28 | 29 | 30 | 33 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chatify_app", 3 | "short_name": "chatify_app", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | --------------------------------------------------------------------------------