[
  {
    "path": ".gitignore",
    "content": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\nmigrate_working_dir/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.iws\n.idea/\n\n# The .vscode folder contains launch configuration and tasks you configure in\n# VS Code which you may wish to be included in version control, so this line\n# is commented out by default.\n#.vscode/\n\n# Flutter/Dart/Pub related\n**/doc/api/\n**/ios/Flutter/.last_build_id\n.dart_tool/\n.flutter-plugins\n.flutter-plugins-dependencies\n.packages\n.pub-cache/\n.pub/\n/build/\n\n# Symbolication related\napp.*.symbols\n\n# Obfuscation related\napp.*.map.json\n\n# Android Studio will place build artifacts here\n/android/app/debug\n/android/app/profile\n/android/app/release\n"
  },
  {
    "path": ".metadata",
    "content": "# This file tracks properties of this Flutter project.\n# Used by Flutter tool to assess capabilities and perform upgrades etc.\n#\n# This file should be version controlled.\n\nversion:\n  revision: e5c8614e789b1d3f7ef8d9a77295b884b5b396e0\n  channel: master\n\nproject_type: app\n\n# Tracks metadata for the flutter migrate command\nmigration:\n  platforms:\n    - platform: root\n      create_revision: e5c8614e789b1d3f7ef8d9a77295b884b5b396e0\n      base_revision: e5c8614e789b1d3f7ef8d9a77295b884b5b396e0\n    - platform: android\n      create_revision: e5c8614e789b1d3f7ef8d9a77295b884b5b396e0\n      base_revision: e5c8614e789b1d3f7ef8d9a77295b884b5b396e0\n    - platform: ios\n      create_revision: e5c8614e789b1d3f7ef8d9a77295b884b5b396e0\n      base_revision: e5c8614e789b1d3f7ef8d9a77295b884b5b396e0\n\n  # User provided section\n\n  # List of Local paths (relative to this file) that should be\n  # ignored by the migrate tool.\n  #\n  # Files that are not part of the templates will be ignored by default.\n  unmanaged_files:\n    - 'lib/main.dart'\n    - 'ios/Runner.xcodeproj/project.pbxproj'\n"
  },
  {
    "path": "README.md",
    "content": "# Flutter-WhatsApp-Clone-Clean-Architecture\n WhatsApp Clone with Flutter, Firebase, Bloc, Clean Code & Clean Architecture🔥🔥❤️\n\n## [Watch it on YouTube](https://www.youtube.com/watch?v=INxbhrOeiuk)\n\n\n##  Some of the cool features applied in the project:\n- Flutter bloc(cubit)\n- Enhanced clean architecture.\n- Firebase Firestore, Firebase Storage, and Firebase Auth.\n- Real-Time Changes from Firebase using Streams.\n- Phone Number Authentication\n- 1-1 Chatting with Contacts Only\n- Text, Image, GIF, Audio(Recording), Video & Emoji Sharing\n- Online/Offline Status\n- Seen Message\n- Replying to Messages\n- Auto Scroll on New Messages\n- Custom gallery & camera & video display\nNow, I am working on the status and video calling.\n\n## Getting Started\n\nThis project is a starting point for a Flutter application.\n\nA few resources to get you started if this is your first Flutter project:\n\n- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)\n- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)\n\nFor help getting started with Flutter development, view the\n[online documentation](https://docs.flutter.dev/), which offers tutorials,\nsamples, guidance on mobile development, and a full API reference.\n"
  },
  {
    "path": "analysis_options.yaml",
    "content": "# This file configures the analyzer, which statically analyzes Dart code to\n# check for errors, warnings, and lints.\n#\n# The issues identified by the analyzer are surfaced in the UI of Dart-enabled\n# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be\n# invoked from the command line by running `flutter analyze`.\n\n# The following line activates a set of recommended lints for Flutter apps,\n# packages, and plugins designed to encourage good coding practices.\ninclude: package:flutter_lints/flutter.yaml\n\nlinter:\n  # The lint rules applied to this project can be customized in the\n  # section below to disable rules from the `package:flutter_lints/flutter.yaml`\n  # included above or to enable additional rules. A list of all available lints\n  # and their documentation is published at\n  # https://dart-lang.github.io/linter/lints/index.html.\n  #\n  # Instead of disabling a lint rule for the entire project in the\n  # section below, it can also be suppressed for a single line of code\n  # or a specific dart file by using the `// ignore: name_of_lint` and\n  # `// ignore_for_file: name_of_lint` syntax on the line or in the file\n  # producing the lint.\n  rules:\n    # avoid_print: false  # Uncomment to disable the `avoid_print` rule\n    # prefer_single_quotes: true  # Uncomment to enable the `prefer_single_quotes` rule\n\n# Additional information about this file can be found at\n# https://dart.dev/guides/language/analysis-options\n"
  },
  {
    "path": "android/.gitignore",
    "content": "gradle-wrapper.jar\n/.gradle\n/captures/\n/gradlew\n/gradlew.bat\n/local.properties\nGeneratedPluginRegistrant.java\n\n# Remember to never publicly share your keystore.\n# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app\nkey.properties\n**/*.keystore\n**/*.jks\n"
  },
  {
    "path": "android/app/build.gradle",
    "content": "def localProperties = new Properties()\ndef localPropertiesFile = rootProject.file('local.properties')\nif (localPropertiesFile.exists()) {\n    localPropertiesFile.withReader('UTF-8') { reader ->\n        localProperties.load(reader)\n    }\n}\n\ndef flutterRoot = localProperties.getProperty('flutter.sdk')\nif (flutterRoot == null) {\n    throw new GradleException(\"Flutter SDK not found. Define location with flutter.sdk in the local.properties file.\")\n}\n\ndef flutterVersionCode = localProperties.getProperty('flutter.versionCode')\nif (flutterVersionCode == null) {\n    flutterVersionCode = '1'\n}\n\ndef flutterVersionName = localProperties.getProperty('flutter.versionName')\nif (flutterVersionName == null) {\n    flutterVersionName = '1.0'\n}\n\napply plugin: 'com.android.application'\napply plugin: 'kotlin-android'\napply from: \"$flutterRoot/packages/flutter_tools/gradle/flutter.gradle\"\napply plugin: 'com.google.gms.google-services'\n\nandroid {\n   // compileSdkVersion flutter.compileSdkVersion\n    compileSdkVersion 33\n    ndkVersion flutter.ndkVersion\n\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n\n    kotlinOptions {\n        jvmTarget = '1.8'\n    }\n\n    sourceSets {\n        main.java.srcDirs += 'src/main/kotlin'\n    }\n\n    defaultConfig {\n        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).\n        applicationId \"mogohary99.whatsapp_flutter_clone\"\n        // You can update the following values to match your application needs.\n        // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.\n        minSdkVersion 21\n        targetSdkVersion flutter.targetSdkVersion\n        versionCode flutterVersionCode.toInteger()\n        versionName flutterVersionName\n        multiDexEnabled true\n    }\n\n    buildTypes {\n        release {\n            // TODO: Add your own signing config for the release build.\n            // Signing with the debug keys for now, so `flutter run --release` works.\n            signingConfig signingConfigs.debug\n        }\n    }\n}\n\nflutter {\n    source '../..'\n}\n\ndependencies {\n    implementation \"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version\"\n    implementation 'com.android.support:multidex:2.0.1'\n    implementation platform('com.google.firebase:firebase-bom:31.0.2')\n}\n"
  },
  {
    "path": "android/app/google-services.json",
    "content": "{\n  \"project_info\": {\n    \"project_number\": \"528108582188\",\n    \"project_id\": \"whatsapp-8d793\",\n    \"storage_bucket\": \"whatsapp-8d793.appspot.com\"\n  },\n  \"client\": [\n    {\n      \"client_info\": {\n        \"mobilesdk_app_id\": \"1:528108582188:android:6544c1493d3433f4f26889\",\n        \"android_client_info\": {\n          \"package_name\": \"mogohary99.whatsapp_flutter_clone\"\n        }\n      },\n      \"oauth_client\": [\n        {\n          \"client_id\": \"528108582188-0d3v7bqfv5vtdhc08th823se96cgsqk0.apps.googleusercontent.com\",\n          \"client_type\": 1,\n          \"android_info\": {\n            \"package_name\": \"mogohary99.whatsapp_flutter_clone\",\n            \"certificate_hash\": \"09199a03d91f7c6cd3061042942deb2c3f3a93d0\"\n          }\n        },\n        {\n          \"client_id\": \"528108582188-nveih6hahfhv7sh0cep1kdj8rjgm1loa.apps.googleusercontent.com\",\n          \"client_type\": 3\n        }\n      ],\n      \"api_key\": [\n        {\n          \"current_key\": \"AIzaSyBa-_MafiWD6xzy9aAgoK1hfQ6yjp3u_zg\"\n        }\n      ],\n      \"services\": {\n        \"appinvite_service\": {\n          \"other_platform_oauth_client\": [\n            {\n              \"client_id\": \"528108582188-nveih6hahfhv7sh0cep1kdj8rjgm1loa.apps.googleusercontent.com\",\n              \"client_type\": 3\n            }\n          ]\n        }\n      }\n    }\n  ],\n  \"configuration_version\": \"1\"\n}"
  },
  {
    "path": "android/app/src/debug/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"mogohary99.whatsapp_flutter_clone\">\n    <!-- The INTERNET permission is required for development. Specifically,\n         the Flutter tool needs it to communicate with the running application\n         to allow setting breakpoints, to provide hot reload, etc.\n    -->\n    <uses-permission android:name=\"android.permission.INTERNET\"/>\n</manifest>\n"
  },
  {
    "path": "android/app/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"mogohary99.whatsapp_flutter_clone\">\n    <uses-permission android:name=\"android.permission.READ_CONTACTS\"/>\n    <uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>\n    <uses-permission android:name=\"android.permission.INTERNET\"/>\n    <uses-permission  android:name=\"android.permission.READ_PHONE_STATE\"/>\n    <uses-permission  android:name=\"android.permission.RECORD_AUDIO\"  />\n    <uses-permission  android:name=\"android.permission.CAMERA\"  />\n    <uses-permission  android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"  />\n    <uses-permission  android:name=\"android.permission.ACCESS_NETWORK_STATE\"  />\n    <!-- The Agora SDK requires Bluetooth permissions in case users are using Bluetooth devices.-->\n    <uses-permission  android:name=\"android.permission.BLUETOOTH\"  />\n   <application\n        android:label=\"whatsapp_flutter_clone\"\n        android:name=\"${applicationName}\"\n        android:icon=\"@mipmap/ic_launcher\">\n        <activity\n            android:name=\".MainActivity\"\n            android:exported=\"true\"\n            android:launchMode=\"singleTop\"\n            android:theme=\"@style/LaunchTheme\"\n            android:configChanges=\"orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode\"\n            android:hardwareAccelerated=\"true\"\n            android:windowSoftInputMode=\"adjustResize\">\n            <!-- Specifies an Android theme to apply to this Activity as soon as\n                 the Android process has started. This theme is visible to the user\n                 while the Flutter UI initializes. After that, this theme continues\n                 to determine the Window background behind the Flutter UI. -->\n            <meta-data\n              android:name=\"io.flutter.embedding.android.NormalTheme\"\n              android:resource=\"@style/NormalTheme\"\n              />\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\"/>\n                <category android:name=\"android.intent.category.LAUNCHER\"/>\n            </intent-filter>\n        </activity>\n       <activity\n           android:name=\"com.yalantis.ucrop.UCropActivity\"\n           android:screenOrientation=\"portrait\"\n           android:theme=\"@style/Theme.AppCompat.Light.NoActionBar\"/>\n        <!-- Don't delete the meta-data below.\n             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->\n        <meta-data\n            android:name=\"flutterEmbedding\"\n            android:value=\"2\" />\n    </application>\n</manifest>\n"
  },
  {
    "path": "android/app/src/main/kotlin/mogohary99/whatsapp_flutter_clone/MainActivity.kt",
    "content": "package mogohary99.whatsapp_flutter_clone\n\nimport io.flutter.embedding.android.FlutterActivity\n\nclass MainActivity: FlutterActivity() {\n}\n"
  },
  {
    "path": "android/app/src/main/res/drawable/launch_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Modify this file to customize your launch splash screen -->\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:drawable=\"@android:color/white\" />\n\n    <!-- You can insert your own image assets here -->\n    <!-- <item>\n        <bitmap\n            android:gravity=\"center\"\n            android:src=\"@mipmap/launch_image\" />\n    </item> -->\n</layer-list>\n"
  },
  {
    "path": "android/app/src/main/res/drawable-v21/launch_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Modify this file to customize your launch splash screen -->\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:drawable=\"?android:colorBackground\" />\n\n    <!-- You can insert your own image assets here -->\n    <!-- <item>\n        <bitmap\n            android:gravity=\"center\"\n            android:src=\"@mipmap/launch_image\" />\n    </item> -->\n</layer-list>\n"
  },
  {
    "path": "android/app/src/main/res/values/styles.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->\n    <style name=\"LaunchTheme\" parent=\"@android:style/Theme.Light.NoTitleBar\">\n        <!-- Show a splash screen on the activity. Automatically removed when\n             the Flutter engine draws its first frame -->\n        <item name=\"android:windowBackground\">@drawable/launch_background</item>\n    </style>\n    <!-- Theme applied to the Android Window as soon as the process has started.\n         This theme determines the color of the Android Window while your\n         Flutter UI initializes, as well as behind your Flutter UI while its\n         running.\n\n         This Theme is only used starting with V2 of Flutter's Android embedding. -->\n    <style name=\"NormalTheme\" parent=\"@android:style/Theme.Light.NoTitleBar\">\n        <item name=\"android:windowBackground\">?android:colorBackground</item>\n    </style>\n</resources>\n"
  },
  {
    "path": "android/app/src/main/res/values-night/styles.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->\n    <style name=\"LaunchTheme\" parent=\"@android:style/Theme.Black.NoTitleBar\">\n        <!-- Show a splash screen on the activity. Automatically removed when\n             the Flutter engine draws its first frame -->\n        <item name=\"android:windowBackground\">@drawable/launch_background</item>\n    </style>\n    <!-- Theme applied to the Android Window as soon as the process has started.\n         This theme determines the color of the Android Window while your\n         Flutter UI initializes, as well as behind your Flutter UI while its\n         running.\n\n         This Theme is only used starting with V2 of Flutter's Android embedding. -->\n    <style name=\"NormalTheme\" parent=\"@android:style/Theme.Black.NoTitleBar\">\n        <item name=\"android:windowBackground\">?android:colorBackground</item>\n    </style>\n</resources>\n"
  },
  {
    "path": "android/app/src/profile/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"mogohary99.whatsapp_flutter_clone\">\n    <!-- The INTERNET permission is required for development. Specifically,\n         the Flutter tool needs it to communicate with the running application\n         to allow setting breakpoints, to provide hot reload, etc.\n    -->\n    <uses-permission android:name=\"android.permission.INTERNET\"/>\n</manifest>\n"
  },
  {
    "path": "android/build.gradle",
    "content": "buildscript {\n    ext.kotlin_version = '1.7.10'\n    repositories {\n        google()\n        mavenCentral()\n    }\n\n    dependencies {\n        classpath 'com.android.tools.build:gradle:7.2.0'\n        classpath \"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version\"\n        classpath 'com.google.gms:google-services:4.3.13'\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        mavenCentral()\n        maven { url 'https://jitpack.io' }\n    }\n}\n\nrootProject.buildDir = '../build'\nsubprojects {\n    project.buildDir = \"${rootProject.buildDir}/${project.name}\"\n}\nsubprojects {\n    project.evaluationDependsOn(':app')\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "android/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-7.5-all.zip\n"
  },
  {
    "path": "android/gradle.properties",
    "content": "org.gradle.jvmargs=-Xmx1536M\nandroid.useAndroidX=true\nandroid.enableJetifier=true\n"
  },
  {
    "path": "android/settings.gradle",
    "content": "include ':app'\n\ndef localPropertiesFile = new File(rootProject.projectDir, \"local.properties\")\ndef properties = new Properties()\n\nassert localPropertiesFile.exists()\nlocalPropertiesFile.withReader(\"UTF-8\") { reader -> properties.load(reader) }\n\ndef flutterSdkPath = properties.getProperty(\"flutter.sdk\")\nassert flutterSdkPath != null, \"flutter.sdk not set in local.properties\"\napply from: \"$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle\"\n"
  },
  {
    "path": "ios/.gitignore",
    "content": "**/dgph\n*.mode1v3\n*.mode2v3\n*.moved-aside\n*.pbxuser\n*.perspectivev3\n**/*sync/\n.sconsign.dblite\n.tags*\n**/.vagrant/\n**/DerivedData/\nIcon?\n**/Pods/\n**/.symlinks/\nprofile\nxcuserdata\n**/.generated/\nFlutter/App.framework\nFlutter/Flutter.framework\nFlutter/Flutter.podspec\nFlutter/Generated.xcconfig\nFlutter/ephemeral/\nFlutter/app.flx\nFlutter/app.zip\nFlutter/flutter_assets/\nFlutter/flutter_export_environment.sh\nServiceDefinitions.json\nRunner/GeneratedPluginRegistrant.*\n\n# Exceptions to above rules.\n!default.mode1v3\n!default.mode2v3\n!default.pbxuser\n!default.perspectivev3\n"
  },
  {
    "path": "ios/Flutter/AppFrameworkInfo.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n  <key>CFBundleDevelopmentRegion</key>\n  <string>en</string>\n  <key>CFBundleExecutable</key>\n  <string>App</string>\n  <key>CFBundleIdentifier</key>\n  <string>io.flutter.flutter.app</string>\n  <key>CFBundleInfoDictionaryVersion</key>\n  <string>6.0</string>\n  <key>CFBundleName</key>\n  <string>App</string>\n  <key>CFBundlePackageType</key>\n  <string>FMWK</string>\n  <key>CFBundleShortVersionString</key>\n  <string>1.0</string>\n  <key>CFBundleSignature</key>\n  <string>????</string>\n  <key>CFBundleVersion</key>\n  <string>1.0</string>\n  <key>MinimumOSVersion</key>\n  <string>11.0</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "ios/Flutter/Debug.xcconfig",
    "content": "#include \"Generated.xcconfig\"\n"
  },
  {
    "path": "ios/Flutter/Release.xcconfig",
    "content": "#include \"Generated.xcconfig\"\n"
  },
  {
    "path": "ios/Runner/AppDelegate.swift",
    "content": "import UIKit\nimport Flutter\n\n@UIApplicationMain\n@objc class AppDelegate: FlutterAppDelegate {\n  override func application(\n    _ application: UIApplication,\n    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?\n  ) -> Bool {\n    GeneratedPluginRegistrant.register(with: self)\n    return super.application(application, didFinishLaunchingWithOptions: launchOptions)\n  }\n}\n"
  },
  {
    "path": "ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"size\" : \"20x20\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-20x20@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"20x20\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-20x20@3x.png\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"size\" : \"29x29\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-29x29@1x.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"29x29\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-29x29@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"29x29\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-29x29@3x.png\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"size\" : \"40x40\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-40x40@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"40x40\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-40x40@3x.png\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"size\" : \"60x60\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-60x60@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"60x60\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-60x60@3x.png\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"size\" : \"20x20\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-20x20@1x.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"20x20\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-20x20@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"29x29\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-29x29@1x.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"29x29\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-29x29@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"40x40\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-40x40@1x.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"40x40\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-40x40@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"76x76\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-76x76@1x.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"76x76\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-76x76@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"83.5x83.5\",\n      \"idiom\" : \"ipad\",\n      \"filename\" : \"Icon-App-83.5x83.5@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"1024x1024\",\n      \"idiom\" : \"ios-marketing\",\n      \"filename\" : \"Icon-App-1024x1024@1x.png\",\n      \"scale\" : \"1x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}\n"
  },
  {
    "path": "ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"LaunchImage.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"LaunchImage@2x.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"LaunchImage@3x.png\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}\n"
  },
  {
    "path": "ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md",
    "content": "# Launch Screen Assets\n\nYou can customize the launch screen with your own desired assets by replacing the image files in this directory.\n\nYou 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."
  },
  {
    "path": "ios/Runner/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"12121\" systemVersion=\"16G29\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"12089\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <layoutGuides>\n                        <viewControllerLayoutGuide type=\"top\" id=\"Ydg-fD-yQy\"/>\n                        <viewControllerLayoutGuide type=\"bottom\" id=\"xbc-2k-c8Z\"/>\n                    </layoutGuides>\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <imageView opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" image=\"LaunchImage\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"YRO-k0-Ey4\">\n                            </imageView>\n                        </subviews>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <constraints>\n                            <constraint firstItem=\"YRO-k0-Ey4\" firstAttribute=\"centerX\" secondItem=\"Ze5-6b-2t3\" secondAttribute=\"centerX\" id=\"1a2-6s-vTC\"/>\n                            <constraint firstItem=\"YRO-k0-Ey4\" firstAttribute=\"centerY\" secondItem=\"Ze5-6b-2t3\" secondAttribute=\"centerY\" id=\"4X2-HB-R7a\"/>\n                        </constraints>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n    <resources>\n        <image name=\"LaunchImage\" width=\"168\" height=\"185\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "ios/Runner/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"10117\" systemVersion=\"15F34\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" initialViewController=\"BYZ-38-t0r\">\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"10085\"/>\n    </dependencies>\n    <scenes>\n        <!--Flutter View Controller-->\n        <scene sceneID=\"tne-QT-ifu\">\n            <objects>\n                <viewController id=\"BYZ-38-t0r\" customClass=\"FlutterViewController\" sceneMemberID=\"viewController\">\n                    <layoutGuides>\n                        <viewControllerLayoutGuide type=\"top\" id=\"y3c-jy-aDJ\"/>\n                        <viewControllerLayoutGuide type=\"bottom\" id=\"wfy-db-euE\"/>\n                    </layoutGuides>\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"8bC-Xf-vdC\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"600\" height=\"600\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"calibratedWhite\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"dkx-z0-nzr\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "ios/Runner/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleDisplayName</key>\n\t<string>Whatsapp Flutter Clone</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>whatsapp_flutter_clone</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>$(FLUTTER_BUILD_NAME)</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>$(FLUTTER_BUILD_NUMBER)</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UIViewControllerBasedStatusBarAppearance</key>\n\t<false/>\n\t<key>CADisableMinimumFrameDurationOnPhone</key>\n\t<true/>\n\t<key>UIApplicationSupportsIndirectInputEvents</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "ios/Runner/Runner-Bridging-Header.h",
    "content": "#import \"GeneratedPluginRegistrant.h\"\n"
  },
  {
    "path": "ios/Runner.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 54;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };\n\t\t3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };\n\t\t74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };\n\t\t97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };\n\t\t97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };\n\t\t97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXCopyFilesBuildPhase section */\n\t\t9705A1C41CF9048500538489 /* Embed Frameworks */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"\";\n\t\t\tdstSubfolderSpec = 10;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tname = \"Embed Frameworks\";\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXCopyFilesBuildPhase section */\n\n/* Begin PBXFileReference section */\n\t\t1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = \"<group>\"; };\n\t\t1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = \"<group>\"; };\n\t\t3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = \"<group>\"; };\n\t\t74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"Runner-Bridging-Header.h\"; sourceTree = \"<group>\"; };\n\t\t74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = \"<group>\"; };\n\t\t9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = \"<group>\"; };\n\t\t9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = \"<group>\"; };\n\t\t97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\t97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\t97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t97C146EB1CF9000F007C117D /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t9740EEB11CF90186004384FC /* Flutter */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,\n\t\t\t\t9740EEB21CF90195004384FC /* Debug.xcconfig */,\n\t\t\t\t7AFA3C8E1D35360C0083082E /* Release.xcconfig */,\n\t\t\t\t9740EEB31CF90195004384FC /* Generated.xcconfig */,\n\t\t\t);\n\t\t\tname = Flutter;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t97C146E51CF9000F007C117D = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9740EEB11CF90186004384FC /* Flutter */,\n\t\t\t\t97C146F01CF9000F007C117D /* Runner */,\n\t\t\t\t97C146EF1CF9000F007C117D /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t97C146EF1CF9000F007C117D /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t97C146EE1CF9000F007C117D /* Runner.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t97C146F01CF9000F007C117D /* Runner */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t97C146FA1CF9000F007C117D /* Main.storyboard */,\n\t\t\t\t97C146FD1CF9000F007C117D /* Assets.xcassets */,\n\t\t\t\t97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,\n\t\t\t\t97C147021CF9000F007C117D /* Info.plist */,\n\t\t\t\t1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,\n\t\t\t\t1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,\n\t\t\t\t74858FAE1ED2DC5600515810 /* AppDelegate.swift */,\n\t\t\t\t74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,\n\t\t\t);\n\t\t\tpath = Runner;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t97C146ED1CF9000F007C117D /* Runner */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget \"Runner\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t9740EEB61CF901F6004384FC /* Run Script */,\n\t\t\t\t97C146EA1CF9000F007C117D /* Sources */,\n\t\t\t\t97C146EB1CF9000F007C117D /* Frameworks */,\n\t\t\t\t97C146EC1CF9000F007C117D /* Resources */,\n\t\t\t\t9705A1C41CF9048500538489 /* Embed Frameworks */,\n\t\t\t\t3B06AD1E1E4923F5004D2608 /* Thin Binary */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = Runner;\n\t\t\tproductName = Runner;\n\t\t\tproductReference = 97C146EE1CF9000F007C117D /* Runner.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t97C146E61CF9000F007C117D /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 1300;\n\t\t\t\tORGANIZATIONNAME = \"\";\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t97C146ED1CF9000F007C117D = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 7.3.1;\n\t\t\t\t\t\tLastSwiftMigration = 1100;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject \"Runner\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 97C146E51CF9000F007C117D;\n\t\t\tproductRefGroup = 97C146EF1CF9000F007C117D /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t97C146ED1CF9000F007C117D /* Runner */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t97C146EC1CF9000F007C117D /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,\n\t\t\t\t3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,\n\t\t\t\t97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,\n\t\t\t\t97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\talwaysOutOfDate = 1;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Thin Binary\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"/bin/sh \\\"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\\\" embed_and_thin\";\n\t\t};\n\t\t9740EEB61CF901F6004384FC /* Run Script */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\talwaysOutOfDate = 1;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Run Script\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"/bin/sh \\\"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\\\" build\";\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t97C146EA1CF9000F007C117D /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,\n\t\t\t\t1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\t97C146FA1CF9000F007C117D /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t97C146FB1CF9000F007C117D /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t97C147001CF9000F007C117D /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t249021D3217E4FDB00AE95B9 /* Profile */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 11.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSUPPORTED_PLATFORMS = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Profile;\n\t\t};\n\t\t249021D4217E4FDB00AE95B9 /* Profile */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCURRENT_PROJECT_VERSION = \"$(FLUTTER_BUILD_NUMBER)\";\n\t\t\t\tENABLE_BITCODE = NO;\n\t\t\t\tINFOPLIST_FILE = Runner/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = mogohary99.whatsappFlutterClone;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"Runner/Runner-Bridging-Header.h\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t};\n\t\t\tname = Profile;\n\t\t};\n\t\t97C147031CF9000F007C117D /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 11.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t97C147041CF9000F007C117D /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 11.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSUPPORTED_PLATFORMS = iphoneos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t97C147061CF9000F007C117D /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCURRENT_PROJECT_VERSION = \"$(FLUTTER_BUILD_NUMBER)\";\n\t\t\t\tENABLE_BITCODE = NO;\n\t\t\t\tINFOPLIST_FILE = Runner/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = mogohary99.whatsappFlutterClone;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"Runner/Runner-Bridging-Header.h\";\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t97C147071CF9000F007C117D /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCURRENT_PROJECT_VERSION = \"$(FLUTTER_BUILD_NUMBER)\";\n\t\t\t\tENABLE_BITCODE = NO;\n\t\t\t\tINFOPLIST_FILE = Runner/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = mogohary99.whatsappFlutterClone;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"Runner/Runner-Bridging-Header.h\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t97C146E91CF9000F007C117D /* Build configuration list for PBXProject \"Runner\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t97C147031CF9000F007C117D /* Debug */,\n\t\t\t\t97C147041CF9000F007C117D /* Release */,\n\t\t\t\t249021D3217E4FDB00AE95B9 /* Profile */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget \"Runner\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t97C147061CF9000F007C117D /* Debug */,\n\t\t\t\t97C147071CF9000F007C117D /* Release */,\n\t\t\t\t249021D4217E4FDB00AE95B9 /* Profile */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 97C146E61CF9000F007C117D /* Project object */;\n}\n"
  },
  {
    "path": "ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>PreviewsEnabled</key>\n\t<false/>\n</dict>\n</plist>\n"
  },
  {
    "path": "ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1300\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"97C146ED1CF9000F007C117D\"\n               BuildableName = \"Runner.app\"\n               BlueprintName = \"Runner\"\n               ReferencedContainer = \"container:Runner.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"97C146ED1CF9000F007C117D\"\n            BuildableName = \"Runner.app\"\n            BlueprintName = \"Runner\"\n            ReferencedContainer = \"container:Runner.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"97C146ED1CF9000F007C117D\"\n            BuildableName = \"Runner.app\"\n            BlueprintName = \"Runner\"\n            ReferencedContainer = \"container:Runner.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Profile\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"97C146ED1CF9000F007C117D\"\n            BuildableName = \"Runner.app\"\n            BlueprintName = \"Runner\"\n            ReferencedContainer = \"container:Runner.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "ios/Runner.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"group:Runner.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>PreviewsEnabled</key>\n\t<false/>\n</dict>\n</plist>\n"
  },
  {
    "path": "lib/config/agora_config.dart",
    "content": "class AgoraConfig{\n  static const String token = '';\n  static const String appId = '97bc1546a8174ed0a7a7c9acdfca61f5';\n  static const String appCertificate = '56cae9b6d2854e0a833f11c5ccc61cbe';\n}"
  },
  {
    "path": "lib/core/enums/messge_type.dart",
    "content": "enum MessageType{\n text('text'),\n image('image'),\n gif('gif'),\n video('video'),\n audio('audio'),\n location('location'),\n contact('contact'),\n poll('poll');\n\nconst MessageType(this.type);\nfinal String type;\n}\n\nextension ConvertMessage on String{\n  MessageType toEnum(){\n    switch(this){\n      case 'text':\n        return MessageType.text;\n      case 'image':\n        return MessageType.image;\n      case 'gif':\n        return MessageType.gif;\n      case 'video':\n        return MessageType.video;\n      case 'audio':\n        return MessageType.audio;\n      case 'location':\n        return MessageType.location;\n      case 'contact':\n        return MessageType.contact;\n      case 'poll':\n        return MessageType.poll;\n      default:\n        return MessageType.text;\n    }\n  }\n}"
  },
  {
    "path": "lib/core/error/exceptions.dart",
    "content": "\nclass LocalDatabaseException implements Exception {\n  final String message;\n\n  const LocalDatabaseException({\n    required this.message,\n  });\n}\n\nclass CachedException implements Exception {\n  final String message;\n\n  const CachedException({\n    required this.message,\n  });\n}\n"
  },
  {
    "path": "lib/core/error/failure.dart",
    "content": "import 'package:equatable/equatable.dart';\n\nabstract class Failure extends Equatable {\n  final String message;\n\n  const Failure(this.message);\n\n  @override\n  List<Object> get props => [message];\n}\n\nclass ServerFailure extends Failure{\n  const ServerFailure(super.message);\n}\n\nclass LocalDatabaseFailure extends Failure{\n  const LocalDatabaseFailure(super.message);\n\n}\n\nclass CachedFailure extends Failure{\n  const CachedFailure(super.message);\n\n}"
  },
  {
    "path": "lib/core/extensions/extensions.dart",
    "content": "import 'package:flutter/material.dart';\n\nextension ContextExtension on BuildContext {\n  MediaQueryData get mediaQuery => MediaQuery.of(this);\n\n  TextTheme get textTheme => Theme.of(this).textTheme;\n\n  ThemeData get theme => Theme.of(this);\n\n  ColorScheme get colorScheme => Theme.of(this).colorScheme;\n}\n\nextension MediaQueryExtension on BuildContext {\n  Size get size => mediaQuery.size;\n  double height(double value) => mediaQuery.size.height * value;\n\n  double width(double value) => mediaQuery.size.width * value;\n}\n\nextension TextThemeExtension on BuildContext {\n  TextStyle? get displayLarge => textTheme.displayLarge;\n\n  TextStyle? get displayMedium => textTheme.displayMedium;\n\n  TextStyle? get displaySmall => textTheme.displaySmall;\n\n  TextStyle? get headlineLarge => textTheme.headlineLarge;\n\n  TextStyle? get headlineMedium => textTheme.headlineMedium;\n\n  TextStyle? get headlineSmall => textTheme.headlineSmall;\n\n  TextStyle? get titleLarge => textTheme.titleLarge;\n\n  TextStyle? get titleMedium => textTheme.titleMedium;\n\n  TextStyle? get titleSmall => textTheme.titleSmall;\n\n  TextStyle? get bodyLarge => textTheme.bodyLarge;\n\n  TextStyle? get bodyMedium => textTheme.bodyMedium;\n\n  TextStyle? get bodySmall => textTheme.bodySmall;\n\n  TextStyle? get labelLarge => textTheme.labelLarge;\n\n  TextStyle? get labelSmall => textTheme.labelSmall;\n}\n\n"
  },
  {
    "path": "lib/core/extensions/time_extension.dart",
    "content": "import '/core/functions/date_converter.dart';\n\nextension DateUtil on DateTime {\n  String get lastSeen {\n    return 'last seen ${DateConverter.getLastSeenDayTime(this)} at ${DateConverter.dateConverterHoursAmPmMode(this)}';\n  }\n  String get amPmMode{\n    return DateConverter.dateConverterHoursAmPmMode(this);\n  }\n  String get chatDayTime{\n    return DateConverter.getChatDayTime(this);\n  }\n  String get chatContactTime{\n    return DateConverter.getChatContactTime(this);\n  }\n  bool isSameDay(DateTime day2){\n    return DateConverter.isSameDay(this, day2);\n  }\n}"
  },
  {
    "path": "lib/core/functions/app_dialogs.dart",
    "content": "import 'package:flutter/material.dart';\nimport '/core/extensions/extensions.dart';\n\nimport '../utils/constants/strings_manager.dart';\nimport '../utils/constants/values_manager.dart';\nimport 'navigator.dart';\n\nclass AppDialogs {\n  static Future<void> permissionDialog(\n    BuildContext context, {\n    required VoidCallback onContinuePressed,\n        required String contentText,\n  }) {\n    return _showMyDialog(\n      context: context,\n      contentPadding: EdgeInsets.zero,\n      borderRadius: AppSize.s8,\n      content: Column(\n        children: [\n          Container(\n            width: double.infinity,\n            height: AppSize.s120,\n            decoration: BoxDecoration(\n              //color: AppColors.primary,\n              color: context.colorScheme.secondaryContainer,\n              borderRadius: const BorderRadius.only(\n                topLeft: Radius.circular(AppSize.s8),\n                topRight: Radius.circular(AppSize.s8),\n              ),\n            ),\n            child: const Icon(\n              Icons.phone,\n              color: Colors.white,\n              size: 50,\n            ),\n          ),\n          Padding(\n            padding: const EdgeInsets.symmetric(\n              horizontal: AppPadding.p28,\n              vertical: AppPadding.p28,\n            ),\n            child: Text(\n              contentText,\n              //style: Theme.of(context).textTheme.bodyLarge,\n              style: context.titleSmall!.copyWith(\n                height: 1.5,\n              ),\n            ),\n          )\n        ],\n      ),\n      actions: <Widget>[\n        TextButton(\n          child: const Text(\n            'Not Now',\n          ),\n          onPressed: () {\n            navigatePop(context);\n          },\n        ),\n        TextButton(\n          onPressed: onContinuePressed,\n          child: const Text(\n            'Continue',\n          ),\n        ),\n      ],\n    );\n  }\n\n  static Future<void> submitPhoneDialog({\n    required BuildContext context,\n    required String phoneNumber,\n    required VoidCallback okPressed,\n  }) {\n    return _showMyDialog(\n      context: context,\n      actionSpacer: true,\n      borderRadius: 3,\n      contentPadding: const EdgeInsets.only(\n        top: AppPadding.p20,\n        right: AppPadding.p20,\n        left: AppPadding.p20,\n      ),\n      content: Column(\n        crossAxisAlignment: CrossAxisAlignment.start,\n        children: [\n          const Text(AppStrings.youEnteredThePhoneNum),\n          Padding(\n            padding: const EdgeInsets.symmetric(\n              vertical: AppPadding.p20,\n            ),\n            child: Text(\n              phoneNumber,\n              style: context.titleMedium,\n            ),\n          ),\n          const Text(AppStrings.isThisOk),\n        ],\n      ),\n      actions: <Widget>[\n        TextButton(\n          child: Text(\n            AppStrings.edit,\n            style: TextStyle(\n              color: context.colorScheme.secondary,\n              fontWeight: FontWeight.w500,\n            ),\n          ),\n          onPressed: () {\n            Navigator.of(context).pop();\n          },\n        ),\n        TextButton(\n          onPressed: okPressed,\n          child: Text(\n            AppStrings.ok,\n            style: TextStyle(\n              color: context.colorScheme.secondary,\n              fontWeight: FontWeight.w500,\n            ),\n          ),\n        ),\n      ],\n    );\n  }\n}\n\nFuture<void> _showMyDialog({\n  required BuildContext context,\n  double borderRadius = 0,\n  required Widget content,\n  required List<Widget> actions,\n  bool actionSpacer = false,\n  EdgeInsetsGeometry? contentPadding,\n}) async {\n  return showDialog<void>(\n    context: context,\n    barrierDismissible: false, // user must tap button!\n    builder: (BuildContext context) {\n      return AlertDialog(\n        contentPadding: contentPadding,\n        shape: RoundedRectangleBorder(\n          borderRadius: BorderRadius.all(\n            Radius.circular(borderRadius),\n          ),\n        ),\n        content: SingleChildScrollView(\n          child: content,\n        ),\n        actions: actions,\n        actionsAlignment: actionSpacer\n            ? MainAxisAlignment.spaceBetween\n            : MainAxisAlignment.end,\n      );\n    },\n  );\n}\n"
  },
  {
    "path": "lib/core/functions/date_converter.dart",
    "content": "\nclass DateConverter{\n\n  static String getChatContactTime(DateTime dateTime){\n    DateTime now = DateTime.now();\n    DateTime yesterday = now.subtract(const Duration(days: 1));\n    DateTime localDateTime = dateTime.toLocal();\n\n    if (localDateTime.day == now.day && localDateTime.month == now.month && localDateTime.year == now.year) {\n      return dateConverterHoursAmPmMode(dateTime);\n    }\n    else if (localDateTime.day == yesterday.day && localDateTime.month == yesterday.month && localDateTime.year == yesterday.year) {\n      return 'Yesterday';\n    }else{\n      return dateConverterMonthNum(dateTime.toString());\n    }\n  }\n\n  static String getChatDayTime(DateTime dateTime){\n    DateTime now = DateTime.now();\n    DateTime yesterday = now.subtract(const Duration(days: 1));\n    DateTime localDateTime = dateTime.toLocal();\n\n    if (localDateTime.day == now.day && localDateTime.month == now.month && localDateTime.year == now.year) {\n      return 'Today';\n    }\n    else if (localDateTime.day == yesterday.day && localDateTime.month == yesterday.month && localDateTime.year == yesterday.year) {\n      return 'Yesterday';\n    }else{\n      return dateConverterMonth(dateTime.toString());\n    }\n  }\n  static String getLastSeenDayTime(DateTime dateTime){\n    DateTime now = DateTime.now();\n    DateTime yesterday = now.subtract(const Duration(days: 1));\n    DateTime localDateTime = dateTime.toLocal();\n\n    if (localDateTime.day == now.day && localDateTime.month == now.month && localDateTime.year == now.year) {\n      return 'today';\n    }\n    else if (localDateTime.day == yesterday.day && localDateTime.month == yesterday.month && localDateTime.year == yesterday.year) {\n      return 'yesterday';\n    }else{\n      return dateConverterMonthNum(dateTime.toString());\n    }\n  }\n\n  static bool isSameDay(DateTime nowTime,DateTime priviesTime){\n    DateTime now = nowTime.toLocal();\n    DateTime privies = priviesTime.toLocal();\n    if(now.day ==privies.day && now.month == privies.month && now.year == privies.year){\n      return true;\n    }\n    return false;\n  }\n\n  //2022-12-07 12:01:17.696\n  static String dateConverterHoursAmPmMode(DateTime dateTime){\n    String string = dateTime.toString();\n    int i = 0;\n    String s = \"\";\n    int mode = int.parse(string[11] + string[12]);\n    List<String> duration = ['am', 'pm'];\n\n\n    if(mode > 11) {\n      if(mode != 12) mode -= 12;\n\n      mode < 10 ? s += '0$mode' : s += '$mode' ;\n\n      for (i = 13; i < 16; ++i) {\n        s += string.split('')[i];\n      }\n\n      s += ' ${duration[1]}';\n\n    }\n    else{\n\n      for (i = 11; i < 16; ++i) {\n        s += string.split('')[i];\n      }\n\n      s += ' ${duration[0]}';\n    }\n\n    return s;\n  }\n  //2022-12-07 12:01:17.696\n  static String dateConverterMonth(String string){\n    int i = 0;\n    String s = \"\";\n    String monthNum = string.split('')[5] + string.split('')[6];\n    String dayNum = string.split('')[8] + string.split('')[9];\n\n    List <String> m = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n    List <String> mN = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'];\n\n    for (i = 0; i < 12; ++i) {\n      if (monthNum == mN[i]) {\n        s = '$dayNum ${m[i]} ';\n        break;\n      }\n    }\n\n    for (i = 0; i < 4; ++i) {\n      s += string.split('')[i];\n    }\n\n    return s;\n  }\n\n  static String dateConverterMonthNum(String string){\n    int i = 0;\n    String s = \"\";\n    String monthNum = string.split('')[5] + string.split('')[6];\n    String dayNum = string.split('')[8] + string.split('')[9];\n\n    List <String> m = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n    List <String> mN = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'];\n\n    for (i = 0; i < 12; ++i) {\n      if (monthNum == mN[i]) {\n        s = '$dayNum/${mN[i]}/';\n        break;\n      }\n    }\n\n    for (i = 2; i < 4; ++i) {\n      s += string.split('')[i];\n    }\n\n    return s;\n  }\n\n  static String dateConverterOnly(String string) {\n    String s = \"\";\n    s = string.split(\"T\")[0];\n    return s;\n  }\n\n  static String dateConverterSince(String string){\n    String s = \"\";\n    int apiDay = int.parse(string.split(\"\")[8] + string.split(\"\")[9]);\n    int currentDay = DateTime.now().day;\n\n    if(currentDay == apiDay) s = \"Today\";\n    else if(currentDay == apiDay + 1) s = \"Yesterday\";\n    else if(currentDay > apiDay + 1) s = \"Since ${currentDay - apiDay} days\";\n\n    return s;\n  }\n\n  static String dateConverterHours24Mode(String string){\n    int i = 0;\n    String s = \"\";\n\n    for (i = 11; i < 16; ++i) {\n      s += string.split('')[i];\n    }\n\n    return s;\n  }\n\n\n}"
  },
  {
    "path": "lib/core/functions/navigator.dart",
    "content": "import 'package:flutter/material.dart';\n\nvoid navigatePop(\n  BuildContext context,\n) {\n  Navigator.of(context).pop();\n}\n\nvoid navigateAndRemove(\n  BuildContext context,\n  String routeName, {\n  Object? arguments,\n}) {\n  Navigator.of(context).pushNamedAndRemoveUntil(\n    routeName,\n    arguments: arguments,\n    (route) => false,\n  );\n}\n\nFuture<dynamic> navigateTo(\n  BuildContext context,\n  String routeName, {\n  Object? arguments,\n}) {\n   return Navigator.of(context).pushNamed(\n    routeName,\n    arguments: arguments,\n  );\n}\n\nvoid navigateAndReplace(\n  BuildContext context,\n  String routeName, {\n  Object? arguments,\n}) {\n  Navigator.of(context).pushReplacementNamed(\n    routeName,\n    arguments: arguments,\n  );\n}\n"
  },
  {
    "path": "lib/core/network/cache_helper.dart",
    "content": "import 'package:shared_preferences/shared_preferences.dart';\n\nclass CacheHelper {\n  final SharedPreferences _sharedPreferences;\n\n  CacheHelper(this._sharedPreferences);\n\n  dynamic getData({required String key}) {\n    return _sharedPreferences.get(key);\n  }\n\n  Future<bool> saveData({\n    required String key,\n    required dynamic value,\n  }) async {\n    if (value is String) return await _sharedPreferences.setString(key, value);\n    if (value is double) return await _sharedPreferences.setDouble(key, value);\n    if (value is bool) return await _sharedPreferences.setBool(key, value);\n    return await _sharedPreferences.setInt(key, value);\n  }\n\n  void removeData({required String key})async{\n   await _sharedPreferences.remove(key);\n  }\n}\n"
  },
  {
    "path": "lib/core/services/services_locator.dart",
    "content": "import 'package:cloud_firestore/cloud_firestore.dart';\nimport 'package:firebase_auth/firebase_auth.dart';\nimport 'package:firebase_storage/firebase_storage.dart';\nimport 'package:get_it/get_it.dart';\nimport 'package:shared_preferences/shared_preferences.dart';\nimport 'package:whatsapp_flutter_clone/features/data/data_source/call/call_data_source.dart';\nimport 'package:whatsapp_flutter_clone/features/data/repository/call_repository.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/repository/base_call_repository.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/usecases/call/call_stream_usecase.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/usecases/call/end_call_usecase.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/usecases/call/make_call_usecase.dart';\nimport 'package:whatsapp_flutter_clone/features/presentation/controllers/call_cubit/call_cubit.dart';\nimport 'package:whatsapp_flutter_clone/features/presentation/controllers/chat_background_cubit/chat_background_cubit.dart';\n\nimport '../../features/data/data_source/auth/local/auth_local_data_source.dart';\nimport '../../features/data/data_source/auth/remote/auth_remote_data_source.dart';\nimport '../../features/data/data_source/chat/remote/chat_remote_data_source.dart';\nimport '../../features/data/data_source/select_contact/local/get_contacts_local_data_source.dart';\nimport '../../features/data/data_source/select_contact/remote/select_contact_remote_data_source.dart';\nimport '../../features/data/repository/auth_repository.dart';\nimport '../../features/data/repository/chat_repository.dart';\nimport '../../features/data/repository/select_contact_Repository.dart';\nimport '../../features/domain/repository/base_auth_repository.dart';\nimport '../../features/domain/repository/base_chat_repository.dart';\nimport '../../features/domain/repository/base_select_contact_repository.dart';\nimport '../../features/domain/usecases/auth/get_cached_local_current_uid_usecase.dart';\nimport '../../features/domain/usecases/auth/get_current_uid_usecase.dart';\nimport '../../features/domain/usecases/auth/get_current_user_usecase.dart';\nimport '../../features/domain/usecases/auth/get_user_by_id_usecase.dart';\nimport '../../features/domain/usecases/auth/save_userdata_to_firebase_usecase.dart';\nimport '../../features/domain/usecases/auth/set_user_state_usecase.dart';\nimport '../../features/domain/usecases/auth/sign_in_with_phone_number_usecase.dart';\nimport '../../features/domain/usecases/auth/signout_usecase.dart';\nimport '../../features/domain/usecases/auth/update_profile_pic_usecase.dart';\nimport '../../features/domain/usecases/auth/verify_otp_usecase.dart';\nimport '../../features/domain/usecases/chat/get_chat_messages_usecase.dart';\nimport '../../features/domain/usecases/chat/get_contacts_chat_usecase.dart';\nimport '../../features/domain/usecases/chat/get_num_of_message_not_seen_usecase.dart';\nimport '../../features/domain/usecases/chat/send_file_message_usecase.dart';\nimport '../../features/domain/usecases/chat/send_gif_message_usecase.dart';\nimport '../../features/domain/usecases/chat/send_text_message_usecase.dart';\nimport '../../features/domain/usecases/chat/set_chat_message_seen_usecase.dart';\nimport '../../features/domain/usecases/select_contact/get_all_contacts_usecase.dart';\nimport '../../features/domain/usecases/select_contact/get_contacts_not_on_whats_usecase.dart';\nimport '../../features/domain/usecases/select_contact/get_contacts_on_whats_usecase.dart';\nimport '../../features/presentation/controllers/auth_cubit/auth_cubit.dart';\nimport '../../features/presentation/controllers/bottom_chat_cubit/bottom_chat_cubit.dart';\nimport '../../features/presentation/controllers/chat_cubit/chat_cubit.dart';\nimport '../../features/presentation/controllers/select_contact_cubit/select_contact_cubit.dart';\nimport '../network/cache_helper.dart';\n\nfinal sl = GetIt.instance;\n\nFuture<void> init() async {\n  ///shared prefs\n  final sharedPref = await SharedPreferences.getInstance();\n\n  sl.registerLazySingleton<SharedPreferences>(() => sharedPref);\n  sl.registerLazySingleton<CacheHelper>(() => CacheHelper(sl()));\n\n  ///cubit\n  sl.registerFactory(\n      () => AuthCubit(sl(), sl(), sl(), sl(), sl(), sl(), sl(), sl(), sl()));\n  sl.registerFactory(() => SelectContactCubit(sl(), sl(), sl()));\n  sl.registerFactory(() => ChatCubit(sl(), sl(), sl(), sl(), sl(), sl(),sl()));\n  sl.registerLazySingleton(() => BottomChatCubit());\n  sl.registerLazySingleton(() => ChatBackgroundCubit());\n  sl.registerLazySingleton(() => CallCubit(sl(), sl(), sl()));\n\n  ///use case\n  /////////auth\n  sl.registerLazySingleton(() => SignInWithPhoneNumberUseCase(sl()));\n  sl.registerLazySingleton(() => VerifyOtpUseCase(sl()));\n  sl.registerLazySingleton(() => SaveUserDataToFirebaseUseCase(sl()));\n  sl.registerLazySingleton(() => GetCurrentUidUseCase(sl()));\n  sl.registerLazySingleton(() => SignOutUseCase(sl()));\n  sl.registerLazySingleton(() => GetCachedLocalCurrentUidUseCase(sl()));\n  sl.registerLazySingleton(() => GetUserByIdUseCase(sl()));\n  sl.registerLazySingleton(() => SetUserStateUseCase(sl()));\n  sl.registerLazySingleton(() => GetCurrentUserUseCase(sl()));\n  sl.registerLazySingleton(() => UpdateProfilePicUseCase(sl()));\n  ////////select contact\n  sl.registerLazySingleton(() => GetAllContactsUseCase(sl()));\n  sl.registerLazySingleton(() => GetContactsOnWhatsUseCase(sl()));\n  sl.registerLazySingleton(() => GetContactsNotOnWhatsUseCase(sl()));\n  ///////chat\n  sl.registerLazySingleton(() => SendTextMessageUseCase(sl()));\n  sl.registerLazySingleton(() => GetContactsChatUseCase(sl()));\n  sl.registerLazySingleton(() => GetChatMessagesUseCase(sl()));\n  sl.registerLazySingleton(() => SetChatMessageSeenUseCase(sl()));\n  sl.registerLazySingleton(() => SendGifMessageUseCase(sl()));\n  sl.registerLazySingleton(() => SendFileMessageUseCase(sl()));\n  sl.registerLazySingleton(() => GetNumberOfMessageNotSeenUseCase(sl()));\n  // sl.registerLazySingleton(() => GetContactNameUseCase(sl()));\n  /////call\n  sl.registerLazySingleton(() => CallStreamUseCase(sl()));\n  sl.registerLazySingleton(() => EndCallUseCase(sl()));\n  sl.registerLazySingleton(() => MakeCallUseCase(sl()));\n  ///repository\n  sl.registerLazySingleton<BaseAuthRepository>(\n    () => AuthRepository(localDataSource: sl(), remoteDataSource: sl()),\n  );\n\n  sl.registerLazySingleton<BaseSelectContactRepository>(\n    () => SelectContactRepository(sl(), sl()),\n  );\n\n  sl.registerLazySingleton<BaseChatRepository>(() => ChatRepository(sl()));\n\n  sl.registerLazySingleton<BaseCallRepository>(() => CallRepository(sl()));\n  ///remote data source\n  sl.registerLazySingleton<BaseAuthRemoteDataSource>(\n    () => AuthRemoteDataSource(\n      auth: sl(),\n      firestore: sl(),\n      firebaseStorage: sl(),\n    ),\n  );\n  sl.registerLazySingleton<BaseSelectContactsRemoteDataSource>(\n    () => SelectContactsRemoteDataSource(sl(), sl()),\n  );\n  sl.registerLazySingleton<BaseChatRemoteDataSource>(\n    () => ChatRemoteDataSource(sl(), sl(), sl()),\n  );\n\n  sl.registerLazySingleton(() => CallDataSource(sl(), sl()));\n  /// local data source\n  sl.registerLazySingleton<BaseAuthLocalDataSource>(\n    () => AuthLocalDataSource(sharedPreferences: sl()),\n  );\n  sl.registerLazySingleton<BaseSelectContactsLocalDataSource>(\n    () => SelectContactsLocalDataSource(),\n  );\n\n  //External\n  final auth = FirebaseAuth.instance;\n  final firestore = FirebaseFirestore.instance;\n  final firebaseStorage = FirebaseStorage.instance;\n\n  sl.registerLazySingleton(() => auth);\n  sl.registerLazySingleton(() => firestore);\n  sl.registerLazySingleton(() => firebaseStorage);\n}\n"
  },
  {
    "path": "lib/core/shared/bloc_observer.dart",
    "content": "import 'package:flutter/foundation.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\n\nclass MyBlocObserver extends BlocObserver {\n  @override\n  void onCreate(BlocBase bloc) {\n    super.onCreate(bloc);\n    if (kDebugMode) {\n      print('onCreate -- ${bloc.runtimeType}');\n    }\n  }\n\n  @override\n  void onChange(BlocBase bloc, Change change) {\n    super.onChange(bloc, change);\n    if (kDebugMode) {\n      print('onChange -- ${bloc.runtimeType}, $change');\n    }\n  }\n\n  @override\n  void onError(BlocBase bloc, Object error, StackTrace stackTrace) {\n    if (kDebugMode) {\n      print('onError -- ${bloc.runtimeType}, $error');\n    }\n    super.onError(bloc, error, stackTrace);\n  }\n\n  @override\n  void onClose(BlocBase bloc) {\n    super.onClose(bloc);\n    if (kDebugMode) {\n      print('onClose -- ${bloc.runtimeType}');\n    }\n  }\n}"
  },
  {
    "path": "lib/core/shared/commen.dart",
    "content": "import 'dart:io';\n\nimport 'package:flutter/material.dart';\nimport 'package:giphy_get/giphy_get.dart';\nimport 'package:image_cropper/image_cropper.dart';\nimport 'package:image_picker/image_picker.dart';\n\nvoid showSnackBar({\n  required BuildContext context,\n  required String content,\n}) {\n  ScaffoldMessenger.of(context).showSnackBar(\n    SnackBar(\n      content: Text(content),\n    ),\n  );\n}\n\nFuture<File?> pickImageFromGallery(BuildContext context) async {\n  File? image;\n  try {\n    final pickedImage =\n    await ImagePicker().pickImage(source: ImageSource.gallery);\n    if (pickedImage != null) {\n      image = File(pickedImage.path);\n    }\n  } catch (e) {\n    showSnackBar(\n      context: context,\n      content: e.toString(),\n    );\n  }\n  return image;\n}\n\nFuture<GiphyGif?> pickGif(BuildContext context) async {\n  GiphyGif? gif;\n  try {\n    gif = await GiphyGet.getGif(\n      context: context,\n      apiKey: 'GmpyPrPF9RVZ1LJY1iAe6O8MTWrBpNob',\n\n    );\n  } catch (e) {\n    showSnackBar(context: context, content: e.toString());\n  }\n  return gif;\n}\n\n\nFuture<CroppedFile?> cropImage(String path)async{\n  return ImageCropper().cropImage(\n    sourcePath: path,\n    aspectRatioPresets: Platform.isAndroid\n        ? [\n      CropAspectRatioPreset.square,\n      CropAspectRatioPreset.ratio3x2,\n      CropAspectRatioPreset.original,\n      CropAspectRatioPreset.ratio4x3,\n      CropAspectRatioPreset.ratio16x9\n    ]\n        : [\n      CropAspectRatioPreset.original,\n      CropAspectRatioPreset.square,\n      CropAspectRatioPreset.ratio3x2,\n      CropAspectRatioPreset.ratio4x3,\n      CropAspectRatioPreset.ratio5x3,\n      CropAspectRatioPreset.ratio5x4,\n      CropAspectRatioPreset.ratio7x5,\n      CropAspectRatioPreset.ratio16x9\n    ],\n    aspectRatio: const CropAspectRatio(\n      ratioX: 1.0,\n      ratioY: 1.0,\n    ),\n    compressQuality: 100,\n    maxWidth: 400,\n    maxHeight: 400,\n    compressFormat: ImageCompressFormat.jpg,\n    cropStyle: CropStyle.rectangle,\n    uiSettings: [\n      AndroidUiSettings(\n        toolbarColor: Colors.teal,\n        toolbarTitle: \"Profile Image\",\n        statusBarColor: Colors.teal,\n        backgroundColor: Colors.white,\n        hideBottomControls: true,\n        lockAspectRatio: false,\n        initAspectRatio: CropAspectRatioPreset.square,\n        toolbarWidgetColor: Colors.white\n      ),\n    ],\n  );\n}\n"
  },
  {
    "path": "lib/core/shared/message_replay.dart",
    "content": "import 'package:equatable/equatable.dart';\nimport '/core/enums/messge_type.dart';\n\nclass MessageReplay extends Equatable {\n  final String message;\n  final bool isMe;\n  final MessageType messageType;\n  final String repliedTo;\n\n  const MessageReplay( {\n    required this.message,\n    required this.isMe,\n    required this.messageType,\n    required this.repliedTo,\n  });\n\n  @override\n  List<Object?> get props => [\n        message,\n        isMe,\n        messageType,\n    repliedTo,\n      ];\n}\n"
  },
  {
    "path": "lib/core/shared/pop_up_menu_item_model.dart",
    "content": "import 'package:equatable/equatable.dart';\nimport 'package:flutter/animation.dart';\n\nclass PopUpMenuItemModel extends Equatable{\n  final String name;\n  final VoidCallback onTap;\n\n  const PopUpMenuItemModel({required this.name, required this.onTap,});\n\n  @override\n  List<Object?> get props => [name,onTap];\n}"
  },
  {
    "path": "lib/core/usecase/base_use_case.dart",
    "content": "import 'package:dartz/dartz.dart';\nimport 'package:equatable/equatable.dart';\n\nimport '../error/failure.dart';\n\nabstract class BaseUseCase<T, Parameters>{\n  Future<Either<Failure ,T>> call(Parameters parameters);\n}\n\nabstract class StreamBaseUseCase<T, Parameters>{\n  Stream<T> call(Parameters parameters);\n}\n\n\n\nclass NoParameters extends Equatable{\n  const NoParameters();\n  @override\n  List<Object?> get props => [];\n}"
  },
  {
    "path": "lib/core/utils/constants/assets_manager.dart",
    "content": "const String imgPath = 'assets/images';\nclass AppImage{\n  static const String landingImg = '$imgPath/bg.png';\n  static const String genericProfileImage = '$imgPath/user3.png';\n  static const String qrCode = '$imgPath/qr-code.png';\n  static const String chatBackground = '$imgPath/chat-bg.png';\n  static const String chatBackground2 = '$imgPath/wall1.jpg';\n  static const String chatBackground3 = '$imgPath/wall2.jpg';\n  static const String chatBackgroundDark = '$imgPath/chat-bg-dark.png';\n  static const String splashLightImg = '$imgPath/splash_light.png';\n  static const String trashContainerImg = '$imgPath/trash_container.png';\n  static const String trashCoverImg = '$imgPath/trash_cover.png';\n}"
  },
  {
    "path": "lib/core/utils/constants/font_manager.dart",
    "content": "import 'package:flutter/material.dart';\n\nclass FontConstants {\n  static const String fontFamily = \"Montserrat\";\n}\n\nclass FontWeightManager {\n  static const FontWeight light = FontWeight.w300;\n  static const FontWeight regular = FontWeight.w400;\n  static const FontWeight medium = FontWeight.w500;\n  static const FontWeight semiBold = FontWeight.w600;\n  static const FontWeight bold = FontWeight.w700;\n}\n\nclass FontSize {\n  static const double s12 = 12.0;\n  static const double s14 = 14.0;\n  static const double s16 = 16.0;\n  static const double s17 = 17.0;\n  static const double s18 = 18.0;\n  static const double s20 = 20.0;\n  static const double s22 = 22.0;\n  static const double s26 = 26.0;\n  static const double s28 = 28.0;\n}\n"
  },
  {
    "path": "lib/core/utils/constants/strings_manager.dart",
    "content": "class AppStrings {\n  static const String appName = \"WhatsApp \";\n  static const String noRouteFound = \"noRouteFound\";\n\n  //landing screen\n  static const String welcomeToWhatsApp = 'Welcome to WhatsApp';\n  static const String readOur = 'Read our ';\n  static const String privacyPolicy = 'Privacy Policy';\n  static const String tapAgreeAnd = '. Tap \"Agree And Continue\" to accept the ';\n  static const String termsOfService = 'Terms of Service';\n  static const String agreeAndContinue = 'AGREE AND CONTINUE';\n\n  //login screen\n  static const String enterYourPhoneNumber = 'Enter your phone number';\n  static const String whatsAppWillNeed =\n      'WhatsApp will need to verify your phone number.';\n  static const String whatIsMyNumber = 'What\\'s my number?';\n  static const String phoneNumber = 'Phone number';\n  static const String carrierChargesMayApply = 'Carrier charges may apply';\n  static const String next = 'NEXT';\n  static const String pickCountry = 'Choose a country';\n\n  //alert dialog\n  static const String toRetrieveYourPhone =\n      'To retrieve your phone number, WhatsApp needs permissions to make and manage your calls. Without this permission, WhatsApp will be unable to retrieve your phone number from the SIM.';\n  static const String youEnteredThePhoneNum = 'You entered the phone number:';\n  static const String isThisOk =\n      'Is this OK, or would you like to edit the number?';\n  static const String edit = 'EDIT';\n  static const String ok = 'OK';\n\n  //otp screen\n  static const String verifyingYourNumber = 'Verifying Your Number';\n  static const String waitingToDetectSms =\n      'Waiting to automatically detect an sms sent to';\n  static const String wrongNumber = 'Wrong number?';\n  static const String enter6DigitCode = 'Enter 6-digit code';\n  static const String resendSms = 'Resend SMS';\n\n  //login profile info\n  static const String profileInfo = 'Profile info';\n  static const String pleaseProvideYourName =\n      'Please provide your name and an optional profile photo';\n  static const String typeYourNameHere = 'Type your name here';\n  static const String profilePhoto = 'Profile photo';\n  static const String camera = 'Camera';\n  static const String gallery = 'Gallery';\n\n  //login loading screen\n  static const String initializing = 'Initializing...';\n  static const String pleaseWaitAMoment = 'Please wait a moment';\n\n  /////\n  static const String heyThere = 'Hey there! I am using WhatsApp.';\n\n// select contact\n  static const String selectContact = 'Select contact';\n  static const String contacts = 'contacts';\n  static const String newGroup = 'New group';\n  static const String newContact = 'New contact';\n  static const String newCommunity = 'New Community';\n  static const String contactsOnWhatsApp = 'Contacts on WhatsApp';\n  static const String inviteToWhatsApp = 'Invite to WhatsApp';\n  static const String inviteAFriend = 'Invite a friend';\n  static const String refresh = 'Refresh';\n  static const String help = 'Help';\n  static const String invite = 'Invite';\n\n  /// Main Layout screen\n  static const String chats = 'CHATS';\n  static const String calls = 'Calls';\n  static const String status = 'Status';\n  static const String newBroadcast = 'New broadcast';\n  static const String linkedDevices = 'Linked devices';\n  static const String starredMessage = 'Starred message';\n  static const String settings = 'Settings';\n\n  //chat\n  static const String viewContact = 'View contact';\n  static const String mediaLinksAndDocs = 'Media, links, and docs';\n  static const String search = 'Search';\n  static const String muteNotifications = 'Mute notifications';\n  static const String disappearingMessages = 'Disappearing messages';\n  static const String wallpaper = 'Wallpaper';\n  static const String more = 'More';\n  static const String report = 'Report';\n  static const String block = 'Block';\n  static const String clearChat = 'Clear chat';\n\n  //status\n  static const String statusPrivacy = 'Status privacy';\n\n  //call\n  static const String clearCallLog = 'Clear call log';\n\n  //setting and profile\n  static const String profile = 'Profile';\n  static const String name = 'Name';\n  static const String phone = 'Phone';\n  static const String about = 'About';\n  static const String thisIsNotYourUser =\n      'This is not your username or pin. This name will be visible to your WhatsApp contacts.';\n\n  //sender profile\n  static const String muteNotification = 'Mute Notifications';\n  static const String customNotification = 'Custom Notifications';\n  static const String  mediaVisibility = 'Media visibility';\n  static const String encryption = 'Encryption';\n  static const String messagesAndCallsAre = 'Messages and calls are end-to-end encrypted. Tap to verify.';\n  static const String disappearingMessage = 'Disappearing Messages';\n  static const String off = 'Off';\n  static const String call = 'Call';\n  static const String video = 'Video';\n}\n"
  },
  {
    "path": "lib/core/utils/constants/values_manager.dart",
    "content": "class AppMargin {\n  static const double m8 = 8.0;\n  static const double m12 = 12.0;\n  static const double m14 = 14.0;\n  static const double m16 = 16.0;\n  static const double m18 = 18.0;\n  static const double m20 = 20.0;\n}\n\nclass AppPadding {\n  static const double p2 = 2.0;\n  static const double p8 = 8.0;\n  static const double p10 = 10.0;\n  static const double p12 = 12.0;\n  static const double p14 = 14.0;\n  static const double p16 = 16.0;\n  static const double p18 = 18.0;\n  static const double p20 = 20.0;\n  static const double p28 = 28.0;\n  static const double p100 = 100.0;\n}\n\nclass AppSize {\n  static const double s0 = 0;\n  static const double s1 = 1;\n  static const int s2 = 2;\n  static const double s1_5 = 1.5;\n  static const double s4 = 4.0;\n  static const double s8 = 8.0;\n  static const double s12 = 12.0;\n  static const double s14 = 14.0;\n  static const double s16 = 16.0;\n  static const double s18 = 18.0;\n  static const double s20 = 20.0;\n  static const double s28 = 28.0;\n  static const double s40 = 40.0;\n  static const double s60 = 60.0;\n  static const double s80 = 80.0;\n  static const double s90 = 90.0;\n  static const double s100 = 100.0;\n  static const double s120 = 120.0;\n  static const double s140 = 140.0;\n  static const double s160 = 160.0;\n  static const double s190 = 190.0;\n}\n"
  },
  {
    "path": "lib/core/utils/routes/routes_manager.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/entities/call.dart';\nimport 'package:whatsapp_flutter_clone/features/presentation/views/calls/call_screen.dart';\nimport 'package:whatsapp_flutter_clone/features/presentation/views/wallpaper/wallpaper_screen.dart';\n\nimport '../../../features/domain/entities/user.dart';\nimport '../../../features/presentation/views/camera/camera_screen.dart';\nimport '../../../features/presentation/views/camera/sending_image_view_page.dart';\nimport '../../../features/presentation/views/camera/sending_video_view_page.dart';\nimport '../../../features/presentation/views/chat/chat_screen.dart';\nimport '../../../features/presentation/views/login/login_landing_screen.dart';\nimport '../../../features/presentation/views/login/login_loading_screen.dart';\nimport '../../../features/presentation/views/login/login_otp_screen.dart';\nimport '../../../features/presentation/views/login/login_profile_info_screen.dart';\nimport '../../../features/presentation/views/login/login_screen.dart';\nimport '../../../features/presentation/views/main_layout/main_layout_screen.dart';\nimport '../../../features/presentation/views/select_contact/select_contact_screen.dart';\nimport '../../../features/presentation/views/sender_profile/sender_profile_page.dart';\nimport '../../../features/presentation/views/settings/profile_screen.dart';\nimport '../../../features/presentation/views/settings/settings_screen.dart';\nimport '../../../features/presentation/views/splash/splash_screen.dart';\nimport '../constants/strings_manager.dart';\n\nclass Routes {\n  static const String splashRoute = '/';\n  static const String landingRoute = '/landing';\n  static const String loginRoute = '/login';\n  static const String otpRoute = '/otp';\n  static const String loginProfileInfoRoute = '/login-profile';\n  static const String loginLoadingRoute = '/login-loading';\n  static const String mainLayoutRoute = '/main-layout';\n  static const String selectContactRoute = '/select-contact';\n  static const String settingsRoute = '/settings';\n  static const String chatRoute = '/chat';\n  static const String cameraRoute = '/camera';\n  static const String sendingImageViewRoute = '/sending-image-view';\n  static const String sendingVideoViewRoute = '/sending-video-view';\n  static const String profileRoute = '/profile';\n  static const String senderUserProfileRoute = '/sender-profile';\n  static const String wallpaperRoute = '/wallpaper';\n  static const String callRoute = '/call-route';\n}\n\nclass AppRoutes {\n  static Route<dynamic> onGenerateRoute(RouteSettings settings) {\n    switch (settings.name) {\n      case Routes.splashRoute:\n        return MaterialPageRoute(\n          builder: (_) => const SplashScreen(),\n        );\n      case Routes.landingRoute:\n        return MaterialPageRoute(\n          builder: (_) => const LandingScreen(),\n        );\n      case Routes.loginRoute:\n        return MaterialPageRoute(\n          builder: (_) =>  const LoginScreen(),\n        );\n      case Routes.otpRoute:\n        final phoneNumber = settings.arguments as String;\n        return MaterialPageRoute(\n          builder: (_) =>  OtpScreen(phoneNumber: phoneNumber),\n        );\n      case Routes.loginProfileInfoRoute:\n        return MaterialPageRoute(\n          builder: (_) => const LoginProfileInfoScreen(),\n        );\n      case Routes.loginLoadingRoute:\n        return MaterialPageRoute(\n          builder: (_) => const LoginLoadingScreen(),\n        );\n      case Routes.mainLayoutRoute:\n        return MaterialPageRoute(\n          builder: (_) => const MainLayoutScreen(),\n        );\n      case Routes.selectContactRoute:\n        return MaterialPageRoute(\n          builder: (_) => const SelectContactScreen(),\n        );\n      case Routes.settingsRoute:\n        return MaterialPageRoute(\n          builder: (_) =>  SettingsScreen(),\n        );\n      case Routes.chatRoute:\n        final arguments =settings.arguments as Map<String,dynamic>;\n        final String name =arguments['name'];\n        final String uId = arguments['uId'];\n        return MaterialPageRoute(\n          builder: (_) => ChatScreen(name: name,uId: uId,),\n        );\n      case Routes.cameraRoute:\n        final arguments =settings.arguments as Map<String,dynamic>;\n        //final String name =arguments['name'];\n        final String uId = arguments['uId'];\n        return MaterialPageRoute(\n          builder: (_) =>  CameraScreen(receiverId: uId),\n        );\n      case Routes.sendingImageViewRoute:\n        final arguments =settings.arguments as Map<String,dynamic>;\n        //final String name =arguments['name'];\n        final String uId = arguments['uId'];\n        final String path = arguments['path'];\n        return MaterialPageRoute(\n          builder: (_) => SendingImageViewPage(path: path,receiverId: uId),\n        );\n      case Routes.sendingVideoViewRoute:\n        final arguments =settings.arguments as Map<String,dynamic>;\n        //final String name =arguments['name'];\n        final String uId = arguments['uId'];\n        final String path = arguments['path'];\n        return MaterialPageRoute(\n          builder: (_) => SendingVideoViewPage(path: path,receiverId: uId),\n        );\n      case Routes.profileRoute:\n        final argument = settings.arguments as UserEntity;\n        return MaterialPageRoute(\n          builder: (_) => ProfileScreen(user: argument),\n        );\n      case Routes.senderUserProfileRoute:\n        final argument = settings.arguments as UserEntity;\n        return MaterialPageRoute(\n          builder: (_) => SenderUserProfilePage(user: argument),\n        );\n      case Routes.wallpaperRoute:\n        return MaterialPageRoute(\n          builder: (_) => const WallpaperScreen(),\n        );\n      case Routes.callRoute:\n        final arguments =settings.arguments as Map<String,dynamic>;\n        final Call call = arguments['call'];\n        final String channelId = arguments['channelId'];\n        return MaterialPageRoute(\n          builder: (_) => CallScreen(call: call,channelId: channelId),\n        );\n      default:\n        return unDefinedRoute();\n    }\n  }\n\n  static Route<dynamic> unDefinedRoute() {\n    return MaterialPageRoute(\n      builder: (_) => Scaffold(\n        appBar: AppBar(\n          title: const Text(\n            AppStrings.noRouteFound,\n          ),\n        ),\n        body: const Center(\n          child: Text(\n            AppStrings.noRouteFound,\n          ),\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/core/utils/thems/my_colors.dart",
    "content": "import 'package:flutter/material.dart';\n\nclass MyColors {\n  /// Base Colors\n  final Color black = Colors.black;\n  final Color black1 = const Color(0xFF121212);\n  final Color black2 = const Color(0xFF18171d); // 900\n  final Color black3 = const Color(0xFF242329); // 900\n  final Color onyx = const Color(0xFF45444B); // 900\n  final Color textBlack = const Color(0XFF4F5054);\n  final Color grey = Colors.grey;\n  final Color abbey = const Color(0xFF464648);\n  final Color dimGray = const Color(0xFF666666);\n  final Color textIconColorGray = Colors.grey[300]!;\n  final Color white = Colors.white;\n  final Color white1 = const Color(0xFFFAFAFA);\n  final Color white2 = const Color(0xFFECECF4);\n  final Color transparent = Colors.transparent;\n  final Color shadow = const Color.fromRGBO(33, 22, 156, 0.1);\n  final Color blackLight=  const Color(0XFF646464);\n  final Color secondary = const Color(0XFF128C7E); //primary\n  final Color primary = const Color(0XFF008069); //primary2\n  final Color primary1 = const Color(0XFF1EBEA5); //primaryLight1\n\n  final Color lightGreen = const Color(0XFF25D366);\n  final Color teaGreen = const Color(0XFFDCF8C6);\n\n  final Color checkMarkBlue = const Color(0XFF34B7F1);\n\n  final Color round = const Color(0XFF25D167);//coloo\n  final Color timeBackgroundColor = const Color(0XFFF0F2F4);\n}\n\nabstract class IColors {\n  MyColors get _colors;\n\n  Color? scaffoldBackgroundColor;\n  Color? appBarColor;\n  Color? primaryColor;\n\n  //Color? tabBarColor;\n  //Color? tapBarSelectedColor;\n  //Color? tapBarNormalColor;\n  Brightness? brightness;\n\n  ColorScheme? colorScheme;\n}\n\nclass LightColors implements IColors {\n  @override\n  final MyColors _colors = MyColors();\n\n  @override\n  ColorScheme? colorScheme;\n\n  @override\n  Color? appBarColor;\n\n  @override\n  Color? scaffoldBackgroundColor;\n\n  @override\n  Brightness? brightness;\n\n  @override\n  Color? primaryColor;\n\n  LightColors() {\n    appBarColor = _colors.white;\n    scaffoldBackgroundColor = _colors.white;\n    primaryColor = _colors.primary;\n    colorScheme = ColorScheme(\n      brightness: Brightness.light,\n      primary: _colors.primary,\n      //to appbar\n      onPrimary: _colors.white1,\n      //to text on appbar\n      primaryContainer: _colors.white2,\n      // to other text on appbar,action icon\n      secondary: _colors.secondary,\n      secondaryContainer: _colors.primary1,\n      //to fab\n      onSecondary: _colors.white1,\n      error: _colors.black,\n      onError: _colors.white1,\n      background: _colors.white1,\n      onBackground: _colors.black1,\n      onSecondaryContainer: _colors.lightGreen,//landing image\n      surface: _colors.teaGreen,\n      onSurface: _colors.dimGray,\n      surfaceVariant: _colors.timeBackgroundColor,\n      onSurfaceVariant: _colors.blackLight,\n      onInverseSurface: _colors.grey,\n      onTertiary: _colors.checkMarkBlue,\n      onTertiaryContainer: _colors.onyx,\n      onPrimaryContainer: _colors.round\n    );\n    brightness = Brightness.light;\n  }\n}\n"
  },
  {
    "path": "lib/core/utils/thems/styles_manager.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../constants/font_manager.dart';\n\nTextStyle _getTextStyle(double fontSize, FontWeight fontWeight, Color color) {\n  return TextStyle(\n    fontSize: fontSize,\n    fontFamily: FontConstants.fontFamily,\n    color: color,\n    fontWeight: fontWeight,\n  );\n}\n\n// regular style\nTextStyle getRegularStyle({\n  double fontSize = FontSize.s12,\n  required Color color,\n}) {\n  return _getTextStyle(\n    fontSize,\n    FontWeightManager.regular,\n    color,\n  );\n}\n\n// medium style\nTextStyle getMediumStyle({\n  double fontSize = FontSize.s12,\n  required Color color,\n}) {\n  return _getTextStyle(\n    fontSize,\n    FontWeightManager.medium,\n    color,\n  );\n}\n\n// medium style\nTextStyle getLightStyle({\n  double fontSize = FontSize.s12,\n  required Color color,\n}) {\n  return _getTextStyle(\n    fontSize,\n    FontWeightManager.light,\n    color,\n  );\n}\n\n// bold style\nTextStyle getBoldStyle({\n  double fontSize = FontSize.s12,\n  required Color color,\n}) {\n  return _getTextStyle(\n    fontSize,\n    FontWeightManager.bold,\n    color,\n  );\n}\n\n// semibold style\nTextStyle getSemiBoldStyle({\n  double fontSize = FontSize.s12,\n  required Color color,\n}) {\n  return _getTextStyle(\n    fontSize,\n    FontWeightManager.semiBold,\n    color,\n  );\n}\n"
  },
  {
    "path": "lib/core/utils/thems/theme_manager.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter/services.dart';\n\nimport '/core/utils/thems/styles_manager.dart';\nimport 'my_colors.dart';\nimport '../constants/font_manager.dart';\nimport '../constants/values_manager.dart';\n\nThemeData createTheme(IColors iColors) => ThemeData(\n  scaffoldBackgroundColor: iColors.scaffoldBackgroundColor,\n  primaryColor: iColors.primaryColor,\n  colorScheme: iColors.colorScheme,\n  brightness: iColors.brightness,\n  textTheme: _textTheme(iColors),\n  appBarTheme: _appBarTheme(iColors),\n  popupMenuTheme: _popupMenuThemeData(iColors),\n  tabBarTheme: tabBarTheme(),\n  textButtonTheme: _textButtonThemeData(iColors),\n  elevatedButtonTheme: _elevatedButtonThemeData(iColors),\n  inputDecorationTheme: _inputDecorationTheme(iColors),\n  dividerColor: iColors.colorScheme!.secondaryContainer,\n  progressIndicatorTheme: ProgressIndicatorThemeData(\n    color: iColors.primaryColor,\n  ),\n);\n\nTextTheme _textTheme(IColors iColors) {\n  return TextTheme(\n      displayLarge: getSemiBoldStyle(\n        color: iColors.colorScheme!.secondary,\n        fontSize: FontSize.s20,\n      ),\n      //for appbar\n      headlineLarge: getBoldStyle(\n        color: iColors.colorScheme!.onPrimary,\n        fontSize: 18,\n      ),\n      bodySmall: getRegularStyle(\n          color: iColors.colorScheme!.primaryContainer,\n          fontSize: 13\n      ),\n      //for list tile title\n      headlineMedium: getMediumStyle(\n        //color: AppColors.textBlack,\n        color: iColors.colorScheme!.onSurface,\n        fontSize: FontSize.s17,\n      ),\n\n      labelLarge: getBoldStyle(\n        color: iColors.colorScheme!.onPrimary,\n        fontSize: 14,\n      ),\n      //for list tile subtitle\n      bodyMedium: getMediumStyle(\n        color: iColors.colorScheme!.onInverseSurface,\n        fontSize: FontSize.s14,\n      ),\n      //for time card\n      displaySmall: TextStyle(\n          color: iColors.colorScheme!.onSurfaceVariant,\n          fontSize: 16,\n          fontWeight: FontWeight.w500\n      ),\n      //////////////////////////////////////////////login\n      titleLarge: getMediumStyle(\n        color: iColors.colorScheme!.onSurface,\n        fontSize: FontSize.s17,\n      ),\n      titleMedium: getMediumStyle(\n        color: iColors.colorScheme!.onInverseSurface,\n        fontSize: FontSize.s14,\n      ),\n      titleSmall: getSemiBoldStyle(\n        //color: AppColors.blackLight,\n        color: iColors.colorScheme!.onSurfaceVariant,\n        fontSize: FontSize.s14,\n      )\n  );\n}\n\nAppBarTheme _appBarTheme(IColors colors) {\n  return AppBarTheme(\n    color: colors.colorScheme!.primary,\n    elevation: 0,\n    systemOverlayStyle: SystemUiOverlayStyle(\n      statusBarColor: colors.colorScheme!.primary,\n      statusBarIconBrightness: Brightness.light,\n    ),\n    titleTextStyle: TextStyle(\n      color: colors.colorScheme!.onPrimary,\n      fontSize: AppSize.s20,\n      fontWeight: FontWeightManager.semiBold,\n    ),\n    actionsIconTheme: IconThemeData(\n      color: colors.colorScheme!.primaryContainer,\n      size: FontSize.s26,\n    ),\n  );\n}\n\nTabBarTheme tabBarTheme() {\n  return const TabBarTheme(\n    labelStyle: TextStyle(\n      fontSize: FontSize.s14,\n      fontWeight: FontWeightManager.bold,\n    ),\n  );\n}\n\nTextButtonThemeData _textButtonThemeData(IColors colors) {\n  return TextButtonThemeData(\n    style: TextButton.styleFrom(\n      textStyle: TextStyle(\n        color: colors.colorScheme!.secondary,\n        fontWeight: FontWeightManager.medium,\n      ),\n    ),\n  );\n}\n\nPopupMenuThemeData _popupMenuThemeData(IColors iColors) {\n  return PopupMenuThemeData(\n    shape: RoundedRectangleBorder(\n      borderRadius: BorderRadius.circular(3),\n    ),\n    textStyle: TextStyle(\n      color: iColors.colorScheme!.onSurface,\n      fontWeight: FontWeightManager.medium,\n      fontSize: FontSize.s17,\n    ),\n  );\n}\n\nInputDecorationTheme _inputDecorationTheme(IColors iColors) {\n  return InputDecorationTheme(\n    hintStyle: TextStyle(\n      color: iColors.colorScheme!.onInverseSurface,\n    ),\n    focusedBorder: UnderlineInputBorder(\n      borderSide: BorderSide(\n        color: iColors.colorScheme!.secondary,\n        width: 2,\n      ),\n    ),\n    enabledBorder: UnderlineInputBorder(\n      borderSide: BorderSide(\n        color: iColors.colorScheme!.secondary,\n        width: 2,\n      ),\n    ),\n  );\n}\n\nElevatedButtonThemeData _elevatedButtonThemeData(IColors iColors) {\n  return ElevatedButtonThemeData(\n    style: ElevatedButton.styleFrom(\n      backgroundColor: iColors.colorScheme!.secondary,\n      textStyle: TextStyle(\n        color: iColors.colorScheme!.onSecondary,\n        fontWeight: FontWeightManager.medium,\n      ),\n      padding: const EdgeInsets.symmetric(\n        horizontal: AppSize.s20,\n        vertical: AppSize.s14,\n      ),\n    ),\n  );\n}\n"
  },
  {
    "path": "lib/features/data/data_source/auth/local/auth_local_data_source.dart",
    "content": "import 'package:shared_preferences/shared_preferences.dart';\n\nabstract class BaseAuthLocalDataSource {\n  Future<void> setUserLoggedIn(String uid);\n\n  Future<void> removeUser(String uid);\n\n  String? getUser();\n}\n\nclass AuthLocalDataSource extends BaseAuthLocalDataSource {\n  final SharedPreferences sharedPreferences;\n\n  AuthLocalDataSource({required this.sharedPreferences});\n\n  @override\n  Future<void> setUserLoggedIn(String uid) {\n    return sharedPreferences.setString('uid', uid);\n  }\n\n  @override\n  Future<void> removeUser(String uid) {\n    return sharedPreferences.remove(uid);\n  }\n\n  @override\n  String? getUser() {\n    return sharedPreferences.getString('uid');\n  }\n}\n"
  },
  {
    "path": "lib/features/data/data_source/auth/remote/auth_remote_data_source.dart",
    "content": "import 'dart:io';\n\nimport 'package:cloud_firestore/cloud_firestore.dart';\nimport 'package:firebase_auth/firebase_auth.dart';\nimport 'package:firebase_storage/firebase_storage.dart';\nimport 'package:flutter/foundation.dart';\n\nimport '../../../../../core/utils/constants/strings_manager.dart';\nimport '../../../../domain/usecases/auth/sign_in_with_phone_number_usecase.dart';\nimport '../../../../domain/usecases/auth/verify_otp_usecase.dart';\nimport '../../../../domain/usecases/auth/save_userdata_to_firebase_usecase.dart';\nimport '../../../models/user_model.dart';\n\nabstract class BaseAuthRemoteDataSource {\n  Future<void> signInWithPhoneNumber(\n      SignInWithPhoneNumberParameters parameters);\n\n  Future<void> verifyOtp(VerifyOtpParameters parameters);\n\n  Future<void> saveUserDataToFirebase(UserDataParameters parameters);\n\n  Future<String> getCurrentUid();\n\n  Future<void> signOut();\n\n  Future<UserModel> getCurrentUser();\n\n  Stream<UserModel> getUserById(String uId);\n\n  Future<void> setUserState(bool isOnline);\n  Future<void> updateProfilePic(String path);\n}\n\nclass AuthRemoteDataSource extends BaseAuthRemoteDataSource {\n  final FirebaseAuth auth;\n  final FirebaseFirestore firestore;\n  final FirebaseStorage firebaseStorage;\n\n  String _verificationId = '';\n\n  AuthRemoteDataSource({\n    required this.auth,\n    required this.firestore,\n    required this.firebaseStorage,\n  });\n\n  @override\n  Future<String> getCurrentUid() async => auth.currentUser!.uid;\n\n  @override\n  Future<void> signOut() async => await auth.signOut();\n\n  @override\n  Future<void> signInWithPhoneNumber(\n      SignInWithPhoneNumberParameters parameters) async {\n    await auth.verifyPhoneNumber(\n      phoneNumber: parameters.phoneNumber,\n      verificationCompleted: (AuthCredential credential) async {\n        await auth.signInWithCredential(credential);\n        if (kDebugMode) {\n          print(\"phone verified : Token ${credential.token}\");\n        }\n      },\n      verificationFailed: (e) {\n        throw Exception(e.message);\n      },\n      codeSent: (String verificationId, int? resendToken) {\n        _verificationId = verificationId;\n      },\n      codeAutoRetrievalTimeout: (String verificationId) {\n        //_verificationId = verificationId;\n        if (kDebugMode) {\n          print(\"time out :$verificationId\");\n        }\n      },\n      timeout: const Duration(minutes: 1),\n    );\n  }\n\n  @override\n  Future<void> verifyOtp(VerifyOtpParameters parameters) async {\n    PhoneAuthCredential credential = PhoneAuthProvider.credential(\n      verificationId: _verificationId,\n      smsCode: parameters.smsOtpCode,\n    );\n    await auth.signInWithCredential(credential);\n  }\n\n  @override\n  Future<void> saveUserDataToFirebase(UserDataParameters parameters) async {\n    String uId = await getCurrentUid();\n\n    String photoUrl = '';\n    if (parameters.profilePic != null) {\n      photoUrl = await _storeFileToFirebase(\n        'profilePic/$uId',\n        parameters.profilePic!,\n      );\n    }\n\n    var user = UserModel(\n      name: parameters.name,\n      uId: uId,\n      status: AppStrings.heyThere,\n      profilePic: photoUrl,\n      phoneNumber: auth.currentUser!.phoneNumber!,\n      isOnline: true,\n      groupId: const [],\n      lastSeen: DateTime.now(),\n    );\n    var userDoc = await firestore.collection('users').doc(uId).get();\n    if (userDoc.exists) {\n      await firestore.collection('users').doc(uId).update(user.toMap());\n    } else {\n      await firestore.collection('users').doc(uId).set(user.toMap());\n    }\n  }\n\n  Future<String> _storeFileToFirebase(String path, File file) async {\n    UploadTask uploadTask = firebaseStorage.ref().child(path).putFile(file);\n    TaskSnapshot snap = await uploadTask;\n    String downloadUrl = await snap.ref.getDownloadURL();\n    return downloadUrl;\n  }\n\n  Future<void> _deleteFileFromFirebase(String path)async{\n    return await firebaseStorage.refFromURL(path).delete();\n  }\n\n  @override\n  Future<UserModel> getCurrentUser() async {\n    var userData =\n        await firestore.collection('users').doc(await getCurrentUid()).get();\n    UserModel user = UserModel.fromMap(userData.data()!);\n    return user;\n  }\n\n  @override\n  Stream<UserModel> getUserById(String uId) {\n    print('doneee');\n    return firestore.collection('users').doc(uId).snapshots().map(\n          (event){\n            return UserModel.fromMap(event.data()!);\n          },\n        );\n  }\n\n  @override\n  Future<void> setUserState(bool isOnline) async {\n    await firestore.collection('users').doc(auth.currentUser!.uid).update({\n      'isOnline': isOnline,\n      'lastSeen': DateTime.now().millisecondsSinceEpoch,\n    });\n  }\n\n  @override\n  Future<void> updateProfilePic(String path)async {\n    String uId = auth.currentUser!.uid;\n    //firstly delete previus image\n    var userData = await firestore.collection('users').doc(uId).get();\n    UserModel user = UserModel.fromMap(userData.data()!);\n    if(user.profilePic.isNotEmpty){\n      await _deleteFileFromFirebase(user.profilePic);\n    }\n    //then upload new image\n    String photoUrl = await _storeFileToFirebase(\n      'profilePic/$uId',\n      File(path),\n    );\n    await firestore.collection('users').doc(auth.currentUser!.uid).update({\n      'profilePic': photoUrl,\n    });\n  }\n}\n"
  },
  {
    "path": "lib/features/data/data_source/call/call_data_source.dart",
    "content": "import 'package:cloud_firestore/cloud_firestore.dart';\nimport 'package:firebase_auth/firebase_auth.dart';\nimport 'package:uuid/uuid.dart';\nimport '../../../../core/functions/navigator.dart';\nimport '../../../../core/utils/routes/routes_manager.dart';\nimport '/features/data/models/call_model.dart';\n\nimport '../../../domain/usecases/call/end_call_usecase.dart';\nimport '../../../domain/usecases/call/make_call_usecase.dart';\nimport '../../models/user_model.dart';\n\nabstract class BaseCallDataSource {\n  Future<CallModel> makeCall(MakeCallParameters parameters);\n  Future<void> endCall(EndCallParameters parameters);\n  Stream<DocumentSnapshot> callStream();\n}\n\nclass CallDataSource extends BaseCallDataSource {\n  final FirebaseFirestore _firestore;\n  final FirebaseAuth _auth;\n\n  CallDataSource(this._firestore, this._auth);\n\n  Future<UserModel> _currentUser() async {\n    var userDataMap =\n    await _firestore.collection('users').doc(_auth.currentUser!.uid).get();\n    UserModel user = UserModel.fromMap(userDataMap.data()!);\n    return user;\n  }\n\n  @override\n  Stream<DocumentSnapshot> callStream() =>\n      _firestore.collection('call').doc(_auth.currentUser!.uid).snapshots();\n\n  @override\n  Future<void> endCall(EndCallParameters parameters) async {\n    await _firestore.collection('call').doc(parameters.callerId).delete();\n    await _firestore.collection('call').doc(parameters.receiverId).delete();\n  }\n\n  @override\n  Future<CallModel> makeCall(MakeCallParameters parameters)async {\n    String callId = const Uuid().v1();\n    UserModel currentUser = await _currentUser();\n    CallModel senderCallData = CallModel(\n      callerId: currentUser.uId,\n      callerName: currentUser.name,\n      callerPic: currentUser.profilePic,\n      receiverId: parameters.receiverId,\n      receiverName: parameters.receiverName,\n      receiverPic: parameters.receiverPic,\n      callId: callId,\n      hasDialled: true,\n    );\n\n    CallModel receiverCallData = CallModel(\n      callerId: currentUser.uId,\n      callerName: currentUser.name,\n      callerPic: currentUser.profilePic,\n      receiverId: parameters.receiverId,\n      receiverName: parameters.receiverName,\n      receiverPic: parameters.receiverPic,\n      callId: callId,\n      hasDialled: false,\n    );\n\n    await _firestore\n        .collection('call')\n        .doc(senderCallData.callerId)\n        .set(senderCallData.toMap());\n    await _firestore\n        .collection('call')\n        .doc(senderCallData.receiverId)\n        .set(receiverCallData.toMap());\n   return senderCallData;\n  }\n}\n"
  },
  {
    "path": "lib/features/data/data_source/chat/local/chat_local_data_source.dart",
    "content": "import 'package:flutter/cupertino.dart';\nimport 'package:giphy_get/giphy_get.dart';\n\nabstract class BaseChatLocalDataSource{\n  Future<GiphyGif?> pickGif(BuildContext context);\n}\n\nclass ChatLocalDataSource extends BaseChatLocalDataSource{\n  @override\n  Future<GiphyGif?> pickGif(BuildContext context)async {\n    GiphyGif? gif;\n      gif = await GiphyGet.getGif(\n        context: context,\n        apiKey: 'GmpyPrPF9RVZ1LJY1iAe6O8MTWrBpNob',\n\n      );\n      return gif;\n  }\n\n}"
  },
  {
    "path": "lib/features/data/data_source/chat/remote/chat_remote_data_source.dart",
    "content": "import 'dart:io';\n\nimport 'package:cloud_firestore/cloud_firestore.dart';\nimport 'package:firebase_auth/firebase_auth.dart';\nimport 'package:firebase_storage/firebase_storage.dart';\nimport 'package:uuid/uuid.dart';\n\nimport '../../../../../core/enums/messge_type.dart';\nimport '../../../../../core/shared/message_replay.dart';\nimport '../../../../domain/usecases/chat/get_chat_messages_usecase.dart';\nimport '../../../../domain/usecases/chat/send_file_message_usecase.dart';\nimport '../../../../domain/usecases/chat/send_gif_message_usecase.dart';\nimport '../../../../domain/usecases/chat/send_text_message_usecase.dart';\nimport '../../../../domain/usecases/chat/set_chat_message_seen_usecase.dart';\nimport '../../../models/contact_chat_model.dart';\nimport '../../../models/message_model.dart';\nimport '../../../models/user_model.dart';\n\nabstract class BaseChatRemoteDataSource {\n  Future<void> sendTextMessage(TextMessageParameters parameters);\n\n  Future<void> sendFileMessage(FileMessageParameters parameters);\n\n  Future<void> sendGifMessage(GifMessageParameters parameters);\n\n  Stream<List<MessageModel>> getChatMessages(\n      GetChatMessagesParameters parameters);\n\n  Stream<List<ContactChatModel>> getContactsChat(Map<String, dynamic> map);\n\n  Future<void> setChatMessageSeen(SetChatMessageSeenParameters parameters);\n  Stream<int> getNumOfMessageNotSeen(String senderId);\n}\n\nclass ChatRemoteDataSource extends BaseChatRemoteDataSource {\n  final FirebaseFirestore _firestore;\n  final FirebaseAuth _auth;\n  final FirebaseStorage firebaseStorage;\n\n  ChatRemoteDataSource(this._firestore, this._auth, this.firebaseStorage);\n\n  Future<UserModel> _currentUser() async {\n    var userDataMap =\n        await _firestore.collection('users').doc(_auth.currentUser!.uid).get();\n    UserModel user = UserModel.fromMap(userDataMap.data()!);\n    return user;\n  }\n\n  @override\n  Future<void> sendTextMessage(TextMessageParameters parameters) async {\n    UserModel receiverUserData;\n    var timeSent = DateTime.now();\n    var messageId = const Uuid().v1();\n    var userDataMap =\n        await _firestore.collection('users').doc(parameters.receiverId).get();\n    receiverUserData = UserModel.fromMap(userDataMap.data()!);\n    UserModel senderUser = await _currentUser();\n\n    /// this is bad to call sender user here i will refactor it.\n    _saveDataToContactsSubCollection(\n      senderUser,\n      receiverUserData,\n      parameters.text,\n      timeSent,\n    );\n    _saveMessageToMessageSubCollection(\n      senderId: senderUser.uId,\n      receiverId: parameters.receiverId,\n      text: parameters.text,\n      timeSent: timeSent,\n      messageId: messageId,\n      messageType: MessageType.text,\n      messageReplay: parameters.messageReplay,\n      senderUserName: senderUser.name,\n    );\n  }\n\n  void _saveDataToContactsSubCollection(\n    UserModel senderUserData,\n    UserModel receiverUserData,\n    String text,\n    DateTime timeSent,\n  ) async {\n    // users -> receiver user id => chats -> current user id -> set data\n    ContactChatModel receiverChatContact = ContactChatModel(\n      name: senderUserData.name,\n      profilePic: senderUserData.profilePic,\n      contactId: senderUserData.uId,\n      lastMessage: text,\n      timeSent: timeSent,\n      phoneNumber: senderUserData.phoneNumber,\n    );\n    await _firestore\n        .collection('users')\n        .doc(receiverUserData.uId)\n        .collection('chats')\n        .doc(senderUserData.uId)\n        .set(receiverChatContact.toMAp());\n\n    // users -> current user id => chats -> receiver user id -> set data\n    ContactChatModel senderChatContact = ContactChatModel(\n      name: receiverUserData.name,\n      profilePic: receiverUserData.profilePic,\n      contactId: receiverUserData.uId,\n      lastMessage: text,\n      timeSent: timeSent,\n      phoneNumber: receiverUserData.phoneNumber,\n    );\n    await _firestore\n        .collection('users')\n        .doc(senderUserData.uId)\n        .collection('chats')\n        .doc(receiverUserData.uId)\n        .set(senderChatContact.toMAp());\n  }\n\n  void _saveMessageToMessageSubCollection({\n    required String senderId,\n    required String receiverId,\n    required String text,\n    required DateTime timeSent,\n    required String messageId,\n    required MessageType messageType,\n    required MessageReplay? messageReplay,\n    required String senderUserName,\n  }) async {\n    MessageModel message = MessageModel(\n      senderId: senderId,\n      receiverId: receiverId,\n      text: text,\n      messageId: messageId,\n      timeSent: timeSent,\n      isSeen: false,\n      messageType: messageType,\n      repliedMessage: messageReplay == null ? '' : messageReplay.message,\n      senderName: senderUserName,\n      repliedTo: messageReplay == null\n          ? ''\n          : messageReplay.isMe\n              ? senderUserName\n              : messageReplay.repliedTo,\n      repliedMessageType:\n          messageReplay == null ? MessageType.text : messageReplay.messageType,\n    );\n    // users -> sender id -> chats -> receiver id -> messages ->message id ->store message\n    await _firestore\n        .collection('users')\n        .doc(senderId)\n        .collection('chats')\n        .doc(receiverId)\n        .collection('messages')\n        .doc(messageId)\n        .set(message.toMap());\n    // users -> receiver id -> chats -> sender id -> messages ->message id ->store message\n    await _firestore\n        .collection('users')\n        .doc(receiverId)\n        .collection('chats')\n        .doc(senderId)\n        .collection('messages')\n        .doc(messageId)\n        .set(message.toMap());\n  }\n\n  @override\n  Future<void> sendFileMessage(FileMessageParameters parameters) async {\n    DateTime timeSent = DateTime.now();\n    String messageId = const Uuid().v1();\n    UserModel senderUser = await _currentUser();\n    var fileUrl = await _storeFileToFirebase(\n      'chat/${parameters.messageType.type}/${senderUser.uId}/${parameters.receiverId}/$messageId}',\n      parameters.file,\n    );\n    UserModel receiverUserData;\n\n    var userDataMap =\n        await _firestore.collection('users').doc(parameters.receiverId).get();\n    receiverUserData = UserModel.fromMap(userDataMap.data()!);\n\n    String contactMessage;\n    switch (parameters.messageType) {\n      case MessageType.image:\n        contactMessage = '📷 Photo';\n        break;\n      case MessageType.video:\n        contactMessage = '🎥 Video';\n        break;\n      case MessageType.audio:\n        contactMessage = '🎙️ Audio';\n        break;\n      case MessageType.gif:\n        contactMessage = 'Gif';\n        break;\n      default:\n        contactMessage = 'Other';\n    }\n\n    _saveDataToContactsSubCollection(\n      senderUser,\n      receiverUserData,\n      contactMessage,\n      timeSent,\n    );\n    _saveMessageToMessageSubCollection(\n      senderId: senderUser.uId,\n      receiverId: parameters.receiverId,\n      text: fileUrl,\n      timeSent: timeSent,\n      messageId: messageId,\n      messageType: parameters.messageType,\n      messageReplay: parameters.messageReplay,\n      senderUserName: senderUser.name\n    );\n  }\n\n  Future<String> _storeFileToFirebase(String path, File file) async {\n    UploadTask uploadTask = firebaseStorage.ref().child(path).putFile(file);\n    TaskSnapshot snap = await uploadTask;\n    String downloadUrl = await snap.ref.getDownloadURL();\n    return downloadUrl;\n  }\n\n  @override\n  Future<void> sendGifMessage(GifMessageParameters parameters) async {\n    UserModel receiverUserData;\n    var timeSent = DateTime.now();\n    var messageId = const Uuid().v1();\n    var userDataMap =\n        await _firestore.collection('users').doc(parameters.receiverId).get();\n    receiverUserData = UserModel.fromMap(userDataMap.data()!);\n    UserModel senderUser = await _currentUser();\n    _saveDataToContactsSubCollection(\n      senderUser,\n      receiverUserData,\n      'Gif',\n      timeSent,\n    );\n    _saveMessageToMessageSubCollection(\n      senderId: senderUser.uId,\n      receiverId: parameters.receiverId,\n      text: parameters.gifUrl,\n      timeSent: timeSent,\n      messageId: messageId,\n      messageType: MessageType.gif,\n      senderUserName: senderUser.name,\n      messageReplay: parameters.messageReplay\n    );\n  }\n\n  @override\n  Stream<List<MessageModel>> getChatMessages(\n      GetChatMessagesParameters parameters) {\n    return _firestore\n        .collection('users')\n        .doc(_auth.currentUser!.uid)\n        .collection('chats')\n        .doc(parameters.receiverId)\n        .collection('messages')\n        .orderBy('timeSent')\n        .snapshots()\n        .map((event) {\n      List<MessageModel> messages = [];\n      for (var document in event.docs) {\n        messages.add(MessageModel.fromMap(document.data()));\n      }\n      return messages;\n    });\n  }\n\n  @override\n  Stream<List<ContactChatModel>> getContactsChat(Map<String, dynamic> map) {\n    return _firestore\n        .collection('users')\n        .doc(_auth.currentUser!.uid)\n        .collection('chats')\n        .orderBy('timeSent', descending: true)\n        .snapshots()\n        .asyncMap((event) async{\n      List<ContactChatModel> contacts = [];\n      for (var document in event.docs) {\n        ContactChatModel contactChat =\n            ContactChatModel.fromMap(document.data());\n        var userData = await _firestore\n            .collection('users')\n            .doc(contactChat.contactId)\n            .get();\n        var user = UserModel.fromMap(userData.data()!);\n        contacts.add(\n          ContactChatModel(\n            name: map.containsKey(contactChat.contactId)\n                ? map[contactChat.contactId]['name']\n                : user.name,\n            profilePic: user.profilePic,\n            contactId: user.uId,\n            lastMessage: contactChat.lastMessage,\n            timeSent: contactChat.timeSent,\n            phoneNumber: contactChat.phoneNumber,\n          ),\n        );\n      }\n      return contacts;\n    });\n  }\n\n  @override\n  Stream<int> getNumOfMessageNotSeen(String senderId){\n    return _firestore\n        .collection('users')\n        .doc(_auth.currentUser!.uid)\n        .collection('chats')\n        .doc(senderId)\n        .collection('messages')\n        .orderBy('timeSent')\n        .snapshots()\n        .map((event) {\n      int num= 0;\n      for (var document in event.docs) {\n        MessageModel message = MessageModel.fromMap(document.data());\n        if(message.senderId == senderId){\n          if(!message.isSeen){\n            num++;\n          }\n        }\n      }\n      return num;\n    });\n  }\n\n  @override\n  Future<void> setChatMessageSeen(\n      SetChatMessageSeenParameters parameters) async {\n    await _firestore\n        .collection('users')\n        .doc(_auth.currentUser!.uid)\n        .collection('chats')\n        .doc(parameters.receiverId)\n        .collection('messages')\n        .doc(parameters.messageId)\n        .update({\n      'isSeen': true,\n    });\n    // users -> receiver id -> chats -> sender id -> messages ->message id ->store message\n    await _firestore\n        .collection('users')\n        .doc(parameters.receiverId)\n        .collection('chats')\n        .doc(_auth.currentUser!.uid)\n        .collection('messages')\n        .doc(parameters.messageId)\n        .update({\n      'isSeen': true,\n    });\n  }\n}\n"
  },
  {
    "path": "lib/features/data/data_source/firebase_storage_remote_data_source.dart",
    "content": "import 'dart:io';\n\nimport 'package:firebase_storage/firebase_storage.dart';\n\nabstract class BaseFirebaseStorageRemoteDataSource{\n  Future<String> storeFileToFirebase(String path, File file);\n}\n\nclass FirebaseStorageRemoteDataSource extends BaseFirebaseStorageRemoteDataSource{\n  final FirebaseStorage firebaseStorage;\n\n  FirebaseStorageRemoteDataSource(this.firebaseStorage);\n\n  @override\n  Future<String> storeFileToFirebase(String path, File file) async{\n    UploadTask uploadTask =firebaseStorage.ref().child(path).putFile(file);\n    TaskSnapshot snap = await uploadTask;\n    String downloadUrl = await snap.ref.getDownloadURL();\n    return downloadUrl;\n  }\n\n}"
  },
  {
    "path": "lib/features/data/data_source/select_contact/local/get_contacts_local_data_source.dart",
    "content": "import 'package:flutter_contacts/flutter_contacts.dart';\nimport '/core/error/exceptions.dart';\n\nabstract class BaseSelectContactsLocalDataSource{\n  Future<List<Contact>> getContacts();\n}\n\nclass SelectContactsLocalDataSource extends BaseSelectContactsLocalDataSource{\n  @override\n  Future<List<Contact>> getContacts()async {\n   if(await FlutterContacts.requestPermission()){\n     return await FlutterContacts.getContacts(withProperties: true,);\n   }else{\n     throw(const CachedException(message: 'Not Allowed to get contacts'));\n   }\n  }\n}"
  },
  {
    "path": "lib/features/data/data_source/select_contact/remote/select_contact_remote_data_source.dart",
    "content": "import 'package:cloud_firestore/cloud_firestore.dart';\nimport 'package:firebase_auth/firebase_auth.dart';\nimport 'package:flutter_contacts/contact.dart';\n\nimport '/features/data/models/user_model.dart';\n\n\nabstract class BaseSelectContactsRemoteDataSource {\n  Future<void> getAllContacts(List<Contact> contacts);\n\n  Future<Map<String, dynamic>> contactsOnWhatsApp();\n\n  Future<List<Contact>> contactsNotOnWhatsApp();\n\n// Future<String> getContactName(ContactNameParameters parameters);\n}\n\nclass SelectContactsRemoteDataSource\n    extends BaseSelectContactsRemoteDataSource {\n  final FirebaseFirestore firestore;\n  final FirebaseAuth _auth;\n\n  SelectContactsRemoteDataSource(this.firestore, this._auth);\n\n  List<Contact> _contactsNotOnWhatsApp = [];\n\n  Map<String, dynamic> contactsOnWhatsAppMap = {};\n\n  @override\n  Future<List<Contact>> contactsNotOnWhatsApp() async => _contactsNotOnWhatsApp;\n\n  @override\n  Future<Map<String, dynamic>> contactsOnWhatsApp() async =>\n      contactsOnWhatsAppMap;\n\n  @override\n  Future<void> getAllContacts(List<Contact> contacts) async {\n    _contactsNotOnWhatsApp = [];\n    //contactsOnWhatsAppMap = {};\n    Map<String, dynamic> allContacts;\n    var userCollection = await firestore.collection('users').get();\n    String phoneNum;\n    bool numFound = false;\n    for (int i = 0; i < contacts.length; i++) {\n      numFound = false;\n      phoneNum = contacts[i].phones.isNotEmpty\n          ? contacts[i].phones[0].number.replaceAll(' ', '')\n          : '';\n    /*\n      if (userCollection.docs\n          .where((element) => element.data().containsValue(phoneNum))\n          .isNotEmpty) {\n        print(phoneNum);\n      }\n      */\n      for (var document in userCollection.docs) {\n        var userData = UserModel.fromMap(document.data());\n        if (phoneNum == userData.phoneNumber &&\n            userData.uId != _auth.currentUser!.uid) {\n          contactsOnWhatsAppMap.addAll({\n            userData.uId : {\n              'uId': userData.uId,\n              'profilePic': userData.profilePic,\n              'status': userData.status,\n              'name': contacts[i].displayName,\n            }\n          });\n          numFound = true;\n          break;\n        }\n      }\n      if (!numFound) _contactsNotOnWhatsApp.add(contacts[i]);\n    }\n  }\n/*\n  @override\n  Future<String> getContactName(ContactNameParameters parameters) async {\n      if (contactsOnWhatsAppMap.containsKey(parameters.uId)) {\n        return contactsOnWhatsAppMap[parameters.uId]['name'];\n      }\n    var user = await firestore.collection('users').doc(parameters.uId).get();\n    var userData = UserModel.fromMap(user.data()!);\n    return userData.phoneNumber;\n  }\n\n */\n}\n"
  },
  {
    "path": "lib/features/data/models/call_model.dart",
    "content": "import '../../domain/entities/call.dart';\n\nclass CallModel extends Call {\n  const CallModel({\n    required super.callerId,\n    required super.callerName,\n    required super.callerPic,\n    required super.receiverId,\n    required super.receiverName,\n    required super.receiverPic,\n    required super.callId,\n    required super.hasDialled,\n  });\n\n  Map<String, dynamic> toMap() {\n    return {\n      'callerId': callerId,\n      'callerName': callerName,\n      'callerPic': callerPic,\n      'receiverId': receiverId,\n      'receiverName': receiverName,\n      'receiverPic': receiverPic,\n      'callId': callId,\n      'hasDialled': hasDialled,\n    };\n  }\n\n  factory CallModel.fromMap(Map<String, dynamic> map) {\n    return CallModel(\n      callerId: map['callerId'] ?? '',\n      callerName: map['callerName'] ?? '',\n      callerPic: map['callerPic'] ?? '',\n      receiverId: map['receiverId'] ?? '',\n      receiverName: map['receiverName'] ?? '',\n      receiverPic: map['receiverPic'] ?? '',\n      callId: map['callId'] ?? '',\n      hasDialled: map['hasDialled'] ?? false,\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/data/models/contact_chat_model.dart",
    "content": "import '../../domain/entities/contact_chat.dart';\n\nclass ContactChatModel extends ContactChat {\n  const ContactChatModel({\n    required super.name,\n    required super.profilePic,\n    required super.contactId,\n    required super.lastMessage,\n    required super.timeSent,\n    required super.phoneNumber,\n  });\n\n  Map<String, dynamic> toMAp() => {\n        'name': name,\n        'profilePic': profilePic,\n        'contactId': contactId,\n        'lastMessage': lastMessage,\n        'timeSent': timeSent.millisecondsSinceEpoch,\n        'phoneNumber' : phoneNumber,\n      };\n\n  factory ContactChatModel.fromMap(Map<String, dynamic> map) =>\n      ContactChatModel(\n        name: map['name'],\n        profilePic: map['profilePic'],\n        contactId: map['contactId'],\n        lastMessage: map['lastMessage'],\n        timeSent: DateTime.fromMillisecondsSinceEpoch(map['timeSent']),\n        phoneNumber: map['phoneNumber'],\n      );\n}\n"
  },
  {
    "path": "lib/features/data/models/message_model.dart",
    "content": "import 'package:whatsapp_flutter_clone/core/enums/messge_type.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/entities/message.dart';\n\nclass MessageModel extends Message {\n  const MessageModel({\n    required super.senderId,\n    required super.receiverId,\n    required super.text,\n    required super.messageId,\n    required super.timeSent,\n    required super.isSeen,\n    required super.messageType,\n    required super.repliedMessage,\n    required super.repliedTo,\n    required super.repliedMessageType,\n    required super.senderName,\n  });\n\n  Map<String, dynamic> toMap() => {\n        'senderId': senderId,\n        'receiverId': receiverId,\n        'text': text,\n        'messageId': messageId,\n        'timeSent': timeSent.millisecondsSinceEpoch,\n        'isSeen': isSeen,\n        'messageType': messageType.type,\n        'repliedMessage': repliedMessage,\n        'repliedTo': repliedTo,\n        'repliedMessageType': repliedMessageType.type,\n        'senderName': senderName,\n      };\n\n  factory MessageModel.fromMap(Map<String, dynamic> map) => MessageModel(\n        senderId: map['senderId'],\n        receiverId: map['receiverId'],\n        text: map['text'],\n        messageId: map['messageId'],\n        timeSent: DateTime.fromMillisecondsSinceEpoch(map['timeSent']),\n        isSeen: map['isSeen'],\n        messageType: (map['messageType'] as String).toEnum(),\n        repliedMessage: map['repliedMessage'],\n        repliedTo: map['repliedTo'],\n        repliedMessageType: (map['repliedMessageType'] as String).toEnum(),\n        senderName: map['senderName'],\n      );\n}\n"
  },
  {
    "path": "lib/features/data/models/user_model.dart",
    "content": "import '../../domain/entities/user.dart';\n\nclass UserModel extends UserEntity {\n  const UserModel({\n    required super.name,\n    required super.uId,\n    required super.status,\n    required super.profilePic,\n    required super.phoneNumber,\n    required super.isOnline,\n    required super.groupId,\n    required super.lastSeen,\n  });\n\n  Map<String, dynamic> toMap() {\n    return {\n      'name': name,\n      'uId': uId,\n      'status': status,\n      'profilePic': profilePic,\n      'phoneNumber': phoneNumber,\n      'isOnline': isOnline,\n      'groupId': groupId,\n      'lastSeen': lastSeen.millisecondsSinceEpoch,\n    };\n  }\n\n  factory UserModel.fromMap(Map<String, dynamic> map) {\n    return UserModel(\n      name: map['name'] ?? '',\n      uId: map['uId'] ?? '',\n      status: map['status'] ?? '',\n      profilePic: map['profilePic'] ?? '',\n      phoneNumber: map['phoneNumber'],\n      isOnline: map['isOnline'] ?? false,\n      groupId: List<String>.from(map['groupId']),\n      lastSeen: DateTime.fromMillisecondsSinceEpoch(map['lastSeen']),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/data/repository/auth_repository.dart",
    "content": "import 'package:dartz/dartz.dart';\nimport 'package:firebase_auth/firebase_auth.dart';\n\nimport '/features/data/models/user_model.dart';\nimport '/features/domain/entities/user.dart';\nimport '../../../core/error/exceptions.dart';\nimport '../../../core/error/failure.dart';\nimport '../../domain/repository/base_auth_repository.dart';\nimport '../../domain/usecases/auth/save_userdata_to_firebase_usecase.dart';\nimport '../../domain/usecases/auth/sign_in_with_phone_number_usecase.dart';\nimport '../../domain/usecases/auth/verify_otp_usecase.dart';\nimport '../data_source/auth/local/auth_local_data_source.dart';\nimport '../data_source/auth/remote/auth_remote_data_source.dart';\n\nclass AuthRepository extends BaseAuthRepository {\n  final BaseAuthRemoteDataSource remoteDataSource;\n  final BaseAuthLocalDataSource localDataSource;\n\n  AuthRepository({\n    required this.remoteDataSource,\n    required this.localDataSource,\n  });\n\n  @override\n  Future<Either<Failure, void>> signInWithPhoneNumber(\n    SignInWithPhoneNumberParameters parameters,\n  ) async {\n    final result = await remoteDataSource.signInWithPhoneNumber(parameters);\n    try {\n      return Right(result);\n    } on FirebaseAuthException catch (failure) {\n      return Left(ServerFailure(failure.message!));\n    }\n  }\n\n  @override\n  Future<Either<Failure, void>> verifyOtp(\n      VerifyOtpParameters parameters) async {\n    final result = await remoteDataSource.verifyOtp(parameters);\n    try {\n      return Right(result);\n    } on FirebaseAuthException catch (failure) {\n      return Left(ServerFailure(failure.message!));\n    }\n  }\n\n  @override\n  Future<Either<Failure, void>> saveUserDataToFirebase(\n      UserDataParameters parameters) async {\n    final result = await remoteDataSource.saveUserDataToFirebase(parameters);\n    localDataSource.setUserLoggedIn(await remoteDataSource.getCurrentUid());\n    try {\n      return Right(result);\n    } on FirebaseAuthException catch (failure) {\n      return Left(ServerFailure(failure.message!));\n    }\n  }\n\n  @override\n  Future<Either<Failure, String>> getCurrentUid() async {\n    final result = await remoteDataSource.getCurrentUid();\n    //final result = await _getUid();\n    try {\n      return Right(result);\n    } on FirebaseAuthException catch (failure) {\n      return Left(ServerFailure(failure.message!));\n    }\n  }\n\n  @override\n  Future<Either<Failure, void>> signOut() async {\n    final result = await remoteDataSource.signOut();\n    await localDataSource.removeUser(localDataSource.getUser()!);\n    try {\n      return Right(result);\n    } on FirebaseAuthException catch (failure) {\n      return Left(ServerFailure(failure.message!));\n    }\n  }\n\n  @override\n  Future<Either<Failure, String>> getCachedLocalCurrentUid() async {\n    final result = await localDataSource.getUser();\n    try {\n      return Right(result!);\n    } on CachedException catch (failure) {\n      return Left(CachedFailure(failure.message));\n    }\n  }\n\n  @override\n  Future<Either<Failure, UserModel>> getCurrentUser() async {\n    final result = await remoteDataSource.getCurrentUser();\n    try {\n      return Right(result);\n    } on FirebaseAuthException catch (failure) {\n      return Left(ServerFailure(failure.message!));\n    }\n  }\n\n  @override\n  Future<Either<Failure, void>> setUserState(bool isOnline) async {\n    final result = await remoteDataSource.setUserState(isOnline);\n    try {\n      return Right(result);\n    } on FirebaseAuthException catch (failure) {\n      return Left(ServerFailure(failure.message!));\n    }\n  }\n\n  @override\n  Stream<UserEntity> getUserById(String uId) {\n    return remoteDataSource.getUserById(uId);\n  }\n\n  @override\n  Future<Either<Failure, void>> updateProfilePic(String path) async {\n    final result = await remoteDataSource.updateProfilePic(path);\n    try {\n      return Right(result);\n    } on FirebaseAuthException catch (failure) {\n      return Left(ServerFailure(failure.message!));\n    }\n  }\n}\n"
  },
  {
    "path": "lib/features/data/repository/call_repository.dart",
    "content": "import 'package:cloud_firestore/cloud_firestore.dart';\nimport 'package:dartz/dartz.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/entities/call.dart';\n\nimport '../../../core/error/failure.dart';\nimport '../../domain/repository/base_call_repository.dart';\nimport '../../domain/usecases/call/end_call_usecase.dart';\nimport '../../domain/usecases/call/make_call_usecase.dart';\nimport '../data_source/call/call_data_source.dart';\n\nclass CallRepository extends BaseCallRepository{\n  final CallDataSource _callDataSource;\n\n  CallRepository(this._callDataSource);\n\n  @override\n  Stream<DocumentSnapshot<Object?>> callStream() => _callDataSource.callStream();\n\n  @override\n  Future<Either<Failure, void>> endCall(EndCallParameters parameters) async{\n    final result = await _callDataSource.endCall(parameters);\n    try{\n      return Right(result);\n    }on FirebaseException catch(failure){\n      return Left(ServerFailure(failure.message!));\n    }\n  }\n\n  @override\n  Future<Either<Failure, Call>> makeCall(MakeCallParameters parameters)async {\n    final result = await _callDataSource.makeCall(parameters);\n    try{\n      return Right(result);\n    }on FirebaseException catch(failure){\n      return Left(ServerFailure(failure.message!));\n    }\n  }\n}"
  },
  {
    "path": "lib/features/data/repository/chat_repository.dart",
    "content": "import 'package:cloud_firestore/cloud_firestore.dart';\nimport 'package:dartz/dartz.dart';\n\nimport '../../../core/error/failure.dart';\nimport '../../domain/entities/contact_chat.dart';\nimport '../../domain/entities/message.dart';\nimport '../../domain/repository/base_chat_repository.dart';\nimport '../../domain/usecases/chat/get_chat_messages_usecase.dart';\nimport '../../domain/usecases/chat/send_file_message_usecase.dart';\nimport '../../domain/usecases/chat/send_gif_message_usecase.dart';\nimport '../../domain/usecases/chat/send_text_message_usecase.dart';\nimport '../../domain/usecases/chat/set_chat_message_seen_usecase.dart';\nimport '../data_source/chat/remote/chat_remote_data_source.dart';\n\nclass ChatRepository extends BaseChatRepository {\n  final BaseChatRemoteDataSource _remoteDataSource;\n  //final BaseSelectContactRepository _selectContactRepository;\n\n  ChatRepository(this._remoteDataSource);\n\n  @override\n  Stream<List<Message>> getChatMessages(GetChatMessagesParameters parameters) {\n   return _remoteDataSource.getChatMessages(parameters);\n  }\n\n  @override\n  Stream<List<ContactChat>> getContactsChat(Map<String,dynamic> map) {\n    return  _remoteDataSource.getContactsChat(map);\n  }\n\n  @override\n  Future<Either<Failure, void>> sendFileMessage(FileMessageParameters parameters)async {\n    final result = await _remoteDataSource.sendFileMessage(parameters);\n    try{\n      return Right(result);\n    }on FirebaseException catch(failure){\n      return Left(ServerFailure(failure.message!));\n    }\n  }\n\n  @override\n  Future<Either<Failure, void>> sendTextMessage(TextMessageParameters parameters) async {\n    final result = await _remoteDataSource.sendTextMessage(parameters);\n    try{\n      return Right(result);\n    }on FirebaseException catch(failure){\n      return Left(ServerFailure(failure.message!));\n    }\n  }\n\n  @override\n  Future<Either<Failure, void>> setChatMessageSeen(SetChatMessageSeenParameters parameters)async {\n    final result = await _remoteDataSource.setChatMessageSeen(parameters);\n    try{\n      return Right(result);\n    }on FirebaseException catch(failure){\n      return Left(ServerFailure(failure.message!));\n    }\n  }\n\n  @override\n  Future<Either<Failure, void>> sendGifMessage(GifMessageParameters parameters)async {\n\n    final result = await _remoteDataSource.sendGifMessage(parameters);\n    try{\n      return Right(result);\n    }on FirebaseException catch(failure){\n      return Left(ServerFailure(failure.message!));\n    }\n  }\n\n  @override\n  Stream<int> getNumOfMessageNotSeen(String senderId) {\n    return _remoteDataSource.getNumOfMessageNotSeen(senderId);\n  }\n}\n"
  },
  {
    "path": "lib/features/data/repository/select_contact_Repository.dart",
    "content": "import 'package:dartz/dartz.dart';\nimport 'package:firebase_auth/firebase_auth.dart';\nimport 'package:flutter_contacts/contact.dart';\n\nimport '../../../core/error/exceptions.dart';\nimport '../../../core/error/failure.dart';\nimport '../../domain/repository/base_select_contact_repository.dart';\nimport '../data_source/select_contact/local/get_contacts_local_data_source.dart';\nimport '../data_source/select_contact/remote/select_contact_remote_data_source.dart';\n\nclass SelectContactRepository extends BaseSelectContactRepository{\n  final BaseSelectContactsRemoteDataSource remoteDataSource;\n  final BaseSelectContactsLocalDataSource localDataSource;\n\n  SelectContactRepository(this.remoteDataSource, this.localDataSource);\n\n  @override\n  Future<Either<Failure, void>> getAllContacts() async{\n    final result = await remoteDataSource.getAllContacts(await localDataSource.getContacts());\n    try{\n      return Right(result);\n    }on CachedException catch(failure){\n      return Left(CachedFailure(failure.message));\n    }on FirebaseAuthException catch(failure){\n      return Left(ServerFailure(failure.message!));\n    }\n  }\n\n  @override\n  Future<Either<Failure, List<Contact>>> getContactsNotOnWhatsApp()async {\n    final result = await remoteDataSource.contactsNotOnWhatsApp();\n    try{\n      return Right(result);\n    }on FirebaseAuthException catch(failure){\n      return Left(ServerFailure(failure.message!));\n    }\n  }\n\n  @override\n  Future<Either<Failure, Map<String,dynamic>>> getContactsOnWhatsApp()async {\n    final result = await remoteDataSource.contactsOnWhatsApp();\n    try{\n      return Right(result);\n    }on FirebaseAuthException catch(failure){\n      return Left(ServerFailure(failure.message!));\n    }\n  }\n/*\n  @override\n  Future<Either<Failure, String>> getContactName(ContactNameParameters parameters)async {\n    final result = await remoteDataSource.getContactName(parameters);\n    try{\n      return Right(result);\n    }on CachedException catch(failure){\n      return Left(CachedFailure(failure.message));\n    }\n  }\n\n */\n}"
  },
  {
    "path": "lib/features/domain/entities/call.dart",
    "content": "import 'package:equatable/equatable.dart';\n\nclass Call extends Equatable {\n  final String callerId;\n  final String callerName;\n  final String callerPic;\n  final String receiverId;\n  final String receiverName;\n  final String receiverPic;\n  final String callId;\n  final bool hasDialled;\n\n  const Call({\n    required this.callerId,\n    required this.callerName,\n    required this.callerPic,\n    required this.receiverId,\n    required this.receiverName,\n    required this.receiverPic,\n    required this.callId,\n    required this.hasDialled,\n  });\n\n  @override\n  List<Object?> get props => [\n        callerId,\n        callerName,\n        callerPic,\n        receiverId,\n        receiverName,\n        receiverPic,\n        callId,\n        hasDialled,\n      ];\n}\n"
  },
  {
    "path": "lib/features/domain/entities/contact_chat.dart",
    "content": "import 'package:equatable/equatable.dart';\n\nclass ContactChat extends Equatable {\n  final String name;\n  final String profilePic;\n  final String contactId;\n  final String lastMessage;\n  final DateTime timeSent;\n  final String phoneNumber;\n\n  const ContactChat({\n    required this.name,\n    required this.profilePic,\n    required this.contactId,\n    required this.lastMessage,\n    required this.timeSent,\n    required this.phoneNumber,\n  });\n\n  @override\n  List<Object?> get props => [\n        name,\n        profilePic,\n        contactId,\n        lastMessage,\n        timeSent,\n    phoneNumber,\n      ];\n}\n"
  },
  {
    "path": "lib/features/domain/entities/message.dart",
    "content": "import 'package:equatable/equatable.dart';\n\nimport '../../../core/enums/messge_type.dart';\n\nclass Message extends Equatable {\n  final String senderId;\n  final String receiverId;\n  final String senderName;\n  final String text;\n  final String messageId;\n  final DateTime timeSent;\n  final bool isSeen;\n  final MessageType messageType;\n  //replay message\n  final String repliedMessage;\n  final String repliedTo;\n  final MessageType repliedMessageType;\n\n  const Message({\n    required this.senderId,\n    required this.receiverId,\n    required this.text,\n    required this.messageId,\n    required this.timeSent,\n    required this.isSeen,\n    required this.messageType,\n    required this.repliedMessage,\n    required this.repliedTo,\n    required this.repliedMessageType,\n    required this.senderName,\n  });\n\n  @override\n  List<Object?> get props => [\n    senderId,\n    receiverId,\n    text,\n    messageId,\n    timeSent,\n    isSeen,\n    messageType,\n    repliedMessage,\n    repliedTo,\n    repliedMessageType,\n    senderName,\n  ];\n}\n"
  },
  {
    "path": "lib/features/domain/entities/user.dart",
    "content": "import 'package:equatable/equatable.dart';\n\nclass UserEntity extends Equatable {\n  final String name;\n  final String uId;\n  final String status;\n  final String profilePic;\n  final String phoneNumber;\n  final bool isOnline;\n  final List<String> groupId;\n  final DateTime lastSeen;\n\n  const UserEntity({\n    required this.name,\n    required this.uId,\n    required this.status,\n    required this.profilePic,\n    required this.phoneNumber,\n    required this.isOnline,\n    required this.groupId,\n    required this.lastSeen,\n  });\n\n  @override\n  List<Object?> get props => [\n    name,\n    uId,\n    status,\n    profilePic,\n    phoneNumber,\n    isOnline,\n    groupId,\n    lastSeen,\n  ];\n}\n"
  },
  {
    "path": "lib/features/domain/repository/base_auth_repository.dart",
    "content": "import 'package:dartz/dartz.dart';\n\nimport '../../../core/error/failure.dart';\nimport '../entities/user.dart';\nimport '../usecases/auth/save_userdata_to_firebase_usecase.dart';\nimport '../usecases/auth/sign_in_with_phone_number_usecase.dart';\nimport '../usecases/auth/verify_otp_usecase.dart';\n\nabstract class BaseAuthRepository{\n  Future<Either<Failure, void>> signInWithPhoneNumber(SignInWithPhoneNumberParameters parameters);\n  Future<Either<Failure, void>> verifyOtp(VerifyOtpParameters parameters);\n  Future<Either<Failure,void>> saveUserDataToFirebase(UserDataParameters parameters);\n  Future<Either<Failure,String>> getCurrentUid();\n  Future<Either<Failure,String>> getCachedLocalCurrentUid();\n  Future<Either<Failure,void>> signOut();\n  Future<Either<Failure,UserEntity>> getCurrentUser();\n  Stream<UserEntity> getUserById(String uId);\n  Future<Either<Failure,void>> setUserState(bool isOnline);\n  Future<Either<Failure,void>> updateProfilePic(String path);\n}"
  },
  {
    "path": "lib/features/domain/repository/base_call_repository.dart",
    "content": "import 'package:cloud_firestore/cloud_firestore.dart';\nimport 'package:dartz/dartz.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/entities/call.dart';\n\nimport '../../../core/error/failure.dart';\nimport '../usecases/call/end_call_usecase.dart';\nimport '../usecases/call/make_call_usecase.dart';\n\nabstract class BaseCallRepository{\nFuture<Either<Failure,Call>> makeCall(MakeCallParameters parameters);\nFuture<Either<Failure,void>> endCall(EndCallParameters parameters);\nStream<DocumentSnapshot> callStream();\n}"
  },
  {
    "path": "lib/features/domain/repository/base_chat_repository.dart",
    "content": "import 'package:dartz/dartz.dart';\n\nimport '../../../core/error/failure.dart';\nimport '../entities/contact_chat.dart';\nimport '../entities/message.dart';\nimport '../usecases/chat/get_chat_messages_usecase.dart';\nimport '../usecases/chat/send_file_message_usecase.dart';\nimport '../usecases/chat/send_gif_message_usecase.dart';\nimport '../usecases/chat/send_text_message_usecase.dart';\nimport '../usecases/chat/set_chat_message_seen_usecase.dart';\n\nabstract class BaseChatRepository{\n  Future<Either<Failure,void>> sendTextMessage(TextMessageParameters parameters);\n  Future<Either<Failure,void>> sendFileMessage(FileMessageParameters parameters);\n  Future<Either<Failure,void>> sendGifMessage(GifMessageParameters parameters);\n  Stream<List<ContactChat>> getContactsChat(Map<String,dynamic> map);\n  Stream<List<Message>> getChatMessages(GetChatMessagesParameters parameters);\n  Future<Either<Failure,void>> setChatMessageSeen(SetChatMessageSeenParameters parameters);\n  Stream<int> getNumOfMessageNotSeen(String senderId);\n}"
  },
  {
    "path": "lib/features/domain/repository/base_select_contact_repository.dart",
    "content": "import 'package:dartz/dartz.dart';\nimport 'package:flutter_contacts/contact.dart';\n\nimport '../../../core/error/failure.dart';\nimport '../usecases/select_contact/get_contact_name_usecase.dart';\n\nabstract class BaseSelectContactRepository{\nFuture<Either<Failure,void>> getAllContacts();\nFuture<Either<Failure,List<Contact>>> getContactsNotOnWhatsApp();\nFuture<Either<Failure,Map<String,dynamic>>> getContactsOnWhatsApp();\n//Future<Either<Failure,String>> getContactName(ContactNameParameters parameters);\n}"
  },
  {
    "path": "lib/features/domain/usecases/auth/get_cached_local_current_uid_usecase.dart",
    "content": "import 'package:dartz/dartz.dart';\n\nimport '../../../../core/error/failure.dart';\nimport '../../../../core/usecase/base_use_case.dart';\nimport '../../repository/base_auth_repository.dart';\n\nclass GetCachedLocalCurrentUidUseCase extends BaseUseCase<String , NoParameters>{\n  final BaseAuthRepository baseFirebaseRepository;\n\n  GetCachedLocalCurrentUidUseCase(this.baseFirebaseRepository);\n  @override\n  Future<Either<Failure, String>> call(NoParameters parameters)async {\n    return await baseFirebaseRepository.getCachedLocalCurrentUid();\n  }\n\n}"
  },
  {
    "path": "lib/features/domain/usecases/auth/get_current_uid_usecase.dart",
    "content": "import 'package:dartz/dartz.dart';\n\nimport '../../../../core/error/failure.dart';\nimport '../../../../core/usecase/base_use_case.dart';\nimport '../../repository/base_auth_repository.dart';\n\nclass GetCurrentUidUseCase extends BaseUseCase<String, NoParameters>{\n  final BaseAuthRepository baseFirebaseRepository;\n\n  GetCurrentUidUseCase(this.baseFirebaseRepository);\n  @override\n  Future<Either<Failure, String>> call(NoParameters parameters) async{\n    return await baseFirebaseRepository.getCurrentUid();\n  }\n\n}"
  },
  {
    "path": "lib/features/domain/usecases/auth/get_current_user_usecase.dart",
    "content": "import 'package:dartz/dartz.dart';\nimport 'package:whatsapp_flutter_clone/core/error/failure.dart';\nimport 'package:whatsapp_flutter_clone/core/usecase/base_use_case.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/entities/user.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/repository/base_auth_repository.dart';\n\nclass GetCurrentUserUseCase extends BaseUseCase<UserEntity,NoParameters>{\n  final BaseAuthRepository _authRepository;\n\n  GetCurrentUserUseCase(this._authRepository);\n  @override\n  Future<Either<Failure, UserEntity>> call(NoParameters parameters) async{\n    return await _authRepository.getCurrentUser();\n  }\n}"
  },
  {
    "path": "lib/features/domain/usecases/auth/get_user_by_id_usecase.dart",
    "content": "import '../../../../core/usecase/base_use_case.dart';\nimport '../../entities/user.dart';\nimport '../../repository/base_auth_repository.dart';\n\nclass GetUserByIdUseCase extends StreamBaseUseCase<UserEntity, String> {\n  final BaseAuthRepository _baseAuthRepository;\n\n  GetUserByIdUseCase(this._baseAuthRepository);\n\n  @override\n  Stream<UserEntity> call(String parameters) {\n    return _baseAuthRepository.getUserById(parameters);\n  }\n}\n"
  },
  {
    "path": "lib/features/domain/usecases/auth/save_userdata_to_firebase_usecase.dart",
    "content": "import 'dart:io';\n\nimport 'package:dartz/dartz.dart';\nimport 'package:equatable/equatable.dart';\n\nimport '../../../../core/error/failure.dart';\nimport '../../../../core/usecase/base_use_case.dart';\nimport '../../repository/base_auth_repository.dart';\n\n\nclass SaveUserDataToFirebaseUseCase extends BaseUseCase<void ,UserDataParameters>{\n  final BaseAuthRepository baseFirebaseRepository;\n\n  SaveUserDataToFirebaseUseCase(this.baseFirebaseRepository);\n  @override\n  Future<Either<Failure, void>> call(UserDataParameters parameters) async{\n    return await baseFirebaseRepository.saveUserDataToFirebase(parameters);\n  }\n\n}\n\nclass UserDataParameters extends Equatable {\n  final String name;\n  final File? profilePic;\n\n  const UserDataParameters({required this.name,  this.profilePic});\n\n  @override\n  List<Object?> get props => [\n        name,\n        profilePic,\n      ];\n}\n"
  },
  {
    "path": "lib/features/domain/usecases/auth/set_user_state_usecase.dart",
    "content": "import 'package:dartz/dartz.dart';\n\nimport '../../../../core/error/failure.dart';\nimport '../../../../core/usecase/base_use_case.dart';\nimport '../../repository/base_auth_repository.dart';\n\nclass SetUserStateUseCase extends BaseUseCase<void , bool>{\n  final BaseAuthRepository _baseAuthRepository;\n\n  SetUserStateUseCase(this._baseAuthRepository);\n  @override\n  Future<Either<Failure, void>> call(bool parameters) async{\n    return await _baseAuthRepository.setUserState(parameters);\n  }\n\n}"
  },
  {
    "path": "lib/features/domain/usecases/auth/sign_in_with_phone_number_usecase.dart",
    "content": "import 'package:dartz/dartz.dart';\nimport 'package:equatable/equatable.dart';\n\nimport '../../../../core/error/failure.dart';\nimport '../../../../core/usecase/base_use_case.dart';\nimport '../../repository/base_auth_repository.dart';\n\nclass SignInWithPhoneNumberUseCase extends BaseUseCase<void, SignInWithPhoneNumberParameters> {\n  final BaseAuthRepository baseFirebaseRepository;\n\n  SignInWithPhoneNumberUseCase(this.baseFirebaseRepository);\n  @override\n  Future<Either<Failure, void>> call(SignInWithPhoneNumberParameters parameters) async{\n   return await baseFirebaseRepository.signInWithPhoneNumber(parameters);\n  }\n\n}\n\nclass SignInWithPhoneNumberParameters extends Equatable {\n  final String phoneNumber;\n\n  const SignInWithPhoneNumberParameters({required this.phoneNumber});\n\n  @override\n  List<Object> get props => [phoneNumber];\n}"
  },
  {
    "path": "lib/features/domain/usecases/auth/signout_usecase.dart",
    "content": "import 'package:dartz/dartz.dart';\n\nimport '../../../../core/error/failure.dart';\nimport '../../../../core/usecase/base_use_case.dart';\nimport '../../repository/base_auth_repository.dart';\n\nclass SignOutUseCase extends BaseUseCase<void,NoParameters>{\n  final BaseAuthRepository baseFirebaseRepository;\n\n  SignOutUseCase(this.baseFirebaseRepository);\n  @override\n  Future<Either<Failure, void>> call(NoParameters parameters)async {\n    return await baseFirebaseRepository.signOut();\n  }\n\n}"
  },
  {
    "path": "lib/features/domain/usecases/auth/update_profile_pic_usecase.dart",
    "content": "import 'package:dartz/dartz.dart';\nimport 'package:whatsapp_flutter_clone/core/error/failure.dart';\nimport 'package:whatsapp_flutter_clone/core/usecase/base_use_case.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/repository/base_auth_repository.dart';\n\nclass UpdateProfilePicUseCase extends BaseUseCase<void,String>{\n  final BaseAuthRepository _baseAuthRepository;\n\n  UpdateProfilePicUseCase(this._baseAuthRepository);\n  @override\n  Future<Either<Failure, void>> call(String parameters)async {\n    return await _baseAuthRepository.updateProfilePic(parameters);\n  }\n\n}"
  },
  {
    "path": "lib/features/domain/usecases/auth/verify_otp_usecase.dart",
    "content": "import 'package:dartz/dartz.dart';\nimport 'package:equatable/equatable.dart';\n\nimport '../../../../core/error/failure.dart';\nimport '../../../../core/usecase/base_use_case.dart';\nimport '../../repository/base_auth_repository.dart';\n\nclass VerifyOtpUseCase extends BaseUseCase<void, VerifyOtpParameters> {\n  final BaseAuthRepository baseFirebaseRepository;\n\n  VerifyOtpUseCase(this.baseFirebaseRepository);\n\n  @override\n  Future<Either<Failure, void>> call(VerifyOtpParameters parameters)async {\n    return await baseFirebaseRepository.verifyOtp(parameters);\n  }\n}\n\nclass VerifyOtpParameters extends Equatable {\n  final String smsOtpCode;\n\n  const VerifyOtpParameters({required this.smsOtpCode});\n\n  @override\n  List<Object> get props => [smsOtpCode];\n\n}"
  },
  {
    "path": "lib/features/domain/usecases/call/call_stream_usecase.dart",
    "content": "import 'package:cloud_firestore/cloud_firestore.dart';\n\nimport '../../../../core/usecase/base_use_case.dart';\nimport '../../repository/base_call_repository.dart';\n\nclass CallStreamUseCase extends StreamBaseUseCase<DocumentSnapshot,NoParameters>{\n  final BaseCallRepository _baseCallRepository;\n\n  CallStreamUseCase(this._baseCallRepository);\n  @override\n  Stream<DocumentSnapshot> call(NoParameters parameters) {\n    return _baseCallRepository.callStream();\n  }\n}"
  },
  {
    "path": "lib/features/domain/usecases/call/end_call_usecase.dart",
    "content": "import 'package:dartz/dartz.dart';\nimport 'package:equatable/equatable.dart';\n\nimport '../../../../core/error/failure.dart';\nimport '../../../../core/usecase/base_use_case.dart';\nimport '../../repository/base_call_repository.dart';\n\nclass EndCallUseCase extends BaseUseCase<void, EndCallParameters> {\n  final BaseCallRepository _baseCallRepository;\n\n  EndCallUseCase(this._baseCallRepository);\n\n  @override\n  Future<Either<Failure, void>> call(EndCallParameters parameters) async {\n    return await _baseCallRepository.endCall(parameters);\n  }\n}\n\nclass EndCallParameters extends Equatable {\n  final String callerId;\n  final String receiverId;\n\n  const EndCallParameters({\n    required this.callerId,\n    required this.receiverId,\n  });\n\n  @override\n  List<Object?> get props => [\n        callerId,\n        receiverId,\n      ];\n}\n"
  },
  {
    "path": "lib/features/domain/usecases/call/make_call_usecase.dart",
    "content": "import 'package:dartz/dartz.dart';\nimport 'package:equatable/equatable.dart';\nimport 'package:flutter/cupertino.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/entities/call.dart';\n\nimport '../../../../core/error/failure.dart';\nimport '../../../../core/usecase/base_use_case.dart';\nimport '../../repository/base_call_repository.dart';\n\nclass MakeCallUseCase extends BaseUseCase<Call, MakeCallParameters> {\n  final BaseCallRepository _baseCallRepository;\n\n  MakeCallUseCase(this._baseCallRepository);\n\n  @override\n  Future<Either<Failure, Call>> call(MakeCallParameters parameters) async {\n    return await _baseCallRepository.makeCall(parameters);\n  }\n}\n\nclass MakeCallParameters extends Equatable {\n  final String receiverId;\n  final String receiverName;\n  final String receiverPic;\n\n  const MakeCallParameters({\n    required this.receiverId,\n    required this.receiverName,\n    required this.receiverPic,\n  });\n\n  @override\n  List<Object?> get props => [\n        receiverId,\n        receiverName,\n        receiverPic,\n      ];\n}\n"
  },
  {
    "path": "lib/features/domain/usecases/chat/get_chat_messages_usecase.dart",
    "content": "import 'package:dartz/dartz.dart';\nimport 'package:equatable/equatable.dart';\n\nimport '../../../../core/error/failure.dart';\nimport '../../../../core/usecase/base_use_case.dart';\nimport '../../entities/message.dart';\nimport '../../repository/base_chat_repository.dart';\n/*\nclass GetChatMessagesUseCase extends StreamBaseUseCase<List<Message>, NoParameters>{\n  final BaseChatRepository _baseChatRepository;\n\n  GetChatMessagesUseCase(this._baseChatRepository);\n  @override\n  Stream<Either<Failure, List<Message>>> call(NoParameters parameters) {\n    return _baseChatRepository.getChatMessages();\n  }\n}\n\n */\n\nclass GetChatMessagesUseCase extends StreamBaseUseCase<List<Message>, GetChatMessagesParameters>{\n  final BaseChatRepository _baseChatRepository;\n\n  GetChatMessagesUseCase(this._baseChatRepository);\n\n  @override\n  Stream<List<Message>> call(GetChatMessagesParameters parameters) {\n    return _baseChatRepository.getChatMessages(parameters);\n  }\n\n}\n\nclass GetChatMessagesParameters extends Equatable {\n\n  final String receiverId;\n\n  const GetChatMessagesParameters(\n      {required this.receiverId,});\n\n  @override\n  List<Object?> get props => [\n    receiverId,\n  ];\n}"
  },
  {
    "path": "lib/features/domain/usecases/chat/get_contacts_chat_usecase.dart",
    "content": "import 'package:dartz/dartz.dart';\n\nimport '../../../../core/error/failure.dart';\nimport '../../../../core/usecase/base_use_case.dart';\nimport '../../entities/contact_chat.dart';\nimport '../../repository/base_chat_repository.dart';\n\nclass GetContactsChatUseCase extends StreamBaseUseCase<List<ContactChat>,Map<String,dynamic> >{\n  final BaseChatRepository _baseChatRepository;\n\n  GetContactsChatUseCase(this._baseChatRepository);\n  @override\n  Stream<List<ContactChat>> call(Map<String,dynamic>  parameters) {\n    return _baseChatRepository.getContactsChat(parameters);\n  }\n}"
  },
  {
    "path": "lib/features/domain/usecases/chat/get_num_of_message_not_seen_usecase.dart",
    "content": "\nimport '../../../../core/usecase/base_use_case.dart';\nimport '../../repository/base_chat_repository.dart';\n\nclass GetNumberOfMessageNotSeenUseCase extends StreamBaseUseCase<int,String>{\n  final BaseChatRepository _baseChatRepository;\n\n  GetNumberOfMessageNotSeenUseCase(this._baseChatRepository);\n  @override\n  Stream<int> call(String parameters) {\n    return _baseChatRepository.getNumOfMessageNotSeen(parameters);\n  }\n}"
  },
  {
    "path": "lib/features/domain/usecases/chat/send_file_message_usecase.dart",
    "content": "import 'dart:io';\n\nimport 'package:dartz/dartz.dart';\nimport 'package:equatable/equatable.dart';\nimport 'package:whatsapp_flutter_clone/core/enums/messge_type.dart';\nimport 'package:whatsapp_flutter_clone/core/error/failure.dart';\nimport 'package:whatsapp_flutter_clone/core/shared/message_replay.dart';\nimport 'package:whatsapp_flutter_clone/core/usecase/base_use_case.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/repository/base_chat_repository.dart';\n\nclass SendFileMessageUseCase extends BaseUseCase<void, FileMessageParameters> {\n  final BaseChatRepository _baseChatRepository;\n\n  SendFileMessageUseCase(this._baseChatRepository);\n\n  @override\n  Future<Either<Failure, void>> call(FileMessageParameters parameters) async {\n    return await _baseChatRepository.sendFileMessage(parameters);\n  }\n}\n\nclass FileMessageParameters extends Equatable {\n  final String receiverId;\n  final MessageType messageType;\n  final File file;\n  final MessageReplay? messageReplay;\n\n  const FileMessageParameters({\n    required this.receiverId,\n    required this.messageType,\n    required this.file,\n    this.messageReplay,\n  });\n\n  @override\n  List<Object?> get props => [\n        receiverId,\n        messageType,\n        file,\n    messageReplay,\n      ];\n}\n"
  },
  {
    "path": "lib/features/domain/usecases/chat/send_gif_message_usecase.dart",
    "content": "import 'package:dartz/dartz.dart';\nimport 'package:equatable/equatable.dart';\nimport 'package:whatsapp_flutter_clone/core/error/failure.dart';\nimport 'package:whatsapp_flutter_clone/core/shared/message_replay.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/repository/base_chat_repository.dart';\n\nimport '../../../../core/usecase/base_use_case.dart';\n\nclass SendGifMessageUseCase extends BaseUseCase<void, GifMessageParameters> {\n  final BaseChatRepository _baseChatRepository;\n\n  SendGifMessageUseCase(this._baseChatRepository);\n\n  @override\n  Future<Either<Failure, void>> call(GifMessageParameters parameters) async {\n    return await _baseChatRepository.sendGifMessage(parameters);\n  }\n}\n\nclass GifMessageParameters extends Equatable {\n  final String receiverId;\n  final String gifUrl;\n  final MessageReplay? messageReplay;\n\n  const GifMessageParameters({\n    required this.receiverId,\n    required this.gifUrl,\n    this.messageReplay,\n  });\n\n  @override\n  List<Object?> get props => [\n        receiverId,\n        gifUrl,\n    messageReplay,\n      ];\n}\n"
  },
  {
    "path": "lib/features/domain/usecases/chat/send_text_message_usecase.dart",
    "content": "import 'package:dartz/dartz.dart';\nimport 'package:equatable/equatable.dart';\nimport 'package:whatsapp_flutter_clone/core/shared/message_replay.dart';\n\nimport '../../../../core/error/failure.dart';\nimport '../../../../core/usecase/base_use_case.dart';\nimport '../../repository/base_chat_repository.dart';\n\nclass SendTextMessageUseCase extends BaseUseCase<void, TextMessageParameters> {\n  final BaseChatRepository _baseChatRepository;\n\n  SendTextMessageUseCase(this._baseChatRepository);\n\n  @override\n  Future<Either<Failure, void>> call(TextMessageParameters parameters) async {\n    return await _baseChatRepository.sendTextMessage(parameters);\n  }\n}\n\nclass TextMessageParameters extends Equatable {\n  final String text;\n  final String receiverId;\n  final MessageReplay? messageReplay;\n\n  //final UserModel senderUser;\n\n  const TextMessageParameters({\n    required this.receiverId,\n    required this.text,\n    this.messageReplay,\n  });\n\n  @override\n  List<Object?> get props => [\n        text,\n        receiverId,\n        messageReplay,\n        //senderUser,\n      ];\n}\n"
  },
  {
    "path": "lib/features/domain/usecases/chat/set_chat_message_seen_usecase.dart",
    "content": "import 'package:dartz/dartz.dart';\nimport 'package:equatable/equatable.dart';\nimport 'package:whatsapp_flutter_clone/core/error/failure.dart';\nimport 'package:whatsapp_flutter_clone/core/usecase/base_use_case.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/repository/base_chat_repository.dart';\n\nclass SetChatMessageSeenUseCase extends BaseUseCase<void,SetChatMessageSeenParameters>{\n  final BaseChatRepository _baseChatRepository;\n\n  SetChatMessageSeenUseCase(this._baseChatRepository);\n  @override\n  Future<Either<Failure, void>> call(SetChatMessageSeenParameters parameters)async {\n    return await _baseChatRepository.setChatMessageSeen(parameters);\n  }\n\n}\n\nclass SetChatMessageSeenParameters extends Equatable{\n  final String receiverId;\n  final String messageId;\n\n  const SetChatMessageSeenParameters({required this.receiverId, required this.messageId});\n\n  @override\n  List<Object?> get props => [receiverId,messageId,];\n}"
  },
  {
    "path": "lib/features/domain/usecases/select_contact/get_all_contacts_usecase.dart",
    "content": "import 'package:dartz/dartz.dart';\n\nimport '../../../../core/error/failure.dart';\nimport '../../../../core/usecase/base_use_case.dart';\nimport '../../repository/base_select_contact_repository.dart';\n\nclass GetAllContactsUseCase extends BaseUseCase<void, NoParameters>{\n  final BaseSelectContactRepository _baseSelectContactRepository;\n\n  GetAllContactsUseCase(this._baseSelectContactRepository);\n  @override\n  Future<Either<Failure, void>> call(NoParameters parameters)async {\n   return await _baseSelectContactRepository.getAllContacts();\n  }\n}"
  },
  {
    "path": "lib/features/domain/usecases/select_contact/get_contact_name_usecase.dart",
    "content": "import 'package:dartz/dartz.dart';\nimport 'package:equatable/equatable.dart';\nimport 'package:whatsapp_flutter_clone/core/error/failure.dart';\nimport 'package:whatsapp_flutter_clone/core/usecase/base_use_case.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/repository/base_select_contact_repository.dart';\n/*\nclass GetContactNameUseCase extends BaseUseCase<String, ContactNameParameters>{\n  final BaseSelectContactRepository _selectContactRepository;\n\n  GetContactNameUseCase(this._selectContactRepository);\n\n  @override\n  Future<Either<Failure, String>> call(ContactNameParameters parameters)async {\n   return await _selectContactRepository.getContactName(parameters);\n  }\n\n}\n\nclass ContactNameParameters extends Equatable{\n  final String uId;\n\n  const ContactNameParameters(this.uId);\n\n  @override\n  List<Object?> get props => [uId];\n}\n\n */"
  },
  {
    "path": "lib/features/domain/usecases/select_contact/get_contacts_not_on_whats_usecase.dart",
    "content": "import 'package:dartz/dartz.dart';\nimport 'package:flutter_contacts/contact.dart';\nimport 'package:whatsapp_flutter_clone/core/error/failure.dart';\nimport 'package:whatsapp_flutter_clone/core/usecase/base_use_case.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/repository/base_select_contact_repository.dart';\n\nclass GetContactsNotOnWhatsUseCase extends BaseUseCase<List<Contact>, NoParameters>{\n  final BaseSelectContactRepository _baseSelectContactRepository;\n\n  GetContactsNotOnWhatsUseCase(this._baseSelectContactRepository);\n  @override\n  Future<Either<Failure, List<Contact>>> call(NoParameters parameters) async{\n    return await _baseSelectContactRepository.getContactsNotOnWhatsApp();\n  }\n\n}"
  },
  {
    "path": "lib/features/domain/usecases/select_contact/get_contacts_on_whats_usecase.dart",
    "content": "import 'package:dartz/dartz.dart';\n\nimport '../../../../core/error/failure.dart';\nimport '../../../../core/usecase/base_use_case.dart';\nimport '../../repository/base_select_contact_repository.dart';\n\nclass GetContactsOnWhatsUseCase extends BaseUseCase<Map<String,dynamic>, NoParameters>{\n  final BaseSelectContactRepository _baseSelectContactRepository;\n\n  GetContactsOnWhatsUseCase(this._baseSelectContactRepository);\n  @override\n  Future<Either<Failure, Map<String,dynamic>>> call(NoParameters parameters)async {\n   return await _baseSelectContactRepository.getContactsOnWhatsApp();\n  }\n\n}"
  },
  {
    "path": "lib/features/presentation/components/contact_profile_pic_dialog.dart",
    "content": "import 'package:cached_network_image/cached_network_image.dart';\nimport 'package:flutter/material.dart';\n\nimport '/core/extensions/extensions.dart';\nimport '../../../core/utils/constants/assets_manager.dart';\nimport '../../domain/entities/contact_chat.dart';\n\nFuture<void> showContactProfilePicDialog(\n  BuildContext context, {\n  required ContactChat contact,\n}) {\n  return showDialog(\n    context: context,\n    builder: (context) {\n      return AlertDialog(\n        scrollable: true,\n        contentPadding: EdgeInsets.zero,\n        alignment: Alignment.topCenter,\n        content: Stack(\n          children: [\n            Hero(\n              tag: contact.contactId,\n              child: CachedNetworkImage(\n                width: 400,\n                height: 300,\n                imageUrl: contact.profilePic,\n                placeholder: (context, url) => Stack(\n                  children: [\n                    Image.asset(AppImage.genericProfileImage),\n                    const Align(\n                      alignment: Alignment.center,\n                      child: CircularProgressIndicator(),\n                    )\n                  ],\n                ),\n                errorWidget: (context, url, error) => Image.asset(\n                  AppImage.genericProfileImage,\n                ),\n                //height: 180.0,\n                fit: BoxFit.cover,\n              ),\n            ),\n            Positioned(\n              top: 0,\n              right: 0,\n              left: 0,\n              child: Container(\n                padding: const EdgeInsets.symmetric(\n                  vertical: 8,\n                  horizontal: 8,\n                ),\n                color: Colors.black26,\n                child: Text(\n                  contact.name,\n                  style: const TextStyle(\n                    color: Colors.white,\n                    fontSize: 20,\n                  ),\n                ),\n              ),\n            )\n          ],\n        ),\n        actionsAlignment: MainAxisAlignment.spaceBetween,\n        actionsPadding: const EdgeInsets.symmetric(vertical: 5, horizontal: 5),\n        actions: [\n          IconButton(\n            onPressed: () {},\n            icon: Icon(\n              Icons.message,\n              color: context.colorScheme.secondary,\n              size: 25,\n            ),\n          ),\n          IconButton(\n            onPressed: () {},\n            icon: Icon(\n              Icons.call,\n              color: context.colorScheme.primary,\n              size: 25,\n            ),\n          ),\n          IconButton(\n            onPressed: () {},\n            icon: Icon(\n              Icons.videocam,\n              color: context.colorScheme.primary,\n              size: 25,\n            ),\n          ),\n          IconButton(\n            onPressed: () {},\n            icon: Icon(\n              Icons.info_outline_rounded,\n              color: context.colorScheme.primary,\n              size: 25,\n            ),\n          ),\n        ],\n      );\n    },\n  );\n}\n"
  },
  {
    "path": "lib/features/presentation/components/custom_list_tile.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '/core/extensions/extensions.dart';\nimport '../../../core/utils/constants/assets_manager.dart';\n\nclass CustomListTile extends StatelessWidget {\n  final Widget? leading;\n  final String title;\n  final String? subTitle;\n  final String? time;\n  final Widget? titleButton;\n  final int numOfMessageNotSeen;\n  final VoidCallback onTap;\n  final VoidCallback? onLeadingTap;\n\n  const CustomListTile({\n    super.key,\n    this.leading,\n    required this.title,\n    this.subTitle,\n    this.time,\n    this.numOfMessageNotSeen = 0,\n    this.titleButton,\n    required this.onTap,\n    this.onLeadingTap,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return ListTile(\n      onTap: onTap,\n      leading: leading ??\n          InkWell(\n            onTap: onLeadingTap,\n            child: CircleAvatar(\n              radius: 20,\n              backgroundColor: Colors.white,\n              child: Image.asset(AppImage.genericProfileImage),\n            ),\n          ),\n      title: Row(\n        children: [\n          Expanded(\n            child: Text(\n              title,\n              //style: context.headlineSmall,\n              style: context.headlineMedium,\n              overflow: TextOverflow.ellipsis,\n              maxLines: 1,\n            ),\n          ),\n          if (time != null)\n            Text(\n              time!,\n              style: numOfMessageNotSeen>0\n                  ? context.labelLarge!.copyWith(color: context.colorScheme.onPrimaryContainer)\n                  : context.bodyMedium,\n            ),\n          if (titleButton != null)\n            SizedBox(\n              height: 40,\n              child: titleButton!,\n            ),\n        ],\n      ),\n      subtitle: subTitle != null\n          ? Padding(\n              padding: const EdgeInsets.only(top: 3),\n              child: Row(\n                children: [\n                  //Icon(Icons.done_all,size: 20,),\n                  Expanded(\n                    child: Text(\n                      subTitle!,\n                      style: context.bodyMedium,\n                      overflow: TextOverflow.ellipsis,\n                      maxLines: 1,\n                    ),\n                  ),\n                  if ( numOfMessageNotSeen >0 )\n                    CircleAvatar(\n                      minRadius: 12,\n                      backgroundColor: context.colorScheme.onPrimaryContainer,\n                      child: Padding(\n                        padding: const EdgeInsets.all(4.0),\n                        child: Text(\n                          numOfMessageNotSeen.toString(),\n                          style: context.labelLarge,\n                        ),\n                      ),\n                    ),\n                ],\n              ),\n            )\n          : null,\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/components/custom_network_image.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../../../core/utils/constants/assets_manager.dart';\n\nclass CustomNetworkImage extends StatelessWidget {\n  final String imageUrl;\n\n  const CustomNetworkImage({super.key, required this.imageUrl});\n  @override\n  Widget build(BuildContext context) {\n    return ClipOval(\n      child: CircleAvatar(\n        backgroundColor: Colors.white,\n        backgroundImage: const AssetImage(AppImage.genericProfileImage),\n        child: Image.network(\n          imageUrl ?? '',\n          errorBuilder: ((context, error, stackTrace) => const SizedBox()),\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/components/custom_pop_up_menu_button.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../../../../../core/shared/pop_up_menu_item_model.dart';\n\nclass CustomPopUpMenuButton extends StatelessWidget {\n  final List<PopUpMenuItemModel> buttons;\n  const CustomPopUpMenuButton({\n  super.key, required this.buttons,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return PopupMenuButton(\n      icon: const Icon(Icons.more_vert),\n      onSelected: (value){\n        buttons[value].onTap();\n      },\n      itemBuilder: (context) {\n        return buttons.map((e) {\n          int index = buttons.indexOf(e);\n          return PopupMenuItem(\n            value: index,\n            child: FittedBox(\n              fit: BoxFit.fill,\n              child: Text(e.name),\n            ),\n          );\n        }).toList();\n      },\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/components/custom_text.dart",
    "content": "import 'package:flutter/material.dart';\n\nclass CustomText extends StatelessWidget {\n  final String text;\n  final TextTheme textStyle;\n  const CustomText({super.key, required this.text, required this.textStyle});\n\n  @override\n  Widget build(BuildContext context) {\n    ThemeData theme =Theme.of(context);\n    return Text(\n      text,\n      style: theme.textTheme.bodyMedium\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/components/default_button.dart",
    "content": "import 'package:flutter/material.dart';\n\nclass DefaultButton extends StatelessWidget {\n  final String text;\n  final VoidCallback onPress;\n  final double? width;\n\n  const DefaultButton({\n    super.key,\n    required this.text,\n    required this.onPress,\n    this.width,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return SizedBox(\n      width: width,\n      child: ElevatedButton(\n        onPressed: onPress,\n        child: Text(text),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/components/loader.dart",
    "content": "import 'package:flutter/material.dart';\n\nclass Loader extends StatelessWidget {\n  const Loader({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return const Center(\n      child: CircularProgressIndicator(),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/components/my_cached_net_image.dart",
    "content": "import 'package:cached_network_image/cached_network_image.dart';\nimport 'package:flutter/material.dart';\n\nimport '../../../core/utils/constants/assets_manager.dart';\n\nclass MyCachedNetImage extends StatelessWidget {\n  final String imageUrl;\n  final double radius;\n\n  const MyCachedNetImage({\n    super.key,\n    required this.imageUrl,\n    required this.radius,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return ClipOval(\n      child: CachedNetworkImage(\n        imageUrl: imageUrl,\n        width: radius * 2,\n        height: radius * 2,\n        placeholder: (context, url) => Stack(\n          children: [\n            Image.asset(AppImage.genericProfileImage),\n            const Align(\n              alignment: Alignment.center,\n              child: CircularProgressIndicator(),\n            )\n          ],\n        ),\n        errorWidget: (context, url, error) =>\n            Image.asset(AppImage.genericProfileImage),\n        //height: 180.0,\n        fit: BoxFit.cover,\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/components/update_profile_pic_model_bottom_sheet.dart",
    "content": "import 'dart:io';\n\nimport 'package:flutter/material.dart';\n\nimport '../controllers/auth_cubit/auth_cubit.dart';\nimport '/core/extensions/extensions.dart';\nimport '../../../core/functions/navigator.dart';\nimport '../../../core/shared/commen.dart';\nimport '../../../core/utils/constants/font_manager.dart';\nimport '../../../core/utils/constants/strings_manager.dart';\n\nFuture<void> showUpdateProfilePicModelBottomSheet(BuildContext context) {\n  return showModalBottomSheet(\n    context: context,\n    shape: const RoundedRectangleBorder(\n      borderRadius: BorderRadius.only(\n        topLeft: Radius.circular(10),\n        topRight: Radius.circular(10),\n      ),\n    ),\n    builder: (context) {\n      return Padding(\n        padding: const EdgeInsets.all(20.0),\n        child: Column(\n          mainAxisSize: MainAxisSize.min,\n          mainAxisAlignment: MainAxisAlignment.start,\n          crossAxisAlignment: CrossAxisAlignment.start,\n          children: [\n            Text(\n              AppStrings.profilePhoto,\n              style: context.titleLarge,\n            ),\n            Row(\n              children: [\n                PickProfileImage(\n                  onTap: () {},\n                  icon: Icons.photo_camera,\n                  name: AppStrings.camera,\n                ),\n                const SizedBox(width: 40),\n                PickProfileImage(\n                  onTap: () {\n                    selectImageFromGallery(context);\n                  },\n                  icon: Icons.photo,\n                  name: AppStrings.gallery,\n                ),\n              ],\n            )\n          ],\n        ),\n      );\n    },\n  );\n}\n\nvoid selectImageFromGallery(BuildContext context) async {\n  File? image = await pickImageFromGallery(context);\n  if(image != null){\n    cropImage(image.path).then((value) {\n      if(value != null) {\n        AuthCubit.get(context).updateProfilePic(value.path);\n      }\n      navigatePop(context);\n    });\n  }\n}\n\nclass PickProfileImage extends StatelessWidget {\n  final VoidCallback onTap;\n  final String name;\n  final IconData icon;\n\n  const PickProfileImage({\n  super.key,\n  required this.onTap,\n  required this.name,\n  required this.icon,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return Column(\n      mainAxisAlignment: MainAxisAlignment.center,\n      children: [\n        GestureDetector(\n          onTap: onTap,\n          child: Container(\n            padding: const EdgeInsets.all(12),\n            margin: const EdgeInsets.only(\n              bottom: 10,\n              top: 30,\n            ),\n            decoration: BoxDecoration(\n              shape: BoxShape.circle,\n              border: Border.all(\n                color: Colors.grey.shade200,\n              ),\n            ),\n            child: Icon(\n              icon,\n              color: context.colorScheme.secondary,\n            ),\n          ),\n        ),\n        Text(\n          name,\n          style: context.titleMedium!.copyWith(\n            fontWeight: FontWeightManager.regular,\n          ),\n        ),\n      ],\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/controllers/auth_cubit/auth_cubit.dart",
    "content": "import 'dart:io';\n\nimport 'package:country_picker/country_picker.dart';\nimport 'package:equatable/equatable.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\n\nimport '../../../../core/usecase/base_use_case.dart';\nimport '../../../domain/entities/user.dart';\nimport '../../../domain/usecases/auth/get_cached_local_current_uid_usecase.dart';\nimport '../../../domain/usecases/auth/get_current_user_usecase.dart';\nimport '../../../domain/usecases/auth/get_user_by_id_usecase.dart';\nimport '../../../domain/usecases/auth/save_userdata_to_firebase_usecase.dart';\nimport '../../../domain/usecases/auth/set_user_state_usecase.dart';\nimport '../../../domain/usecases/auth/signout_usecase.dart';\nimport '../../../domain/usecases/auth/sign_in_with_phone_number_usecase.dart';\nimport '../../../domain/usecases/auth/update_profile_pic_usecase.dart';\nimport '../../../domain/usecases/auth/verify_otp_usecase.dart';\n\npart 'auth_state.dart';\n\nclass AuthCubit extends Cubit<AuthState> {\n  final SignInWithPhoneNumberUseCase _signInWithPhoneNumberUseCase;\n  final VerifyOtpUseCase _verifyOtpUseCase;\n  final SaveUserDataToFirebaseUseCase _saveUserDataToFirebaseUseCase;\n  final SignOutUseCase _signOutUseCase;\n  final GetCachedLocalCurrentUidUseCase _cachedLocalCurrentUid;\n  final GetUserByIdUseCase _getUserByIdUseCase;\n  final SetUserStateUseCase _setUserStateUseCase;\n  final GetCurrentUserUseCase _getCurrentUserUseCase;\n  final UpdateProfilePicUseCase _updateProfilePicUseCase;\n\n  AuthCubit(\n    this._signInWithPhoneNumberUseCase,\n    this._verifyOtpUseCase,\n    this._saveUserDataToFirebaseUseCase,\n    this._signOutUseCase,\n    this._cachedLocalCurrentUid,\n    this._getUserByIdUseCase,\n    this._setUserStateUseCase,\n    this._getCurrentUserUseCase,\n    this._updateProfilePicUseCase,\n  ) : super(AuthInitial());\n\n  static AuthCubit get(context) => BlocProvider.of(context);\n\n  Country? country;\n\n  void setCountry(Country myCountry) {\n    country = myCountry;\n    emit(SetCountrySuccessState());\n  }\n\n  Future<void> signInWithPhoneNumber({required String phoneNumber}) async {\n    emit(SignInLoadingState());\n    final result = await _signInWithPhoneNumberUseCase(\n      SignInWithPhoneNumberParameters(\n        phoneNumber: phoneNumber,\n      ),\n    );\n    result.fold(\n      (l) {\n        emit(SignInErrorState());\n      },\n      (r) => emit(SignInSuccessState()),\n    );\n  }\n\n  Future<void> verifyOtp({required String smsOtpCode}) async {\n    emit(VerifyOtpLoadingState());\n    final result = await _verifyOtpUseCase(\n      VerifyOtpParameters(\n        smsOtpCode: smsOtpCode,\n      ),\n    );\n    result.fold(\n      (l) => emit(VerifyOtpErrorState()),\n      (r) => emit(VerifyOtpSuccessState()),\n    );\n  }\n\n  Future<void> saveUserDataToFirebase({\n    required String name,\n    File? profilePic,\n  }) async {\n    emit(SaveUserDataToFirebaseLoadingState());\n    final result = await _saveUserDataToFirebaseUseCase(UserDataParameters(\n      name: name,\n      profilePic: profilePic,\n    ));\n    result.fold(\n      (l) => emit(SaveUserDataToFirebaseErrorState()),\n      (r) => emit(SaveUserDataToFirebaseSuccessState()),\n    );\n  }\n\n  Future<void> signOut() async {\n    emit(SignOutLoadingState());\n    final result = await _signOutUseCase(const NoParameters());\n    result.fold(\n      (l) => emit(SignOutErrorState()),\n      (r) => emit(SignOutSuccessState()),\n    );\n  }\n\n  UserEntity? userEntity;\n\n  Future<void> getCurrentUser() async {\n    emit(GetCurrentUserLoadingState());\n    final result = await _getCurrentUserUseCase(const NoParameters());\n    result.fold(\n      (l) => emit(GetCurrentUserErrorState()),\n      (r) {\n        userEntity = r;\n        emit(GetCurrentUserSuccessState());\n      },\n    );\n  }\n\n  Future<void> getCachedCurrentUid() async {\n    final result = await _cachedLocalCurrentUid(const NoParameters());\n    result.fold(\n      (l) => emit(GetCurrentLocalErrorState()),\n      (r) => emit(GetCurrentLocalSuccessState(r)),\n    );\n  }\n\n  Stream<UserEntity> getUserById(String uId) {\n    return _getUserByIdUseCase(uId);\n  }\n\n  Future<void> setUserState(bool isOnline) async {\n    final result = await _setUserStateUseCase(isOnline);\n    result.fold(\n      (l) => emit(SetUserStateErrorState()),\n      (r) => emit(SetUserStateSuccessState()),\n    );\n  }\n\n  Future<void> updateProfilePic(String path) async {\n    emit(UpdateProfilePicLoadingState());\n    final result = await _updateProfilePicUseCase(path);\n    result.fold(\n      (l) => emit(UpdateProfilePicErrorState()),\n      (r) => emit(UpdateProfilePicSuccessState()),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/controllers/auth_cubit/auth_state.dart",
    "content": "part of 'auth_cubit.dart';\n\nabstract class AuthState extends Equatable {\n  const AuthState();\n}\n\nclass AuthInitial extends AuthState {\n  @override\n  List<Object> get props => [];\n}\n\nclass SetCountrySuccessState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n\n\nclass SignInLoadingState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass SignInSuccessState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass SignInErrorState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass VerifyOtpLoadingState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass VerifyOtpSuccessState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass VerifyOtpErrorState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass SaveUserDataToFirebaseLoadingState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass SaveUserDataToFirebaseSuccessState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass SaveUserDataToFirebaseErrorState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass SignOutLoadingState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass SignOutSuccessState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass SignOutErrorState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n\n\nclass GetCurrentLocalSuccessState extends AuthState{\n  final String uId;\n\n  const GetCurrentLocalSuccessState(this.uId);\n  @override\n  List<Object?> get props => [uId];\n}\n\nclass GetCurrentLocalErrorState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass SetUserStateErrorState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass SetUserStateSuccessState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n/////get current user\nclass GetCurrentUserLoadingState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass GetCurrentUserErrorState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass GetCurrentUserSuccessState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n//update profile pic\nclass UpdateProfilePicLoadingState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass UpdateProfilePicErrorState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass UpdateProfilePicSuccessState extends AuthState{\n  @override\n  List<Object?> get props => [];\n}"
  },
  {
    "path": "lib/features/presentation/controllers/bottom_chat_cubit/bottom_chat_cubit.dart",
    "content": "import 'package:equatable/equatable.dart';\nimport 'package:flutter/cupertino.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\n\npart 'bottom_chat_state.dart';\n\nclass BottomChatCubit extends Cubit<BottomChatState> {\n  BottomChatCubit() : super(BottomChatInitial());\n\n  static BottomChatCubit get(context) => BlocProvider.of(context);\n\n  bool isShownSendButton = false;\n  bool isShowEmoji = false;\n  bool isRecording = false;\n\n  void showEmojiContainer() {\n    isShowEmoji = true;\n    emit(ShowEmojiContainerState());\n  }\n\n  void hideEmojiContainer() {\n    isShowEmoji = false;\n    emit(HideEmojiContainerState());\n  }\n\n  void toggleEmojiKeyboard(FocusNode focusNode) {\n    if (isShowEmoji) {\n      hideEmojiContainer();\n      focusNode.requestFocus();\n    } else {\n      focusNode.unfocus();\n      showEmojiContainer();\n    }\n  }\n\n  void onTextFieldValChanged(String val) {\n    if (val.trim().isNotEmpty) {\n      isShownSendButton = true;\n      emit(IsShowSendButtonTrueState());\n    } else {\n      isShownSendButton = false;\n      emit(IsShowSendButtonFalseState());\n    }\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/controllers/bottom_chat_cubit/bottom_chat_state.dart",
    "content": "part of 'bottom_chat_cubit.dart';\n\nabstract class BottomChatState extends Equatable {\n  const BottomChatState();\n}\n\nclass BottomChatInitial extends BottomChatState {\n  @override\n  List<Object> get props => [];\n}\n\nclass ShowEmojiContainerState extends BottomChatState {\n  @override\n  List<Object> get props => [];\n}\n\nclass HideEmojiContainerState extends BottomChatState {\n  @override\n  List<Object> get props => [];\n}\n\nclass ToggleEmojiKeyboardState extends BottomChatState {\n  @override\n  List<Object> get props => [];\n}\n\n\nclass IsShowSendButtonFalseState extends BottomChatState {\n  @override\n  List<Object> get props => [];\n}\n\nclass IsShowSendButtonTrueState extends BottomChatState {\n  @override\n  List<Object> get props => [];\n}"
  },
  {
    "path": "lib/features/presentation/controllers/call_cubit/call_cubit.dart",
    "content": "import 'package:cloud_firestore/cloud_firestore.dart';\nimport 'package:equatable/equatable.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/entities/call.dart';\n\nimport '../../../../core/usecase/base_use_case.dart';\nimport '../../../domain/usecases/call/call_stream_usecase.dart';\nimport '../../../domain/usecases/call/end_call_usecase.dart';\nimport '../../../domain/usecases/call/make_call_usecase.dart';\n\npart 'call_state.dart';\n\nclass CallCubit extends Cubit<CallState> {\n  final CallStreamUseCase _callStreamUseCase;\n  final EndCallUseCase _endCallUseCase;\n  final MakeCallUseCase _makeCallUseCase;\n\n  CallCubit(\n    this._callStreamUseCase,\n    this._endCallUseCase,\n    this._makeCallUseCase,\n  ) : super(CallInitial());\n\n  static CallCubit get(context) => BlocProvider.of(context);\n\n  Stream<DocumentSnapshot> callStream() =>\n      _callStreamUseCase(const NoParameters());\n\n  Future<void> makeCall({\n    required String receiverId,\n    required String receiverName,\n    required String receiverPic,\n  }) async {\n    emit(MakeCallLoadingState());\n    final result = await _makeCallUseCase(\n      MakeCallParameters(\n        receiverId: receiverId,\n        receiverName: receiverName,\n        receiverPic: receiverPic,\n      ),\n    );\n    result.fold(\n      (l) => emit(MakeCallErrorState()),\n      (r) => emit(MakeCallSuccessState(call: r)),\n    );\n  }\n\n  Future<void> endCall({\n    required String receiverId,\n    required String callerId,\n  }) async {\n    emit(EndCallLoadingState());\n    final result = await _endCallUseCase(\n      EndCallParameters(\n        receiverId: receiverId,\n        callerId: callerId,\n      ),\n    );\n    result.fold(\n      (l) => emit(EndCallErrorState()),\n      (r) => emit(EndCallSuccessState()),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/controllers/call_cubit/call_state.dart",
    "content": "part of 'call_cubit.dart';\n\nabstract class CallState extends Equatable {\n  const CallState();\n}\n\nclass CallInitial extends CallState {\n  @override\n  List<Object> get props => [];\n}\n\nclass MakeCallLoadingState extends CallState {\n  @override\n  List<Object> get props => [];\n}\n\nclass MakeCallSuccessState extends CallState {\n  final Call call;\n\n  const MakeCallSuccessState({required this.call});\n  @override\n  List<Object> get props => [];\n}\n\nclass MakeCallErrorState extends CallState {\n  @override\n  List<Object> get props => [];\n}\n\nclass EndCallLoadingState extends CallState {\n  @override\n  List<Object> get props => [];\n}\n\nclass EndCallSuccessState extends CallState {\n  @override\n  List<Object> get props => [];\n}\n\nclass EndCallErrorState extends CallState {\n  @override\n  List<Object> get props => [];\n}"
  },
  {
    "path": "lib/features/presentation/controllers/chat_background_cubit/chat_background_cubit.dart",
    "content": "import 'package:equatable/equatable.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\nimport 'package:whatsapp_flutter_clone/core/utils/constants/assets_manager.dart';\n\npart 'chat_background_state.dart';\n\nclass ChatBackgroundCubit extends Cubit<ChatBackgroundState> {\n  ChatBackgroundCubit() : super(ChatBackgroundInitial());\n  static ChatBackgroundCubit get(context) => BlocProvider.of(context);\n\n  String backgroundImage =AppImage.chatBackground;\n\n  void changeBackground(String image){\n    emit(ChangeBackgroundLoadingState());\n    backgroundImage= image;\n    emit(ChangeBackgroundSuccessState());\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/controllers/chat_background_cubit/chat_background_state.dart",
    "content": "part of 'chat_background_cubit.dart';\n\nabstract class ChatBackgroundState extends Equatable {\n  const ChatBackgroundState();\n}\n\nclass ChatBackgroundInitial extends ChatBackgroundState {\n  @override\n  List<Object> get props => [];\n}\n\nclass ChangeBackgroundLoadingState extends ChatBackgroundState {\n  @override\n  List<Object> get props => [];\n}\n\nclass ChangeBackgroundSuccessState extends ChatBackgroundState {\n  @override\n  List<Object> get props => [];\n}\n"
  },
  {
    "path": "lib/features/presentation/controllers/chat_cubit/chat_cubit.dart",
    "content": "import 'dart:io';\n\nimport 'package:equatable/equatable.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\n\nimport '../../../../core/enums/messge_type.dart';\nimport '../../../../core/shared/message_replay.dart';\nimport '../../../domain/entities/contact_chat.dart';\nimport '../../../domain/entities/message.dart';\nimport '../../../domain/usecases/chat/get_chat_messages_usecase.dart';\nimport '../../../domain/usecases/chat/get_contacts_chat_usecase.dart';\nimport '../../../domain/usecases/chat/get_num_of_message_not_seen_usecase.dart';\nimport '../../../domain/usecases/chat/send_file_message_usecase.dart';\nimport '../../../domain/usecases/chat/send_gif_message_usecase.dart';\nimport '../../../domain/usecases/chat/send_text_message_usecase.dart';\nimport '../../../domain/usecases/chat/set_chat_message_seen_usecase.dart';\n\npart 'chat_state.dart';\n\nclass ChatCubit extends Cubit<ChatState> {\n  final SendTextMessageUseCase _sendTextMessageUseCase;\n  final GetContactsChatUseCase _getContactsChatUseCase;\n  final GetChatMessagesUseCase _getChatMessagesUseCase;\n  final SetChatMessageSeenUseCase _setChatMessageSeenUseCase;\n  final SendGifMessageUseCase _sendGifMessageUseCase;\n  final SendFileMessageUseCase _sendFileMessageUseCase;\n  final GetNumberOfMessageNotSeenUseCase _getNumberOfMessageNotSeenUseCase;\n\n  // final GetContactNameUseCase _getContactNameUseCase;\n\n  ChatCubit(\n    this._sendTextMessageUseCase,\n    this._getContactsChatUseCase,\n    this._getChatMessagesUseCase,\n    this._setChatMessageSeenUseCase,\n    this._sendGifMessageUseCase,\n    this._sendFileMessageUseCase,\n    this._getNumberOfMessageNotSeenUseCase,\n  ) : super(ChatInitial());\n\n  static ChatCubit get(context) => BlocProvider.of(context);\n\n  MessageReplay? messageReplay;\n\n  void onMessageSwipe({\n    required String message,\n    required bool isMe,\n    required MessageType messageType,\n    required String repliedTo,\n  }) {\n    emit(MessageSwipeLoadingState());\n    messageReplay = MessageReplay(\n      message: message,\n      isMe: isMe,\n      messageType: messageType,\n      repliedTo: repliedTo,\n    );\n    emit(MessageSwipeState());\n  }\n\n  void cancelReplay() {\n    messageReplay = null;\n    emit(CancelReplayState());\n  }\n\n  //////////////////////////////////////////////////////////////\n  ///sending messages\n  Future<void> sendTextMessage({\n    required String text,\n    required String receiverId,\n  }) async {\n    emit(SendMessageLoadingState());\n    final result = await _sendTextMessageUseCase(\n      TextMessageParameters(\n        text: text,\n        receiverId: receiverId,\n        messageReplay: messageReplay,\n      ),\n    );\n    messageReplay = null;\n    result.fold(\n      (l) => emit(SendMessageErrorState()),\n      (r) => emit(SendMessageSuccessState()),\n    );\n  }\n\n  Future<void> sendGifMessage({\n    required String receiverId,\n    required String gifUrl,\n  }) async {\n    final result = await _sendGifMessageUseCase(\n      GifMessageParameters(\n        receiverId: receiverId,\n        gifUrl: gifUrl,\n        messageReplay: messageReplay,\n      ),\n    );\n    messageReplay = null;\n    result.fold(\n      (l) => emit(SendMessageErrorState()),\n      (r) => emit(SendMessageSuccessState()),\n    );\n  }\n\n  Future<void> sendFileMessage({\n    required String receiverId,\n    required MessageType messageType,\n    required File file,\n  }) async {\n    final result = await _sendFileMessageUseCase(\n      FileMessageParameters(\n        receiverId: receiverId,\n        messageType: messageType,\n        file: file,\n        messageReplay: messageReplay,\n      ),\n    );\n    messageReplay = null;\n    result.fold(\n      (l) => emit(SendMessageErrorState()),\n      (r) => emit(SendMessageSuccessState()),\n    );\n  }\n\n  //////////////////////////////////////////////////////////////\n\n  ///get messages\n  Stream<List<ContactChat>> getContactsChat(Map<String, dynamic> map) {\n    return _getContactsChatUseCase(map);\n  }\n\n  Stream<List<Message>> getChatMessages(String receiverId) {\n    return _getChatMessagesUseCase(\n      GetChatMessagesParameters(\n        receiverId: receiverId,\n      ),\n    );\n  }\n\n  //////////////////////////////////////////////////////////////\n\n  ///set message seen\n  Future<void> setChatMessageSeen({\n    required String receiverId,\n    required String messageId,\n  }) async {\n    final result = await _setChatMessageSeenUseCase(\n      SetChatMessageSeenParameters(\n        receiverId: receiverId,\n        messageId: messageId,\n      ),\n    );\n    result.fold(\n      (l) => null,\n      (r) => null,\n    );\n  }\n\n  ///get num of messages not seen\n  Stream<int> numOfMessageNotSeen(String senderId) =>\n      _getNumberOfMessageNotSeenUseCase(senderId);\n}\n"
  },
  {
    "path": "lib/features/presentation/controllers/chat_cubit/chat_state.dart",
    "content": "part of 'chat_cubit.dart';\n\nabstract class ChatState extends Equatable {\n  const ChatState();\n}\n\nclass ChatInitial extends ChatState {\n  @override\n  List<Object> get props => [];\n}\n\nclass SendMessageLoadingState extends ChatState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass SendMessageSuccessState extends ChatState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass SendMessageErrorState extends ChatState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass GetContactNameErrorState extends ChatState{\n  @override\n  List<Object?> get props => [];\n}\nclass GetContactNameSuccessState extends ChatState{\n  @override\n  List<Object?> get props => [];\n}\n\n//message swipe\nclass MessageSwipeLoadingState extends ChatState{\n  @override\n  List<Object?> get props => [];\n}\nclass MessageSwipeState extends ChatState{\n  @override\n  List<Object?> get props => [];\n}\n\nclass CancelReplayState extends ChatState{\n  @override\n  List<Object?> get props => [];\n}"
  },
  {
    "path": "lib/features/presentation/controllers/select_contact_cubit/select_contact_cubit.dart",
    "content": "import 'package:equatable/equatable.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\nimport 'package:flutter_contacts/contact.dart';\n\nimport '../../../../core/usecase/base_use_case.dart';\nimport '../../../domain/usecases/select_contact/get_all_contacts_usecase.dart';\nimport '../../../domain/usecases/select_contact/get_contacts_not_on_whats_usecase.dart';\nimport '../../../domain/usecases/select_contact/get_contacts_on_whats_usecase.dart';\n\npart 'select_contact_state.dart';\n\nclass SelectContactCubit extends Cubit<SelectContactState> {\n  final GetAllContactsUseCase _getAllContactsUseCase;\n  final GetContactsOnWhatsUseCase _getContactsOnWhatsUseCase;\n  final GetContactsNotOnWhatsUseCase _getContactsNotOnWhatsUseCase;\n\n  SelectContactCubit(\n    this._getAllContactsUseCase,\n    this._getContactsOnWhatsUseCase,\n    this._getContactsNotOnWhatsUseCase,\n  ) : super(SelectContactInitial());\n\n  static SelectContactCubit get(context) => BlocProvider.of(context);\n\n  Future<void> getAllContacts() async {\n    emit(GetAllContactsLoadingState());\n    final result = await _getAllContactsUseCase(const NoParameters());\n    result.fold(\n      (l) => emit(GetAllContactsErrorState()),\n      (r) => emit(GetAllContactsSuccessState()),\n    );\n  }\n\n///////////\n  List<Contact> contactNotOnWhats=[];\n\n  Future<void> getContactsNotOnWhatsApp() async {\n    emit(GetContactsNotOnWhatsLoadingState());\n    contactNotOnWhats = [];\n    final result = await _getContactsNotOnWhatsUseCase(const NoParameters());\n    result.fold(\n      (l) => emit(GetContactsNotOnWhatsErrorState()),\n      (r) {\n        for (var element in r) {\n          contactNotOnWhats.add(element);\n        }\n        emit(GetContactsNotOnWhatsSuccessState());\n      } ,\n    );\n  }\n\n////////////\n  Map<String,dynamic> contactOnWhats={};\n  Future<void> getContactsOnWhatsApp() async {\n    emit(GetContactsOnWhatsLoadingState());\n    //contactOnWhats = {};\n    final result = await _getContactsOnWhatsUseCase(const NoParameters());\n    result.fold(\n      (l) => emit(GetContactsOnWhatsErrorState()),\n      (r) {\n        contactOnWhats.addAll(r);\n        emit(GetContactsOnWhatsSuccessState());\n      },\n    );\n  }\n\n}\n"
  },
  {
    "path": "lib/features/presentation/controllers/select_contact_cubit/select_contact_state.dart",
    "content": "part of 'select_contact_cubit.dart';\n\nabstract class SelectContactState extends Equatable {\n  const SelectContactState();\n}\n\nclass SelectContactInitial extends SelectContactState {\n  @override\n  List<Object> get props => [];\n}\n///get all contacts\nclass GetAllContactsLoadingState extends SelectContactState {\n  @override\n  List<Object> get props => [];\n}\n\nclass GetAllContactsSuccessState extends SelectContactState {\n  @override\n  List<Object> get props => [];\n}\n\nclass GetAllContactsErrorState extends SelectContactState {\n  @override\n  List<Object> get props => [];\n}\n///get contacts not on whats\nclass GetContactsNotOnWhatsLoadingState extends SelectContactState {\n  @override\n  List<Object> get props => [];\n}\n\nclass GetContactsNotOnWhatsSuccessState extends SelectContactState {\n  @override\n  List<Object> get props => [];\n}\n\nclass GetContactsNotOnWhatsErrorState extends SelectContactState {\n  @override\n  List<Object> get props => [];\n}\n/// get contacts on whatsApp\nclass GetContactsOnWhatsLoadingState extends SelectContactState {\n  @override\n  List<Object> get props => [];\n}\n\nclass GetContactsOnWhatsSuccessState extends SelectContactState {\n  @override\n  List<Object> get props => [];\n}\n\nclass GetContactsOnWhatsErrorState extends SelectContactState {\n  @override\n  List<Object> get props => [];\n}"
  },
  {
    "path": "lib/features/presentation/views/calls/call_pickup_screen.dart",
    "content": "import 'package:cloud_firestore/cloud_firestore.dart';\nimport 'package:flutter/material.dart';\nimport 'package:flutter/services.dart';\nimport 'package:whatsapp_flutter_clone/core/functions/navigator.dart';\nimport 'package:whatsapp_flutter_clone/core/utils/routes/routes_manager.dart';\nimport 'package:whatsapp_flutter_clone/features/data/models/call_model.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/entities/call.dart';\nimport 'package:whatsapp_flutter_clone/features/presentation/controllers/call_cubit/call_cubit.dart';\n\nclass CallPickupScreen extends StatelessWidget {\n  final Widget scaffold;\n\n  const CallPickupScreen({super.key, required this.scaffold});\n\n  @override\n  Widget build(BuildContext context) {\n    SystemChrome.setSystemUIOverlayStyle(\n      const SystemUiOverlayStyle(\n        statusBarColor: Colors.white,\n        statusBarIconBrightness: Brightness.dark,\n      ),\n    );\n    return StreamBuilder<DocumentSnapshot>(\n      stream: CallCubit.get(context).callStream(),\n      builder: (context, snapshot) {\n        if (snapshot.hasData && snapshot.data!.data() != null) {\n          Call call =\n              CallModel.fromMap(snapshot.data!.data()! as Map<String, dynamic>);\n          if (!call.hasDialled) {\n            return Scaffold(\n              body: Container(\n                alignment: Alignment.center,\n                padding: EdgeInsets.symmetric(vertical: 20),\n                child: Column(\n                  mainAxisAlignment: MainAxisAlignment.center,\n                  children: [\n                    const Text(\n                      'Incoming call...',\n                      style: TextStyle(\n                        fontSize: 20,\n                        color: Colors.black,\n                      ),\n                    ),\n                    const SizedBox(\n                      height: 10,\n                    ),\n                    CircleAvatar(\n                      radius: 60,\n                      backgroundImage: NetworkImage(call.callerPic),\n                    ),\n                    const SizedBox(\n                      height: 50,\n                    ),\n                    Text(\n                      call.callerName,\n                      style: const TextStyle(\n                        fontSize: 20,\n                        color: Colors.black,\n                        fontWeight: FontWeight.bold,\n                      ),\n                    ),\n                    const SizedBox(\n                      height: 75,\n                    ),\n                    Row(\n                      mainAxisAlignment: MainAxisAlignment.center,\n                      children: [\n                        IconButton(\n                          onPressed: () {},\n                          icon: const Icon(\n                            Icons.call_end,\n                            color: Colors.red,\n                            size: 40,\n                          ),\n                        ),\n                        const SizedBox(\n                          width: 50,\n                        ),\n                        IconButton(\n                          onPressed: () {\n                            navigateTo(\n                              context,\n                              Routes.callRoute,\n                              arguments: {\n                                'call': call,\n                                'channelId': call.callId,\n                              },\n                            );\n                          },\n                          icon: const Icon(\n                            Icons.call,\n                            color: Colors.green,\n                            size: 40,\n                          ),\n                        ),\n                      ],\n                    )\n                  ],\n                ),\n              ),\n            );\n          }\n        }\n        return scaffold;\n      },\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/calls/call_screen.dart",
    "content": "import 'package:agora_uikit/agora_uikit.dart';\nimport 'package:flutter/material.dart';\nimport 'package:whatsapp_flutter_clone/config/agora_config.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/entities/call.dart';\nimport 'package:whatsapp_flutter_clone/features/presentation/components/loader.dart';\n\nclass CallScreen extends StatefulWidget {\n  final String channelId;\n  final Call call;\n\n  const CallScreen({super.key, required this.channelId, required this.call});\n\n  @override\n  State<CallScreen> createState() => _CallScreenState();\n}\n\nclass _CallScreenState extends State<CallScreen> {\n  AgoraClient? client;\n  String baseUrl = '';\n\n  @override\n  void initState() {\n    super.initState();\n    client = AgoraClient(\n      agoraConnectionData: AgoraConnectionData(\n        appId: AgoraConfig.appId,\n        channelName: widget.channelId,\n        //tokenUrl: baseUrl,\n      ),\n    );\n    initAgora();\n  }\n\n  void initAgora()async{\n    await client!.initialize();\n  }\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      body: client ==null ? Loader(): SafeArea(child: Stack(\n        children: [\n          AgoraVideoViewer(client: client!),\n          AgoraVideoButtons(client: client!),\n        ],\n      )),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/calls/calls_page.dart",
    "content": "import 'package:flutter/material.dart';\n\nclass CallsPage extends StatelessWidget {\n  const CallsPage({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return const Center(\n      child: Text('calls'),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/camera/camera_screen.dart",
    "content": "import 'package:camera/camera.dart';\nimport 'package:flutter/material.dart';\n\nimport '../../../../core/functions/navigator.dart';\nimport '../../../../core/utils/routes/routes_manager.dart';\nimport '../../components/loader.dart';\nimport 'components/camera_appbar.dart';\nimport 'components/select_image_from_gallery_button.dart';\n\nlate List<CameraDescription> cameras;\n\nclass CameraScreen extends StatefulWidget {\n  final String receiverId;\n  const CameraScreen({super.key, required this.receiverId,});\n\n  @override\n  State<CameraScreen> createState() => _CameraScreenState();\n}\n\nclass _CameraScreenState extends State<CameraScreen> {\n  late CameraController _cameraController;\n  late Future<void> _cameraValue;\n  bool isFlashOn = false;\n  bool isCameraFront = true;\n  bool isRecording = false;\n\n  @override\n  void initState() {\n    super.initState();\n    _cameraController = CameraController(cameras[0], ResolutionPreset.high);\n    _cameraValue = _cameraController.initialize();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      backgroundColor: Colors.black,\n      appBar: CameraAppBar(\n        isFlashOn: isFlashOn,\n        onFlashPressed: toggleFlash,\n      ),\n      body: Column(\n        children: [\n          Expanded(\n            child: Stack(\n              children: [\n                FutureBuilder(\n                  future: _cameraValue,\n                  builder: (context, snapshot) {\n                    if (snapshot.connectionState == ConnectionState.done) {\n                      return SizedBox(\n                        width: double.infinity,\n                        child: CameraPreview(_cameraController),\n                      );\n                    } else {\n                      return const Loader();\n                    }\n                  },\n                ),\n                Align(\n                  alignment: Alignment.bottomCenter,\n                  child: Padding(\n                    padding: const EdgeInsets.symmetric(horizontal: 8),\n                    child: Row(\n                      mainAxisAlignment: MainAxisAlignment.spaceBetween,\n                      children: [\n                         SelectImageFromGalleryButton(receiverId: widget.receiverId),\n                        GestureDetector(\n                          onTap: () {\n                            if (!isRecording) takePhoto(context);\n                          },\n                          onLongPress: ()async {\n                            await _cameraController.startVideoRecording();\n                            setState(() {\n                              isRecording =true;\n                            });\n\n                          },\n                          onLongPressUp: () async{\n                            XFile videoPath = await _cameraController.stopVideoRecording();\n                            setState(() {\n                              isRecording = false;\n                            });\n                            if(!mounted) return;\n                            navigateTo(context, Routes.sendingVideoViewRoute, arguments: {\n                              'uId' : widget.receiverId,\n                              'path' : videoPath.path,\n                            },);\n                          },\n                          child: cameraIcon(),\n                        ),\n                        GestureDetector(\n                          onTap: toggleCameraFront,\n                          child: const CircleAvatar(\n                            radius: 30,\n                            backgroundColor: Colors.black38,\n                            child: Icon(\n                              Icons.flip_camera_ios,\n                              size: 30,\n                            ),\n                          ),\n                        ),\n                      ],\n                    ),\n                  ),\n                )\n              ],\n            ),\n          ),\n          const Padding(\n            padding: EdgeInsets.only(top: 8, bottom: 8),\n            child: Text(\n              'Hold for video, tap for photo',\n              style: TextStyle(fontSize: 16),\n            ),\n          ),\n        ],\n      ),\n    );\n  }\n\n  Icon cameraIcon() {\n    return isRecording\n        ? const Icon(\n            Icons.radio_button_on,\n            color: Colors.red,\n            size: 80,\n          )\n        : const Icon(\n            Icons.panorama_fish_eye,\n            size: 80,\n            color: Colors.white,\n          );\n  }\n\n  void toggleFlash() {\n    setState(() {\n      isFlashOn = !isFlashOn;\n    });\n    isFlashOn\n        ? _cameraController.setFlashMode(FlashMode.torch)\n        : _cameraController.setFlashMode(FlashMode.off);\n  }\n\n  void toggleCameraFront() {\n    setState(() {\n      isCameraFront = !isCameraFront;\n    });\n    int cameraPos = isCameraFront ? 0 : 1;\n    _cameraController =\n        CameraController(cameras[cameraPos], ResolutionPreset.high);\n    _cameraValue = _cameraController.initialize();\n  }\n\n  void takePhoto(BuildContext context) async {\n    XFile file = await _cameraController.takePicture();\n    if(!mounted) return;\n    navigateTo(context, Routes.sendingImageViewRoute, arguments: {\n      'path': file.path,\n      'uId' : widget.receiverId,\n    });\n  }\n\n\n\n  @override\n  void dispose() {\n    super.dispose();\n    _cameraController.dispose();\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/camera/components/camera_appbar.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter/services.dart';\n\nimport '../../../../../core/functions/navigator.dart';\n\nclass CameraAppBar extends StatelessWidget implements PreferredSizeWidget {\n  final VoidCallback onFlashPressed;\n  final bool isFlashOn;\n\n  const CameraAppBar({\n    super.key,\n    required this.onFlashPressed,\n    required this.isFlashOn,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return AppBar(\n      backgroundColor: Colors.black,\n      systemOverlayStyle: const SystemUiOverlayStyle(\n        statusBarColor: Colors.black,\n      ),\n      leading: IconButton(\n        // iconSize: 30,\n        onPressed: () {\n          navigatePop(context);\n        },\n        icon: const Icon(Icons.clear),\n      ),\n      actions: [\n        IconButton(\n          onPressed: onFlashPressed,\n          icon: Icon(\n            isFlashOn ? Icons.flash_on : Icons.flash_off,\n          ),\n        ),\n      ],\n    );\n  }\n\n  @override\n  Size get preferredSize => const Size.fromHeight(kToolbarHeight);\n}\n"
  },
  {
    "path": "lib/features/presentation/views/camera/components/image_view_top_row_icons.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../../../../../core/functions/navigator.dart';\n\nclass ImageViewTopRowIcons extends StatelessWidget {\n  final VoidCallback onCropButtonTaped;\n  const ImageViewTopRowIcons({\n  super.key, required this.onCropButtonTaped,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return Row(\n      children: [\n        IconButton(\n          splashRadius: 20,\n          iconSize: 30,\n          color: Colors.white,\n          onPressed: () {\n            navigatePop(context);\n          },\n          icon: const Icon(Icons.clear),\n        ),\n        const Spacer(),\n        IconButton(\n          splashRadius: 20,\n          color: Colors.white,\n          icon: const Icon(\n            Icons.crop_rotate,\n            size: 27,\n          ),\n          onPressed: onCropButtonTaped,\n        ),\n        IconButton(\n          splashRadius: 20,\n          color: Colors.white,\n          icon: const Icon(\n            Icons.emoji_emotions_outlined,\n            size: 27,\n          ),\n          onPressed: () {},\n        ),\n        IconButton(\n          splashRadius: 20,\n          color: Colors.white,\n          icon: const Icon(\n            Icons.title,\n            size: 27,\n          ),\n          onPressed: (){},\n        ),\n        IconButton(\n          splashRadius: 20,\n          color: Colors.white,\n          splashColor: Colors.black38,\n          icon: const Icon(\n            Icons.edit,\n            size: 27,\n          ),\n          onPressed: () {},\n        ),\n      ],\n    );\n  }\n}\n\n"
  },
  {
    "path": "lib/features/presentation/views/camera/components/select_image_from_gallery_button.dart",
    "content": "import 'dart:io';\n\nimport 'package:flutter/material.dart';\n\nimport '../../../../../core/functions/navigator.dart';\nimport '../../../../../core/shared/commen.dart';\nimport '../../../../../core/utils/routes/routes_manager.dart';\n\nclass SelectImageFromGalleryButton extends StatelessWidget {\n  final String receiverId;\n\n  const SelectImageFromGalleryButton({\n    super.key,\n    required this.receiverId,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return GestureDetector(\n      onTap: () {\n        selectImageFromGallery(context);\n      },\n      child: const CircleAvatar(\n        radius: 30,\n        backgroundColor: Colors.black38,\n        child: Icon(\n          Icons.photo,\n          size: 30,\n        ),\n      ),\n    );\n  }\n\n  void selectImageFromGallery(BuildContext context) async {\n    File? image = await pickImageFromGallery(context);\n    //if (!mounted) return;\n    if (image != null) {\n      // ignore: use_build_context_synchronously\n      navigateTo(\n        context,\n        Routes.sendingImageViewRoute,\n        arguments: {\n          'path': image.path,\n          'uId': receiverId,\n        },\n      );\n    }\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/camera/components/sending_image_video_bottom_roww_widget.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '/core/extensions/extensions.dart';\nimport '../../../../../core/utils/constants/font_manager.dart';\n\nclass SendingImageVideoBottomRowWidget extends StatelessWidget {\n  const SendingImageVideoBottomRowWidget({\n  super.key, required this.onSendButtonTaped,\n  });\n\n  final VoidCallback onSendButtonTaped;\n\n  @override\n  Widget build(BuildContext context) {\n    return Row(\n      children: [\n        Expanded(\n          child: Container(\n            margin: const EdgeInsets.all(8),\n            padding: const EdgeInsets.symmetric(horizontal: 10),\n            decoration: BoxDecoration(\n              color: const Color(0XFF1F2C34),\n              borderRadius: BorderRadius.circular(26),\n            ),\n            child: TextField(\n              // controller: _messageController,\n              cursorColor: context.colorScheme.secondary,\n              // focusNode: focusNode,\n              cursorHeight: 30,\n              cursorWidth: 3,\n              maxLines: null,\n              textInputAction: TextInputAction.done,\n              style: const TextStyle(\n                fontSize: 20,\n                color: Colors.white,\n                fontWeight: FontWeight.w500,\n              ),\n              textAlignVertical: TextAlignVertical.bottom,\n              decoration: const InputDecoration(\n                filled: true,\n                //fillColor: Colors,\n                hintText: 'Add caption...',\n                hintStyle: TextStyle(\n                  color: Colors.white,\n                  fontSize: 20,\n                  fontWeight: FontWeightManager.regular,\n                ),\n                border: InputBorder.none,\n                enabledBorder: InputBorder.none,\n                focusedBorder: InputBorder.none,\n              ),\n            ),\n          ),\n        ),\n        Padding(\n          padding: const EdgeInsets.all(8.0),\n          child: CircleAvatar(\n            radius: 24,\n            backgroundColor: context.colorScheme.secondary,\n            child: GestureDetector(\n              onTap: onSendButtonTaped,\n              child: const Icon(\n                Icons.send,\n                color: Colors.white,\n                size: 24,\n              ),\n            ),\n          ),\n        ),\n      ],\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/camera/components/video_view_top_row_widget.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../../../../../core/functions/navigator.dart';\n\nclass VideoViewTopRowWidget extends StatelessWidget {\n  const VideoViewTopRowWidget({\n  super.key,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return Row(\n      children: [\n        IconButton(\n          splashRadius: 20,\n          iconSize: 30,\n          color: Colors.white,\n          onPressed: () {\n            navigatePop(context);\n          },\n          icon: const Icon(Icons.clear),\n        ),\n        const Spacer(),\n        IconButton(\n          splashRadius: 20,\n          color: Colors.white,\n          icon: const Icon(\n            Icons.emoji_emotions_outlined,\n            size: 27,\n          ),\n          onPressed: () {},\n        ),\n        IconButton(\n          splashRadius: 20,\n          color: Colors.white,\n          icon: const Icon(\n            Icons.title,\n            size: 27,\n          ),\n          onPressed: () {},\n        ),\n        IconButton(\n          splashRadius: 20,\n          color: Colors.white,\n          splashColor: Colors.black38,\n          icon: const Icon(\n            Icons.edit,\n            size: 27,\n          ),\n          onPressed: () {},\n        ),\n      ],\n    );\n  }\n}"
  },
  {
    "path": "lib/features/presentation/views/camera/sending_image_view_page.dart",
    "content": "import 'dart:io';\n\nimport 'package:flutter/material.dart';\n\nimport '../../../../core/enums/messge_type.dart';\nimport '../../../../core/shared/commen.dart';\nimport '../../controllers/chat_cubit/chat_cubit.dart';\nimport 'components/image_view_top_row_icons.dart';\nimport 'components/sending_image_video_bottom_roww_widget.dart';\n\nclass SendingImageViewPage extends StatefulWidget {\n  String path;\n  final String receiverId;\n\n   SendingImageViewPage({\n    super.key,\n    required this.path,\n    required this.receiverId,\n  });\n\n  @override\n  State<SendingImageViewPage> createState() => _SendingImageViewPageState();\n}\n\nclass _SendingImageViewPageState extends State<SendingImageViewPage> {\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      backgroundColor: Colors.black,\n      body: SafeArea(\n        child: Stack(\n          children: [\n            Image.file(\n              File(widget.path),\n              fit: BoxFit.contain,\n              width: double.infinity,\n              height: double.infinity,\n            ),\n            ImageViewTopRowIcons(\n              onCropButtonTaped: () {\n                cropImage(widget.path).then((value) {\n                  widget.path = value!.path;\n                  setState(() {\n\n                  });\n                });\n              },\n            ),\n            Positioned(\n              bottom: 5,\n              right: 0,\n              left: 0,\n              child: SendingImageVideoBottomRowWidget(\n                onSendButtonTaped: () {\n                  ChatCubit.get(context).sendFileMessage(\n                    receiverId: widget.receiverId,\n                    messageType: MessageType.image,\n                    file: File(widget.path),\n                  );\n                  //to back to chat screen\n                  int count = 0;\n                  Navigator.of(context).popUntil((route) => count++ >= 2);\n                },\n              ),\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/camera/sending_video_view_page.dart",
    "content": "import 'dart:io';\n\nimport 'package:flutter/material.dart';\nimport 'package:video_player/video_player.dart';\n\nimport '../../../../core/enums/messge_type.dart';\nimport '../../controllers/chat_cubit/chat_cubit.dart';\nimport 'components/sending_image_video_bottom_roww_widget.dart';\nimport 'components/video_view_top_row_widget.dart';\n\nclass SendingVideoViewPage extends StatefulWidget {\n  final String path;\n  final String receiverId;\n\n  const SendingVideoViewPage({\n    super.key,\n    required this.path,\n    required this.receiverId,\n  });\n\n  @override\n  State<SendingVideoViewPage> createState() => _SendingVideoViewPageState();\n}\n\nclass _SendingVideoViewPageState extends State<SendingVideoViewPage> {\n  late VideoPlayerController _controller;\n\n  @override\n  void initState() {\n    super.initState();\n    _controller = VideoPlayerController.file(File(widget.path))\n      ..initialize().then((value) {\n        // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.\n        setState(() {});\n      });\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      backgroundColor: Colors.black,\n      body: SafeArea(\n        child: Stack(\n          children: [\n            Visibility(\n              visible: _controller.value.isInitialized,\n              child: SizedBox(\n                width: double.infinity,\n                child: AspectRatio(\n                  aspectRatio: _controller.value.aspectRatio,\n                  child: VideoPlayer(_controller),\n                ),\n              ),\n            ),\n            playPauseButton(),\n            const VideoViewTopRowWidget(),\n            Positioned(\n              bottom: 5,\n              right: 0,\n              left: 0,\n              child: SendingImageVideoBottomRowWidget(\n                onSendButtonTaped: () {\n                  ChatCubit.get(context).sendFileMessage(\n                    receiverId: widget.receiverId,\n                    messageType: MessageType.video,\n                    file: File(widget.path),\n                  );\n                  //to back to chat screen\n                  int count = 0;\n                  Navigator.of(context).popUntil((route) => count++ >= 2);\n                },\n              ),\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n\n  Align playPauseButton() {\n    return Align(\n      alignment: Alignment.center,\n      child: InkWell(\n        onTap: () {\n          setState(() {\n            _controller.value.isPlaying\n                ? _controller.pause()\n                : _controller.play();\n          });\n        },\n        child: CircleAvatar(\n          radius: 30,\n          backgroundColor: Colors.black38,\n          child: Icon(\n            _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,\n            color: Colors.white,\n          ),\n        ),\n      ),\n    );\n  }\n\n  @override\n  void dispose() {\n    super.dispose();\n    _controller.dispose();\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/chat/chat_screen.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\nimport 'package:whatsapp_flutter_clone/features/presentation/views/calls/call_pickup_screen.dart';\n\nimport '../../controllers/chat_background_cubit/chat_background_cubit.dart';\nimport 'components/bottom_field/bottom_chat_with_icon.dart';\nimport 'components/chat_appbar.dart';\nimport 'components/message/messages_list.dart';\nimport 'components/bottom_field/recording_mic.dart';\n\nclass ChatScreen extends StatelessWidget {\n  final String name;\n  final String uId;\n\n  const ChatScreen({super.key, required this.name, required this.uId});\n\n  @override\n  Widget build(BuildContext context) {\n    return CallPickupScreen(\n      scaffold: Scaffold(\n        appBar: ChatAppBar(name: name, receiverId: uId),\n        body: Stack(\n          children: [\n            BlocBuilder<ChatBackgroundCubit, ChatBackgroundState>(\n              builder: ((context, state) {\n                return Image.asset(\n                  ChatBackgroundCubit.get(context).backgroundImage,\n                  fit: BoxFit.fill,\n                  width: double.infinity,\n                  height: double.infinity,\n                );\n              }),\n            ),\n            Column(\n              mainAxisAlignment: MainAxisAlignment.end,\n              crossAxisAlignment: CrossAxisAlignment.start,\n              children: [\n                MessagesList(receiverId: uId),\n                BottomChatWithIcon(receiverId: uId),\n              ],\n            ),\n            RecordingMic(receiverId: uId),\n          ],\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/chat/components/bottom_field/attchment_pop_up.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter_contacts/flutter_contacts.dart';\n\nclass AttchementPopUp extends StatelessWidget {\n   const AttchementPopUp({\n    super.key,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return PopupMenuButton(\n      //RotationTransition to rotate icon with degree\n      icon: const RotationTransition(\n        turns: AlwaysStoppedAnimation(-45 / 360),\n        child: Icon(\n          Icons.attach_file,\n          color: Colors.grey,\n          size: 26,\n        ),\n      ),\n      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16),),\n     // offset: const Offset(0, -340),\n      offset: const Offset(0, -350),\n      onSelected: (v){\n        if (FocusScope.of(context).hasFocus) {\n          Future.delayed(const Duration(milliseconds: 50)).whenComplete(\n                () {\n              FocusScope.of(context).unfocus();\n              FocusScope.of(context).dispose();\n            },\n          );\n        }\n      },\n      onCanceled: () {\n        if (!FocusScope.of(context).hasFocus) {\n          Future.delayed(const Duration(milliseconds: 50))\n              .whenComplete(() => FocusScope.of(context).unfocus());\n          FocusScope.of(context).dispose();\n        }\n      },\n      constraints: const BoxConstraints.tightFor(width: double.infinity),\n      itemBuilder: (context) {\n        return [\n          PopupMenuItem(\n            padding: const EdgeInsets.only(left: 40, right: 40, bottom: 15),\n            enabled: false,\n            onTap: () {},\n            child: Wrap(\n              spacing: 8,\n              runAlignment: WrapAlignment.spaceBetween,\n              children: [\n                AttchmentCard(\n                  name: 'Document',\n                  color: Colors.deepPurpleAccent,\n                  icon: Icons.insert_drive_file,\n                  onPress: () {\n                  },\n                ),\n                AttchmentCard(\n                  name: 'Camera',\n                  color: Colors.redAccent,\n                  icon: Icons.camera_alt,\n                  onPress: () {},\n                ),\n                AttchmentCard(\n                  name: 'Gallery',\n                  color: Colors.purpleAccent,\n                  icon: Icons.photo,\n                  onPress: () {},\n                ),\n                AttchmentCard(\n                  name: 'Audio',\n                  color: Colors.deepOrange,\n                  icon: Icons.headset_mic_rounded,\n                  onPress: () {},\n                ),\n                AttchmentCard(\n                  name: 'Location',\n                  color: Colors.green,\n                  icon: Icons.location_on,\n                  onPress: () {},\n                ),\n                AttchmentCard(\n                  name: 'Contact',\n                  color: Colors.cyan,\n                  icon: Icons.person,\n                  onPress: () {\n                    FlutterContacts.openExternalPick();\n                  },\n                ),\n                AttchmentCard(\n                  name: 'Poll',\n                  color: Colors.teal,\n                  icon: Icons.poll,\n                  onPress: () {},\n                ),\n              ],\n            ),\n          ),\n        ];\n      },\n    );\n  }\n}\n\nclass AttchmentCard extends StatelessWidget {\n  final String name;\n  final IconData icon;\n  final Color color;\n  final VoidCallback onPress;\n\n  const AttchmentCard({\n    super.key,\n    required this.name,\n    required this.icon,\n    required this.color,\n    required this.onPress,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return Container(\n      width: 90,\n      padding: const EdgeInsets.only(top: 15),\n      child: Column(\n        children: [\n          CircleAvatar(\n            radius: 28,\n            backgroundColor: color,\n            child: IconButton(\n              onPressed: onPress,\n              splashRadius: 28,\n              color: Colors.white,\n              icon: Icon(icon),\n            ),\n          ),\n          const SizedBox(\n            height: 10,\n          ),\n          Text(name),\n        ],\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/chat/components/bottom_field/bottom_chat_field.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\nimport 'package:whatsapp_flutter_clone/core/extensions/extensions.dart';\n\nimport '../../../../../../core/functions/navigator.dart';\nimport '../../../../../../core/shared/message_replay.dart';\nimport '../../../../../../core/utils/constants/font_manager.dart';\nimport '../../../../../../core/utils/routes/routes_manager.dart';\nimport '../../../../controllers/chat_cubit/chat_cubit.dart';\nimport 'attchment_pop_up.dart';\nimport '../message/message_replay_preview.dart';\n\nclass BottomChatField extends StatelessWidget {\n  final TextEditingController messageController;\n  final FocusNode focusNode;\n  final Function(String) onTextFieldValueChanged;\n  final bool isShowEmoji;\n  final VoidCallback toggleEmojiKeyboard;\n  final String receiverId;\n\n  const BottomChatField({\n    super.key,\n    required this.messageController,\n    required this.focusNode,\n    required this.onTextFieldValueChanged,\n    required this.isShowEmoji,\n    required this.toggleEmojiKeyboard,\n    required this.receiverId,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return Container(\n      width: MediaQuery.of(context).size.width - 65,\n      margin: const EdgeInsets.only(\n        right: 5,\n      ),\n      decoration: BoxDecoration(\n        color: Colors.white,\n        borderRadius: BorderRadius.circular(26),\n      ),\n      child: Column(\n        children: [\n          BlocBuilder<ChatCubit, ChatState>(\n            builder: (context, state) {\n              MessageReplay? messageReplay =\n                  ChatCubit.get(context).messageReplay;\n              if (messageReplay == null) {\n                return const SizedBox();\n              }\n              return MessageReplayPreview(\n                messageReplay: messageReplay,\n              );\n            },\n          ),\n          Row(\n            crossAxisAlignment: CrossAxisAlignment.end,\n            children: [\n              SizedBox(\n                width: 35,\n                child: IconButton(\n                  onPressed: toggleEmojiKeyboard,\n                  color: Colors.grey,\n                  iconSize: 25,\n                  icon: Icon(\n                    isShowEmoji\n                        ? Icons.keyboard\n                        : Icons.emoji_emotions_outlined,\n                  ),\n                ),\n              ),\n              Flexible(\n                child: ConstrainedBox(\n                  constraints: const BoxConstraints(\n                    minWidth: double.infinity,\n                    maxWidth: double.infinity,\n                    minHeight: 25,\n                    maxHeight: 135,\n                  ),\n                  child: Scrollbar(\n                    child: TextField(\n                      onChanged: onTextFieldValueChanged,\n                      /*\n                      onChanged: (val) {\n                        if (val.isNotEmpty) {\n                          setState(() {\n                            isShownSendButton = true;\n                          });\n                        } else {\n                          setState(() {\n                            isShownSendButton = false;\n                          });\n                        }\n                      },\n\n                       */\n                      controller: messageController,\n                      cursorColor: context.colorScheme.secondary,\n                      focusNode: focusNode,\n                      cursorHeight: 30,\n                      cursorWidth: 3,\n                      maxLines: null,\n                      textInputAction: TextInputAction.newline,\n                      style: TextStyle(\n                        fontSize: 20,\n                        //color: AppColors.blackLight,\n                        color: context.colorScheme.onTertiaryContainer,\n                        fontWeight: FontWeight.w500,\n                      ),\n                      textAlignVertical: TextAlignVertical.bottom,\n                      decoration: const InputDecoration(\n                        filled: true,\n                        fillColor: Colors.white,\n                        hintText: 'Message',\n                        hintStyle: TextStyle(\n                          color: Colors.grey,\n                          fontSize: 20,\n                          fontWeight: FontWeightManager.regular,\n                        ),\n                        border: InputBorder.none,\n                        enabledBorder: InputBorder.none,\n                        focusedBorder: InputBorder.none,\n                      ),\n                    ),\n                  ),\n                ),\n              ),\n              const AttchementPopUp(),\n              if (messageController.text.isEmpty)\n                IconButton(\n                  onPressed: () {\n                    navigateTo(context, Routes.cameraRoute, arguments: {\n                      'uId': receiverId,\n                    });\n                  },\n                  color: Colors.grey,\n                  iconSize: 26,\n                  icon: const Icon(Icons.camera_alt_rounded),\n                ),\n            ],\n          ),\n        ],\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/chat/components/bottom_field/bottom_chat_with_icon.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\nimport 'package:giphy_get/giphy_get.dart';\n\nimport '../../../../../../core/shared/commen.dart';\nimport '../../../../controllers/bottom_chat_cubit/bottom_chat_cubit.dart';\nimport '../../../../controllers/chat_cubit/chat_cubit.dart';\nimport 'bottom_chat_field.dart';\nimport 'emoji_picker_widget.dart';\n\nclass BottomChatWithIcon extends StatefulWidget {\n  final String receiverId;\n\n  const BottomChatWithIcon({\n    super.key,\n    required this.receiverId,\n  });\n\n  @override\n  State<BottomChatWithIcon> createState() => _BottomChatWithIconState();\n}\n\nclass _BottomChatWithIconState extends State<BottomChatWithIcon> {\n  final TextEditingController messageController = TextEditingController();\n  FocusNode focusNode = FocusNode();\n\n  @override\n  void initState() {\n    super.initState();\n    focusNode.addListener(() {\n      if (focusNode.hasFocus) {\n        //hideEmojiContainer();\n      }\n    });\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return BlocConsumer<  BottomChatCubit, BottomChatState>(\n      listener: (context, state) {},\n      builder: (context, state) {\n        BottomChatCubit cubit = BottomChatCubit.get(context);\n        return WillPopScope(\n          child: Column(\n            // mainAxisAlignment: MainAxisAlignment.start,\n            crossAxisAlignment: CrossAxisAlignment.start,\n            children: [\n              Padding(\n                padding: const EdgeInsets.all(4.0),\n                child: Row(\n                  mainAxisSize: MainAxisSize.min,\n                  crossAxisAlignment: CrossAxisAlignment.end,\n                  // mainAxisAlignment: MainAxisAlignment.start,\n                  children: [\n                    BottomChatField(\n                      receiverId: widget.receiverId,\n                      focusNode: focusNode,\n                      isShowEmoji: cubit.isShowEmoji,\n                      messageController: messageController,\n                      onTextFieldValueChanged: (val) =>\n                          cubit.onTextFieldValChanged(val),\n                      toggleEmojiKeyboard: () =>\n                          cubit.toggleEmojiKeyboard(focusNode),\n                    ),\n                    if (cubit.isShownSendButton)\n                      BlocBuilder<ChatCubit, ChatState>(\n                        builder: (context, state) {\n                          return GestureDetector(\n                            onTap: () {\n                              ChatCubit.get(context).sendTextMessage(\n                                text: messageController.text.trim(),\n                                receiverId: widget.receiverId,\n                              );\n                              messageController.clear();\n                            },\n                            child: Container(\n                              decoration: BoxDecoration(\n                                borderRadius: BorderRadius.circular(50.00),\n                                color: Colors.teal,\n                              ),\n                              width: 50,\n                              height: 50,\n                              child: Icon(\n                                Icons.send,\n                                color: Colors.teal[50],\n                              ),\n                            ),\n                          );\n                        },\n                      ),\n                  ],\n                ),\n              ),\n              Offstage(\n                offstage: !cubit.isShowEmoji,\n                child: BlocBuilder<ChatCubit, ChatState>(\n                  builder: (context, state) {\n                    return EmojiPickerWidget(\n                      messageController: messageController,\n                      onGifButtonTap: () {\n                        selectGif(ChatCubit.get(context));\n                      },\n                    );\n                  },\n                ),\n              ),\n            ],\n          ),\n          onWillPop: () {\n            if (cubit.isShowEmoji) {\n              cubit.hideEmojiContainer();\n            } else {\n              Navigator.pop(context);\n            }\n            return Future.value(false);\n          },\n        );\n      },\n    );\n  }\n\n  void selectGif(ChatCubit cubit) async {\n    final gif = await pickGif(context);\n    sendGifMessage(gif, cubit);\n  }\n\n  void sendGifMessage(GiphyGif? gif, ChatCubit cubit) {\n    if (gif != null) {\n      cubit.sendGifMessage(\n        receiverId: widget.receiverId,\n        gifUrl: gif.url!,\n      );\n    }\n  }\n\n  @override\n  void dispose() {\n    super.dispose();\n    messageController.dispose();\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/chat/components/bottom_field/emoji_picker_widget.dart",
    "content": "import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';\nimport 'package:flutter/material.dart';\n\nimport '/core/extensions/extensions.dart';\n\n\nclass EmojiPickerWidget extends StatelessWidget {\n  final TextEditingController messageController;\n  final VoidCallback onGifButtonTap;\n\n  const EmojiPickerWidget({\n    super.key,\n    required this.onGifButtonTap,\n    required this.messageController,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return SizedBox(\n      height: 250,\n      child: Stack(\n        alignment: Alignment.bottomCenter,\n        children: [\n          EmojiPicker(\n            onEmojiSelected: (category, emoji) {\n              //messageController.text = messageController.text + emoji.emoji;\n            },\n            onBackspacePressed: () {\n              messageController.text.trimRight();\n            },\n            textEditingController: messageController,\n            config: Config(\n              columns: 8,\n              iconColorSelected: context.colorScheme.secondary,\n              indicatorColor: context.colorScheme.secondary,\n              backspaceColor: Colors.black26,\n            ),\n          ),\n          Container(\n            height: 40,\n            width: double.infinity,\n            color: Colors.grey[200],\n            padding: const EdgeInsets.symmetric(\n              horizontal: 16,\n              vertical: 5,\n            ),\n            child: Row(\n              mainAxisAlignment: MainAxisAlignment.center,\n              children: [\n                InkWell(\n                  onTap: onGifButtonTap,\n                  child: Container(\n                    decoration: BoxDecoration(\n                      borderRadius: BorderRadius.circular(10),\n                      border: Border.all(\n                        width: 2,\n                        color: context.colorScheme.onSurface,\n                      ),\n                    ),\n                    child: const Icon(\n                      Icons.gif,\n                      size: 30,\n                      color: Colors.black26,\n                    ),\n                  ),\n                ),\n              ],\n            ),\n          ),\n        ],\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/chat/components/bottom_field/recording_mic.dart",
    "content": "import 'dart:io';\n\nimport 'package:audio_waveforms/audio_waveforms.dart';\nimport 'package:flutter/material.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\nimport 'package:whatsapp_flutter_clone/core/enums/messge_type.dart';\nimport 'package:whatsapp_flutter_clone/features/presentation/controllers/chat_cubit/chat_cubit.dart';\nimport 'recording_mic_widget.dart';\n\nimport '../../../../controllers/bottom_chat_cubit/bottom_chat_cubit.dart';\n\nclass RecordingMic extends StatefulWidget {\n  final String receiverId;\n  const RecordingMic({super.key, required this.receiverId,});\n\n  @override\n  State<RecordingMic> createState() => _RecordingMicState();\n}\n\nclass _RecordingMicState extends State<RecordingMic> {\n  late final RecorderController recorderController;\n\n  @override\n  void initState() {\n    super.initState();\n    recorderController = RecorderController();\n  }\n\n  @override\n  Widget build(BuildContext context)\n{\n    return BlocBuilder<BottomChatCubit, BottomChatState>(\n      builder: (context, state) {\n        BottomChatCubit cubit = BottomChatCubit.get(context);\n        return Visibility(\n          visible: !cubit.isShownSendButton,\n          child: RecordingMicWidget(\n            onVerticalScrollComplete: () {},\n            onHorizontalScrollComplete: () {\n              cancelRecord();\n            },\n            onLongPress: () {\n              startRecording();\n            },\n            onLongPressCancel: () {\n              stopRecording();\n            },\n            onSend: () {\n              stopRecording();\n            },\n            onTapCancel: () {\n              cancelRecord();\n            },\n          ),\n        );\n      },\n    );\n  }\n\n\n  void startRecording() async {\n    if (await recorderController.checkPermission()) {\n      await recorderController.record();\n    }\n  }\n\n  void cancelRecord() async {\n    await recorderController.stop();\n  }\n\n  void stopRecording() async {\n    final path = await recorderController.stop();\n    ChatCubit.get(context).sendFileMessage(\n      receiverId: widget.receiverId,\n      messageType: MessageType.audio,\n      file: File(path!),\n    );\n  }\n\n  @override\n  void dispose() {\n    super.dispose();\n    recorderController.dispose();\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/chat/components/bottom_field/recording_mic_widget.dart",
    "content": "import 'dart:math';\n\nimport 'package:flutter/material.dart';\nimport 'package:shimmer/shimmer.dart';\nimport '/core/extensions/extensions.dart';\nimport '/core/utils/constants/assets_manager.dart';\nimport 'timer.dart';\n\nclass RecordingMicWidget extends StatefulWidget {\n  const RecordingMicWidget({\n    Key? key,\n    required this.onVerticalScrollComplete,\n    required this.onHorizontalScrollComplete,\n    required this.onLongPress,\n    required this.onLongPressCancel,\n    required this.onSend,\n    required this.onTapCancel,\n  }) : super(key: key);\n\n  final VoidCallback onVerticalScrollComplete;\n  final VoidCallback onHorizontalScrollComplete;\n  final VoidCallback onLongPress;\n  final VoidCallback onLongPressCancel;\n  final VoidCallback onSend;\n  final VoidCallback onTapCancel;\n\n  @override\n  _RecordingMicWidgetState createState() => _RecordingMicWidgetState();\n}\n\nclass _RecordingMicWidgetState extends State<RecordingMicWidget>\n    with SingleTickerProviderStateMixin {\n  double micDx = 4;\n  double micDy = 4;\n\n  double micWidth = 50;\n  double micHeight = 50;\n\n  bool isVerticalScroll = true;\n  bool showSwipeOptions = false;\n  bool isVerticalActionComplete = false;\n  bool isHorizontalActionComplete = false;\n  bool isShowMic = false;\n  bool isShowTime = false;\n  late AnimationController _animationController;\n\n  //Mic\n  late Animation<double> _micTranslateTop;\n  late Animation<double> _micRotationFirst;\n  late Animation<double> _micTranslateRight;\n  late Animation<double> _micTranslateLeft;\n  late Animation<double> _micRotationSecond;\n  late Animation<double> _micTranslateDown;\n  late Animation<double> _micInsideTrashTranslateDown;\n\n  //Trash Can\n  late Animation<double> _trashWithCoverTranslateTop;\n  late Animation<double> _trashCoverRotationFirst;\n  late Animation<double> _trashCoverTranslateLeft;\n  late Animation<double> _trashCoverRotationSecond;\n  late Animation<double> _trashCoverTranslateRight;\n  late Animation<double> _trashWithCoverTranslateDown;\n\n  @override\n  void initState() {\n    super.initState();\n    _animationController = AnimationController(\n      vsync: this,\n      duration: const Duration(milliseconds: 2500),\n    );\n\n    //Mic\n\n    _micTranslateTop = Tween(begin: 0.0, end: -150.0).animate(\n      CurvedAnimation(\n        parent: _animationController,\n        curve: const Interval(0.0, 0.45, curve: Curves.easeOut),\n      ),\n    );\n\n    _micRotationFirst = Tween(begin: 0.0, end: pi).animate(\n      CurvedAnimation(\n        parent: _animationController,\n        curve: const Interval(0.0, 0.2),\n      ),\n    );\n\n    _micTranslateRight = Tween(begin: 0.0, end: 13.0).animate(\n      CurvedAnimation(\n        parent: _animationController,\n        curve: const Interval(0.0, 0.1),\n      ),\n    );\n\n    _micTranslateLeft = Tween(begin: 0.0, end: -13.0).animate(\n      CurvedAnimation(\n        parent: _animationController,\n        curve: const Interval(0.1, 0.2),\n      ),\n    );\n\n    _micRotationSecond = Tween(begin: 0.0, end: pi).animate(\n      CurvedAnimation(\n        parent: _animationController,\n        curve: const Interval(0.2, 0.45),\n      ),\n    );\n\n    _micTranslateDown = Tween(begin: 0.0, end: 150.0).animate(\n      CurvedAnimation(\n        parent: _animationController,\n        curve: const Interval(0.45, 0.79, curve: Curves.easeInOut),\n      ),\n    );\n\n    _micInsideTrashTranslateDown = Tween(begin: 0.0, end: 55.0).animate(\n      CurvedAnimation(\n        parent: _animationController,\n        curve: const Interval(0.95, 1.0, curve: Curves.easeInOut),\n      ),\n    );\n\n\n    //Trash Can\n\n    _trashWithCoverTranslateTop = Tween(begin: 30.0, end: -25.0).animate(\n      CurvedAnimation(\n        parent: _animationController,\n        curve: const Interval(0.45, 0.6),\n      ),\n    );\n\n    _trashCoverRotationFirst = Tween(begin: 0.0, end: -pi / 3).animate(\n      CurvedAnimation(\n        parent: _animationController,\n        curve: const Interval(0.6, 0.7),\n      ),\n    );\n\n    _trashCoverTranslateLeft = Tween(begin: 0.0, end: -18.0).animate(\n      CurvedAnimation(\n        parent: _animationController,\n        curve: const Interval(0.6, 0.7),\n      ),\n    );\n\n    _trashCoverRotationSecond = Tween(begin: 0.0, end: pi / 3).animate(\n      CurvedAnimation(\n        parent: _animationController,\n        curve: const Interval(0.8, 0.9),\n      ),\n    );\n\n    _trashCoverTranslateRight = Tween(begin: 0.0, end: 18.0).animate(\n      CurvedAnimation(\n        parent: _animationController,\n        curve: const Interval(0.8, 0.9),\n      ),\n    );\n\n    _trashWithCoverTranslateDown = Tween(begin: 0.0, end: 55.0).animate(\n      CurvedAnimation(\n        parent: _animationController,\n        curve: const Interval(0.95, 1.0, curve: Curves.easeInOut),\n      ),\n    );\n  }\n\n\n  @override\n  Widget build(BuildContext context) {\n    //Size screenSize = context.size;\n    return Stack(\n      children: [\n        Positioned(\n          bottom: 4,\n          right: 50,\n          child: Visibility(\n            visible: showSwipeOptions || isVerticalActionComplete,\n            child: Padding(\n              padding: const EdgeInsets.only(right: 4.0),\n              child: Container(\n                decoration: BoxDecoration(\n                  borderRadius: BorderRadius.circular(26.00),\n                  color: Colors.white,\n                ),\n                width: context.width(1) - 65,\n                height: 50,\n              ),\n            ),\n          ),\n        ),\n        Positioned(\n          bottom: 15,\n          right: 70,\n          child: Visibility(\n            visible: showSwipeOptions,\n            child: Shimmer.fromColors(\n              direction: ShimmerDirection.rtl,\n              baseColor: Colors.grey.shade500,\n              highlightColor: Colors.grey.shade300,\n              child: Row(\n                crossAxisAlignment: CrossAxisAlignment.center,\n                children: const [\n                  Icon(\n                    Icons.chevron_left,\n                  ),\n                  Text(\n                    \"swipe to cancel\",\n                    style: TextStyle(fontSize: 16),\n                  ),\n                ],\n              ),\n            ),\n          ),\n        ),\n        Positioned(\n          bottom: 15,\n          right: 70,\n          child: Visibility(\n            visible: isVerticalActionComplete,\n            child: GestureDetector(\n              onTap: () {\n                setState(() {\n                  isVerticalActionComplete = false;\n                  isShowMic =false;\n                  isShowTime = false;\n                });\n                widget.onTapCancel();\n              },\n              child: const Text(\n                \"Cancel\",\n                style: TextStyle(\n                  fontSize: 16,\n                  color: Colors.red,\n                ),\n              ),\n            ),\n          ),\n        ),\n        Positioned(\n          bottom: 120,\n          right: 0,\n          child: Visibility(\n            visible: showSwipeOptions,\n            child: Container(\n              width: 50,\n              height: 50,\n              decoration: BoxDecoration(\n                borderRadius: BorderRadius.circular(50.00),\n                color: Colors.white,\n              ),\n              child: Shimmer.fromColors(\n                baseColor: Colors.grey.shade500,\n                highlightColor: Colors.grey.shade300,\n                child: const Icon(\n                  Icons.lock_rounded,\n                  size: 30,\n                ),\n              ),\n            ),\n          ),\n        ),\n        Positioned(\n          bottom: micDy,\n          right: micDx,\n          child: GestureDetector(\n            // this is used when the recording is locked and you want to save the audio\n            onTap: () {\n              if (isVerticalActionComplete) {\n                setState(() {\n                  isVerticalActionComplete = false;\n                  isShowMic =false;\n                  isShowTime=false;\n                });\n                widget.onSend();\n              }\n            },\n\n            onLongPress: () {\n              widget.onLongPress();\n              isVerticalActionComplete = false;\n              isHorizontalActionComplete = false;\n\n              setState(() {\n                micWidth = 80;\n                micHeight = 80;\n                showSwipeOptions = true;\n                isShowMic =true;\n                isShowTime=true;\n              });\n            },\n\n            onLongPressEnd: (LongPressEndDetails lg) {\n              setState(() {\n                micWidth = 50;\n                micHeight = 50;\n                micDy = 4;\n                micDx = 4;\n                showSwipeOptions = false;\n              });\n              if (!isVerticalActionComplete && !isHorizontalActionComplete) {\n                widget.onLongPressCancel();\n                setState(() {\n                  isShowMic =false;\n                  isShowTime=false;\n                });\n              }\n            },\n\n            onLongPressMoveUpdate: (LongPressMoveUpdateDetails longPressData) {\n              longPressUpdate(longPressData);\n            },\n\n            child: Container(\n              decoration: BoxDecoration(\n                borderRadius: BorderRadius.circular(50.00),\n                color: Colors.teal,\n              ),\n              width: micWidth,\n              height: micHeight,\n              child: Icon(\n                isVerticalActionComplete ? Icons.send : Icons.mic,\n                color: Colors.teal[50],\n              ),\n            ),\n          ),\n        ),\n        Positioned(\n          left: 10,\n          bottom: -10,\n          child: Visibility(\n            visible: isShowMic,\n            child: Column(\n              mainAxisAlignment: MainAxisAlignment.end,\n              children: [\n                AnimatedBuilder(\n                  animation: _animationController,\n                  builder: (context, child) {\n                    return Transform(\n                      transform: Matrix4.identity()\n                        ..translate(0.0, 10)..translate(\n                            _micTranslateRight.value)..translate(\n                            _micTranslateLeft.value)..translate(\n                            0.0, _micTranslateTop.value)..translate(\n                            0.0, _micTranslateDown.value)..translate(\n                            0.0, _micInsideTrashTranslateDown.value),\n                      child: Transform.rotate(\n                        angle: _micRotationFirst.value,\n                        child: Transform.rotate(\n                          angle: _micRotationSecond.value,\n                          child: child,\n                        ),\n                      ),\n                    );\n                  },\n                  child:  const Icon(\n                    Icons.mic,\n                    color: Color(0xFFef5552),\n                    size: 30,\n                  ),\n                ),\n                AnimatedBuilder(\n                  animation: _trashWithCoverTranslateTop,\n                  builder: (context, child) {\n                    return Transform(\n                      transform: Matrix4.identity()\n                        ..translate(\n                            0.0, _trashWithCoverTranslateTop.value)..translate(\n                            0.0, _trashWithCoverTranslateDown.value),\n                      child: child,\n                    );\n                  },\n                  child: Column(\n                    children: [\n                      AnimatedBuilder(\n                        animation: _trashCoverRotationFirst,\n                        builder: (context, child) {\n                          return Transform(\n                            transform: Matrix4.identity()\n                              ..translate(\n                                  _trashCoverTranslateLeft.value)..translate(\n                                  _trashCoverTranslateRight.value),\n                            child: Transform.rotate(\n                              angle: _trashCoverRotationSecond.value,\n                              child: Transform.rotate(\n                                angle: _trashCoverRotationFirst.value,\n                                child: child,\n                              ),\n                            ),\n                          );\n                        },\n                        child: const Image(\n                          //image: AssetImage('assets/images/trash_cover.png'),\n                          image: AssetImage(AppImage.trashCoverImg),\n                          width: 30,\n                        ),\n                      ),\n                      const Padding(\n                        padding: EdgeInsets.only(top: 1.5),\n                        child: Image(\n                          image:\n                          //AssetImage('assets/images/trash_container.png'),\n                          AssetImage(AppImage.trashContainerImg),\n                          width: 30,\n                        ),\n                      ),\n                    ],\n                  ),\n                ),\n              ],\n            ),\n          ),\n        ),\n         Positioned(\n          bottom: 15,\n          left: 45,\n          child: Visibility(\n            visible: isShowTime,\n            child: const TimerWidget(),\n          ),\n        ),\n      ],\n    );\n  }\n\n  void longPressUpdate(LongPressMoveUpdateDetails longPressData) {\n    //determine the direction of the swipe\n    if (longPressData.localPosition.direction > 1) {\n      isVerticalScroll = false;\n    } else {\n      isVerticalScroll = true;\n    }\n\n    // handle the swipe data and move the mic in vertical direction\n    if (isVerticalScroll) {\n      if (longPressData.localPosition.dy < 0) {\n        if (longPressData.localPosition.dy > -100) {\n          setState(() {\n            micDy = -longPressData.localPosition.dy;\n          });\n        } else {\n          // reset only once\n          if (showSwipeOptions) {\n            isVerticalActionComplete = true;\n            widget.onVerticalScrollComplete();\n            showSwipeOptions = false;\n            resetMicPosition();\n          }\n        }\n      } else {\n        resetMicPosition();\n      }\n    }\n\n    // handle the swipe data and move the mic in horizontal direction\n    if (!isVerticalScroll) {\n      if (longPressData.localPosition.dx < 0) {\n        if (longPressData.localPosition.dx > -150) {\n          setState(() {\n            micDx = -longPressData.localPosition.dx;\n          });\n        } else {\n          // reset only once\n          if (showSwipeOptions) {\n            isHorizontalActionComplete = true;\n            isShowTime=false;\n            _animationController.forward().then((_) {\n              _animationController.reset();\n              setState(() {\n                isShowMic =false;\n              });\n\n            });\n            widget.onHorizontalScrollComplete();\n            showSwipeOptions = false;\n            resetMicPosition();\n          }\n        }\n      } else {\n        resetMicPosition();\n      }\n    }\n\n    // reset mic size when the swipe reaches the vertical bounds\n    if (longPressData.localPosition.dy < -100 && micHeight != 50) {\n      setState(() {\n        micWidth = 50;\n        micHeight = 50;\n      });\n    }\n\n    // reset mic size when the swipe reaches the horizontal bounds\n    if (longPressData.localPosition.dy < -150 && micWidth != 50) {\n      setState(() {\n        micWidth = 50;\n        micHeight = 50;\n      });\n    }\n  }\n\n  void resetMicPosition() {\n    setState(() {\n      micDx = 4;\n      micDy = 4;\n    });\n  }\n\n  @override\n  void dispose() {\n    _animationController.dispose();\n    super.dispose();\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/chat/components/bottom_field/timer.dart",
    "content": "import 'dart:async';\n\nimport 'package:flutter/material.dart';\n\n/// This widget shows the count-up timer\nclass TimerWidget extends StatefulWidget {\n  const TimerWidget({Key? key}) : super(key: key);\n\n  @override\n  _TimerWidgetState createState() => _TimerWidgetState();\n}\n\nclass _TimerWidgetState extends State<TimerWidget> {\n  Duration duration = const Duration();\n  Timer? timer;\n\n  @override\n  void initState() {\n    super.initState();\n    startTimer();\n  }\n\n  void startTimer() {\n    timer = Timer.periodic(const Duration(seconds: 1), (_) => addTimer());\n  }\n\n  void addTimer() {\n    const addSeconds = 1;\n\n    setState(() {\n      final seconds = duration.inSeconds + addSeconds;\n      duration = Duration(seconds: seconds);\n    });\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    String twoDigits(int n) => n.toString().padLeft(2, '0');\n    final minutes = twoDigits(duration.inMinutes.remainder(60));\n    final seconds = twoDigits(duration.inSeconds.remainder(60));\n    return Text(\n      \"$minutes:$seconds\",\n      style: TextStyle(\n        fontSize: 20,\n        color: Colors.teal.shade700,\n      ),\n    );\n  }\n\n  @override\n  void dispose() {\n    timer?.cancel();\n    super.dispose();\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/chat/components/chat_appbar.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\nimport 'package:whatsapp_flutter_clone/features/presentation/controllers/call_cubit/call_cubit.dart';\n\nimport '../../../components/custom_network_image.dart';\nimport '/core/extensions/time_extension.dart';\nimport '/core/functions/navigator.dart';\nimport '/core/shared/pop_up_menu_item_model.dart';\nimport '/core/utils/constants/strings_manager.dart';\nimport '/core/utils/routes/routes_manager.dart';\nimport '../../../../domain/entities/user.dart';\nimport '../../../components/custom_pop_up_menu_button.dart';\nimport '../../../components/loader.dart';\nimport '../../../controllers/auth_cubit/auth_cubit.dart';\n\nclass ChatAppBar extends StatelessWidget implements PreferredSizeWidget {\n  final String name;\n  final String receiverId;\n\n  const ChatAppBar({\n    super.key,\n    required this.name,\n    required this.receiverId,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return StreamBuilder<UserEntity>(\n        stream: AuthCubit.get(context).getUserById(receiverId),\n        builder: (context, snapshot) {\n          if (snapshot.connectionState == ConnectionState.waiting) {\n            return const Loader();\n          }\n          UserEntity userdata = snapshot.data!;\n          return AppBar(\n            leadingWidth: 70,\n            titleSpacing: 0,\n            leading: Container(\n              margin: const EdgeInsets.only(bottom: 5),\n              decoration: BoxDecoration(\n                borderRadius: BorderRadius.circular(50),\n              ),\n              child: InkWell(\n                borderRadius: BorderRadius.circular(50),\n                onTap: () {\n                  navigateAndRemove(context, Routes.mainLayoutRoute);\n                },\n                child: Row(\n                  children: [\n                    const Icon(Icons.arrow_back_rounded),\n                    Hero(\n                      tag: userdata.uId,\n                      child: CustomNetworkImage(imageUrl: userdata.profilePic),\n                    ),\n                  ],\n                ),\n              ),\n            ),\n            title: SizedBox(\n              width: double.infinity,\n              height: kToolbarHeight,\n              child: InkWell(\n                onTap: () {\n                  navigateTo(\n                    context,\n                    Routes.senderUserProfileRoute,\n                    arguments: userdata,\n                  );\n                },\n                child: Padding(\n                  padding: const EdgeInsets.symmetric(horizontal: 5),\n                  child: Column(\n                    mainAxisAlignment: MainAxisAlignment.center,\n                    crossAxisAlignment: CrossAxisAlignment.start,\n                    children: [\n                      Text(name),\n                      Text(\n                        userdata.isOnline\n                            ? 'Online'\n                            : userdata.lastSeen.lastSeen,\n                        style: const TextStyle(\n                          fontSize: 10,\n                          fontWeight: FontWeight.normal,\n                        ),\n                      ),\n                    ],\n                  ),\n                ),\n              ),\n            ),\n            actions: [\n              BlocConsumer<CallCubit,CallState>(\n                listener: (context,state){\n                  if(state is MakeCallSuccessState){\n                    navigateTo(\n                      context,\n                      Routes.callRoute,\n                      arguments: {\n                        'call': state.call,\n                        'channelId': state.call.callId,\n                      },\n                    );\n                  }\n                },\n                builder: (context,state){\n                  return IconButton(\n                    onPressed: () {\n                      CallCubit.get(context).makeCall(\n                        receiverId: receiverId,\n                        receiverName: name,\n                        receiverPic: userdata.profilePic,\n                      );\n                    },\n                    splashRadius: 20,\n                    icon: const Icon(Icons.videocam),\n                  );\n                },\n              ),\n              IconButton(\n                onPressed: () {},\n                splashRadius: 20,\n                icon: const Icon(Icons.call),\n              ),\n              CustomPopUpMenuButton(\n                buttons: _buttons(context),\n              ),\n            ],\n          );\n        });\n  }\n\n  List<PopUpMenuItemModel> _buttons(context) => [\n        PopUpMenuItemModel(\n          name: AppStrings.viewContact,\n          onTap: () {},\n        ),\n        PopUpMenuItemModel(\n          name: AppStrings.mediaLinksAndDocs,\n          onTap: () {},\n        ),\n        PopUpMenuItemModel(\n          name: AppStrings.search,\n          onTap: () {},\n        ),\n        PopUpMenuItemModel(\n          name: AppStrings.muteNotifications,\n          onTap: () {},\n        ),\n        PopUpMenuItemModel(\n          name: AppStrings.disappearingMessages,\n          onTap: () {},\n        ),\n        PopUpMenuItemModel(\n          name: AppStrings.wallpaper,\n          onTap: () {\n            navigateTo(context, Routes.wallpaperRoute);\n          },\n        ),\n        PopUpMenuItemModel(\n          name: AppStrings.more,\n          onTap: () {},\n        ),\n      ];\n\n  @override\n  Size get preferredSize => const Size.fromHeight(kToolbarHeight);\n}\n\nclass CustomAppBar extends StatelessWidget implements PreferredSizeWidget {\n  const CustomAppBar({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return AppBar(\n    );\n  }\n\n  @override\n  Size get preferredSize => const Size.fromHeight(kToolbarHeight);\n}\n"
  },
  {
    "path": "lib/features/presentation/views/chat/components/message/first_message_small_curved_bubble.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '/core/extensions/extensions.dart';\n\n\nclass FirstMessageSmallCurvedBubble extends StatelessWidget {\n  final bool isMe;\n\n  const FirstMessageSmallCurvedBubble({\n    super.key,\n    required this.isMe,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return ClipPath(\n      clipper: MyCustomClipper(isMe),\n      child: Container(\n        width: 10,\n        height: 15,\n        decoration: BoxDecoration(\n          color: isMe ? context.colorScheme.surface : Colors.white,\n        ),\n      ),\n    );\n  }\n}\n\nclass MyCustomClipper extends CustomClipper<Path> {\n  final bool isMe;\n\n  MyCustomClipper(this.isMe);\n\n  @override\n  Path getClip(Size size) {\n    Path path = Path();\n    return isMe\n        ? myCustomRightPath(path, size)\n        : senderCustomLeftPath(path, size);\n  }\n\n  Path myCustomRightPath(Path path, Size size) {\n    double w = size.width;\n    double h = size.height;\n    path.lineTo(w - 2.5, 0);\n    path.quadraticBezierTo(w, 2.5, w - 2.5, 5);\n    path.lineTo(0, h);\n    path.close();\n    return path;\n  }\n\n  Path senderCustomLeftPath(Path path, Size size) {\n    double w = size.width;\n    double h = size.height;\n    path.lineTo(2.5, 0);\n    path.quadraticBezierTo(0, 2.5, 2.5, 5);\n    path.lineTo(w, h);\n    path.lineTo(w, 0);\n    path.close();\n    return path;\n  }\n\n  @override\n  bool shouldReclip(covariant CustomClipper<Path> oldClipper) {\n    return true;\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/chat/components/message/message_replay_card.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../../../../../../core/enums/messge_type.dart';\nimport '../../../../controllers/chat_cubit/chat_cubit.dart';\n\nclass ReplayMessageCard extends StatelessWidget {\n  final bool showCloseButton;\n  final MessageType repliedMessageType;\n  final String text;\n  final bool isMe;\n  final String repliedTo;\n\n  //final MessageReplay messageReplay;\n\n  const ReplayMessageCard({\n    super.key,\n    this.showCloseButton = false,\n    required this.repliedMessageType,\n    required this.text,\n    required this.isMe, required this.repliedTo,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return ClipRRect(\n      borderRadius: BorderRadius.circular(5),\n      child: Container(\n        padding: const EdgeInsets.only(\n          left: 10,\n          right: 5,\n          top: 5,\n          bottom: 8,\n        ),\n        decoration: BoxDecoration(\n          //color: Color(0xffF5F7F6),\n          color: Colors.black.withOpacity(0.03),\n          border: Border(\n            left: BorderSide(\n              color: isMe ? Colors.teal : Colors.deepPurple,\n              width: 5,\n            ),\n          ),\n        ),\n        child: Column(\n          crossAxisAlignment: CrossAxisAlignment.start,\n          children: [\n            Row(\n              children: [\n                Expanded(\n                  child: Text(\n                    isMe ? 'You' : repliedTo,\n                    style: TextStyle(\n                      fontWeight: FontWeight.bold,\n                      color: isMe ? Colors.teal : Colors.deepPurple,\n                    ),\n                  ),\n                ),\n                if (showCloseButton)\n                  GestureDetector(\n                    onTap: () {\n                      ChatCubit.get(context).cancelReplay();\n                    },\n                    child: const Icon(\n                      Icons.close,\n                      size: 16,\n                    ),\n                  )\n              ],\n            ),\n            const SizedBox(height: 8),\n            ReplayMessageContent(\n              repliedMessageType: repliedMessageType,\n              text: text,\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n}\n\nclass ReplayMessageContent extends StatelessWidget {\n  //final MessageReplay messageReplay;\n  final MessageType repliedMessageType;\n  final String text;\n\n  const ReplayMessageContent({\n    super.key,\n    required this.repliedMessageType,\n    required this.text,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    switch (repliedMessageType) {\n      case MessageType.text:\n        return Text(\n          text,\n          style: const TextStyle(color: Colors.black38, fontSize: 14),\n          maxLines: 3,\n          overflow: TextOverflow.ellipsis,\n        );\n      case MessageType.image:\n        return Row(\n          children: const [\n            Icon(Icons.image,color: Colors.black38,),\n            SizedBox(width: 4,),\n            Text(\n              'Photo',\n              style: TextStyle(color: Colors.black38, fontSize: 14),\n            ),\n          ],\n        );\n      case MessageType.gif:\n        return Row(\n          children: const [\n            Icon(Icons.gif),\n            Text(\n              'GIF',\n              style: TextStyle(color: Colors.black38, fontSize: 14),\n            ),\n          ],\n        );\n      case MessageType.video:\n        return Row(\n          children: const [\n            Icon(Icons.videocam),\n            Text(\n              'Video',\n              style: TextStyle(color: Colors.black38, fontSize: 14),\n            ),\n          ],\n        );\n      case MessageType.audio:\n        return Row(\n          children: const [\n            Icon(\n              Icons.mic,\n              size: 18,\n              color: Colors.black38,\n            ),\n            Text(\n              'Voice message',\n              style: TextStyle(color: Colors.black38, fontSize: 14),\n            ),\n          ],\n        );\n      default:\n        return Text(\n          text,\n          maxLines: 3,\n          overflow: TextOverflow.ellipsis,\n        );\n    }\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/chat/components/message/message_replay_preview.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../../../../../../core/shared/message_replay.dart';\nimport 'message_replay_card.dart';\n\nclass MessageReplayPreview extends StatelessWidget {\n  final MessageReplay messageReplay;\n\n  const MessageReplayPreview({\n    super.key,\n    required this.messageReplay,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return Container(\n      padding: const EdgeInsets.all(8),\n      decoration: const BoxDecoration(\n        //color: Colors.white12,\n        color: Colors.white,\n        borderRadius: BorderRadius.only(\n          topRight: Radius.circular(12),\n          topLeft: Radius.circular(12),\n        ),\n      ),\n      child: ReplayMessageCard(\n        //messageReplay: messageReplay,\n        showCloseButton: true,\n        isMe: messageReplay.isMe,\n        text: messageReplay.message,\n        repliedMessageType: messageReplay.messageType,\n        repliedTo: messageReplay.repliedTo,\n      ),\n    );\n  }\n}\n\n"
  },
  {
    "path": "lib/features/presentation/views/chat/components/message/messages_list.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter/scheduler.dart';\n\nimport '/core/extensions/extensions.dart';\nimport '/core/extensions/time_extension.dart';\nimport '../../../../../../core/functions/date_converter.dart';\nimport '../../../../../domain/entities/message.dart';\nimport '../../../../controllers/chat_cubit/chat_cubit.dart';\nimport 'sender_message_card.dart';\nimport 'my_message_card.dart';\n\nclass MessagesList extends StatefulWidget {\n  final String receiverId;\n\n  const MessagesList({\n    super.key,\n    required this.receiverId,\n  });\n\n  @override\n  State<MessagesList> createState() => _MessagesListState();\n}\n\nclass _MessagesListState extends State<MessagesList> {\n  late ScrollController messageController = ScrollController();\n\n\n  void scrollToBottom() {\n    final bottomOffset = messageController.position.maxScrollExtent;\n    messageController.animateTo(\n      bottomOffset,\n      duration: const Duration(milliseconds: 1000),\n      curve: Curves.easeInOut,\n    );\n  }\n  @override\n  void dispose() {\n    messageController.dispose();\n    super.dispose();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    bool isFirst = false;\n    return Expanded(\n      child: StreamBuilder<List<Message>>(\n        stream: ChatCubit.get(context).getChatMessages(widget.receiverId),\n        builder: (context, snapshot) {\n          if (snapshot.connectionState == ConnectionState.waiting) {\n            return const SizedBox();\n          }\n          //to scroll  to bottom\n          SchedulerBinding.instance.addPostFrameCallback((_) {\n            messageController\n                .jumpTo(messageController.position.maxScrollExtent);\n          });\n          return ListView.builder(\n            controller: messageController,\n            itemCount: snapshot.data?.length,\n            shrinkWrap: true,\n            padding: EdgeInsets.only(bottom: 5),\n            physics: const BouncingScrollPhysics(),\n            itemBuilder: (context, index) {\n              var message = snapshot.data![index];\n              ////////////////////////////////////////////\n              isFirst = false;\n              var priviesMessage =\n                  (index > 0) ? snapshot.data![index - 1] : null;\n              //check to make message small bubble for first message\n              if (index == 0 ||\n                  message.senderId != priviesMessage!.senderId ||\n                  !message.timeSent.isSameDay(priviesMessage.timeSent)) {\n                isFirst = true;\n              }\n              /////////////////////////////////////////////\n              //set chat message seen\n              if (!message.isSeen &&\n                  message.receiverId != widget.receiverId) {\n                ChatCubit.get(context).setChatMessageSeen(\n                  receiverId: widget.receiverId,\n                  messageId: message.messageId,\n                );\n              }\n              return Column(\n                children: [\n                  if (index == 0 ||\n                      !DateConverter.isSameDay(\n                        message.timeSent,\n                        snapshot.data![index - 1].timeSent,\n                      ))\n                    ChatTimeCard(dateTime: message.timeSent),\n                  if (message.receiverId == widget.receiverId)\n                    MyMessageCard(\n                      message: message,\n                      isFirst: isFirst,\n                    ),\n                  if (message.receiverId != widget.receiverId)\n                    SenderMessageCard(\n                      message: message,\n                      isFirst: isFirst,\n                    ),\n                ],\n              );\n            },\n          );\n        },\n      ),\n    );\n  }\n}\n\nclass ChatTimeCard extends StatelessWidget {\n  final DateTime dateTime;\n\n  const ChatTimeCard({\n    super.key,\n    required this.dateTime,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return FittedBox(\n      fit: BoxFit.scaleDown,\n      child: Container(\n        margin: const EdgeInsets.all(5),\n        alignment: Alignment.center,\n        padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 8,),\n        decoration: BoxDecoration(\n          color: context.colorScheme.surfaceVariant,\n          borderRadius: BorderRadius.circular(10),\n        ),\n        child: Text(\n          dateTime.chatDayTime,\n          style: context.displaySmall,\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/chat/components/message/my_message_card.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:swipe_to/swipe_to.dart';\n\nimport '/core/extensions/extensions.dart';\nimport '../../../../../domain/entities/message.dart';\nimport '../../../../controllers/chat_cubit/chat_cubit.dart';\nimport 'first_message_small_curved_bubble.dart';\nimport '../message_content/message_content.dart';\nimport 'message_replay_card.dart';\n\nclass MyMessageCard extends StatelessWidget {\n  final Message message;\n  final bool isFirst;\n\n  const MyMessageCard({\n    super.key,\n    required this.message,\n    required this.isFirst,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    final isReplying = message.repliedMessage.isNotEmpty;\n    return SwipeTo(\n      onRightSwipe: () {\n        ChatCubit.get(context).onMessageSwipe(\n          message: message.text,\n          isMe: true,\n          messageType: message.messageType,\n          repliedTo: message.senderName,\n        );\n      },\n      child: Align(\n        alignment: Alignment.centerRight,\n        child: Padding(\n          padding: EdgeInsets.only(top: 5, right: isFirst ? 5 : 15),\n          child: Row(\n            crossAxisAlignment: CrossAxisAlignment.start,\n            mainAxisAlignment: MainAxisAlignment.end,\n            children: [\n              ConstrainedBox(\n                constraints: BoxConstraints(\n                  maxWidth: context.width(0.8),\n                  maxHeight: 400,\n                ),\n                child: Card(\n                  elevation: 2,\n                  margin: const EdgeInsets.all(0),\n                  color: context.colorScheme.surface,\n                  shape: RoundedRectangleBorder(\n                    borderRadius: BorderRadius.only(\n                      topLeft: const Radius.circular(10),\n                      bottomLeft: const Radius.circular(10),\n                      bottomRight: const Radius.circular(10),\n                      topRight:\n                          isFirst ? Radius.zero : const Radius.circular(10),\n                    ),\n                  ),\n                  child: Column(\n                    mainAxisSize: MainAxisSize.min,\n                    crossAxisAlignment: CrossAxisAlignment.end,\n                    children: [\n                      if (isReplying)\n                        Padding(\n                          padding: const EdgeInsets.all(5.0),\n                          child: ReplayMessageCard(\n                            text: message.repliedMessage,\n                            repliedMessageType: message.repliedMessageType,\n                            isMe: message.repliedTo == message.senderName,\n                            repliedTo: message.repliedTo,\n                          ),\n                        ),\n                      MessageContent(\n                        message: message,\n                        isMe: true,\n                      ),\n                    ],\n                  ),\n                ),\n              ),\n              if (isFirst)\n                const FirstMessageSmallCurvedBubble(\n                  isMe: true,\n                ),\n            ],\n          ),\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/chat/components/message/sender_message_card.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:swipe_to/swipe_to.dart';\n\nimport '../../../../../../core/extensions/extensions.dart';\nimport '../../../../../domain/entities/message.dart';\nimport '../../../../controllers/chat_cubit/chat_cubit.dart';\nimport '../message_content/message_content.dart';\nimport 'first_message_small_curved_bubble.dart';\nimport 'message_replay_card.dart';\n\nclass SenderMessageCard extends StatelessWidget {\n  final Message message;\n  final bool isFirst;\n\n  const SenderMessageCard({\n    super.key,\n    required this.message,\n    required this.isFirst,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    final isReplying = message.repliedMessage.isNotEmpty;\n    return SwipeTo(\n      onLeftSwipe: () {\n        ChatCubit.get(context).onMessageSwipe(\n          message: message.text,\n          isMe: false,\n          messageType: message.messageType,\n          repliedTo: message.senderName,\n        );\n      },\n      child: Align(\n        alignment: Alignment.centerLeft,\n        child: Padding(\n          padding: EdgeInsets.only(\n            top: 2.5,\n            left: isFirst ? 5 : 15,\n          ),\n          child: Row(\n            crossAxisAlignment: CrossAxisAlignment.start,\n            mainAxisAlignment: MainAxisAlignment.start,\n            children: [\n              if (isFirst) const FirstMessageSmallCurvedBubble(isMe: false),\n              ConstrainedBox(\n                constraints: BoxConstraints(\n                  maxWidth: context.width(0.8),\n                  maxHeight: 400,\n                ),\n                child: Card(\n                  elevation: 0,\n                  margin: const EdgeInsets.all(0),\n                  color: Colors.white,\n                  shape: RoundedRectangleBorder(\n                    borderRadius: BorderRadius.only(\n                      topRight: const Radius.circular(10),\n                      bottomLeft: const Radius.circular(10),\n                      bottomRight: const Radius.circular(10),\n                      topLeft:\n                          isFirst ? Radius.zero : const Radius.circular(10),\n                    ),\n                  ),\n                  child: Column(\n                    mainAxisSize: MainAxisSize.min,\n                    crossAxisAlignment: CrossAxisAlignment.end,\n                    children: [\n                      if (isReplying)\n                        Padding(\n                          padding: const EdgeInsets.all(5.0),\n                          child: ReplayMessageCard(\n                            text: message.repliedMessage,\n                            repliedMessageType: message.repliedMessageType,\n                            isMe: message.repliedTo != message.senderName,\n                            repliedTo: message.repliedTo,\n                          ),\n                        ),\n                      MessageContent(message: message, isMe: false),\n                    ],\n                  ),\n                ),\n              ),\n            ],\n          ),\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/chat/components/message_content/audio_player_widget.dart",
    "content": "import 'package:audioplayers/audioplayers.dart';\nimport 'package:flutter/material.dart';\nimport 'package:whatsapp_flutter_clone/core/utils/constants/assets_manager.dart';\nimport 'package:whatsapp_flutter_clone/features/domain/entities/message.dart';\nimport 'package:whatsapp_flutter_clone/features/presentation/views/chat/components/message_content/time_sent_widget.dart';\n\nclass AudioPlayerWidget extends StatefulWidget {\n  final Message message;\n  final bool isMe;\n\n  const AudioPlayerWidget({\n    super.key,\n    required this.message,\n    required this.isMe,\n  });\n\n  @override\n  State<AudioPlayerWidget> createState() => _AudioPlayerWidgetState();\n}\n\nclass _AudioPlayerWidgetState extends State<AudioPlayerWidget> {\n  AudioPlayer audioPlayer = AudioPlayer();\n  Duration? totalDuration;\n  Duration? newTiming;\n\n  bool isPlaying = false;\n\n  void initAudio() {\n    debugPrint(\"Audio Initialized\");\n    audioPlayer.play(UrlSource(widget.message.text));\n    audioPlayer.getDuration().then((value) {\n      debugPrint(value.toString());\n    });\n    audioPlayer.onPositionChanged.listen((event) {\n      setState(() {\n        newTiming = event;\n      });\n    });\n    audioPlayer.onDurationChanged.listen((updatedDuration) {\n      totalDuration = updatedDuration;\n    });\n  }\n\n  void pauseAudio() {\n    audioPlayer.pause();\n  }\n\n void stopAudio() {\n    audioPlayer.stop();\n  }\n\n  void seekAudio(Duration durationToSeek) {\n    audioPlayer.seek(durationToSeek);\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Padding(\n      padding: const EdgeInsets.all(5.0),\n      child: Row(\n        crossAxisAlignment: CrossAxisAlignment.start,\n        children: [\n          SizedBox(\n            height: 55,\n            child: Stack(\n              children: [\n                CircleAvatar(\n                  radius: 25,\n                  backgroundColor: Colors.white,\n                  child: Image.asset(AppImage.genericProfileImage,),\n                ),\n                const Positioned(\n                  bottom: 0,\n                  right: 0,\n                  child: Icon(\n                    Icons.mic,\n                    color: Colors.black54,\n                  ),\n                ),\n              ],\n            ),\n          ),\n          GestureDetector(\n            onTap: () {\n              if (isPlaying) {\n                pauseAudio();\n                setState(() {\n                  isPlaying = !isPlaying;\n                });\n              } else {\n                if (newTiming.toString() == \"null\") {\n                  initAudio();\n                } else {\n                  audioPlayer.resume();\n                }\n                setState(() {\n                  isPlaying = !isPlaying;\n                });\n              }\n            },\n            child: Icon(\n              isPlaying ? Icons.pause : Icons.play_arrow_rounded,\n              size: 40,\n              color: Colors.black54,\n            ),\n          ),\n          Expanded(\n            child: Column(\n              mainAxisSize: MainAxisSize.min,\n              children: [\n                SizedBox(\n                  height: 35,\n                  child: Slider(\n                    value: newTiming == null\n                        ? 0\n                        : newTiming!.inMilliseconds.toDouble(),\n                    min: 0,\n                    max: totalDuration == null\n                        ? 20\n                        : totalDuration!.inMilliseconds.toDouble(),\n                    activeColor: Colors.grey,\n\n                    inactiveColor: Colors.black38,\n                    onChanged: (value) {\n                      setState(() {\n                        seekAudio(Duration(milliseconds: value.toInt()));\n                      });\n                    },\n                  ),\n                ),\n                Row(\n                  mainAxisAlignment: MainAxisAlignment.spaceBetween,\n                  children: [\n                    Text(\n                      (newTiming.toString() == \"null\")\n                          ? \"0:00\"\n                          : newTiming.toString().split('.').first,\n                      style: const TextStyle(color: Colors.grey, fontSize: 14),\n                    ),\n                    TimeSentWidget(\n                        message: widget.message,\n                        isMe: widget.isMe,\n                        textColor: Colors.grey)\n                  ],\n                )\n              ],\n            ),\n          ),\n        ],\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/chat/components/message_content/image_widget.dart",
    "content": "import 'package:cached_network_image/cached_network_image.dart';\nimport 'package:flutter/material.dart';\nimport 'package:whatsapp_flutter_clone/features/presentation/views/chat/components/message_content/time_sent_widget.dart';\n\nimport '../../../../../domain/entities/message.dart';\n\nclass ImageWidget extends StatelessWidget {\n  const ImageWidget({\n  super.key,\n  required this.message,\n  required this.isMe,\n  });\n\n  final Message message;\n  final bool isMe;\n\n  @override\n  Widget build(BuildContext context) {\n    return Padding(\n      padding: const EdgeInsets.all(5),\n      child: ClipRRect(\n        borderRadius: BorderRadius.circular(10),\n        child: Stack(\n          children: [\n            CachedNetworkImage(\n              imageUrl: message.text,\n              fit: BoxFit.cover,\n              maxHeightDiskCache: 390,\n              placeholder: (context, url) => const SizedBox(),\n            ),\n            Positioned(\n              bottom: 4,\n              right: 8,\n              child: TimeSentWidget(\n                message: message,\n                isMe: isMe,\n                textColor: Colors.white,\n              ),\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n}"
  },
  {
    "path": "lib/features/presentation/views/chat/components/message_content/message_content.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../../../../../../core/enums/messge_type.dart';\nimport '../../../../../domain/entities/message.dart';\nimport 'audio_player_widget.dart';\nimport 'image_widget.dart';\nimport 'text_widget.dart';\nimport 'video_palyer_widget.dart';\n\nclass MessageContent extends StatelessWidget {\n  final Message message;\n  final bool isMe;\n\n  const MessageContent({\n    super.key,\n    required this.message,\n    required this.isMe,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    switch (message.messageType) {\n      case MessageType.text:\n        return TextWidget(message: message, isMe: isMe);\n      case MessageType.image:\n        return ImageWidget(message: message, isMe: isMe);\n      case MessageType.video:\n        return VideoPlayerItem(message: message, isMe: isMe);\n      case MessageType.audio:\n        return AudioPlayerWidget(message: message, isMe: isMe);\n      default:\n        return TextWidget(message: message, isMe: isMe);\n    }\n  }\n}"
  },
  {
    "path": "lib/features/presentation/views/chat/components/message_content/text_widget.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '/features/presentation/views/chat/components/message_content/time_sent_widget.dart';\nimport '/core/extensions/extensions.dart';\nimport '../../../../../domain/entities/message.dart';\n\nclass TextWidget extends StatelessWidget {\n  const TextWidget({\n  super.key,\n  required this.message,\n  required this.isMe,\n  });\n\n  final Message message;\n  final bool isMe;\n\n  @override\n  Widget build(BuildContext context) {\n    return Wrap(\n      crossAxisAlignment: WrapCrossAlignment.end,\n      alignment: WrapAlignment.end,\n      children: [\n        Padding(\n          padding: const EdgeInsets.all(8.0),\n          child: Text(\n            message.text,\n            style: context.displaySmall,\n            overflow: TextOverflow.visible,\n          ),\n        ),\n        TimeSentWidget(\n          message: message,\n          isMe: isMe,\n          textColor: Colors.grey,\n        ),\n      ],\n    );\n  }\n}"
  },
  {
    "path": "lib/features/presentation/views/chat/components/message_content/time_sent_widget.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '/core/extensions/extensions.dart';\nimport '/core/extensions/time_extension.dart';\nimport '../../../../../domain/entities/message.dart';\n\nclass TimeSentWidget extends StatelessWidget {\n  const TimeSentWidget({\n  super.key,\n  required this.message,\n  required this.isMe,\n  required this.textColor,\n  });\n\n  final Message message;\n  final bool isMe;\n  final Color textColor;\n\n  @override\n  Widget build(BuildContext context) {\n    return Padding(\n      padding: const EdgeInsets.only(right: 4, bottom: 4),\n      child: Row(\n        mainAxisSize: MainAxisSize.min,\n        children: [\n          Text(\n            message.timeSent.amPmMode,\n            style:  TextStyle(\n              fontSize: 13,\n              color: textColor,\n            ),\n          ),\n          const SizedBox(\n            width: 5,\n          ),\n          if (isMe)\n            Icon(\n              Icons.done_all,\n              size: 20,\n              color: message.isSeen ? context.colorScheme.onTertiary : textColor,\n            ),\n        ],\n      ),\n    );\n  }\n}"
  },
  {
    "path": "lib/features/presentation/views/chat/components/message_content/video_palyer_widget.dart",
    "content": "import 'package:cached_video_player/cached_video_player.dart';\nimport 'package:flutter/material.dart';\nimport 'package:whatsapp_flutter_clone/features/presentation/views/chat/components/message_content/time_sent_widget.dart';\n\nimport '../../../../../domain/entities/message.dart';\n\nclass VideoPlayerItem extends StatefulWidget {\n  final Message message;\n  final bool isMe;\n\n  const VideoPlayerItem({\n    super.key,\n    required this.message,\n    required this.isMe,\n  });\n\n  @override\n  _VideoPlayerItemState createState() => _VideoPlayerItemState();\n}\n\nclass _VideoPlayerItemState extends State<VideoPlayerItem> {\n  late CachedVideoPlayerController videoPlayerController;\n  bool isPlay = false;\n\n  @override\n  void initState() {\n    super.initState();\n    videoPlayerController =\n        CachedVideoPlayerController.network(widget.message.text)\n          ..initialize().then((value) {\n            videoPlayerController.setVolume(1);\n          });\n  }\n\n  @override\n  void dispose() {\n    super.dispose();\n    videoPlayerController.dispose();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Padding(\n      padding: const EdgeInsets.all(5.0),\n      child: ClipRRect(\n        borderRadius: BorderRadius.circular(10),\n        child: AspectRatio(\n          aspectRatio: 16 / 9,\n          child: Stack(\n            children: [\n              CachedVideoPlayer(videoPlayerController),\n              Align(\n                alignment: Alignment.center,\n                child: IconButton(\n                  onPressed: () {\n                    if (isPlay) {\n                      videoPlayerController.pause();\n                    } else {\n                      videoPlayerController.play();\n                    }\n                    setState(() {\n                      isPlay = !isPlay;\n                    });\n                  },\n                  icon: Icon(\n                    isPlay ? Icons.pause_circle : Icons.play_circle,\n                    size: 40,\n                  ),\n                ),\n              ),\n              Positioned(\n                bottom: 0,\n                right: 4,\n                child: TimeSentWidget(\n                  message: widget.message,\n                  isMe: widget.isMe,\n                  textColor: Colors.white,\n                ),\n              ),\n            ],\n          ),\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/contacts_chat/components/chat_contact_card.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '/core/extensions/time_extension.dart';\nimport '../../../../../core/functions/navigator.dart';\nimport '../../../../../core/utils/routes/routes_manager.dart';\nimport '../../../../domain/entities/contact_chat.dart';\nimport '../../../components/contact_profile_pic_dialog.dart';\nimport '../../../components/custom_list_tile.dart';\nimport '../../../components/my_cached_net_image.dart';\nimport '../../../controllers/chat_cubit/chat_cubit.dart';\n\nclass ChatContactCard extends StatelessWidget {\n  final ContactChat chatContact;\n\n  //final String? name;\n\n  const ChatContactCard({\n    super.key,\n    required this.chatContact,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    // this stream to get num of message not seen\n    return StreamBuilder<int>(\n      stream: ChatCubit.get(context).numOfMessageNotSeen(chatContact.contactId),\n      builder: (context, snapshot) {\n        return CustomListTile(\n          title: chatContact.name,\n          onTap: () {\n            navigateTo(context, Routes.chatRoute, arguments: {\n              'name': chatContact.name,\n              'uId': chatContact.contactId,\n            });\n          },\n          subTitle: chatContact.lastMessage,\n          time: chatContact.timeSent.chatContactTime,\n          numOfMessageNotSeen: snapshot.data ?? 0,\n          leading: Hero(\n            tag: chatContact.contactId,\n            child: InkWell(\n              borderRadius: BorderRadius.circular(25),\n              onTap: () {\n                showContactProfilePicDialog(context, contact: chatContact,);\n              },\n              child: MyCachedNetImage(\n                imageUrl: chatContact.profilePic,\n                radius: 30,\n              ),\n            ),\n          ),\n        );\n      },\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/contacts_chat/contacts_chat_page.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../../../domain/entities/contact_chat.dart';\nimport '../../components/loader.dart';\nimport '../../controllers/chat_cubit/chat_cubit.dart';\nimport 'components/chat_contact_card.dart';\n\nclass ContactsChatPage extends StatelessWidget {\n  const ContactsChatPage({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return StreamBuilder<List<ContactChat>>(\n      stream: ChatCubit.get(context).getContactsChat({}),\n      builder: (context, snapshot) {\n        if (snapshot.connectionState == ConnectionState.waiting) {\n          return const Loader();\n        }\n        return ListView.builder(\n          padding: const EdgeInsets.only(top: 10),\n          itemCount: snapshot.data!.length,\n          shrinkWrap: true,\n          physics: const BouncingScrollPhysics(),\n          itemBuilder: (context, index) {\n            return ChatContactCard(\n              chatContact: snapshot.data![index],\n            );\n          },\n        );\n      },\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/login/components/landing_image.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../../../../../core/extensions/extensions.dart';\nimport '../../../../../core/utils/constants/assets_manager.dart';\n\nclass LandingImage extends StatelessWidget {\n  const LandingImage({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return Image.asset(\n      AppImage.landingImg,\n      width: context.width(0.65),\n      color: context.colorScheme.onSecondaryContainer,\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/login/components/login_appbar.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter/services.dart';\nimport '/core/extensions/extensions.dart';\n\n\nclass LoginAppBar extends StatelessWidget implements PreferredSizeWidget {\n  final List<Widget>? actions;\n  final Widget? title;\n\n  const LoginAppBar({\n    super.key,\n    this.actions,\n    this.title,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return AppBar(\n      centerTitle: true,\n      systemOverlayStyle: SystemUiOverlayStyle(\n        statusBarColor: context.theme.scaffoldBackgroundColor,\n        statusBarIconBrightness: _brightness(context),\n        statusBarBrightness: _brightness(context),\n      ),\n      backgroundColor: context.theme.scaffoldBackgroundColor,\n      title: title,\n      actions: actions,\n    );\n  }\n\n  Brightness _brightness(BuildContext context) {\n    return context.theme.brightness == Brightness.light\n        ? Brightness.dark\n        : Brightness.light;\n  }\n\n  @override\n  Size get preferredSize => const Size.fromHeight(kToolbarHeight);\n}\n"
  },
  {
    "path": "lib/features/presentation/views/login/components/login_profile_pic.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '/core/extensions/extensions.dart';\nimport '../../../components/update_profile_pic_model_bottom_sheet.dart';\n\n\nclass LoginProfilePic extends StatelessWidget {\n  const LoginProfilePic({\n  super.key,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return GestureDetector(\n      onTap: () {\n        showUpdateProfilePicModelBottomSheet(context);\n      },\n      child: CircleAvatar(\n        radius: 60,\n        backgroundColor: context.colorScheme.onSurface,\n        child: const Icon(\n          Icons.add_a_photo,\n          color: Colors.grey,\n          size: 45,\n        ),\n      ),\n    );\n  }\n}\n\n"
  },
  {
    "path": "lib/features/presentation/views/login/components/privacy_policy_link_and_terms_of_service.dart",
    "content": "import 'package:flutter/gestures.dart';\nimport 'package:flutter/material.dart';\n\nimport '../../../../../core/extensions/extensions.dart';\nimport '../../../../../core/utils/constants/strings_manager.dart';\nimport '../../../../../core/utils/constants/values_manager.dart';\n\nclass PrivacyPolicyLinkAndTermsOfService extends StatelessWidget {\n  const PrivacyPolicyLinkAndTermsOfService({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return Container(\n      alignment: Alignment.center,\n      padding: const EdgeInsets.all(AppPadding.p10),\n      child: Center(\n        child: Text.rich(\n          //style: context.bodyMedium,\n          style: context.titleMedium,\n          textAlign: TextAlign.center,\n          TextSpan(\n            children: <TextSpan>[\n              const TextSpan(\n                text: AppStrings.readOur,\n              ),\n              buildTextSpanBlueButton(\n                text: AppStrings.privacyPolicy,\n                onTap: () {\n                  // code to open / launch terms of service link here\n                },\n                context: context,\n              ),\n              const TextSpan(\n                text: AppStrings.tapAgreeAnd,\n              ),\n              buildTextSpanBlueButton(\n                text: AppStrings.termsOfService,\n                onTap: () {\n                  // code to open / launch terms of service link here\n                },\n                context: context,\n              ),\n            ],\n          ),\n        ),\n      ),\n    );\n  }\n\n  TextSpan buildTextSpanBlueButton({\n    required String text,\n    required VoidCallback onTap,\n    required BuildContext context,\n  }) {\n    return TextSpan(\n      text: text,\n      /*\n      style: context.bodyMedium!.copyWith(\n            color: AppColors.checkMarkBlue,\n          ),\n       */\n      style: context.titleMedium!.copyWith(\n        color: context.colorScheme.onTertiary,\n      ),\n      recognizer: TapGestureRecognizer()..onTap = onTap,\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/login/components/sign_out_button.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\n\nimport '../../../../../core/functions/navigator.dart';\nimport '../../../../../core/utils/routes/routes_manager.dart';\nimport '../../../components/default_button.dart';\nimport '../../../controllers/auth_cubit/auth_cubit.dart';\n\nclass SignOutButton extends StatelessWidget {\n  const SignOutButton\n\n  ({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return BlocConsumer<AuthCubit, AuthState>(\n      listener: (context, state) {\n        if(state is SignOutSuccessState){\n          navigateAndRemove(context, Routes.landingRoute);\n        }\n      },\n      builder: (context, state) {\n        return DefaultButton(\n          text: 'signout',\n          onPress: () {\n            AuthCubit.get(context).signOut();\n          },\n        );\n      },\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/login/login_landing_screen.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../../../../core/extensions/extensions.dart';\nimport '../../../../core/functions/navigator.dart';\nimport '../../../../core/utils/constants/strings_manager.dart';\nimport '../../../../core/utils/constants/values_manager.dart';\nimport '../../../../core/utils/routes/routes_manager.dart';\nimport '../../components/default_button.dart';\nimport 'components/landing_image.dart';\nimport 'components/login_appbar.dart';\nimport 'components/privacy_policy_link_and_terms_of_service.dart';\n\nclass LandingScreen extends StatelessWidget {\n  const LandingScreen({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: const LoginAppBar(),\n      body: SafeArea(\n        child: Column(\n          children: [\n            Text(\n              AppStrings.welcomeToWhatsApp,\n              style: context.displayLarge!.copyWith(\n                fontSize: 28,\n              ),\n            ),\n            const Spacer(),\n            const LandingImage(),\n            const Spacer(),\n            const PrivacyPolicyLinkAndTermsOfService(),\n            const SizedBox(height: AppSize.s14),\n            DefaultButton(\n              text: AppStrings.agreeAndContinue,\n              width: context.width(0.7),\n              onPress: ()  {\n                navigateAndReplace(context, Routes.loginRoute);\n              },\n            ),\n            const SizedBox(height: AppSize.s80),\n          ],\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/login/login_loading_screen.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\n\nimport '../../../../core/extensions/extensions.dart';\nimport '../../../../core/functions/navigator.dart';\nimport '../../../../core/shared/commen.dart';\nimport '../../../../core/utils/constants/strings_manager.dart';\nimport '../../../../core/utils/routes/routes_manager.dart';\nimport '../../controllers/auth_cubit/auth_cubit.dart';\nimport 'components/landing_image.dart';\nimport 'components/login_appbar.dart';\n\nclass LoginLoadingScreen extends StatelessWidget {\n  const LoginLoadingScreen({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return BlocConsumer<AuthCubit, AuthState>(\n      listener: (context, state) {\n        if (state is SaveUserDataToFirebaseSuccessState) {\n          navigateAndRemove(context, Routes.mainLayoutRoute);\n          /*\n          if (kDebugMode) {\n            print('lllll');\n          }\n          sl<CacheHelper>()\n              .saveData(\n            key: AppStrings.uId,\n            value: sl<GetCurrentUidUseCase>().toString(),\n          )\n              .then((value) {\n            Navigator.of(context).pushNamedAndRemoveUntil(\n              Routes.mainLayoutRoute,\n              (route) => false,\n            );\n          });\n          */\n        }\n        if (state is SaveUserDataToFirebaseErrorState) {\n          showSnackBar(context: context, content: 'content err');\n        }\n      },\n      builder: (context, state) {\n        return Scaffold(\n          appBar: const LoginAppBar(\n            title: Text(\n              AppStrings.initializing,\n            ),\n          ),\n          body: Center(\n            child: Column(\n              crossAxisAlignment: CrossAxisAlignment.center,\n              children: [\n                Text(\n                  AppStrings.pleaseWaitAMoment,\n                  style: context.displayLarge,\n                ),\n                const Spacer(),\n                const LandingImage(),\n                const Spacer(),\n                const CircularProgressIndicator(),\n                const SizedBox(height: 60),\n              ],\n            ),\n          ),\n        );\n      },\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/login/login_otp_screen.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\nimport 'package:sms_autofill/sms_autofill.dart';\n\nimport '../../../../core/extensions/extensions.dart';\nimport '../../../../core/functions/navigator.dart';\nimport '../../../../core/utils/constants/font_manager.dart';\nimport '../../../../core/utils/constants/strings_manager.dart';\nimport '../../../../core/utils/constants/values_manager.dart';\nimport '../../../../core/utils/routes/routes_manager.dart';\nimport '../../controllers/auth_cubit/auth_cubit.dart';\nimport 'components/login_appbar.dart';\n\nclass OtpScreen extends StatefulWidget {\n  final String phoneNumber;\n\n  const OtpScreen({super.key, required this.phoneNumber});\n\n  @override\n  State<OtpScreen> createState() => _OtpScreenState();\n}\n\nclass _OtpScreenState extends State<OtpScreen> {\n\n  @override\n  void initState() {\n    super.initState();\n    _listenSmsCode();\n  }\n\n  _listenSmsCode() async {\n    await SmsAutoFill().listenForCode();\n  }\n  @override\n  void dispose() {\n    SmsAutoFill().unregisterListener();\n    super.dispose();\n  }\n  @override\n  Widget build(BuildContext context) {\n    return BlocConsumer<AuthCubit, AuthState>(\n      listener: (context, state) {\n        if (state is VerifyOtpSuccessState) {\n          navigateAndRemove(context, Routes.loginProfileInfoRoute);\n        }\n      },\n      builder: (context, state) {\n        AuthCubit cubit = AuthCubit.get(context);\n        return Scaffold(\n          appBar: LoginAppBar(\n            title: Text(\n              AppStrings.verifyingYourNumber,\n              style: context.displayLarge,\n            ),\n          ),\n          body: Padding(\n            padding: const EdgeInsets.symmetric(horizontal: AppPadding.p20),\n            child: Column(\n              children: [\n                Text(\n                  AppStrings.waitingToDetectSms,\n                  style: context.titleSmall,\n                ),\n                Row(\n                  mainAxisAlignment: MainAxisAlignment.center,\n                  children: [\n                    Text(\n                      widget.phoneNumber,\n                      style: const TextStyle(\n                        color: Colors.black,\n                        fontSize: 14,\n                        fontWeight: FontWeightManager.semiBold,\n                      ),\n                    ),\n                    TextButton(\n                      onPressed: () {},\n                      child: const Text(\n                        AppStrings.wrongNumber,\n                      ),\n                    ),\n                  ],\n                ),\n                SizedBox(\n                  width: context.width(0.45),\n                  child: PinFieldAutoFill(\n                    codeLength: 6,\n                    autoFocus: true,\n                    cursor: Cursor(\n                      color: context.colorScheme.secondary,\n                      enabled: true,\n                      height: 30,\n                    ),\n                    onCodeChanged: (value) {\n                      if (value!.length == 6) {\n                        cubit.verifyOtp(smsOtpCode: value.trim());\n                      }\n                    },\n                  ),\n                  /*\n                  child: TextField(\n                    keyboardType: TextInputType.number,\n                    onChanged: (val) {\n                      if (val.length == 6) {\n                        cubit.verifyOtp(smsOtpCode: val.trim());\n                      }\n                    },\n                    decoration: const InputDecoration(\n                      hintText: ' __  __ __ __',\n                      hintStyle: TextStyle(\n                        fontSize: 20,\n                      ),\n                    ),\n                  ),\n\n                   */\n                ),\n                Padding(\n                  padding: const EdgeInsets.symmetric(vertical: AppPadding.p18),\n                  child: Text(\n                    AppStrings.enter6DigitCode,\n                    style: context.bodySmall,\n                  ),\n                ),\n                Row(\n                  children: [\n                    const Icon(\n                      Icons.message,\n                      color: Colors.grey,\n                    ),\n                    const SizedBox(\n                      width: 16,\n                    ),\n                    const Text(\n                      AppStrings.resendSms,\n                      style: TextStyle(\n                        color: Colors.grey,\n                      ),\n                    ),\n                    const Spacer(),\n                    TweenAnimationBuilder(\n                      tween: Tween(begin: 60.0, end: 0),\n                      duration: const Duration(seconds: 60),\n                      builder: (context, value, child) => Text(\n                        '00:${value.toInt()}',\n                        style: const TextStyle(\n                          color: Colors.grey,\n                        ),\n                      ),\n                      onEnd: () {},\n                    ),\n                  ],\n                ),\n              ],\n            ),\n          ),\n        );\n      },\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/login/login_profile_info_screen.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\n\nimport '/core/extensions/extensions.dart';\nimport '../../../../core/functions/navigator.dart';\nimport '../../../../core/utils/constants/strings_manager.dart';\nimport '../../../../core/utils/constants/values_manager.dart';\nimport '../../../../core/utils/routes/routes_manager.dart';\nimport '../../controllers/auth_cubit/auth_cubit.dart';\nimport '../../controllers/select_contact_cubit/select_contact_cubit.dart';\nimport 'components/login_appbar.dart';\nimport 'components/login_profile_pic.dart';\n\nclass LoginProfileInfoScreen extends StatefulWidget {\n  const LoginProfileInfoScreen({super.key});\n\n  @override\n  State<LoginProfileInfoScreen> createState() => _LoginProfileInfoScreenState();\n}\n\nclass _LoginProfileInfoScreenState extends State<LoginProfileInfoScreen> {\n  TextEditingController nameController = TextEditingController();\n\n  @override\n  Widget build(BuildContext context) {\n    return Builder(builder: (context) {\n      SelectContactCubit.get(context).getAllContacts().then((value) {\n        SelectContactCubit.get(context).getContactsOnWhatsApp();\n        SelectContactCubit.get(context).getContactsNotOnWhatsApp();\n      });\n      return BlocConsumer<AuthCubit, AuthState>(\n        listener: (context, state) {\n          if (state is SaveUserDataToFirebaseLoadingState) {\n            navigateAndRemove(context, Routes.loginLoadingRoute);\n          }\n        },\n        builder: (context, state) {\n          AuthCubit cubit = AuthCubit.get(context);\n          return Scaffold(\n            appBar: LoginAppBar(\n              title: Text(\n                AppStrings.profileInfo,\n                style: context.displayLarge,\n              ),\n            ),\n            body: Padding(\n              padding: const EdgeInsets.all(AppPadding.p18),\n              child: Column(\n                children: [\n                  Text(\n                    AppStrings.pleaseProvideYourName,\n                    textAlign: TextAlign.center,\n                    style: context.titleMedium,\n                  ),\n                  const SizedBox(height: 20),\n                  const LoginProfilePic(),\n                  const SizedBox(height: 20),\n                  Row(\n                    children: [\n                      Expanded(\n                        child: TextField(\n                          cursorHeight: 30,\n                          controller: nameController,\n                          cursorColor: context.colorScheme.secondary,\n                          decoration: const InputDecoration(\n                            hintText: AppStrings.typeYourNameHere,\n                          ),\n                        ),\n                      ),\n                      IconButton(\n                        onPressed: () {},\n                        icon: const Icon(\n                          Icons.emoji_emotions_outlined,\n                          color: Colors.grey,\n                        ),\n                      ),\n                    ],\n                  ),\n                  const Spacer(),\n                  ElevatedButton(\n                    onPressed: () {\n                      if (nameController.text.length > 4) {\n                        cubit.saveUserDataToFirebase(\n                          name: nameController.text,\n                        );\n                      }\n                    },\n                    child: const Text(\n                      AppStrings.next,\n                    ),\n                  ),\n                ],\n              ),\n            ),\n          );\n        },\n      );\n    },);\n  }\n\n  @override\n  void dispose() {\n    nameController.dispose();\n    super.dispose();\n  }\n}\n\n"
  },
  {
    "path": "lib/features/presentation/views/login/login_screen.dart",
    "content": "import 'package:country_picker/country_picker.dart';\nimport 'package:flutter/material.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\n\nimport '../../../../core/extensions/extensions.dart';\nimport '../../../../core/functions/navigator.dart';\nimport '../../../../core/functions/app_dialogs.dart';\nimport '../../../../core/utils/constants/strings_manager.dart';\nimport '../../../../core/utils/constants/values_manager.dart';\nimport '../../../../core/utils/routes/routes_manager.dart';\nimport '../../components/default_button.dart';\nimport '../../controllers/auth_cubit/auth_cubit.dart';\nimport 'components/login_appbar.dart';\n\nclass LoginScreen extends StatefulWidget {\n  const LoginScreen({super.key});\n\n  @override\n  State<LoginScreen> createState() => _LoginScreenState();\n}\n\nclass _LoginScreenState extends State<LoginScreen> {\n  TextEditingController phoneController = TextEditingController();\n  TextEditingController countryCodeController = TextEditingController();\n  late String phoneNumber;\n\n  @override\n  Widget build(BuildContext context) {\n    return BlocConsumer<AuthCubit, AuthState>(\n      listener: (context, state) {\n        if (state is SignInSuccessState) {\n          navigateAndRemove(context, Routes.otpRoute, arguments: phoneNumber);\n        }\n      },\n      builder: (context, state) {\n        AuthCubit cubit = AuthCubit.get(context);\n        return Scaffold(\n          appBar: LoginAppBar(\n            title: Text(\n              AppStrings.enterYourPhoneNumber,\n              style: context.displayLarge,\n            ),\n            actions: [\n              IconButton(\n                onPressed: () {},\n                icon: Icon(\n                  Icons.more_vert,\n                  color: context.colorScheme.onSurfaceVariant,\n                ),\n              ),\n            ],\n          ),\n          body: Padding(\n            padding: const EdgeInsets.symmetric(horizontal: AppPadding.p14),\n            child: Center(\n              child: Column(\n                mainAxisAlignment: MainAxisAlignment.center,\n                children: [\n                  Text(\n                    AppStrings.whatsAppWillNeed,\n                    textAlign: TextAlign.center,\n                    //style: context.bodyLarge,\n                    style: context.titleSmall,\n                  ),\n                  TextButton(\n                    onPressed: () {\n                      AppDialogs.permissionDialog(\n                        context,\n                        onContinuePressed: () {},\n                        contentText: AppStrings.toRetrieveYourPhone,\n                      );\n                    },\n                    child: const Text(\n                      AppStrings.whatIsMyNumber,\n                    ),\n                  ),\n                  SizedBox(\n                    width: context.width(0.7),\n                    child: Column(\n                      children: [\n                        Row(\n                          children: [\n                            Expanded(\n                              child: Center(\n                                child: InkWell(\n                                  onTap: () {\n                                    showCountryPicker(\n                                      context: context,\n                                      showPhoneCode: true,\n                                      onSelect: (myCountry) {\n                                        cubit.setCountry(myCountry);\n                                        countryCodeController.text =\n                                            cubit.country!.phoneCode;\n                                      },\n                                    );\n                                  },\n                                  child: Text(\n                                    cubit.country == null\n                                        ? AppStrings.pickCountry\n                                        : cubit.country!.name,\n                                    textAlign: TextAlign.center,\n                                    style: context.titleLarge,\n                                  ),\n                                ),\n                              ),\n                            ),\n                            Icon(\n                              Icons.arrow_drop_down,\n                              color: context.colorScheme.primary,\n                              size: AppSize.s28,\n                            ),\n                          ],\n                        ),\n                        const Divider(\n                          height: 0,\n                          thickness: 0.7,\n                        ),\n                        Row(\n                          children: [\n                            SizedBox(\n                              width: AppSize.s60,\n                              child: TextField(\n                                //enabled: false,\n                                readOnly: true,\n                                controller: countryCodeController,\n                                style: TextStyle(\n                                    color: context\n                                        .colorScheme.onTertiaryContainer),\n                                decoration: InputDecoration(\n                                  prefix: Container(\n                                    margin: const EdgeInsets.only(right: 10),\n                                    width: 10,\n                                    alignment: Alignment.bottomLeft,\n                                    child: Text(\n                                      '+',\n                                      style: context.titleLarge!.copyWith(\n                                          color: context\n                                              .colorScheme.onTertiaryContainer),\n                                    ),\n                                  ),\n                                ),\n                              ),\n                            ),\n                            const SizedBox(\n                              width: AppSize.s14,\n                            ),\n                            Expanded(\n                              child: TextField(\n                                controller: phoneController,\n                                keyboardType: TextInputType.phone,\n                                cursorColor: context.colorScheme.secondary,\n                                cursorHeight: 30,\n                                style: TextStyle(\n                                    color: context\n                                        .colorScheme.onTertiaryContainer),\n                                decoration: const InputDecoration(\n                                  hintText: AppStrings.phoneNumber,\n                                ),\n                              ),\n                            ),\n                          ],\n                        ),\n                        const SizedBox(height: AppSize.s12),\n                        Text(\n                          AppStrings.carrierChargesMayApply,\n                          style: context.titleMedium,\n                        ),\n                      ],\n                    ),\n                  ),\n                  const Spacer(),\n                  DefaultButton(\n                    text: AppStrings.next,\n                    onPress: ()  {\n                      if (phoneController.text.isNotEmpty &&\n                          countryCodeController.text.isNotEmpty) {\n                        String number = phoneController.text.trim();\n                        phoneNumber = '+${countryCodeController.text}$number';\n                        AppDialogs.submitPhoneDialog(\n                          context: context,\n                          phoneNumber:\n                              '+${countryCodeController.text} ${phoneController.text}',\n                          okPressed: () {\n                            navigatePop(context);\n                            cubit.signInWithPhoneNumber(\n                                phoneNumber: phoneNumber,);\n                          },\n                        );\n                      }\n                    },\n                  ),\n                  const SizedBox(\n                    height: AppSize.s28,\n                  ),\n                ],\n              ),\n            ),\n          ),\n        );\n      },\n    );\n  }\n\n  @override\n  void dispose() {\n    super.dispose();\n    phoneController.dispose();\n    countryCodeController.dispose();\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/main_layout/components/fab.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../../../../../core/functions/navigator.dart';\nimport '../../../../../core/utils/routes/routes_manager.dart';\n\nclass FAB extends StatelessWidget {\n  final int index;\n  const FAB({\n  super.key, required this.index,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    switch(index){\n      case 0:\n        return const ChatsFAB();\n      case 1:\n        return const StatusTwoFAB();\n      case 2:\n        return const CallsFAB();\n      default:\n        return const ChatsFAB();\n    }\n\n  }\n}\n\nclass CallsFAB extends StatelessWidget {\n  const CallsFAB({\n    super.key,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return FloatingActionButton(\n      onPressed: () {},\n      child: const Icon(Icons.add_ic_call_rounded),\n    );\n  }\n}\n\nclass ChatsFAB extends StatelessWidget {\n  const ChatsFAB({\n    super.key,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return FloatingActionButton(\n      onPressed: () {\n        navigateTo(context, Routes.selectContactRoute);\n      },\n      child: const Icon(Icons.message),\n    );\n  }\n}\n\nclass StatusTwoFAB extends StatelessWidget {\n  const StatusTwoFAB({\n    super.key,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return Column(\n      mainAxisAlignment: MainAxisAlignment.end,\n      children: [\n        SizedBox(\n          width: 45,\n          child: FloatingActionButton(\n            onPressed: () {},\n            backgroundColor: const Color(0XFFE9EDEF),\n            child: const Icon(Icons.edit,color: Colors.black54,),\n          ),\n        ),\n        const SizedBox(height: 10),\n        FloatingActionButton(\n          onPressed: () {},\n          child: const Icon(Icons.camera_alt_rounded),\n        ),\n      ],\n    );\n  }\n}"
  },
  {
    "path": "lib/features/presentation/views/main_layout/components/sliver_appbar_actions.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../../../../../core/functions/navigator.dart';\nimport '../../../../../core/shared/pop_up_menu_item_model.dart';\nimport '../../../../../core/utils/constants/strings_manager.dart';\nimport '../../../../../core/utils/routes/routes_manager.dart';\nimport '../../../components/custom_pop_up_menu_button.dart';\n\nList<Widget> buildMainLayoutSliverAppBarActions(\n  BuildContext context, {\n  required int index,\n}) {\n  //this to change pop up for chats calls status\n  switch (index) {\n    case 0:\n      return actionButtons(\n        context,\n        onSearchPressed: () {},\n        popUpMenuItems: _chatPopUpMenuItem(context),\n      );\n    case 1:\n      return actionButtons(\n        context,\n        onSearchPressed: () {},\n        popUpMenuItems: _statusPopUpMenuItem(context),\n      );\n    case 2:\n      return actionButtons(\n        context,\n        onSearchPressed: () {},\n        popUpMenuItems: _callPopUpMenuItem(context),\n      );\n    default:\n      return actionButtons(\n        context,\n        onSearchPressed: () {},\n        popUpMenuItems: _callPopUpMenuItem(context),\n      );\n  }\n}\n\nList<Widget> actionButtons(\n  BuildContext context, {\n  required VoidCallback onSearchPressed,\n  required List<PopUpMenuItemModel> popUpMenuItems,\n}) {\n  return <Widget>[\n    IconButton(\n      onPressed: () {},\n      icon: const Icon(Icons.camera_alt_outlined),\n    ),\n    IconButton(\n      onPressed: () {},\n      icon: const Icon(Icons.search),\n    ),\n    CustomPopUpMenuButton(buttons: popUpMenuItems),\n  ];\n}\n\nList<PopUpMenuItemModel> _chatPopUpMenuItem(BuildContext context) => [\n      PopUpMenuItemModel(\n        name: AppStrings.newGroup,\n        onTap: () {},\n      ),\n      PopUpMenuItemModel(\n        name: AppStrings.newBroadcast,\n        onTap: () {},\n      ),\n      PopUpMenuItemModel(\n        name: AppStrings.linkedDevices,\n        onTap: () {},\n      ),\n      PopUpMenuItemModel(\n        name: AppStrings.starredMessage,\n        onTap: () {},\n      ),\n      PopUpMenuItemModel(\n        name: AppStrings.settings,\n        onTap: () => navigateTo(context, Routes.settingsRoute),\n      ),\n    ];\n\nList<PopUpMenuItemModel> _statusPopUpMenuItem(BuildContext context) => [\n      PopUpMenuItemModel(\n        name: AppStrings.statusPrivacy,\n        onTap: () {},\n      ),\n      PopUpMenuItemModel(\n        name: AppStrings.settings,\n        onTap: () {},\n      ),\n    ];\n\nList<PopUpMenuItemModel> _callPopUpMenuItem(BuildContext context) => [\n      PopUpMenuItemModel(\n        name: AppStrings.clearCallLog,\n        onTap: () {\n        },\n      ),\n      PopUpMenuItemModel(\n        name: AppStrings.settings,\n        onTap: () {},\n      ),\n    ];\n"
  },
  {
    "path": "lib/features/presentation/views/main_layout/main_layout_screen.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../../../../core/utils/constants/strings_manager.dart';\nimport '../../controllers/auth_cubit/auth_cubit.dart';\nimport '../calls/calls_page.dart';\nimport '../contacts_chat/contacts_chat_page.dart';\nimport '../status/status_page.dart';\nimport 'components/fab.dart';\nimport 'components/sliver_appbar_actions.dart';\n\nclass MainLayoutScreen extends StatefulWidget {\n  const MainLayoutScreen({super.key});\n\n  @override\n  State<MainLayoutScreen> createState() => _MainLayoutScreenState();\n}\n\nclass _MainLayoutScreenState extends State<MainLayoutScreen>\n    with TickerProviderStateMixin, WidgetsBindingObserver {\n  //with WidgetsBindingObserver to check online and offline mode\n  // TickerProviderStateMixin to make tabBar\n  late final TabController _tabController;\n\n  @override\n  void initState() {\n    super.initState();\n    _tabController = TabController(length: 3, vsync: this);\n    _tabController.addListener(changeActions);\n    WidgetsBinding.instance\n        .addObserver(this); // to check online and offline mode\n  }\n\n  void changeActions() {\n    buildMainLayoutSliverAppBarActions(\n      context,\n      index: _tabController.index,\n    );\n    setState(() {});\n  }\n// to check online and offline mode\n  @override\n  void didChangeAppLifecycleState(AppLifecycleState state) {\n\n    super.didChangeAppLifecycleState(state);\n    switch (state) {\n      case AppLifecycleState.resumed:\n        AuthCubit.get(context).setUserState(true);\n        break;\n      case AppLifecycleState.detached:\n      case AppLifecycleState.inactive:\n      case AppLifecycleState.paused:\n        AuthCubit.get(context).setUserState(false);\n        break;\n    }\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Builder(builder: (context) {\n      return Scaffold(\n        body: NestedScrollView(\n          body: TabBarView(\n            controller: _tabController,\n            children: const <Widget>[\n              ContactsChatPage(),\n              StatusPage(),\n              CallsPage(),\n            ],\n          ),\n          headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {\n            return <Widget>[\n              SliverAppBar(\n                title: const Text(AppStrings.appName),\n                pinned: true,\n                //automaticallyImplyLeading to remove back button\n                automaticallyImplyLeading: false,\n                floating: true,\n                forceElevated: innerBoxIsScrolled,\n                actions: buildMainLayoutSliverAppBarActions(\n                  context,\n                  index: _tabController.index,\n                ),\n                bottom: TabBar(\n                  indicatorColor: Colors.white,\n                  indicatorWeight: 4,\n                  tabs:  <Tab>[\n                    Tab(text: AppStrings.chats.toUpperCase()),\n                    Tab(text: AppStrings.status.toUpperCase()),\n                    Tab(text: AppStrings.calls.toUpperCase()),\n                  ],\n                  controller: _tabController,\n                ),\n              ),\n            ];\n          },\n        ),\n        floatingActionButton:  FAB(index: _tabController.index),\n      );\n    },);\n  }\n\n  @override\n  void dispose() {\n    super.dispose();\n    WidgetsBinding.instance.removeObserver(this);\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/select_contact/components/contacts_not_on_whatsapp_list.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter_contacts/contact.dart';\n\nimport '../../../../../core/extensions/extensions.dart';\nimport '../../../../../core/utils/constants/font_manager.dart';\nimport '../../../../../core/utils/constants/strings_manager.dart';\nimport '../../../components/custom_list_tile.dart';\n\nclass ContactsNotOnWhatsAppList extends StatelessWidget {\n  final List<Contact> contactNotOnWhats;\n\n  const ContactsNotOnWhatsAppList({\n  super.key,\n  required this.contactNotOnWhats,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return ListView.builder(\n      itemCount: contactNotOnWhats.length,\n      physics: const NeverScrollableScrollPhysics(),\n      shrinkWrap: true,\n      itemBuilder: (context, index) {\n        return CustomListTile(\n          title: contactNotOnWhats[index].displayName,\n          onTap: () {},\n          titleButton: TextButton(\n            onPressed: () {},\n            child: Text(\n              AppStrings.invite,\n              style: TextStyle(\n                color: context.colorScheme.secondary,\n                fontWeight: FontWeightManager.medium,\n              ),\n            ),\n          ),\n          onLeadingTap: () {},\n        );\n      },\n    );\n  }\n}"
  },
  {
    "path": "lib/features/presentation/views/select_contact/components/contacts_on_whatsapp_list.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../../../../../core/functions/navigator.dart';\nimport '../../../../../core/utils/routes/routes_manager.dart';\nimport '../../../components/custom_list_tile.dart';\nimport '../../../components/my_cached_net_image.dart';\n\nclass ContactsOnWhatsAppList extends StatelessWidget {\n  final Map<String, dynamic> contactOnWhats;\n\n  const ContactsOnWhatsAppList({\n  super.key,\n  required this.contactOnWhats,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return ListView.builder(\n      itemCount: contactOnWhats.length,\n      physics: const NeverScrollableScrollPhysics(),\n      shrinkWrap: true,\n      itemBuilder: (context, index) {\n        var contact = contactOnWhats.values.toList()[index];\n        return CustomListTile(\n          title: contact['name'],\n          onTap: () {\n            navigateAndRemove(\n              context,\n              Routes.chatRoute,\n              arguments: {\n                'uId': contact['uId'],\n                'name': contact['name'],\n              },\n            );\n          },\n          onLeadingTap: () {},\n          subTitle: contact['status'],\n          leading: MyCachedNetImage(\n            imageUrl: contact['profilePic'],\n            radius: 22,\n          ),\n        );\n      },\n    );\n  }\n}"
  },
  {
    "path": "lib/features/presentation/views/select_contact/components/new_group_contact_community_buttons_List.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter_contacts/flutter_contacts.dart';\n\nimport '/core/extensions/extensions.dart';\nimport '../../../../../core/utils/constants/assets_manager.dart';\nimport '../../../../../core/utils/constants/strings_manager.dart';\nimport '../../../components/custom_list_tile.dart';\n\nclass NewGroupContactCommunityButtonsList extends StatelessWidget {\n  const NewGroupContactCommunityButtonsList({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return Column(\n      children: [\n        CustomListTile(\n          onTap: () {},\n          leading: CircleAvatar(\n            backgroundColor: context.colorScheme.secondary,\n            child: const Icon(\n              Icons.group,\n              color: Colors.white70,\n            ),\n          ),\n          title: AppStrings.newGroup,\n        ),\n        CustomListTile(\n          onTap: () {\n            FlutterContacts.openExternalInsert();\n          },\n          leading: CircleAvatar(\n            backgroundColor: context.colorScheme.secondary,\n            child: const Icon(\n              Icons.person_add,\n              color: Colors.white70,\n            ),\n          ),\n          title: AppStrings.newContact,\n          titleButton: GestureDetector(\n            onTap: () {\n            },\n            child: Padding(\n              padding: const EdgeInsets.all(4.0),\n              child: Image.asset(\n                AppImage.qrCode,\n              ),\n            ),\n          ),\n        ),\n        CustomListTile(\n          onTap: () {},\n          leading: CircleAvatar(\n            backgroundColor: context.colorScheme.secondary,\n            child: const Icon(\n              Icons.groups,\n              color: Colors.white70,\n            ),\n          ),\n          title: AppStrings.newCommunity,\n        ),\n      ],\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/select_contact/components/select_contact_appbar.dart",
    "content": "import 'package:flutter/foundation.dart';\nimport 'package:flutter/material.dart';\nimport 'package:flutter_contacts/flutter_contacts.dart';\n\nimport '/core/extensions/extensions.dart';\nimport '../../../../../core/shared/pop_up_menu_item_model.dart';\nimport '../../../../../core/utils/constants/strings_manager.dart';\nimport '../../../components/custom_pop_up_menu_button.dart';\nimport '../../../controllers/select_contact_cubit/select_contact_cubit.dart';\n\nclass SelectContactAppBar extends StatelessWidget\n    implements PreferredSizeWidget {\n  final int numOfContacts;\n  final SelectContactState state;\n\n  const SelectContactAppBar({\n    super.key,\n    required this.numOfContacts,\n    required this.state,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return AppBar(\n      title: Column(\n        crossAxisAlignment: CrossAxisAlignment.start,\n        children: [\n          Text(\n            AppStrings.selectContact,\n            style: context.headlineLarge,\n          ),\n          const SizedBox(height: 3),\n          Text(\n            '$numOfContacts ${AppStrings.contacts}',\n            style: context.bodySmall,\n          ),\n        ],\n      ),\n      actions: [\n        if (state is GetAllContactsLoadingState ||\n            state is GetContactsOnWhatsLoadingState)\n           FittedBox(\n            fit: BoxFit.scaleDown,\n            child: SizedBox(\n              width: 18,\n              height: 18,\n              child: CircularProgressIndicator(\n                color: context.colorScheme.onPrimary,\n                strokeWidth: 2,\n              ),\n            ),\n          ),\n        IconButton(\n          onPressed: () {},\n          icon: const Icon(Icons.search),\n        ),\n        CustomPopUpMenuButton(buttons: _buttons(context)),\n      ],\n    );\n  }\n\n  List<PopUpMenuItemModel> _buttons(context) => [\n        PopUpMenuItemModel(\n          name: AppStrings.inviteAFriend,\n          onTap: () {},\n        ),\n        PopUpMenuItemModel(\n          name: AppStrings.contacts,\n          onTap: () {\n            FlutterContacts.openExternalPick().then((value) {\n              if (kDebugMode) {\n                print(value!.displayName);\n              }\n            });\n          },\n        ),\n        PopUpMenuItemModel(\n          name: AppStrings.refresh,\n          onTap: () {\n            SelectContactCubit.get(context).getAllContacts().then((value) {\n              SelectContactCubit.get(context).getContactsOnWhatsApp();\n              SelectContactCubit.get(context).getContactsNotOnWhatsApp();\n            });\n          },\n        ),\n        PopUpMenuItemModel(\n          name: AppStrings.help,\n          onTap: () {},\n        ),\n      ];\n\n  @override\n  Size get preferredSize => const Size.fromHeight(kToolbarHeight);\n}\n"
  },
  {
    "path": "lib/features/presentation/views/select_contact/select_contact_screen.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\n\nimport '../../../../core/utils/constants/strings_manager.dart';\nimport '../../controllers/select_contact_cubit/select_contact_cubit.dart';\nimport 'components/contacts_not_on_whatsapp_list.dart';\nimport 'components/contacts_on_whatsapp_list.dart';\nimport 'components/select_contact_appbar.dart';\nimport 'components/new_group_contact_community_buttons_List.dart';\n\nclass SelectContactScreen extends StatelessWidget {\n  const SelectContactScreen({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return Builder(builder: (context) {\n      SelectContactCubit.get(context).getAllContacts().then((value) {\n        SelectContactCubit.get(context).getContactsOnWhatsApp();\n        SelectContactCubit.get(context).getContactsNotOnWhatsApp();\n      });\n      return BlocConsumer<SelectContactCubit, SelectContactState>(\n        listener: (context, state) {},\n        builder: (context, state) {\n          SelectContactCubit cubit = SelectContactCubit.get(context);\n          return Scaffold(\n            appBar: SelectContactAppBar(\n              numOfContacts:\n                  cubit.contactOnWhats.length + cubit.contactNotOnWhats.length,\n              state: state,\n            ),\n            body: SingleChildScrollView(\n              physics: const ScrollPhysics(),\n              child: Column(\n                crossAxisAlignment: CrossAxisAlignment.start,\n                children: [\n                  const NewGroupContactCommunityButtonsList(),\n                  const SmallText(AppStrings.contactsOnWhatsApp),\n                  ContactsOnWhatsAppList(\n                    contactOnWhats: cubit.contactOnWhats,\n                  ),\n                  const SmallText(AppStrings.inviteToWhatsApp),\n                  ContactsNotOnWhatsAppList(\n                    contactNotOnWhats: cubit.contactNotOnWhats,\n                  ),\n                ],\n              ),\n            ),\n          );\n        },\n      );\n    });\n  }\n}\n\n\n\n\nclass SmallText extends StatelessWidget {\n  final String text;\n\n  const SmallText(\n    this.text, {\n    super.key,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return Padding(\n      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),\n      child: Text(text),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/sender_profile/components/body.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport 'status_container.dart';\nimport 'encryption_container.dart';\nimport 'notification_container.dart';\n\nclass Body extends StatelessWidget {\n  final String status;\n\n  const Body({super.key, required this.status});\n\n  @override\n  Widget build(BuildContext context) {\n    return SliverList(\n      delegate: SliverChildListDelegate(\n        [\n          const SizedBox(height: 20),\n          StatusContainer(status: status),\n          const NotificationContainer(),\n          const EncryptionContainer(),\n          // to fill up the rest of the space to enable scrolling\n          const SizedBox(height: 550),\n        ],\n      ),\n    );\n  }\n}\n\n\n\n\n\n"
  },
  {
    "path": "lib/features/presentation/views/sender_profile/components/encryption_container.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '/core/extensions/extensions.dart';\nimport '../../../../../core/utils/constants/strings_manager.dart';\n\nclass EncryptionContainer extends StatelessWidget {\n  const EncryptionContainer({\n  super.key,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return Container(\n      color: Colors.grey.withOpacity(0.1),\n      child: Container(\n        color: Colors.white,\n        margin: const EdgeInsets.only(top: 10),\n        padding: const EdgeInsets.all(16),\n        child: Column(\n          children: [\n            ListTile(\n              title: Text(\n                AppStrings.encryption,\n                style: context.headlineMedium,\n              ),\n              leading: const Icon(Icons.lock),\n              subtitle: Text(\n                AppStrings.messagesAndCallsAre,\n                style: context.titleMedium,\n              ),\n            ),\n            ListTile(\n              title: Text(\n                AppStrings.disappearingMessage,\n                style: context.headlineMedium,\n              ),\n              leading: const Icon(Icons.timelapse),\n              subtitle:  Text(\n                AppStrings.off,\n                style: context.titleMedium,\n              ),\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n}"
  },
  {
    "path": "lib/features/presentation/views/sender_profile/components/notification_container.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '/core/extensions/extensions.dart';\nimport '../../../../../core/utils/constants/strings_manager.dart';\n\nclass NotificationContainer extends StatelessWidget {\n  const NotificationContainer({\n  super.key,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return Container(\n      color: Colors.grey.withOpacity(0.1),\n      child: Container(\n          color: Colors.white,\n          margin: const EdgeInsets.only(top: 10),\n          padding: const EdgeInsets.all(16),\n          child: Column(\n            children: [\n              ListTile(\n                title: Text(\n                  AppStrings.muteNotification,\n                  style: context.headlineMedium,\n                ),\n                leading: const Icon(Icons.notifications),\n                trailing: Switch(\n                  onChanged: (v) {},\n                  value: false,\n                ),\n              ),\n              ListTile(\n                title: Text(\n                  AppStrings.customNotification,\n                  style: context.headlineMedium,\n                ),\n                leading: const Icon(Icons.music_note),\n              ),\n              ListTile(\n                title: Text(\n                  AppStrings.mediaVisibility,\n                  style: context.headlineMedium,\n                ),\n                leading: const Icon(Icons.image),\n              ),\n            ],\n          )),\n    );\n  }\n}"
  },
  {
    "path": "lib/features/presentation/views/sender_profile/components/phone_and_name.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '/core/extensions/extensions.dart';\n\nclass PhoneAndName extends StatelessWidget {\n  final String name;\n  final String phoneNum;\n\n  const PhoneAndName({\n  super.key,\n  required this.name,\n  required this.phoneNum,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return Column(\n      children:  [\n        const SizedBox(height: 35),\n        Text(\n          name,\n          style: context.headlineMedium!.copyWith(fontSize: 22),\n        ),\n        const SizedBox(height: 10),\n        Text(\n          phoneNum,\n          style: context.bodyMedium,\n        ),\n        const SizedBox(height: 30),\n      ],\n    );\n  }\n}"
  },
  {
    "path": "lib/features/presentation/views/sender_profile/components/sender_profile_icons.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../../../../../core/utils/constants/strings_manager.dart';\nimport '/core/extensions/extensions.dart';\n\nclass SenderProfileIcons extends StatelessWidget {\n   const SenderProfileIcons({\n    Key? key,\n  }) : super(key: key);\n\n  @override\n  Widget build(BuildContext context) {\n    return Row(\n      mainAxisAlignment: MainAxisAlignment.center,\n      children: const [\n        ButtonWidget(text: AppStrings.call,icon: Icons.call),\n        SizedBox(width: 20),\n        ButtonWidget(text: AppStrings.video,icon: Icons.videocam),\n        SizedBox(width: 20),\n        ButtonWidget(text: AppStrings.search,icon: Icons.search),\n\n      ],\n    );\n  }\n}\n\nclass ButtonWidget extends StatelessWidget {\n  final IconData icon;\n  final String text;\n  const ButtonWidget({\n    super.key, required this.icon, required this.text,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return Column(\n      children:  [\n        Icon(\n          icon,\n          size: 30,\n          color: context.colorScheme.secondary,\n        ),\n        const SizedBox(height: 5),\n        Text(\n          text,\n          style: const TextStyle(\n            fontSize: 18,\n            color: Color.fromARGB(255, 8, 141, 125),\n          ),\n        ),\n      ],\n    );\n  }\n}"
  },
  {
    "path": "lib/features/presentation/views/sender_profile/components/sender_user_profile_appbar.dart",
    "content": "import 'dart:math';\n\nimport 'package:flutter/material.dart';\nimport 'package:flutter/services.dart';\nimport 'package:whatsapp_flutter_clone/core/utils/constants/assets_manager.dart';\nimport 'package:whatsapp_flutter_clone/features/presentation/components/custom_network_image.dart';\n\nimport '/core/extensions/extensions.dart';\nimport '../../../../../core/functions/navigator.dart';\nimport '../../../../domain/entities/user.dart';\n\nclass SenderUserProfilePageAppBar extends SliverPersistentHeaderDelegate {\n  BuildContext context;\n  final UserEntity user;\n  Tween<double>? profilePicTranslateTween;\n\n  SenderUserProfilePageAppBar({required this.context, required this.user}) {\n    profilePicTranslateTween = Tween<double>(\n      begin: context.width(1) / 2 - 45 - 40 + 15,\n      end: 40.0,\n    );\n  }\n\n  static final appBarColorTween = ColorTween(\n    begin: Colors.white,\n    end: const Color(0XFF008069),\n  );\n\n  static final statusBarBrightnessTween = Tween<Brightness>(\n    begin: Brightness.dark,\n    end: Brightness.light,\n  );\n\n  static final appbarIconColorTween = ColorTween(\n    begin: Colors.grey[800],\n    end: Colors.white,\n  );\n\n  static final nameTranslateTween = Tween<double>(begin: 20.0, end: 0.0);\n\n  static final nameFontSizeTween = Tween<double>(begin: 20.0, end: 16.0);\n\n  static final profileImageRadiusTween = Tween<double>(begin: 3.5, end: 1.0);\n\n  @override\n  Widget build(\n      BuildContext context, double shrinkOffset, bool overlapsContent) {\n    final relativeScroll = min(shrinkOffset, 45) / 45;\n    final relativeScroll70px = min(shrinkOffset, 70) / 70;\n    SystemChrome.setSystemUIOverlayStyle(\n      SystemUiOverlayStyle(\n        statusBarColor: appBarColorTween.transform(relativeScroll),\n        statusBarIconBrightness:\n            statusBarBrightnessTween.transform(relativeScroll),\n      ),\n    );\n    return Container(\n      color: appBarColorTween.transform(relativeScroll),\n      child: Stack(\n        children: [\n          Stack(\n            children: [\n              Positioned(\n                left: 0,\n                child: IconButton(\n                  onPressed: () {\n                    navigatePop(context);\n                  },\n                  icon: const Icon(Icons.arrow_back, size: 25),\n                  color: appbarIconColorTween.transform(relativeScroll),\n                ),\n              ),\n              Positioned(\n                right: 0,\n                child: IconButton(\n                  onPressed: () {},\n                  icon: const Icon(Icons.more_vert, size: 25),\n                  color: appbarIconColorTween.transform(relativeScroll),\n                ),\n              ),\n              Positioned(\n                top: 15,\n                left: 90,\n                child: displayName(relativeScroll70px),\n              ),\n              Positioned(\n                top: 5,\n                left: profilePicTranslateTween!.transform(relativeScroll70px),\n                child: displayProfilePicture(relativeScroll70px, user),\n              ),\n            ],\n          ),\n        ],\n      ),\n    );\n  }\n\n  Widget displayProfilePicture(\n      double relativeFullScrollOffset, UserEntity user) {\n    return Transform(\n      transform: Matrix4.identity()\n        ..scale(\n          profileImageRadiusTween.transform(relativeFullScrollOffset),\n        ),\n      child: Hero(\n        tag: user.uId,\n        child: CustomNetworkImage(imageUrl: user.profilePic),\n      ),\n    );\n  }\n\n  Widget displayName(double relativeFullScrollOffset) {\n    if (relativeFullScrollOffset >= 0.8) {\n      return Transform(\n        transform: Matrix4.identity()\n          ..translate(\n            0.0,\n            nameTranslateTween.transform((relativeFullScrollOffset - 0.8) * 5),\n          ),\n        child: Text(\n          user.name,\n          style: TextStyle(\n            fontSize: nameFontSizeTween\n                .transform((relativeFullScrollOffset - 0.8) * 5),\n            color: Colors.white,\n            fontWeight: FontWeight.w500,\n          ),\n        ),\n      );\n    }\n\n    return const SizedBox.shrink();\n  }\n\n  @override\n  double get maxExtent => 120;\n\n  @override\n  double get minExtent => 50;\n\n  @override\n  bool shouldRebuild(SenderUserProfilePageAppBar oldDelegate) {\n    return true;\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/sender_profile/components/status_container.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '/core/extensions/extensions.dart';\n\nclass StatusContainer extends StatelessWidget {\n  const StatusContainer({\n    super.key,\n    required this.status,\n  });\n\n  final String status;\n\n  @override\n  Widget build(BuildContext context) {\n    return Container(\n      color: Colors.grey.withOpacity(0.1),\n      child: Container(\n        margin: const EdgeInsets.only(top: 10),\n        padding: const EdgeInsets.all(16),\n        decoration: const BoxDecoration(\n          color: Colors.white,\n          boxShadow: [\n            BoxShadow(\n              color: Colors.white10,\n              offset: Offset(0, 10),\n              blurRadius: 20,\n            ),\n          ],\n        ),\n        child: Text(\n          status,\n          style: context.headlineMedium,\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/sender_profile/sender_profile_page.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../../../domain/entities/user.dart';\nimport 'components/body.dart';\nimport 'components/phone_and_name.dart';\nimport 'components/sender_profile_icons.dart';\nimport 'components/sender_user_profile_appbar.dart';\n\nclass SenderUserProfilePage extends StatelessWidget {\n  final UserEntity user;\n\n  const SenderUserProfilePage({\n    super.key,\n    required this.user,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return SafeArea(\n      child: Scaffold(\n        backgroundColor: Colors.white,\n        body: CustomScrollView(\n          slivers: [\n            SliverPersistentHeader(\n              delegate: SenderUserProfilePageAppBar(\n                context: context,\n                user: user,\n              ),\n              pinned: true,\n            ),\n            SliverToBoxAdapter(\n              child: Column(\n                children: [\n                  PhoneAndName(\n                    name: user.name,\n                    phoneNum: user.phoneNumber,\n                  ),\n                  const SenderProfileIcons(),\n                ],\n              ),\n            ),\n            Body(\n              status: user.status,\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/settings/components/about_card.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '/core/extensions/extensions.dart';\nimport '../../../../../core/utils/constants/strings_manager.dart';\nimport '../../../../domain/entities/user.dart';\n\nclass AboutCard extends StatelessWidget {\n  const AboutCard({\n  super.key,\n  required this.user,\n  });\n\n  final UserEntity user;\n\n  @override\n  Widget build(BuildContext context) {\n    return InkWell(\n      onTap: () {},\n      child: ListTile(\n        leading: const Icon(Icons.info_outline_rounded),\n        title: const Text(AppStrings.about),\n        subtitle: Text(\n          user.status,\n          maxLines: 1,\n          overflow: TextOverflow.ellipsis,\n          style: context.headlineMedium,\n        ),\n        trailing: Icon(\n          Icons.edit,\n          color: context.colorScheme.secondary,\n        ),\n      ),\n    );\n  }\n}"
  },
  {
    "path": "lib/features/presentation/views/settings/components/name_card.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../../../../../core/utils/constants/strings_manager.dart';\nimport '/core/extensions/extensions.dart';\nimport '../../../../domain/entities/user.dart';\n\n\nclass NameCard extends StatelessWidget {\n  const NameCard({\n  super.key,\n  required this.user,\n  });\n\n  final UserEntity user;\n\n  @override\n  Widget build(BuildContext context) {\n    return InkWell(\n      onTap: () {},\n      child: Column(\n        children: [\n          ListTile(\n            leading: const Icon(Icons.person),\n            title: const Text(AppStrings.name),\n            subtitle: Text(\n              user.name,\n              style: context.headlineMedium,\n            ),\n            trailing: Icon(\n              Icons.edit,\n              color: context.colorScheme.secondary,\n            ),\n          ),\n          Padding(\n            padding:\n            const EdgeInsets.only(left: 70, right: 20, bottom: 10),\n            child: Text(\n              AppStrings.thisIsNotYourUser,\n              style: context.titleMedium,\n            ),\n          ),\n          Padding(\n            padding: const EdgeInsets.only(left: 70),\n            child: Divider(\n              color:\n              context.colorScheme.onSurfaceVariant.withOpacity(0.2),\n            ),\n          ),\n        ],\n      ),\n    );\n  }\n}"
  },
  {
    "path": "lib/features/presentation/views/settings/components/phone_card.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '/core/extensions/extensions.dart';\nimport '../../../../../core/utils/constants/strings_manager.dart';\nimport '../../../../domain/entities/user.dart';\n\nclass PhoneCard extends StatelessWidget {\n  const PhoneCard({\n  super.key,\n  required this.user,\n  });\n\n  final UserEntity user;\n\n  @override\n  Widget build(BuildContext context) {\n    return InkWell(\n      onTap: () {},\n      child: ListTile(\n        leading: const Icon(Icons.phone),\n        title: const Text(AppStrings.phone),\n        subtitle: Text(\n          user.phoneNumber,\n          style: context.headlineMedium,\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/settings/components/profile_card.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '/core/extensions/extensions.dart';\nimport '../../../../../core/functions/navigator.dart';\nimport '../../../../../core/utils/constants/assets_manager.dart';\nimport '../../../../../core/utils/routes/routes_manager.dart';\nimport '../../../../domain/entities/user.dart';\nimport '../../../components/my_cached_net_image.dart';\nimport '../../../controllers/auth_cubit/auth_cubit.dart';\n\nclass ProfileCard extends StatelessWidget {\n  const ProfileCard({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return FutureBuilder(\n      future: AuthCubit.get(context).getCurrentUser(),\n      builder: (context,snapshot){\n        if (snapshot.connectionState == ConnectionState.done) {\n            UserEntity user = AuthCubit.get(context).userEntity!;\n              return InkWell(\n              onTap: () {\n                navigateTo(context, Routes.profileRoute, arguments: user);\n              },\n              child: Padding(\n                padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),\n                child: Row(\n                  children: [\n                    Hero(\n                      tag: user.uId,\n                      child: MyCachedNetImage(\n                        radius: 30,\n                        imageUrl: user.profilePic,\n                      ),\n                    ),\n                    const SizedBox(\n                      width: 16,\n                    ),\n                    Expanded(\n                      child: Column(\n                        crossAxisAlignment: CrossAxisAlignment.start,\n                        children: [\n                          Text(\n                            user.name ?? '',\n                            style: context.headlineMedium,\n                          ),\n                          const SizedBox(\n                            height: 5,\n                          ),\n                          Text(\n                            user.status ?? '',\n                            style: context.bodyMedium,\n                            overflow: TextOverflow.ellipsis,\n                          )\n                        ],\n                      ),\n                    ),\n                    //const Spacer(),\n                    Image.asset(\n                      AppImage.qrCode,\n                      width: 30,\n                      color: context.colorScheme.secondary,\n                    ),\n                  ],\n                ),\n              ),\n            );\n        }\n        return const SizedBox();\n      },\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/settings/components/profile_pic_circle_card.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\nimport 'package:whatsapp_flutter_clone/features/presentation/controllers/auth_cubit/auth_cubit.dart';\n\nimport '../../../../domain/entities/user.dart';\nimport '../../../components/my_cached_net_image.dart';\nimport '../../../components/update_profile_pic_model_bottom_sheet.dart';\n\nclass ProfilePicCircleCard extends StatelessWidget {\n  const ProfilePicCircleCard({\n    super.key,\n    required this.user,\n  });\n\n  final UserEntity user;\n\n  @override\n  Widget build(BuildContext context) {\n    UserEntity? newUser;\n    return BlocConsumer<AuthCubit, AuthState>(\n      listener: (context, state) {\n        if (state is UpdateProfilePicSuccessState) {\n        AuthCubit.get(context).getCurrentUser();\n        }\n        if(state is GetCurrentUserSuccessState){\n          newUser = AuthCubit.get(context).userEntity;\n        }\n      },\n      builder: (context, state) {\n        return Stack(\n          children: [\n            GestureDetector(\n              onTap: () {\n                showUpdateProfilePicModelBottomSheet(context);\n              },\n              child: Hero(\n                tag: user.uId,\n                child: MyCachedNetImage(\n                  imageUrl: newUser?.profilePic ?? user.profilePic,\n                  radius: 85,\n                ),\n              ),\n            ),\n            const Positioned(\n              bottom: 0,\n              right: 0,\n              child: CircleAvatar(\n                radius: 20,\n                backgroundColor: Colors.teal,\n                child: Icon(\n                  Icons.camera_alt_rounded,\n                  color: Colors.white,\n                ),\n              ),\n            )\n          ],\n        );\n      },\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/settings/components/setting_bottom_text.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '/core/extensions/extensions.dart';\n\nclass SettingBottomText extends StatelessWidget {\n  const SettingBottomText({\n  super.key,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return Padding(\n      padding: const EdgeInsets.only(bottom: 30, top: 10),\n      child: RichText(\n        textAlign: TextAlign.center,\n        text: TextSpan(\n          children: [\n            TextSpan(\n              text: 'from\\n',\n              style: context.titleMedium,\n            ),\n            TextSpan(\n              text: 'Mohamed Elgohary',\n              style: context.headlineMedium,\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n}"
  },
  {
    "path": "lib/features/presentation/views/settings/components/settings_item_card.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '/core/extensions/extensions.dart';\n\nclass SettingsItemCard extends StatelessWidget {\n  const SettingsItemCard({\n  super.key,\n  required this.item,\n  });\n\n  final Map<String, dynamic> item;\n\n  @override\n  Widget build(BuildContext context) {\n    return InkWell(\n      onTap: item['onTab'],\n      child: Padding(\n        padding: const EdgeInsets.all(25.0),\n        child: Row(\n          children: [\n            Icon(\n              item['icon'],\n              color: context.colorScheme.onSurface.withOpacity(0.6),\n              size: 26,\n            ),\n            const SizedBox(\n              width: 30,\n            ),\n            RichText(\n              text: TextSpan(\n                children: [\n                  TextSpan(\n                    text: '${item['title']}\\n',\n                    style: context.headlineMedium,\n                  ),\n                  TextSpan(\n                    text: item['subtitle'],\n                    style: context.titleMedium,\n                  ),\n                ],\n              ),\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/settings/profile_screen.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../../../../core/utils/constants/strings_manager.dart';\nimport '../../../domain/entities/user.dart';\nimport '../../controllers/auth_cubit/auth_cubit.dart';\nimport 'components/about_card.dart';\nimport 'components/name_card.dart';\nimport 'components/phone_card.dart';\nimport 'components/profile_pic_circle_card.dart';\n\nclass ProfileScreen extends StatelessWidget {\n  final UserEntity user;\n\n  const ProfileScreen({super.key, required this.user});\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n          appBar: AppBar(\n            title: const Text(AppStrings.profile),\n          ),\n          body: Column(\n            children: [\n              const SizedBox(height: 30),\n              ProfilePicCircleCard(user: user),\n              const SizedBox(height: 20),\n              NameCard(user: user),\n              AboutCard(user: user),\n              PhoneCard(user: user)\n            ],\n          ),\n        );\n  }\n}\n\n\n\n\n\n\n"
  },
  {
    "path": "lib/features/presentation/views/settings/settings_screen.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../../../../core/utils/constants/strings_manager.dart';\nimport 'components/profile_card.dart';\nimport 'components/setting_bottom_text.dart';\nimport 'components/settings_item_card.dart';\n\nclass SettingsScreen extends StatelessWidget {\n  SettingsScreen({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: const Text(AppStrings.settings),\n      ),\n      body: SingleChildScrollView(\n        child: Column(\n          children: [\n            const ProfileCard(),\n            ...List<Widget>.generate(\n              _settingItems.length,\n              (index) => SettingsItemCard(\n                item: _settingItems[index],\n              ),\n            ),\n            const SettingBottomText(),\n          ],\n        ),\n      ),\n    );\n  }\n\n  final List<Map<String, dynamic>> _settingItems = [\n    {\n      'icon': Icons.key,\n      'onTab': () {},\n      'title': 'Account',\n      'subtitle': 'Security notifications, change number',\n    },\n    {\n      'icon': Icons.privacy_tip,\n      'onTab': () {},\n      'title': 'Privacy',\n      'subtitle': 'Bloc contacts, disappearing messages',\n    },\n    {\n      'icon': Icons.chat_sharp,\n      'onTab': () {},\n      'title': 'Chats',\n      'subtitle': 'Theme, wallpapers, chat history',\n    },\n    {\n      'icon': Icons.notifications,\n      'onTab': () {},\n      'title': 'Notifications',\n      'subtitle': 'Message, group & call tones',\n    },\n    {\n      'icon': Icons.data_usage,\n      'onTab': () {},\n      'title': 'Storage and data',\n      'subtitle': 'Network usage, auto download',\n    },\n    {\n      'icon': Icons.language,\n      'onTab': () {},\n      'title': 'App language',\n      'subtitle': 'English',\n    },\n    {\n      'icon': Icons.help_outline,\n      'onTab': () {},\n      'title': 'Help',\n      'subtitle': 'Help centre, contact us, privacy policy',\n    },\n    {\n      'icon': Icons.group,\n      'onTab': () {},\n      'title': 'Invite a friend',\n      'subtitle': '',\n    },\n  ];\n}\n"
  },
  {
    "path": "lib/features/presentation/views/splash/components/bottom_text.dart",
    "content": "import 'package:flutter/material.dart';\nimport '/core/extensions/extensions.dart';\n\nclass BottomText extends StatelessWidget {\n  const BottomText({\n  super.key,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return RichText(\n      textAlign: TextAlign.center,\n      text: TextSpan(\n        children: [\n          TextSpan(\n            text: 'from\\n',\n            style: context.headlineMedium,\n          ),\n          TextSpan(\n            text: 'Mohamed El-Gohary',\n            style: context.headlineMedium!.copyWith(\n              color: context.colorScheme.onSecondaryContainer,\n              fontSize: 20,\n            ),\n          ),\n        ],\n      ),\n    );\n  }\n}"
  },
  {
    "path": "lib/features/presentation/views/splash/components/splash_icon.dart",
    "content": "import 'package:flutter/material.dart';\n\nimport '../../../../../core/utils/constants/assets_manager.dart';\n\nclass SplashIcon extends StatelessWidget {\n  const SplashIcon({\n  super.key,\n  });\n\n  @override\n  Widget build(BuildContext context) {\n    return Expanded(\n      child: Center(\n        child: Image.asset(\n          AppImage.splashLightImg,\n          width: 300,\n        ),\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/splash/splash_screen.dart",
    "content": "import 'dart:async';\n\nimport 'package:flutter/material.dart';\nimport 'package:flutter/services.dart';\n\nimport '/core/functions/navigator.dart';\nimport '/core/services/services_locator.dart' as di;\nimport '../../../../core/utils/routes/routes_manager.dart';\nimport '../../../data/data_source/auth/local/auth_local_data_source.dart';\nimport 'components/bottom_text.dart';\nimport 'components/splash_icon.dart';\n\nclass SplashScreen extends StatefulWidget {\n  const SplashScreen({super.key});\n\n  @override\n  State<SplashScreen> createState() => _SplashScreenState();\n}\n\nclass _SplashScreenState extends State<SplashScreen> {\n  Timer? _timer;\n\n  _startDelay() {\n    _timer = Timer(const Duration(seconds: 1), _goNext);\n  }\n\n  _goNext() {\n    di.sl<BaseAuthLocalDataSource>().getUser() != null\n        ? navigateAndRemove(context, Routes.mainLayoutRoute)\n        : navigateAndRemove(context, Routes.landingRoute);\n  }\n\n  @override\n  void initState() {\n    super.initState();\n    _startDelay();\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    SystemChrome.setSystemUIOverlayStyle(\n      const SystemUiOverlayStyle(\n        statusBarColor: Colors.white,\n        statusBarIconBrightness:Brightness.dark,\n      ),\n    );\n    return Scaffold(\n      body: Column(\n        children: const [\n          SplashIcon(),\n          BottomText(),\n          SizedBox(height: 50),\n        ],\n      ),\n    );\n  }\n\n  @override\n  void dispose() {\n    _timer?.cancel();\n    super.dispose();\n  }\n}\n\n\n"
  },
  {
    "path": "lib/features/presentation/views/status/status_page.dart",
    "content": "import 'package:flutter/material.dart';\n\nclass StatusPage extends StatelessWidget {\n  const StatusPage({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return const Center(\n      child: Text('status'),\n    );\n  }\n}\n"
  },
  {
    "path": "lib/features/presentation/views/wallpaper/wallpaper_screen.dart",
    "content": "import 'package:flutter/material.dart';\nimport 'package:whatsapp_flutter_clone/core/functions/navigator.dart';\nimport 'package:whatsapp_flutter_clone/core/utils/constants/assets_manager.dart';\nimport 'package:whatsapp_flutter_clone/features/presentation/controllers/chat_background_cubit/chat_background_cubit.dart';\n\nclass WallpaperScreen extends StatelessWidget {\n  const WallpaperScreen({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: const Text(\n          'Custom Wallpaper',\n        ),\n      ),\n      body: GridView(\n        physics: const BouncingScrollPhysics(),\n        // if you want IOS bouncing effect, otherwise remove this line\n        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(\n          crossAxisCount: 2,\n        ),\n        children: wallpapers.map((name) {\n          return InkWell(\n            onTap: (){\n              ChatBackgroundCubit.get(context).changeBackground(name);\n              navigatePop(context);\n            },\n            child: Card(\n              child: Image.asset(\n                name,\n                fit: BoxFit.cover,\n              ),\n            ),\n          );\n        }).toList(),\n      ),\n    );\n  }\n}\n\nList<String> wallpapers = [\n  AppImage.chatBackground,\n  AppImage.chatBackground2,\n  AppImage.chatBackground3,\n  AppImage.chatBackgroundDark,\n];\n"
  },
  {
    "path": "lib/info.dart",
    "content": "import 'features/domain/entities/contact_chat.dart';\n/*\nList<ContactChat> info2 = [\n  ContactChat(\n    name: 'Rivaan Ranawat',\n    profilePic: 'https://upload.wikimedia.org/wikipedia/commons/8/85/Elon_Musk_Royal_Society_%28crop1%29.jpg',\n    contactId: '1',\n    lastMessage: 'Hey, how are you doing?',\n    timeSent: DateTime.utc(2022),\n  ),\n  ContactChat(\n    name: 'Mohamed Elgohary',\n    profilePic: 'https://upload.wikimedia.org/wikipedia/commons/8/85/Elon_Musk_Royal_Society_%28crop1%29.jpg',\n    contactId: '1',\n    lastMessage: 'Hey, how are you doing?',\n    timeSent: DateTime.utc(2022),\n  ),\n];\n\n */\nconst info = [\n  {\n    'name': 'Rivaan Ranawat',\n    'message': 'Hey, how are you doing?',\n    'time': '3:53 pm',\n    'numOfMessageNotSeen': 50,\n    'profilePic':\n        'https://upload.wikimedia.org/wikipedia/commons/8/85/Elon_Musk_Royal_Society_%28crop1%29.jpg',\n  },\n  {\n    'name': 'John Doe',\n    'message': 'Hello, whats up',\n    'time': '2:25 pm',\n    'numOfMessageNotSeen': 1,\n    'profilePic':\n        'https://www.socialketchup.in/wp-content/uploads/2020/05/fi-vill-JOHN-DOE.jpg',\n  },\n  {\n    'name': 'Naman Ranawat',\n    'message': 'Hello, I want to sleep.',\n    'time': '1:03 pm',\n    'numOfMessageNotSeen': 3,\n    'profilePic':\n        'https://media.cntraveler.com/photos/60596b398f4452dac88c59f8/16:9/w_3999,h_2249,c_limit/MtFuji-GettyImages-959111140.jpg',\n  },\n  {\n    'name': 'Dad',\n    'message': 'Call me, have some work',\n    'time': '12:06 pm',\n    'numOfMessageNotSeen': 0,\n    'profilePic':\n        'https://pbs.twimg.com/profile_images/1419974913260232732/Cy_CUavB.jpg',\n  },\n  {\n    'name': 'Mom',\n    'message': 'You ate food?',\n    'time': '10:00 am',\n    'numOfMessageNotSeen': 20,\n    'profilePic':\n        'https://uploads.dailydot.com/2018/10/olli-the-polite-cat.jpg?auto=compress%2Cformat&ixlib=php-3.3.0',\n  },\n  {\n    'name': 'Jurica',\n    'message': 'Yo!!!!! Long time, no see!?',\n    'time': '9:53 am',\n    'numOfMessageNotSeen': 100,\n    'profilePic':\n        'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8cmFuZG9tJTIwcGVvcGxlfGVufDB8fDB8fA%3D%3D&auto=format&fit=crop&w=900&q=60',\n  },\n  {\n    'name': 'Albert Dera',\n    'message': 'Am I fat?',\n    'time': '7:25 am',\n    'numOfMessageNotSeen': 3,\n    'profilePic':\n        'https://images.unsplash.com/photo-1506794778202-cad84cf45f1d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8NXx8cmFuZG9tJTIwcGVvcGxlfGVufDB8fDB8fA%3D%3D&auto=format&fit=crop&w=900&q=60',\n  },\n  {\n    'name': 'Joseph',\n    'message': 'I am from International Olym...',\n    'time': '6:02 am',\n    'numOfMessageNotSeen': 3,\n    'profilePic':\n        'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8M3x8cmFuZG9tJTIwcGVvcGxlfGVufDB8fDB8fA%3D%3D&auto=format&fit=crop&w=900&q=60',\n  },\n  {\n    'name': 'Sikandar',\n    'message': 'Lets Code!',\n    'time': '4:56 am',\n    'numOfMessageNotSeen': 3,\n    'profilePic':\n        'https://images.unsplash.com/photo-1619194617062-5a61b9c6a049?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MTB8fHJhbmRvbSUyMHBlb3BsZXxlbnwwfHwwfHw%3D&auto=format&fit=crop&w=900&q=60',\n  },\n  {\n    'name': 'Ian Dooley',\n    'message': 'Images by Unsplash',\n    'time': '1:00 am',\n    'numOfMessageNotSeen': 3,\n    'profilePic':\n        'https://images.unsplash.com/photo-1539571696357-5a69c17a67c6?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8NHx8cmFuZG9tJTIwcGVvcGxlfGVufDB8fDB8fA%3D%3D&auto=format&fit=crop&w=900&q=60',\n  },\n];\n\nconst messages = [\n  {\"isMe\": false, \"text\": \"Hey What is up with you!!\", \"time\": \"10:00 am\"},\n  {\"isMe\": true, \"text\": \"im fine,wbu?\", \"time\": \"11:00 am\"},\n  {\"isMe\": false, \"text\": \"I am great man!\", \"time\": \"11:01 am\"},\n  {\n    \"isMe\": false,\n    \"text\": \"Just messaged cuz I had some work.\",\n    \"time\": \"11:01 am\"\n  },\n  {\"isMe\": true, \"text\": \"Obviously, say\", \"time\": \"11:03 am\"},\n  {\n    \"isMe\": false,\n    \"text\": \"haha I wanted you to check out my new channel ^^\",\n    \"time\": \"11:04 am\"\n  },\n  {\n    \"isMe\": true,\n    \"text\": \" Sure, what is the channel name?\",\n    \"time\": \"11:05 am\"\n  },\n  {\n    \"isMe\": false,\n    \"text\": \"Rivaan Ranawat\",\n    \"time\": \"11:06 am\",\n  },\n  {\n    \"isMe\": true,\n    \"text\": \"Looks great to me!\",\n    \"time\": \"11:15 am\",\n  },\n  {\"isMe\": false, \"text\": \"Thanks bro!\", \"time\": \"11:17 am\"},\n  {\"isMe\": false, \"text\": \"Did you subscribe?\", \"time\": \"11:16 am\"},\n  {\"isMe\": true, \"text\": \"Yes, surely bro!\", \"time\": \"11:17 am\"},\n  {\n    \"isMe\": false,\n    \"text\": \"Cool, did you like the content?\",\n    \"time\": \"11:18 am\",\n  },\n  {\n    \"isMe\": true,\n    \"text\": \"I loved it?\",\n    \"time\": \"11:19 am\",\n  },\n  {\n    \"isMe\": false,\n    \"text\": \"OMG! Woah! Thanks!\",\n    \"time\": \"11:20 am\",\n  },\n];\n"
  },
  {
    "path": "lib/main.dart",
    "content": "import 'package:camera/camera.dart';\nimport 'package:firebase_core/firebase_core.dart';\nimport 'package:flutter/material.dart';\nimport 'package:flutter_bloc/flutter_bloc.dart';\nimport 'package:whatsapp_flutter_clone/features/presentation/controllers/call_cubit/call_cubit.dart';\n\nimport 'core/utils/thems/my_colors.dart';\nimport 'core/shared/bloc_observer.dart';\nimport 'core/utils/constants/strings_manager.dart';\nimport 'core/utils/routes/routes_manager.dart';\nimport 'core/services/services_locator.dart' as di;\nimport 'core/utils/thems/theme_manager.dart';\nimport 'features/presentation/controllers/auth_cubit/auth_cubit.dart';\nimport 'features/presentation/controllers/bottom_chat_cubit/bottom_chat_cubit.dart';\nimport 'features/presentation/controllers/chat_background_cubit/chat_background_cubit.dart';\nimport 'features/presentation/controllers/chat_cubit/chat_cubit.dart';\nimport 'features/presentation/controllers/select_contact_cubit/select_contact_cubit.dart';\nimport 'features/presentation/views/camera/camera_screen.dart';\n//csccccccc\nFuture<void> main() async {\n  WidgetsFlutterBinding.ensureInitialized();\n  await Firebase.initializeApp();\n  Bloc.observer = MyBlocObserver();\n  await di.init();\n  cameras = await availableCameras();\n  runApp(const MyApp());\n}\n//kjjkjkjkj\nclass MyApp extends StatelessWidget {\n  const MyApp({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return MultiBlocProvider(\n      providers: [\n        BlocProvider(create: (context) => di.sl<AuthCubit>()..getCurrentUser()),\n        BlocProvider(\n          create: (context) => di.sl<SelectContactCubit>()\n            ..getAllContacts()\n            ..getContactsOnWhatsApp(),\n        ),\n        BlocProvider(create: (context) => di.sl<ChatCubit>()),\n        BlocProvider(create: (context) => di.sl<BottomChatCubit>()),\n        BlocProvider(create: (context) => di.sl<ChatBackgroundCubit>()),\n        BlocProvider(create: (context)=> di.sl<CallCubit>()),\n      ],\n      child: MaterialApp(\n        title: AppStrings.appName,\n        debugShowCheckedModeBanner: false,\n        theme: createTheme(LightColors()),\n        onGenerateRoute: AppRoutes.onGenerateRoute,\n        initialRoute: Routes.splashRoute,\n      ),\n    );\n  }\n}\n"
  },
  {
    "path": "pubspec.yaml",
    "content": "name: whatsapp_flutter_clone\ndescription: A new Flutter application.\n\npublish_to: 'none' # Remove this line if you wish to publish to pub.dev\n\nversion: 1.0.0+1\n\nenvironment:\n  sdk: '>=2.18.6 <3.0.0'\n\ndependencies:\n  flutter:\n    sdk: flutter\n\n  cupertino_icons: ^1.0.2\n  country_picker: ^2.0.16\n  equatable: ^2.0.5\n  dartz: ^0.10.1\n  flutter_bloc: ^8.1.1\n  get_it: ^7.2.0\n  shared_preferences: ^2.0.15\n  flutter_svg: ^1.1.6\n  flutter_contacts: ^1.1.5+1\n  uuid: ^3.0.7\n  intl: ^0.17.0\n  cached_network_image: ^3.2.3\n  giphy_get: ^3.1.1\n  emoji_picker_flutter: ^1.5.1\n  camera: ^0.10.1\n  path_provider: ^2.0.11\n  image_picker: ^0.8.6\n  video_player: ^2.4.9\n  shimmer: ^2.0.0\n  agora_uikit: ^1.1.0\n  audio_waveforms: ^0.1.5+1\n  cached_video_player: ^2.0.3\n  audioplayers: ^1.1.1\n  swipe_to: ^1.0.2\n  sms_autofill: ^2.2.0\n  image_cropper: ^3.0.1\n\n  firebase_auth: ^4.2.5\n  firebase_core: ^2.1.1\n  cloud_firestore: ^4.0.3\n  firebase_storage: ^11.0.3\n\n\ndev_dependencies:\n  flutter_test:\n    sdk: flutter\n\n\n  flutter_lints: ^2.0.0\n\nflutter:\n\n  uses-material-design: true\n\n  assets:\n    - assets/images/\n  #   - images/a_dot_ham.jpeg\n\n  # An image asset can refer to one or more resolution-specific \"variants\", see\n  # https://flutter.dev/assets-and-images/#resolution-aware\n\n  # For details regarding adding assets from package dependencies, see\n  # https://flutter.dev/assets-and-images/#from-packages\n  fonts:\n    - family: Montserrat\n      fonts:\n        - asset: assets/fonts/Montserrat-Bold.ttf\n          weight: 700\n        - asset: assets/fonts/Montserrat-SemiBold.ttf\n          weight: 600\n        - asset: assets/fonts/Montserrat-Medium.ttf\n          weight: 500\n        - asset: assets/fonts/Montserrat-Regular.ttf\n          weight: 400\n        - asset: assets/fonts/Montserrat-Light.ttf\n          weight: 300"
  },
  {
    "path": "test/widget_test.dart",
    "content": "// This is a basic Flutter widget test.\n//\n// To perform an interaction with a widget in your test, use the WidgetTester\n// utility in the flutter_test package. For example, you can send tap and scroll\n// gestures. You can also use WidgetTester to find child widgets in the widget\n// tree, read text, and verify that the values of widget properties are correct.\n\nimport 'package:flutter/material.dart';\nimport 'package:flutter_test/flutter_test.dart';\nimport 'package:whatsapp_flutter_clone/main.dart';\n\n\nvoid main() {\n  testWidgets('Counter increments smoke test', (WidgetTester tester) async {\n    // Build our app and trigger a frame.\n    await tester.pumpWidget( const MyApp());\n\n    // Verify that our counter starts at 0.\n    expect(find.text('0'), findsOneWidget);\n    expect(find.text('1'), findsNothing);\n\n    // Tap the '+' icon and trigger a frame.\n    await tester.tap(find.byIcon(Icons.add));\n    await tester.pump();\n\n    // Verify that our counter has incremented.\n    expect(find.text('0'), findsNothing);\n    expect(find.text('1'), findsOneWidget);\n  });\n}\n"
  }
]