Showing preview only (279K chars total). Download the full file or copy to clipboard to get everything.
Repository: realdiganta/hitup-messenger
Branch: master
Commit: 2011fe3378e6
Files: 108
Total size: 251.3 KB
Directory structure:
gitextract_qp4kc1fo/
├── .gitignore
├── .metadata
├── LICENSE
├── README.md
├── android/
│ ├── .gitignore
│ ├── app/
│ │ ├── build.gradle
│ │ ├── google-services.json
│ │ └── src/
│ │ ├── debug/
│ │ │ └── AndroidManifest.xml
│ │ ├── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── digantakalita/
│ │ │ │ └── coocoo/
│ │ │ │ └── MainActivity.kt
│ │ │ └── res/
│ │ │ ├── drawable/
│ │ │ │ ├── ic_launcher_background.xml
│ │ │ │ └── launch_background.xml
│ │ │ ├── mipmap-anydpi-v26/
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ └── values/
│ │ │ └── styles.xml
│ │ └── profile/
│ │ └── AndroidManifest.xml
│ ├── build.gradle
│ ├── gradle/
│ │ └── wrapper/
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ └── settings.gradle
├── ios/
│ ├── .gitignore
│ ├── Flutter/
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Runner/
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets/
│ │ │ ├── AppIcon.appiconset/
│ │ │ │ └── Contents.json
│ │ │ └── LaunchImage.imageset/
│ │ │ ├── Contents.json
│ │ │ └── README.md
│ │ ├── Base.lproj/
│ │ │ ├── LaunchScreen.storyboard
│ │ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── Runner-Bridging-Header.h
│ ├── Runner.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ └── Runner.xcscheme
│ └── Runner.xcworkspace/
│ ├── contents.xcworkspacedata
│ └── xcshareddata/
│ ├── IDEWorkspaceChecks.plist
│ └── WorkspaceSettings.xcsettings
├── lib/
│ ├── blocs/
│ │ ├── AddFriends/
│ │ │ ├── add_friends_bloc.dart
│ │ │ ├── add_friends_event.dart
│ │ │ └── add_friends_state.dart
│ │ ├── chats/
│ │ │ ├── chat_bloc.dart
│ │ │ ├── chat_event.dart
│ │ │ └── chat_state.dart
│ │ ├── contacts/
│ │ │ ├── contacts_bloc.dart
│ │ │ ├── contacts_event.dart
│ │ │ └── contacts_state.dart
│ │ ├── home/
│ │ │ ├── home_bloc.dart
│ │ │ ├── home_event.dart
│ │ │ └── home_state.dart
│ │ └── timer/
│ │ ├── timer_bloc.dart
│ │ ├── timer_event.dart
│ │ └── timer_state.dart
│ ├── config/
│ │ ├── Constants.dart
│ │ └── Paths.dart
│ ├── constants.dart
│ ├── functions/
│ │ ├── AddFriendsFunction.dart
│ │ ├── BaseFunctions.dart
│ │ ├── ChatFunction.dart
│ │ ├── MQTTFunction.dart
│ │ └── UserDataFunction.dart
│ ├── main.dart
│ ├── managers/
│ │ ├── db_manager.dart
│ │ └── mqtt_manager.dart
│ ├── models/
│ │ ├── ChatMessage.dart
│ │ ├── Conversation.dart
│ │ ├── MyContact.dart
│ │ ├── NonContact.dart
│ │ └── User.dart
│ ├── screens/
│ │ ├── ContactsHelpPage.dart
│ │ ├── account_screen.dart
│ │ ├── addFriends_screen.dart
│ │ ├── chat_screen.dart
│ │ ├── contacts_screen.dart
│ │ ├── enter_name_screen.dart
│ │ ├── friend_profile_screen.dart
│ │ ├── help_screen.dart
│ │ ├── home_screen.dart
│ │ ├── login_screen.dart
│ │ ├── otp_screen.dart
│ │ ├── profile_screen.dart
│ │ ├── settings_screen.dart
│ │ └── update_profile.dart
│ ├── splashscreen.dart
│ ├── stateProviders/
│ │ ├── mqtt_state.dart
│ │ ├── number_state.dart
│ │ └── profilePicUrlState.dart
│ ├── utils/
│ │ ├── Exceptions.dart
│ │ └── SharedObjects.dart
│ └── widgets/
│ ├── AddFriendCard.dart
│ ├── ChatCard.dart
│ ├── ChatItemWidget.dart
│ ├── ContactCard.dart
│ ├── ContactRowWidget.dart
│ ├── DangerCard.dart
│ ├── FriendRequestCard.dart
│ ├── GradientSnackBar.dart
│ ├── ImageFullScreenWidget.dart
│ ├── ListTileProfile.dart
│ ├── NameTextField.dart
│ ├── NoRequestsCard.dart
│ ├── NonContactCard.dart
│ ├── SentRequestCard.dart
│ └── SettingsTile.dart
├── pubspec.yaml
└── test/
└── widget_test.dart
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
# Web related
lib/generated_plugin_registrant.dart
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Exceptions to above rules.
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
================================================
FILE: .metadata
================================================
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: bbfbf1770cca2da7c82e887e4e4af910034800b6
channel: stable
project_type: app
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2020 Diganta Kalita
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
<p align="center"><a href="https://github.com/realdiganta/hitup-messenger"><img src="https://user-images.githubusercontent.com/47485188/101604747-5a6a8d00-3a27-11eb-9c00-8124df47589e.png" alt="Logo" height="140", width="140"/></a></p>
<h1 align="center">HitUp Messenger</h1>
<p align="center">A Fully Functioning Chat Messenger (like Whatsapp) built using Flutter.</p>
<p align="center">
<a href="https://github.com/realdiganta/hitup-messenger"><img src="https://img.shields.io/badge/apk%20size-18%20MB-blueviolet"/></a> <a href="https://github.com/realdiganta/hitup-messenger"><img src="https://img.shields.io/badge/version-1.2.6%2B7-blue"/></a> <a href="https://github.com/realdiganta/hitup-messenger"><img src="https://img.shields.io/badge/license-MIT-orange"/></a>
</p><br/><br/>
<img src="https://user-images.githubusercontent.com/47485188/101521998-9c0a2200-39ac-11eb-964a-79d51b4f89c1.png" alt="Screenshot" height="500" width="270"/> <img src="https://user-images.githubusercontent.com/47485188/101522157-dd023680-39ac-11eb-8851-be5b351d3186.png" alt="Screenshot" height="500" width="270"/> <img src="https://user-images.githubusercontent.com/47485188/101532693-e98d8b80-39ba-11eb-804f-78ccad3f1f31.png" alt="Screenshot" height="500" width="270"/>
## About the project
- Flutter for building the Android & IOS App.
- Firestore database for storing user data.
- Firebase Storage for storing images.
- [MQTT](https://www.hivemq.com/mqtt-essentials/) as messaging protocol hosted in AWS EC2.
- SQLite for storing contacts & chats in Local Database.
- [OneSignal](https://onesignal.com/) for Push Notifications.
## Features
### Super Fast Messaging using MQTT Protocol (MQTT is used by Facebook Messenger)
Architecture:
> When you send a message from the app, the message first goes to the MQTT server. Then the MQTT server sends the message directly to the device of the client who is supposed to receive it. When received, the client stores the message in the local sqlite database first then shows it to the chat screen. (Firestore is in no way used to store or send text messages. Firestore is used only to store user & contacts data). To learn more about MQTT please [refer here](https://www.hivemq.com/mqtt-essentials/).
<br>
### Phone Number Authentication Sign-in
Authentication is done using Firebase.
<br>
<img src="https://user-images.githubusercontent.com/47485188/101533784-476ea300-39bc-11eb-99b7-4fe09cf2c29a.png" alt="Screenshot" height="500" width="270"/> <img src="https://user-images.githubusercontent.com/47485188/101533474-e0e98500-39bb-11eb-8e67-b50827a8a1e0.png" alt="Screenshot" height="500" width="270"/>
### Sending Images
Send & Receive Images (Snapchat style UI).
The images are not stored in Gallery. Instead they are stored in the local sqlite database in bytes format.
<br><br>
<img src="https://user-images.githubusercontent.com/47485188/101521696-2f8f2300-39ac-11eb-9f42-5afd2ad0e36a.gif" alt="Screenshot" height="500" width="270"/>
### Super Fast Loading of Messages (Using SQLite as Local DB to store messages)
Even when the client is offline, he/she can view the messages on opening the chat screen, because the messages are loaded directly from the local sqlite db. And that is the only place where the messages are stored. The MQTT server doesn't store old messages. The MQTT Server only stores the last message sent and then replaces it when a new message is sent.
### Sending texts to Phone Contacts
On the Contacts Screen, you will get a list of all your phone contacts who are also using the messenger and can chat with them. (Just like sending messages to your contacts in Whatsapp)<br>
<img src="https://user-images.githubusercontent.com/47485188/101533031-5dc82f00-39bb-11eb-8f53-035e3f01112d.png" alt="Screenshot" height="500" width="270"/>
<br>
### Adding contacts using username. Sending & Receiving Friend Requests
You can also send friend request to someone using their username. On sending friend request, the other user will get a push notification & and a friend request. If he/she accepts the request then you will get an notification & will be able to chat with the user. (Same as the feature in Snapchat) <br><br>
<img src="https://user-images.githubusercontent.com/47485188/101530774-5ce1ce00-39b8-11eb-88b5-8d6ae66e049e.png" alt="Screenshot" height="500" width="280"/>
### Block Contact<br>
<img src="https://user-images.githubusercontent.com/47485188/101531982-ea71ed80-39b9-11eb-8d8f-190be70c7131.png" alt="Screenshot" height="500" width="280"/>
### Realtime Push Notifications
Using OneSignal. User will get realtime push notifications (even when the app is closed) when
- He/She receives a new message
- He/She receives a friend request
- Someone accepts their friend request
<br>
<img src="https://user-images.githubusercontent.com/47485188/101627059-cce96600-3a43-11eb-83b1-12ab08d20a35.gif" alt="Notification" height="500" width="270"/>
<br><br>
### Change Profile Photo
### Image Compression Before Sending
### Emoji Support
### Neumorphic UI
### Invite Friends Feature
<br>
## Other Important Information
## Installation & Setup (Optional)
1. Firebase
> To change the firestore database, just replace the google-services.json in android/app to your own google-services.json file from your firebase account.
2. MQTT Server
> To transfer messages I am using an MQTT server which I have setup in a EC2 instance on AWS. For details on how to setup your own MQTT server please refer here : [Setup MQTT Server on AWS EC2](http://blog.yatis.io/install-secure-robust-mosquitto-mqtt-broker-aws-ubuntu/). Then change the serverAddress parameter in lib/functions/MQTTFunction.dart file, (connect() function) to the public address of your EC2 instance.
<br>
3. OneSignal
> First create an account in [OneSignal](https://onesignal.com/). Then replace the app_id parameter in lib/functions/UserDataFunction.dart sendNotification() function with your own OneSignal app_id.
## Motivation & Contribution
I want to build this messenger into the biggest open source messenger on the web with all functionalities from the top Messengers like Whatsapp, Telegram, Signal, Snapchat, etc. There a lot of features still to be added like end-to-end encryption, audio messages, audio/video calling, stories, etc. So, we are open to pull requests. Please contribute in any way you can, adding new features, finding or fixing bugs, adding to the documenation, better code commenting, etc.
## Contributing
If you want to contribute to this project other than by coding, please contact me here digantakalita.ai@gmail.com
## License
[MIT License](https://github.com/realdiganta/hitup-messenger/blob/master/LICENSE)
## Supporters
[](https://github.com/realdiganta/hitup-messenger/stargazers)
[](https://github.com/realdiganta/hitup-messenger/network/members)
================================================
FILE: android/.gitignore
================================================
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
================================================
FILE: android/app/build.gradle
================================================
buildscript {
repositories {
// ...
maven { url 'https://plugins.gradle.org/m2/' } // Gradle Plugin Portal
}
dependencies {
// OneSignal-Gradle-Plugin
classpath 'gradle.plugin.com.onesignal:onesignal-gradle-plugin:[0.12.6, 0.99.99]'
}
}
apply plugin: 'com.onesignal.androidsdk.onesignal-gradle-plugin'
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
apply plugin: 'com.google.gms.google-services'
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
compileSdkVersion 28
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.digantakalita.coocoo"
minSdkVersion 21
targetSdkVersion 29
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
}
}
}
flutter {
source '../..'
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.google.firebase:firebase-analytics:17.2.2'
}
================================================
FILE: android/app/google-services.json
================================================
{
"project_info": {
"project_number": "754179280048",
"firebase_url": "https://coocoo-private-fc1e0.firebaseio.com",
"project_id": "coocoo-private-fc1e0",
"storage_bucket": "coocoo-private-fc1e0.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:754179280048:android:05aeea871ac3c2980aff75",
"android_client_info": {
"package_name": "com.digantakalita.coocoo"
}
},
"oauth_client": [
{
"client_id": "754179280048-it11k86jo0o6paa7j49h5822chkn3bfb.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyCBIAEZd1QRl6aclVIvJ1Hwp53HRGz_cL0"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "754179280048-it11k86jo0o6paa7j49h5822chkn3bfb.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:754179280048:android:9879c8ab91f94f440aff75",
"android_client_info": {
"package_name": "com.digantakalita.coocooprivate"
}
},
"oauth_client": [
{
"client_id": "754179280048-7b457bisjiacvm9q5jtfc6v7qveldthc.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "com.digantakalita.coocooprivate",
"certificate_hash": "95d0565459f5ab2a868748443dbeddb9f31ab585"
}
},
{
"client_id": "754179280048-it11k86jo0o6paa7j49h5822chkn3bfb.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyCBIAEZd1QRl6aclVIvJ1Hwp53HRGz_cL0"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "754179280048-it11k86jo0o6paa7j49h5822chkn3bfb.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}
================================================
FILE: android/app/src/debug/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.digantakalita.coocoo">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
================================================
FILE: android/app/src/main/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.digantakalita.coocoo">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:name="io.flutter.app.FlutterApplication"
android:label="HitUp"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
================================================
FILE: android/app/src/main/kotlin/com/digantakalita/coocoo/MainActivity.kt
================================================
package com.digantakalita.coocoo
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}
================================================
FILE: android/app/src/main/res/drawable/ic_launcher_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<vector
android:height="108dp"
android:width="108dp"
android:viewportHeight="108"
android:viewportWidth="108"
xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z"/>
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
</vector>
================================================
FILE: android/app/src/main/res/drawable/launch_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
================================================
FILE: android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
================================================
FILE: android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
================================================
FILE: android/app/src/main/res/values/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">@android:color/white</item>
</style>
</resources>
================================================
FILE: android/app/src/profile/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.digantakalita.coocoo">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
================================================
FILE: android/build.gradle
================================================
buildscript {
ext.kotlin_version = '1.3.50'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.3'
}
}
allprojects {
repositories {
google()
jcenter()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
delete rootProject.buildDir
}
================================================
FILE: android/gradle/wrapper/gradle-wrapper.properties
================================================
#Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
================================================
FILE: android/gradle.properties
================================================
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true
================================================
FILE: android/settings.gradle
================================================
include ':app'
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
================================================
FILE: ios/.gitignore
================================================
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3
================================================
FILE: ios/Flutter/AppFrameworkInfo.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>8.0</string>
</dict>
</plist>
================================================
FILE: ios/Flutter/Debug.xcconfig
================================================
#include "Generated.xcconfig"
================================================
FILE: ios/Flutter/Release.xcconfig
================================================
#include "Generated.xcconfig"
================================================
FILE: ios/Runner/AppDelegate.swift
================================================
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
================================================
FILE: ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
================================================
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
================================================
FILE: ios/Runner/Base.lproj/LaunchScreen.storyboard
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>
================================================
FILE: ios/Runner/Base.lproj/Main.storyboard
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
================================================
FILE: ios/Runner/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>coocoo</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</plist>
================================================
FILE: ios/Runner/Runner-Bridging-Header.h
================================================
#import "GeneratedPluginRegistrant.h"
================================================
FILE: ios/Runner.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
);
path = Runner;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = com.digantakalita.coocoo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = com.digantakalita.coocoo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = com.digantakalita.coocoo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}
================================================
FILE: ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
</Workspace>
================================================
FILE: ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
================================================
FILE: ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
================================================
FILE: ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
================================================
FILE: ios/Runner.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
</Workspace>
================================================
FILE: ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
================================================
FILE: ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
================================================
FILE: lib/blocs/AddFriends/add_friends_bloc.dart
================================================
import 'dart:async';
import 'dart:convert';
import 'package:bloc/bloc.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:coocoo/config/Constants.dart';
import 'package:coocoo/config/Paths.dart';
import 'package:coocoo/functions/AddFriendsFunction.dart';
import 'package:coocoo/functions/BaseFunctions.dart';
import 'package:coocoo/functions/ChatFunction.dart';
import 'package:coocoo/functions/UserDataFunction.dart';
import 'package:coocoo/models/MyContact.dart';
import 'package:coocoo/utils/SharedObjects.dart';
import 'package:coocoo/widgets/GradientSnackBar.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
part 'add_friends_event.dart';
part 'add_friends_state.dart';
class AddFriendsBloc extends Bloc<AddFriendsEvent, AddFriendsState> {
AddFriendsBloc() : super(AddFriendsInitial());
Firestore _firestore = Firestore.instance;
AddFriendsFunction addFriendsFunction = AddFriendsFunction();
ChatFunction chatFunction = ChatFunction();
UserDataFunction userDataFunction = UserDataFunction();
String myName = SharedObjects.prefs.getString(Constants.fullName);
@override
Stream<AddFriendsState> mapEventToState(
AddFriendsEvent event,
) async* {
if (event is SearchHitUpIdEvent) {
yield* mapSearchHitUpIdEventToState(event);
}
if (event is AddButtonClickEvent) {
yield* mapAddButtonClickEventToState(event);
}
if (event is AcceptFriendRequestEvent) {
yield* mapAcceptFriendRequestEventToState(event);
}
if (event is DeclineFriendRequestEvent) {
yield* mapDeclineFriendRequestEventToState(event);
}
}
Stream<AddFriendsState> mapDeclineFriendRequestEventToState(
DeclineFriendRequestEvent event) async* {
yield DecliningFriendRequestState();
await addFriendsFunction
.removeFromFriendRequestsCollection(event.phoneNumber);
addFriendsFunction.removeFromSentRequestsCollection(event.phoneNumber);
yield FriendRequestDeclinedState();
}
Stream<AddFriendsState> mapAcceptFriendRequestEventToState(
AcceptFriendRequestEvent event) async* {
yield AcceptingFriendRequestState();
String chatId = await addFriendsFunction.addToLocalDBAndSubscribe(
event.context, event.phoneNumber);
chatFunction.sendMessageToServer(
event.context, 'Hi, I have accepted your friend request', chatId);
await addFriendsFunction
.removeFromFriendRequestsCollection(event.phoneNumber);
yield FriendRequestAcceptedState();
userDataFunction.sendNotification(toUid:event.phoneNumber, title: "New Notification", content: "$myName has accepted your friend request");
GradientSnackBar.showMessage(event.context, "Friend Request Accepted", 1);
addFriendsFunction.removeFromSentRequestsCollection(event.phoneNumber);
}
Stream<AddFriendsState> mapAddButtonClickEventToState(
AddButtonClickEvent event) async* {
yield SendingFriendRequestState();
await addFriendsFunction.addToLocalDBAndSubscribe(
event.context, event.friend.phoneNumber);
await addFriendsFunction
.addToSentRequestsCollection(event.friend.phoneNumber);
yield FriendRequestSentState(event.friend);
userDataFunction.sendNotification(toUid:event.friend.phoneNumber, title: "New Notification", content: "$myName has sent you a friend request");
addFriendsFunction.addToFriendRequestsCollection(event.friend.phoneNumber);
}
Stream<AddFriendsState> mapSearchHitUpIdEventToState(
SearchHitUpIdEvent event) async* {
yield SearchingHitUpIdState();
final HitUpIdLocation hitUpIdLocation =
await addFriendsFunction.checkHitUpId(event.hitUpId);
// if hitUpId does not exists in local db, friend requests & sent requests
if (hitUpIdLocation == HitUpIdLocation.Nowhere) {
QuerySnapshot snapshot = await _firestore
.collection(Paths.usersPath)
.where("username", isEqualTo: event.hitUpId)
.limit(1)
.getDocuments();
if (snapshot.documents.length > 0) {
DocumentSnapshot doc = snapshot.documents[0];
yield HitUpIdExistsState(MyContact.fromFireStore(doc));
} else {
yield HitUpIdNotExistsState(event.hitUpId);
}
} else {
yield HitUpIdAlreadyThere(event.hitUpId, hitUpIdLocation);
}
}
}
================================================
FILE: lib/blocs/AddFriends/add_friends_event.dart
================================================
part of 'add_friends_bloc.dart';
abstract class AddFriendsEvent extends Equatable {
const AddFriendsEvent();
}
class SearchHitUpIdEvent extends AddFriendsEvent {
final String hitUpId;
SearchHitUpIdEvent(this.hitUpId);
@override
List<Object> get props => [hitUpId];
}
class AddButtonClickEvent extends AddFriendsEvent {
final MyContact friend;
final BuildContext context;
AddButtonClickEvent(this.context, this.friend);
@override
List<Object> get props => [context, friend];
}
class AcceptFriendRequestEvent extends AddFriendsEvent {
final String phoneNumber;
final BuildContext context;
AcceptFriendRequestEvent(this.phoneNumber, this.context);
@override
List<Object> get props => [phoneNumber, context];
}
class DeclineFriendRequestEvent extends AddFriendsEvent{
final String phoneNumber;
DeclineFriendRequestEvent(this.phoneNumber);
@override
List<Object> get props => [phoneNumber];
}
================================================
FILE: lib/blocs/AddFriends/add_friends_state.dart
================================================
part of 'add_friends_bloc.dart';
abstract class AddFriendsState extends Equatable {
const AddFriendsState();
}
class AddFriendsInitial extends AddFriendsState {
@override
List<Object> get props => [];
}
class SearchingHitUpIdState extends AddFriendsState {
@override
List<Object> get props => [];
}
class HitUpIdExistsState extends AddFriendsState {
final MyContact friend;
HitUpIdExistsState(this.friend);
@override
List<Object> get props => [friend];
}
class HitUpIdNotExistsState extends AddFriendsState {
final String hitupId;
HitUpIdNotExistsState(this.hitupId);
@override
List<Object> get props => [hitupId];
}
class HitUpIdAlreadyThere extends AddFriendsState {
final String hitUpId;
final HitUpIdLocation hitUpIdLocation;
HitUpIdAlreadyThere(this.hitUpId, this.hitUpIdLocation);
@override
List<Object> get props => [hitUpId, hitUpIdLocation];
}
class SendingFriendRequestState extends AddFriendsState {
@override
List<Object> get props => [];
}
class FriendRequestSentState extends AddFriendsState {
final MyContact friend;
FriendRequestSentState(this.friend);
@override
List<Object> get props => [friend];
}
class AcceptingFriendRequestState extends AddFriendsState {
@override
List<Object> get props => [];
}
class FriendRequestAcceptedState extends AddFriendsState {
@override
List<Object> get props => [];
}
class DecliningFriendRequestState extends AddFriendsState{
@override
List<Object> get props => [];
}
class FriendRequestDeclinedState extends AddFriendsState{
@override
List<Object> get props => [];
}
================================================
FILE: lib/blocs/chats/chat_bloc.dart
================================================
import 'dart:async';
import 'dart:io';
import 'package:bloc/bloc.dart';
import 'package:coocoo/functions/ChatFunction.dart';
import 'package:coocoo/managers/db_manager.dart';
import 'package:coocoo/models/ChatMessage.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
part 'chat_event.dart';
part 'chat_state.dart';
class ChatBloc extends Bloc<ChatEvent, ChatState> {
ChatBloc() : super(ChatInitial());
ChatFunction chatFunction = ChatFunction();
@override
Stream<ChatState> mapEventToState(
ChatEvent event,
) async* {
if (event is SendMessageEvent) {
chatFunction.sendMessageToServer(event.context, event.msg, event.chatId);
}
if (event is SendImageEvent) {
chatFunction.sendImageToServer(
event.context, event.imageFile, event.chatId);
}
if (event is ReceivedMessageEvent) {
List<ChatMessage> allMessages =
await chatFunction.getAllMsgsFromMessagesTable(event.chatId);
yield (ReceivedMessageState(allMessages));
}
if (event is LoadInitialMessagesEvent) {
List<ChatMessage> lastChatMsgs =
await chatFunction.getAllMsgsFromMessagesTable(event.chatId);
yield (InitialMessagesLoadedState(lastChatMsgs));
}
if (event is BlockUserEvent) {
chatFunction.blockUser(event.context, event.chatId);
yield (BlockedUserState());
DBManager.db.isBlocked(event.chatId);
}
if (event is UnblockUserEvent) {
chatFunction.unBlockUser(event.context, event.chatId);
yield (UnblockedUserState());
}
}
}
================================================
FILE: lib/blocs/chats/chat_event.dart
================================================
part of 'chat_bloc.dart';
abstract class ChatEvent extends Equatable {
const ChatEvent();
}
class SendMessageEvent extends ChatEvent {
final BuildContext context;
final String msg;
final String chatId;
SendMessageEvent(this.context, this.msg, this.chatId);
@override
List<Object> get props => [msg, chatId];
}
class SendImageEvent extends ChatEvent {
final BuildContext context;
final File imageFile;
final String chatId;
SendImageEvent(this.context, this.imageFile, this.chatId);
@override
List<Object> get props => [imageFile, chatId];
}
class ReceivedMessageEvent extends ChatEvent {
final String chatId;
ReceivedMessageEvent(this.chatId);
@override
List<Object> get props => [chatId];
}
class LoadInitialMessagesEvent extends ChatEvent {
final String chatId;
LoadInitialMessagesEvent(this.chatId);
@override
List<Object> get props => [chatId];
}
class BlockUserEvent extends ChatEvent{
final BuildContext context;
final String chatId;
BlockUserEvent(this.context, this.chatId);
@override
List<Object> get props => [context, chatId];
}
class UnblockUserEvent extends ChatEvent{
final BuildContext context;
final String chatId;
UnblockUserEvent(this.context, this.chatId);
@override
List<Object> get props => [context, chatId];
}
================================================
FILE: lib/blocs/chats/chat_state.dart
================================================
part of 'chat_bloc.dart';
abstract class ChatState extends Equatable {
final List<ChatMessage> chatMessages;
const ChatState(this.chatMessages);
}
class ChatInitial extends ChatState {
ChatInitial() : super([]);
@override
List<Object> get props => [];
}
class ReceivedMessageState extends ChatState {
final List<ChatMessage> chatMessages;
ReceivedMessageState(this.chatMessages) : super(chatMessages);
@override
List<Object> get props => [chatMessages];
}
class InitialMessagesLoadedState extends ChatState {
final List<ChatMessage> chatMessages;
InitialMessagesLoadedState(this.chatMessages) : super(chatMessages);
@override
List<Object> get props => [chatMessages];
}
class BlockedUserState extends ChatState {
BlockedUserState() : super([]);
@override
List<Object> get props => [];
}
class UnblockedUserState extends ChatState {
UnblockedUserState() : super([]);
@override
List<Object> get props => [];
}
================================================
FILE: lib/blocs/contacts/contacts_bloc.dart
================================================
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:coocoo/functions/UserDataFunction.dart';
import 'package:coocoo/models/MyContact.dart';
import 'package:equatable/equatable.dart';
part 'contacts_event.dart';
part 'contacts_state.dart';
class ContactsBloc extends Bloc<ContactsEvent, ContactsState> {
ContactsBloc() : super(InitialContactsState());
UserDataFunction userDataFunction = UserDataFunction();
@override
Stream<ContactsState> mapEventToState(
ContactsEvent event,
) async* {
if (event is FetchContactsEvent) {
try {
yield FetchingContactsState();
List<MyContact> contacts = await userDataFunction.getContactsFromDB();
add(ReceivedContactsEvent(contacts));
} on Exception catch (e) {
print(e);
}
}
if (event is ReceivedContactsEvent) {
yield FetchedContactsState(event.contacts);
}
}
}
================================================
FILE: lib/blocs/contacts/contacts_event.dart
================================================
part of 'contacts_bloc.dart';
abstract class ContactsEvent extends Equatable {
const ContactsEvent();
}
class FetchContactsEvent extends ContactsEvent {
@override
String toString() => 'FetchContactsEvent';
@override
List<Object> get props => [];
}
class ReceivedContactsEvent extends ContactsEvent {
final List<MyContact> contacts;
ReceivedContactsEvent(this.contacts);
@override
String toString() => "ReceivedContactsEvent";
@override
List<Object> get props => [contacts];
}
================================================
FILE: lib/blocs/contacts/contacts_state.dart
================================================
part of 'contacts_bloc.dart';
abstract class ContactsState extends Equatable {
const ContactsState();
}
class InitialContactsState extends ContactsState {
@override
String toString() => "InitialContactsState";
@override
List<Object> get props => [];
}
class FetchingContactsState extends ContactsState {
@override
String toString() => "FetchingContactsState";
@override
List<Object> get props => [];
}
class FetchedContactsState extends ContactsState {
final List<MyContact> contacts;
FetchedContactsState(this.contacts);
@override
String toString() => "FetchedContactsState";
@override
List<Object> get props => [contacts];
}
class ErrorState extends ContactsState {
// TODO: Implement errors
@override
List<Object> get props => [];
}
================================================
FILE: lib/blocs/home/home_bloc.dart
================================================
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:coocoo/functions/MQTTFunction.dart';
import 'package:coocoo/managers/db_manager.dart';
import 'package:coocoo/models/Conversation.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/cupertino.dart';
part 'home_event.dart';
part 'home_state.dart';
class HomeBloc extends Bloc<HomeEvent, HomeState> {
HomeBloc() : super(HomeInitial());
MQTTFunction mqttFunction = MQTTFunction();
@override
Stream<HomeState> mapEventToState(
HomeEvent event,
) async* {
if (event is ConnectToServerEvent) {
try {
await mqttFunction.connect(event.context);
} catch (e) {
print("Couln't Connect to Server. Most Probably Internet is Off");
}
add(FetchHomeChatsEvent());
}
if (event is DisconnectEvent) {
mqttFunction.disconnect();
}
if (event is FetchHomeChatsEvent) {
yield* mapFetchHomeChatsEventToState();
}
}
Stream<HomeState> mapFetchHomeChatsEventToState() async* {
List<Conversation> conversations = [];
//TODO: Implement
List<Map<dynamic, dynamic>> dbData =
await DBManager.db.getAlConversationsFromChatTable();
dbData.forEach((dbMap) {
conversations.add(Conversation.fromMap(dbMap));
});
conversations.sort((b, a) => a.time.compareTo(b.time));
yield (FetchedHomeChatsState(conversations));
}
}
================================================
FILE: lib/blocs/home/home_event.dart
================================================
part of 'home_bloc.dart';
abstract class HomeEvent extends Equatable {
const HomeEvent();
}
class FetchHomeChatsEvent extends HomeEvent {
@override
List<Object> get props => [];
}
class ConnectToServerEvent extends HomeEvent {
final BuildContext context;
ConnectToServerEvent(this.context);
@override
List<Object> get props => [context];
}
class DisconnectEvent extends HomeEvent {
@override
List<Object> get props => [];
}
================================================
FILE: lib/blocs/home/home_state.dart
================================================
part of 'home_bloc.dart';
abstract class HomeState extends Equatable {
final List<Conversation> conversations;
const HomeState(this.conversations);
}
class HomeInitial extends HomeState {
HomeInitial() : super([]);
@override
List<Object> get props => [];
}
class FetchedHomeChatsState extends HomeState {
final List<Conversation> conversations;
FetchedHomeChatsState(this.conversations) : super(conversations);
@override
List<Object> get props => [conversations];
}
================================================
FILE: lib/blocs/timer/timer_bloc.dart
================================================
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:coocoo/config/Constants.dart';
import 'package:equatable/equatable.dart';
part 'timer_event.dart';
part 'timer_state.dart';
class TimerBloc extends Bloc<TimerEvent, TimerState> {
TimerBloc() : super(TimerStoppedState());
Stream<int> timerStream;
StreamSubscription<int> timerSubscription;
@override
Stream<TimerState> mapEventToState(
TimerEvent event,
) async* {
if (event is StartTimerEvent) {
timerStream = stopWatchStream();
timerSubscription?.cancel();
timerSubscription = timerStream.listen((int newTick) {
add(TimerTickedEvent(newTick));
});
}
if (event is TimerTickedEvent) {
yield (TimerRunInProgressState(event.newTick));
}
if (event is StopTimerEvent) {
timerSubscription?.cancel();
timerStream = null;
yield (TimerStoppedState());
}
}
Stream<int> stopWatchStream() {
StreamController<int> streamController;
Timer timer;
Duration timerInterval = Duration(seconds: 1);
int counter = Constants.resendOtpTime;
void stopTimer() {
if (timer != null) {
timer.cancel();
timer = null;
counter = Constants.resendOtpTime;
streamController.close();
}
}
void tick(_) {
counter--;
streamController.add(counter);
if (counter < 1) {
add(StopTimerEvent());
}
}
void startTimer() {
timer = Timer.periodic(timerInterval, tick);
}
streamController = StreamController<int>(
onListen: startTimer,
onCancel: stopTimer,
onResume: startTimer,
onPause: stopTimer,
);
return streamController.stream;
}
}
================================================
FILE: lib/blocs/timer/timer_event.dart
================================================
part of 'timer_bloc.dart';
abstract class TimerEvent extends Equatable {
const TimerEvent();
}
class StartTimerEvent extends TimerEvent {
@override
List<Object> get props => [];
}
class TimerTickedEvent extends TimerEvent {
final int newTick;
TimerTickedEvent(this.newTick);
@override
List<Object> get props => [newTick];
}
class StopTimerEvent extends TimerEvent {
@override
List<Object> get props => [];
}
================================================
FILE: lib/blocs/timer/timer_state.dart
================================================
part of 'timer_bloc.dart';
abstract class TimerState extends Equatable {
const TimerState();
}
class TimerInitial extends TimerState {
@override
List<Object> get props => [];
}
class TimerRunInProgressState extends TimerState {
final int newTick;
TimerRunInProgressState(this.newTick);
@override
List<Object> get props => [newTick];
}
class TimerStoppedState extends TimerState {
@override
List<Object> get props => [];
}
================================================
FILE: lib/config/Constants.dart
================================================
import 'package:flutter/material.dart';
class Constants {
static final Color stuffColor = Colors.blueAccent[400];
static final Color textStuffColor = Colors.blueGrey[700];
static final int resendOtpTime = 35;
static const firstRun = "firstRun";
static const sessionUid = "phoneNumber";
static const sessionUsername = 'sessionUsername';
static const fullName = 'fullName';
static const sessionName = 'sessionName';
static const sessionProfilePictureUrl = 'sessionProfilePictureUrl';
static const sessionCountryCode = 'sessionCountryCode';
static const configDarkMode = 'configDarkMode';
static String downloadsDirPath;
static String cacheDirPath;
static const profilePicChangeMsg = "profile_pic_change";
}
================================================
FILE: lib/config/Paths.dart
================================================
class Paths {
/*
Firebase paths
*/
static const String profilePicturePath = 'profile_pictures';
static const String imageAttachmentsPath = 'images';
static const String videoAttachmentsPath = 'videos';
static const String fileAttachmentsPath = 'files';
static const String usersPath = '/users';
static const String contactsPath = 'contacts';
static const String usernameUidMapPath = '/username_uid_map';
static const String chatsPath = '/chats';
static const String chat_messages = '/chat_messages';
static const String messagesPath = 'messages';
static const String friendRequestsPath = 'friend requests';
static const String sentRequestsPath = 'sent requests';
static const String MESSAGES_COLLECTION = "messages";
static const String USERS_COLLECTION = "users";
static const String CALL_COLLECTION = "call";
static const String TIMESTAMP_FIELD = "timestamp";
static const String EMAIL_FIELD = "email";
static const String MESSAGE_TYPE_IMAGE = "image";
}
================================================
FILE: lib/constants.dart
================================================
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
const kMobileTextFieldDecoration = InputDecoration(
hintText: 'Enter Mobile Number',
contentPadding: EdgeInsets.symmetric(vertical: 1.5),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0xFF6A1B9A),
width: 2.0,
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0xFF6A1B9A),
width: 2.0,
),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0xFF6A1B9A),
width: 2.0,
),
),
);
const kChatsGroupsTextStyle = TextStyle(
fontSize: 17.0,
fontWeight: FontWeight.w600,
);
const kCircleNeumorphicStyle = NeumorphicStyle(
shadowDarkColor: Colors.black,
shadowLightColor: Colors.white,
boxShape: NeumorphicBoxShape.circle(),
depth: 7,
intensity: 0.7,
surfaceIntensity: 0.6,
shape: NeumorphicShape.convex,
);
const kChatCircleNeumorphicStyle = NeumorphicStyle(
shadowDarkColor: Colors.black,
shadowLightColor: Colors.white,
boxShape: NeumorphicBoxShape.circle(),
depth: 5,
intensity: 0.65,
surfaceIntensity: 0.6,
);
const kRequestTitleStyle = TextStyle(
fontWeight: FontWeight.w700,
fontSize: 23.0,
);
const double perfectWidth = 411.4; // 683.4;
const kHitUpIdTextFieldDecoration = InputDecoration(
contentPadding: EdgeInsets.symmetric(vertical: 0.0, horizontal: 15.0),
hintText: 'Search Username',
fillColor: Colors.white,
filled: true,
border: OutlineInputBorder(
borderRadius: const BorderRadius.all(
Radius.circular(40.0),
),
),
focusedBorder: OutlineInputBorder(
borderRadius: const BorderRadius.all(
Radius.circular(40.0),
),
),
);
================================================
FILE: lib/functions/AddFriendsFunction.dart
================================================
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:coocoo/config/Constants.dart';
import 'package:coocoo/config/Paths.dart';
import 'package:coocoo/functions/BaseFunctions.dart';
import 'package:coocoo/functions/ChatFunction.dart';
import 'package:coocoo/managers/db_manager.dart';
import 'package:coocoo/managers/mqtt_manager.dart';
import 'package:coocoo/stateProviders/mqtt_state.dart';
import 'package:coocoo/utils/SharedObjects.dart';
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
class AddFriendsFunction extends BaseAddFriendsFunction {
Firestore _firestore = Firestore.instance;
ChatFunction chatFunction = ChatFunction();
String uid = SharedObjects.prefs.getString(Constants.sessionUid);
@override
void dispose() {}
@override
Future<void> addToFriendRequestsCollection(String phoneNumber) async {
// add to friend requests collection of the other user
CollectionReference usersRef = _firestore.collection(Paths.usersPath);
// first get my data
DocumentSnapshot snapshot = await usersRef.document(uid).get();
usersRef
.document(phoneNumber)
.collection(Paths.friendRequestsPath)
.document(uid)
.setData({
'username': snapshot.data['username'],
'photoUrl': snapshot.data['photoUrl'],
'name': snapshot.data['name'],
'phoneNumber': snapshot.data['phoneNumber'],
});
}
@override
Future<String> addToLocalDBAndSubscribe(
BuildContext context, String phoneNumber) async {
DocumentSnapshot docSnapshot = await _firestore
.collection(Paths.usersPath)
.document(phoneNumber)
.get();
String chatId = await chatFunction.createChatIdForContact(phoneNumber);
// create a row for this user, i.e add the contact to my local db
String photoUrl = docSnapshot.data["photoUrl"];
String username = docSnapshot.data["username"];
String name = docSnapshot.data["name"];
await DBManager.db.createRow(phoneNumber, chatId, name, username, photoUrl,
0); // 0 because here this is not a phone contact
// Subscribe to the chatId
MQTTManager manager = context.read<MQTTState>().manager;
print("SUBSCRIBING TO TOPIC : $chatId");
manager.subscribeTopic(chatId);
return chatId;
}
@override
Future<void> addToSentRequestsCollection(String phoneNumber) async {
// add to my sent requests collection
CollectionReference usersRef = _firestore.collection(Paths.usersPath);
// first get the data for the phoneNumber
DocumentSnapshot snapshot = await usersRef.document(phoneNumber).get();
usersRef
.document(uid)
.collection(Paths.sentRequestsPath)
.document(phoneNumber)
.setData({
'username': snapshot.data['username'],
'photoUrl': snapshot.data['photoUrl'],
'name': snapshot.data['name'],
'phoneNumber': snapshot.data['phoneNumber'],
});
}
@override
Future<HitUpIdLocation> checkHitUpId(String hitUpId) async {
bool ans;
// check if hitUpId exists in local db
ans = await DBManager.db.checkIfUsernameExistsInDb(hitUpId);
if (ans) {
return HitUpIdLocation.InLocalDb;
} else {
// check if hitUpId exists in Firebase Friend Requests collection
String uid = SharedObjects.prefs.getString(Constants.sessionUid);
QuerySnapshot snapshot = await _firestore
.collection(Paths.usersPath)
.document(uid)
.collection(Paths.friendRequestsPath)
.where('username', isEqualTo: hitUpId)
.limit(1)
.getDocuments();
if (snapshot.documents.length > 0) {
return HitUpIdLocation.InFriendRequests;
} else {
// check if hitUpId exists in Firebase Sent Requests Collection
snapshot = await _firestore
.collection(Paths.usersPath)
.document(uid)
.collection(Paths.sentRequestsPath)
.where('username', isEqualTo: hitUpId)
.limit(1)
.getDocuments();
if (snapshot.documents.length > 0) {
return HitUpIdLocation.InSentRequests;
} else {
return HitUpIdLocation.Nowhere;
}
}
}
}
@override
Future<void> removeFromFriendRequestsCollection(String phoneNumber) async {
// remove from my friend requests collection
CollectionReference usersRef = _firestore.collection(Paths.usersPath);
await usersRef
.document(uid)
.collection(Paths.friendRequestsPath)
.document(phoneNumber)
.delete();
}
@override
void removeFromSentRequestsCollection(String phoneNumber) {
// remove from the other user's sent requests collection
CollectionReference usersRef = _firestore.collection(Paths.usersPath);
usersRef
.document(phoneNumber)
.collection(Paths.sentRequestsPath)
.document(uid)
.delete();
}
}
================================================
FILE: lib/functions/BaseFunctions.dart
================================================
import 'dart:io';
import 'package:coocoo/models/ChatMessage.dart';
import 'package:coocoo/models/MyContact.dart';
import 'package:coocoo/models/NonContact.dart';
import 'package:flutter/cupertino.dart';
import 'package:permission_handler/permission_handler.dart';
enum HitUpIdLocation {
InLocalDb,
InFriendRequests,
InSentRequests,
Nowhere,
}
abstract class BaseFunction {
void dispose();
}
abstract class BaseUserDataFunction extends BaseFunction {
Future<List<MyContact>> getContactsFromDB();
Future<void> loadPhoneContactsV2(BuildContext context);
Future<List<NonContact>> loadNonContactsV2();
Future<PermissionStatus> askContactPermissions();
void onShare(BuildContext context);
void sendNotification({String toUid, String title, String content});
Future<void> verifyPhoneNumber(
BuildContext context, String phoneNum, Function verificationFailed);
}
abstract class BaseChatFunction extends BaseFunction {
Future<void> createChatIdForContact(String contactPhoneNumber);
void sendMessageToServer(BuildContext context, String msg, String chatId);
void sendImageToServer(BuildContext context, File imageFile, String chatId);
void sendServiceMsgToServer(BuildContext context, String msg, String chatId);
Future<List<ChatMessage>> getAllMsgsFromMessagesTable(String chatId);
void blockUser(BuildContext context, String chatId);
void unBlockUser(BuildContext context, String chatId);
}
abstract class BaseMQTTFunction extends BaseFunction {
Future<void> connect(BuildContext context);
void disconnect();
}
abstract class BaseUIFunction extends BaseFunction {
double cleanValue(double screenWidth, double value);
}
abstract class BaseAddFriendsFunction extends BaseFunction {
Future<String> addToLocalDBAndSubscribe(
BuildContext context, String phoneNumber);
Future<void> addToFriendRequestsCollection(String phoneNumber);
Future<void> addToSentRequestsCollection(String phoneNumber);
Future<HitUpIdLocation> checkHitUpId(String hitUpId);
Future<void> removeFromFriendRequestsCollection(String phoneNumber);
void removeFromSentRequestsCollection(String phoneNumber);
}
================================================
FILE: lib/functions/ChatFunction.dart
================================================
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:coocoo/config/Constants.dart';
import 'package:coocoo/config/Paths.dart';
import 'package:coocoo/functions/BaseFunctions.dart';
import 'package:coocoo/managers/db_manager.dart';
import 'package:coocoo/managers/mqtt_manager.dart';
import 'package:coocoo/models/ChatMessage.dart';
import 'package:coocoo/stateProviders/mqtt_state.dart';
import 'package:coocoo/utils/SharedObjects.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart';
class ChatFunction extends BaseChatFunction {
Firestore _firestore = Firestore.instance;
MQTTManager _manager;
String myUid = SharedObjects.prefs.getString(Constants.sessionUid);
@override
Future<String> createChatIdForContact(String contactPhoneNumber) async {
String chatId;
String uId = SharedObjects.prefs.getString(Constants.sessionUid);
CollectionReference usersCollection =
_firestore.collection(Paths.usersPath);
DocumentReference userRef = usersCollection.document(uId);
DocumentReference contactRef = usersCollection.document(contactPhoneNumber);
DocumentSnapshot userSnapshot = await userRef.get();
// if chatId doesn't exists for that contact then create new ChatId and update it
// for both the user and the contact
// else use the chatId which already exists
if (userSnapshot.data['chats'] == null ||
userSnapshot.data['chats'][contactPhoneNumber] == null) {
chatId = createChatId();
await userRef.setData({
'chats': {contactPhoneNumber: chatId}
}, merge: true);
await contactRef.setData({
'chats': {uId: chatId}
}, merge: true);
} else {
chatId = userSnapshot.data['chats'][contactPhoneNumber];
}
return chatId;
}
String createChatId() {
final Random _random = Random.secure();
final int idLength = 16; // length of the chatId
var values = List<int>.generate(idLength, (i) => _random.nextInt(256));
return base64Url.encode(values);
}
@override
void dispose() {}
@override
void sendMessageToServer(BuildContext context, String msg, String chatId) {
if (_manager == null) {
_manager = context.read<MQTTState>().manager;
}
print("calling send message to server");
Map msgMap = {"msg": "$msg", "type": "text", "uid": "$myUid"};
String msgToSend = json.encode(msgMap);
_manager.publish(msgToSend, chatId);
}
@override
Future<List<ChatMessage>> getAllMsgsFromMessagesTable(String chatId) async {
return await DBManager.db.readAllMessagesfromMessagesTable(chatId);
}
// 2. compress file and get file.
Future<File> testCompressAndGetFile(File file) async {
Directory tempDir = await getTemporaryDirectory();
String tempPath = tempDir.path;
var result = await FlutterImageCompress.compressAndGetFile(
file.absolute.path,
tempPath + "/temp.jpg",
minHeight: 400,
minWidth: 400,
quality: 80,
);
return result;
}
@override
void sendImageToServer(
BuildContext context, File imageFile, String chatId) async {
if (_manager == null) {
_manager = context.read<MQTTState>().manager;
}
// compress the image & make it smaller in size
File newFile = await testCompressAndGetFile(imageFile);
// change the image to bytes format
String base64Image = base64Encode(newFile.readAsBytesSync());
String msgToSend =
'{"msg" : "$base64Image", "type" : "image", "uid" : "$myUid"}';
while (!_manager.getConnectionStatus()) {
print("NOT CONNECTED BEFORE PUBLISHING");
await Future.delayed(Duration(seconds: 1));
}
print("CONNECTED BEFORE PUBLISHING");
_manager.publish(msgToSend, chatId);
}
@override
void sendServiceMsgToServer(BuildContext context, String msg, String chatId) {
if (_manager == null) {
_manager = context.read<MQTTState>().manager;
}
_manager.publish(msg, chatId);
}
@override
void blockUser(BuildContext context, String chatId) {
if (_manager == null) {
_manager = context.read<MQTTState>().manager;
}
DBManager.db.updateBlockStatus(0, chatId);
_manager.unSubscribeTopic(chatId);
}
@override
void unBlockUser(BuildContext context, String chatId) {
if (_manager == null) {
_manager = context.read<MQTTState>().manager;
}
DBManager.db.updateBlockStatus(1, chatId);
_manager.subscribeTopic(chatId);
}
}
================================================
FILE: lib/functions/MQTTFunction.dart
================================================
import 'package:coocoo/config/Constants.dart';
import 'package:coocoo/functions/BaseFunctions.dart';
import 'package:coocoo/managers/mqtt_manager.dart';
import 'package:coocoo/stateProviders/mqtt_state.dart';
import 'package:coocoo/utils/SharedObjects.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:provider/provider.dart';
class MQTTFunction extends BaseMQTTFunction {
MQTTManager _manager;
String loggedInUser;
@override
Future<void> connect(BuildContext context) async {
loggedInUser = SharedObjects.prefs.getString(Constants.sessionUid);
_manager = context.read<MQTTState>().manager;
final String password = "S8x${loggedInUser.substring(1, 6)}S,.@";
if (_manager == null) {
_manager = MQTTManager(
serverAddress: "13.127.199.45",
clientName: loggedInUser,
context: context,
);
_manager.initializeMQTTClient();
// also set the mqtt_manager to the provider
context.read<MQTTState>().setNewManager(_manager);
print(_manager);
}
print("Connecting to server");
await _manager.connect(loggedInUser, password);
}
@override
void dispose() {}
@override
void disconnect() {
if (_manager != null) {
_manager.disconnect();
}
}
}
================================================
FILE: lib/functions/UserDataFunction.dart
================================================
import 'dart:convert';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:contacts_service/contacts_service.dart';
import 'package:coocoo/config/Constants.dart';
import 'package:coocoo/config/Paths.dart';
import 'package:coocoo/functions/BaseFunctions.dart';
import 'package:coocoo/functions/ChatFunction.dart';
import 'package:coocoo/managers/db_manager.dart';
import 'package:coocoo/managers/mqtt_manager.dart';
import 'package:coocoo/models/MyContact.dart';
import 'package:coocoo/models/NonContact.dart';
import 'package:coocoo/stateProviders/mqtt_state.dart';
import 'package:coocoo/stateProviders/number_state.dart';
import 'package:coocoo/utils/SharedObjects.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import 'package:share/share.dart';
class UserDataFunction extends BaseUserDataFunction {
Firestore _firestore = Firestore.instance;
ChatFunction chatFunction = ChatFunction();
@override
void dispose() {}
@override
Future<List<NonContact>> loadNonContactsV2() async {
List<NonContact> _nonContacts = [];
Iterable<Contact> _contacts =
await ContactsService.getContacts(withThumbnails: false);
String countryCode =
SharedObjects.prefs.getString(Constants.sessionCountryCode);
await Future.forEach(_contacts, (_contact) async {
String tempNum = cleanNumber(_contact, countryCode);
if (tempNum != null) {
bool contactExists =
await DBManager.db.checkIfContactExistsInDb(tempNum);
// if contact does not exist in local db then add it to the nonContacts list
if (!contactExists) {
print(tempNum);
_nonContacts.add(NonContact(tempNum, name: _contact.displayName));
}
}
});
return _nonContacts;
}
@override
Future<void> loadPhoneContactsV2(BuildContext context) async {
Iterable<Contact> _contacts =
await ContactsService.getContacts(withThumbnails: false);
String countryCode =
SharedObjects.prefs.getString(Constants.sessionCountryCode);
try {
await Future.forEach(_contacts, (_contact) async {
String tempNum = cleanNumber(_contact, countryCode);
String contactName = _contact.displayName;
if (tempNum != null) {
bool contactExists =
await DBManager.db.checkIfContactExistsInDb(tempNum);
if (!contactExists) {
await addInstalledUserToDBANDSubscribe(
context, tempNum, contactName);
} else if (contactExists) {
// however if contact exists in local db but does not exist in primary firestore
// users database because he deleted his account then remove him from local db
removeUninstalledUserFromDB(context, tempNum);
}
}
});
} catch (e, s) {
print(s);
}
}
void removeUninstalledUserFromDB(BuildContext context, String tempNum) async {
final contactRef = _firestore.collection(Paths.usersPath).document(tempNum);
contactRef.get().then((docSnapshot) async {
if (!docSnapshot.exists) {
// delete the contact from local Database
await DBManager.db.deleteContact(tempNum);
}
});
}
Future<void> addInstalledUserToDBANDSubscribe(
BuildContext context, String tempNum, String contactName) async {
final contactRef = _firestore.collection(Paths.usersPath).document(tempNum);
contactRef.get().then((docSnapshot) async {
// if the user has installed the app then add him as a contact to my db
// else do nothing
if (docSnapshot.exists) {
print("USER $tempNum EXISTS IN DB");
String chatId = await chatFunction.createChatIdForContact(tempNum);
// create a row for this user, i.e add the contact to my local db
String photoUrl = docSnapshot.data["photoUrl"];
String username = docSnapshot.data["username"];
await DBManager.db.createRow(
docSnapshot.documentID,
chatId,
contactName,
username,
photoUrl,
1); // true because here this is a phone contact
// Subscribe to the chatId
MQTTManager manager = context.read<MQTTState>().manager;
print("SUBSCRIBING TO TOPIC : $chatId");
manager.subscribeTopic(chatId);
}
}).catchError((e) {
print("e");
});
}
dynamic cleanNumber(Contact dirtyNumber, String countryCode) {
// when we clean a number, we first remove all the white spaces and hyphens and then
// if the number does not has a country code,i.e, if its length is less than 11
// then we add the user's country code.
try {
String num = dirtyNumber.phones.first.value;
String num2 = num.replaceAll(RegExp(r"\D+"), '');
if (num2.length < 11) {
return "$countryCode$num2";
} else {
return num2;
}
} catch (e) {
return null;
}
}
@override
Future<PermissionStatus> askContactPermissions() async {
PermissionStatus permissionStatus = await _getContactPermission();
return permissionStatus;
}
Future<PermissionStatus> _getContactPermission() async {
PermissionStatus permission = await Permission.contacts.status;
if (permission != PermissionStatus.granted &&
permission != PermissionStatus.restricted) {
Map<Permission, PermissionStatus> permissionStatus = await [
Permission.contacts,
].request();
return permissionStatus[Permission.contacts] ??
PermissionStatus.undetermined;
} else {
return permission;
}
}
@override
Future<List<MyContact>> getContactsFromDB() async {
List<MyContact> contacts = [];
List<Map<dynamic, dynamic>> dbData = await DBManager.db.getAllContacts();
dbData.forEach((map) {
contacts.add(MyContact.fromMap(map));
});
return contacts;
}
@override
void onShare(BuildContext context) async {
// A builder is used to retrieve the context immediately
// surrounding the RaisedButton.
//
// The context's `findRenderObject` returns the first
// RenderObject in its descendent tree when it's not
// a RenderObjectWidget. The RaisedButton's RenderObject
// has its position and size after it's built.
final RenderBox box = context.findRenderObject();
await Share.share(
"https://play.google.com/store/apps/details?id=com.digantakalita.coocoo",
subject: "Lets have our private chats on"
"this New Cool Messenger HitUp from now on. Its way safer than the others.",
sharePositionOrigin: box.localToGlobal(Offset.zero) & box.size);
}
@override
void sendNotification({String toUid, String title, String content}) async {
final String app_id = "98194ba4-9b9a-416b-ab0c-74b851af4f1a";
var body = jsonEncode({
"include_external_user_ids": [toUid],
"app_id": app_id,
"contents": {"en": content},
"headings": {"en": title},
"collapse_id": "123",
"android_channel_id": "0940813c-e319-4ff3-8d52-a202bf767b3a"
});
http.Response response = await http.post(
'https://onesignal.com/api/v1/notifications',
body: body,
headers: {
"content-type": "application/json",
"Authorization":
"Basic ZGY5MWZjZjctYmQ0My00ZDhjLTliYmItNzE0ZjlmOWVkYjYz"
});
if (response.statusCode == 200) {
print("NOTIFICATION SENT SUCCESSFULLY");
} else {
print('Notification Error | Error Code: ${response.statusCode}');
}
}
@override
Future<void> verifyPhoneNumber(BuildContext context, String phoneNum,
Function verificationFailed) async {
final FirebaseAuth _auth = FirebaseAuth.instance;
await _auth.verifyPhoneNumber(
phoneNumber: phoneNum,
timeout: Duration(seconds: 30),
verificationCompleted: null,
verificationFailed: verificationFailed,
codeSent: (String verificationId, [int forceResendingToken]) async {
context.read<NumberState>().setOTP(verificationId);
},
codeAutoRetrievalTimeout: null,
);
}
}
================================================
FILE: lib/main.dart
================================================
import 'package:coocoo/blocs/AddFriends/add_friends_bloc.dart';
import 'package:coocoo/blocs/chats/chat_bloc.dart';
import 'package:coocoo/blocs/contacts/contacts_bloc.dart';
import 'package:coocoo/blocs/timer/timer_bloc.dart';
import 'package:coocoo/screens/home_screen.dart';
import 'package:coocoo/splashscreen.dart';
import 'package:coocoo/stateProviders/number_state.dart';
import 'package:coocoo/stateProviders/profilePicUrlState.dart';
import 'package:coocoo/utils/SharedObjects.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:provider/provider.dart';
import 'blocs/home/home_bloc.dart';
import 'stateProviders/mqtt_state.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
SharedObjects.prefs = await CachedSharedPreferences.getInstance();
runApp(MultiBlocProvider(
providers: [
BlocProvider<ContactsBloc>(
create: (context) => ContactsBloc(),
),
BlocProvider<ChatBloc>(
create: (context) => ChatBloc(),
),
BlocProvider<HomeBloc>(
create: (context) => HomeBloc(),
),
BlocProvider<AddFriendsBloc>(
create: (context) => AddFriendsBloc(),
),
BlocProvider<TimerBloc>(
create: (context) => TimerBloc(),
)
],
child: MyApp(),
));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<MQTTState>(create: (context) => MQTTState()),
ChangeNotifierProvider<NumberState>(
create: (context) => NumberState(),
),
ChangeNotifierProvider<ProfilePicUrlState>(
create: (context) => ProfilePicUrlState()),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'HitUp Messenger',
routes: {
'/homeScreen': (context) => HomeScreen(),
},
theme: ThemeData(
primaryColor: Colors.white,
primarySwatch: Colors.blueGrey,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: SplashScreen(),
),
);
}
}
//Feature Ideas
//TODO: Mood of a user
//TODO: Online Offline...but only to the people whom I wanna show if I am online
//TODO: whether the user is active or not, i.e if she is inside your chat window or is she chatting with someone else
================================================
FILE: lib/managers/db_manager.dart
================================================
import 'package:coocoo/models/ChatMessage.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
class DBManager {
DBManager._();
static final DBManager db = DBManager._();
Database _database;
// final String contactsTable = "Contacts";
final String messagesTable = "Messages";
final String chatsTable = "Chats";
final String phoneNumberColumn = "phoneNumber";
final String chatIdColumn = "chatId";
final String nameColumn = 'name';
final String usernameColumn = 'username';
final String msgColumn = "msg";
final String timeColumn = "time";
final String photoUrlColumn = "photoUrl";
final String msgTypeColumn = 'msgType';
final String isContactColumn = 'isContact';
final String blockStatusColumn = 'blockStat'; // 0 => Blocked, 1 => Unblocked
final String msgStatusColumn = "msgStatus"; // 0=> Received, 1=> Sent
Future<Database> get database async {
if (_database != null) {
return _database;
}
_database = await initDB();
return _database;
}
initDB() async {
String dbPath = await getDatabasesPath();
return await openDatabase(
join(dbPath, "chat_database.db"),
version: 1,
// onCreate is called only if there was no prior database in the specified path
onCreate: (Database db, int version) async {
// we need 3 tables
// 1. for storing users data
// await db.execute(
// "CREATE TABLE $contactsTable ($phoneNumberColumn TEXT PRIMARY KEY, $chatIdColumn TEXT, "
// "$nameColumn TEXT, $usernameColumn TEXT,"
// "$photoUrlColumn TEXT, $isContactColumn INTEGER, $blockStatusColumn INTEGER)");
// 2. for storing the messages for the chat screen
await db.execute("CREATE TABLE $messagesTable ("
"$chatIdColumn TEXT, $msgColumn TEXT, $msgTypeColumn TEXT, "
"$timeColumn INTEGER, $msgStatusColumn INTEGER)");
// 3. for storing the last message to show in the home screen in the chat cards
await db.execute(
"CREATE TABLE $chatsTable ($phoneNumberColumn TEXT PRIMARY KEY, $nameColumn TEXT,"
"$chatIdColumn TEXT, $usernameColumn TEXT, $photoUrlColumn TEXT, $isContactColumn INTEGER, $blockStatusColumn INTEGER,"
" $msgColumn TEXT, $msgTypeColumn TEXT, "
"$timeColumn INTEGER)");
},
);
}
Future<void> updateMessageToChatTable(
String chatId, String newMsg, String msgType, int currTime) async {
final Database db = await database;
int numOfUpdates = await db.rawUpdate(
"UPDATE $chatsTable SET $msgColumn = ?, $timeColumn = ?, $msgTypeColumn = ? WHERE $chatIdColumn = ?",
[newMsg, currTime, msgType, chatId]);
print("$numOfUpdates rows were changed in Chats Table");
}
Future<void> addNewMessageToMessagesTable(String chatId, String newMsg,
String msgType, int currTime, int msgStatus) async {
final Database db = await database;
await db.insert(
messagesTable,
{
chatIdColumn: chatId,
msgColumn: newMsg,
msgTypeColumn: msgType,
timeColumn: currTime,
msgStatusColumn: msgStatus,
},
conflictAlgorithm: ConflictAlgorithm.ignore,
);
}
Future<ChatMessage> readMessageFromChatTable(String chatId) async {
final Database db = await database;
List<Map<String, dynamic>> res = await db.query(chatsTable,
columns: [
msgColumn,
msgTypeColumn,
timeColumn,
chatIdColumn,
msgStatusColumn
],
where: "$chatIdColumn = ?",
whereArgs: [chatId]);
ChatMessage chatMessage = ChatMessage.fromMap(res[0]);
print("Most recent message read From Db :::::::: $chatMessage");
return chatMessage;
}
Future<List<ChatMessage>> readAllMessagesfromMessagesTable(
String chatId) async {
final Database db = await database;
var res = await db
.query(messagesTable, where: "$chatIdColumn = ?", whereArgs: [chatId]);
return res.map((e) => ChatMessage.fromMap(e)).toList();
}
// get all conversations from chat table to show in the home page
Future<List<Map<dynamic, dynamic>>> getAlConversationsFromChatTable() async {
final Database db = await database;
var res = await db.query(chatsTable, where: "$msgColumn IS NOT NULL");
List<Map> output = List<Map>.from(res);
return output;
}
Future<void> updateProfilePicInChatsTable(
String photoUrl, String chatId) async {
final Database db = await database;
await db.rawUpdate(
"UPDATE $chatsTable SET $photoUrlColumn = ? WHERE $chatIdColumn = ?",
[photoUrl, chatId],
);
}
Future<List<Map<dynamic, dynamic>>> getAllContacts() async {
final Database db = await database;
var res = await db.query(
chatsTable,
columns: [
phoneNumberColumn,
nameColumn,
usernameColumn,
photoUrlColumn,
chatIdColumn
],
where: "$isContactColumn = ?",
whereArgs: [1],
);
List<Map> output = List<Map>.from(res);
return output;
}
Future<void> createRow(String phoneNum, String chatId, String contactName,
String username, String photoUrl, int isContact) async {
final Database db = await database;
await db.insert(
chatsTable,
{
phoneNumberColumn: phoneNum,
chatIdColumn: chatId,
nameColumn: contactName,
usernameColumn: username,
photoUrlColumn: photoUrl,
isContactColumn: isContact,
blockStatusColumn: 1, // At first it will be unblocked ofcourse
msgColumn: null,
msgTypeColumn: null,
timeColumn: null,
},
conflictAlgorithm: ConflictAlgorithm.ignore,
);
}
Future<void> deleteContact(String phoneNum) async {
final Database db = await database;
await db.delete(chatsTable,
where: "$phoneNumberColumn = ?", whereArgs: [phoneNum]);
}
Future<bool> checkIfContactExistsInDb(String phoneNumber) async {
final Database db = await database;
var result = await db.rawQuery(
"SELECT COUNT(1) FROM $chatsTable WHERE $phoneNumberColumn = ? LIMIT 1",
[phoneNumber],
);
return result[0]["COUNT(1)"] == 1 ? true : false;
}
Future<bool> checkIfUsernameExistsInDb(String username) async {
final Database db = await database;
var result = await db.rawQuery(
"SELECT COUNT(1) FROM $chatsTable WHERE $usernameColumn = ? LIMIT 1",
[username],
);
return result[0]["COUNT(1)"] == 1 ? true : false;
}
Future<void> deleteTable() async {
final Database db = await database;
await db.delete(chatsTable, where: '1');
}
// check if contact is blocked or unblocked
Future<bool> isBlocked(String chatId) async {
final Database db = await database;
var res = await db.query(chatsTable,
columns: [blockStatusColumn],
where: '$chatIdColumn = ?',
whereArgs: [chatId]);
return (res[0]["blockStat"] == 1 ? false : true);
}
Future<void> updateBlockStatus(int newStatus, String chatId) async {
final Database db = await database;
await db.rawUpdate(
"UPDATE $chatsTable SET $blockStatusColumn = ? WHERE $chatIdColumn = ?",
[newStatus, chatId],
);
}
Future<void> updateName(String newName, String chatId) async {
final Database db = await database;
await db.rawUpdate(
"UPDATE $chatsTable SET $nameColumn = ? WHERE $chatIdColumn = ?",
[newName, chatId],
);
}
}
================================================
FILE: lib/managers/mqtt_manager.dart
================================================
import 'dart:convert';
import 'package:coocoo/blocs/chats/chat_bloc.dart';
import 'package:coocoo/blocs/home/home_bloc.dart';
import 'package:coocoo/config/Constants.dart';
import 'package:coocoo/stateProviders/mqtt_state.dart';
import 'package:coocoo/utils/SharedObjects.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';
import 'package:provider/provider.dart';
import 'db_manager.dart';
class MQTTManager {
MQTTManager({
@required this.serverAddress,
@required this.clientName,
@required this.context,
});
final String serverAddress;
final String clientName;
final BuildContext context;
MqttServerClient _client;
ChatBloc chatBloc;
HomeBloc homeBloc;
void initializeMQTTClient() {
_client = MqttServerClient(serverAddress, clientName);
_client.port = 1883;
_client.keepAlivePeriod = 43200;
_client.logging(on: false);
_client.onDisconnected = onDisconnected;
_client.onConnected = onConnect;
// auto reconnecting when client is disconnected to server
_client.autoReconnect = true;
final connMess = MqttConnectMessage()
.withClientIdentifier(clientName)
.keepAliveFor(
43200) // Must agree with the keep alive set above or not set
.withWillTopic(
'willtopic') // If you set this you must set a will message
.withWillMessage('My Will message')
.withWillRetain()
.withWillQos(MqttQos.atLeastOnce);
_client.connectionMessage = connMess;
}
void disconnect() {
_client.disconnect();
}
bool getConnectionStatus() {
if (_client.connectionStatus.state == MqttConnectionState.connected) {
return true;
} else {
return false;
}
}
Future<void> connect(String username, String password) async {
try {
await _client.connect(username, password);
} on Exception catch (e) {
print('EXAMPLE::client exception - $e');
_client.disconnect();
}
}
void subscribeTopic(String topic) {
_client.subscribe(topic, MqttQos.atLeastOnce);
/// The client has a change notifier object(see the Observable class) which we then listen to to get
/// notifications of published updates to each subscribed topic.
}
void unSubscribeTopic(String topic) {
_client.unsubscribe(topic);
}
Stream<List<MqttReceivedMessage<MqttMessage>>> get messageStream =>
_client.updates;
void publish(String myMessage, String topic) {
final builder = MqttClientPayloadBuilder();
builder.addString(myMessage);
_client.publishMessage(topic, MqttQos.atLeastOnce, builder.payload,
retain: true);
}
void onDisconnected() {
print('Client Disconnect');
}
void onConnect() {
chatBloc = BlocProvider.of<ChatBloc>(context);
homeBloc = BlocProvider.of<HomeBloc>(context);
_client.updates.listen((List<MqttReceivedMessage<MqttMessage>> c) async {
final MqttPublishMessage recMess = c[0].payload;
final String chatId = c[0].topic;
final msg =
MqttPublishPayload.bytesToStringAsString(recMess.payload.message);
print("THIS IS THE MESSAGE BEFORE DECODING");
print(msg);
Map parsedMsg = json.decode(msg);
final int currTime = DateTime.now().millisecondsSinceEpoch;
String myUid = SharedObjects.prefs.getString(Constants.sessionUid);
if (parsedMsg["type"] == "service") {
// mqtt message if any of my contacts changed his/her profile picture
if (parsedMsg["msg"] == Constants.profilePicChangeMsg) {
if (parsedMsg["uid"] != myUid) {
print("Profile Pic Changed For $chatId");
await DBManager.db.updateProfilePicInChatsTable(
parsedMsg["profilePicUrl"], chatId);
homeBloc.add(FetchHomeChatsEvent());
}
}
} else {
// save message to local db
print(parsedMsg["uid"]);
print(myUid);
if (parsedMsg["uid"] == myUid) {
// if uid of message is same as mine then that means
// I sent the message, so save it to db as sent message
print("seetting messages to local db 1");
await DBManager.db.addNewMessageToMessagesTable(
chatId,
parsedMsg["msg"],
parsedMsg["type"],
currTime,
1); // 1 bcox message is sent
} else {
print("seetting messages to local db 0");
// save the message to local db as received message
await DBManager.db.addNewMessageToMessagesTable(
chatId,
parsedMsg["msg"],
parsedMsg["type"],
currTime,
0); // 0 bcox message is received
}
DBManager.db.updateMessageToChatTable(
chatId,
parsedMsg["msg"],
parsedMsg["type"],
currTime,
);
//also notify the bloc that a new message is received so that it
// may read the last message from the local db
chatBloc.add(ReceivedMessageEvent(chatId));
// fetching the chatcards for the homePage
homeBloc.add(FetchHomeChatsEvent());
}
});
}
}
================================================
FILE: lib/models/ChatMessage.dart
================================================
class ChatMessage {
final String msg;
final int time;
final String msgType;
// final int msgStatus;
final String chatId;
final bool isSelf;
ChatMessage({this.msg, this.time, this.msgType, this.chatId, this.isSelf});
factory ChatMessage.fromMap(Map map) {
return ChatMessage(
msg: map["msg"],
time: map["time"],
msgType: map["msgType"],
chatId: map["chatId"],
isSelf: map["msgStatus"] == 1 ? true : false,
);
}
@override
String toString() => "msg : $msg, time : $time, "
"msgType : $msgType, chatId : $chatId, isSelf: $isSelf";
}
================================================
FILE: lib/models/Conversation.dart
================================================
class Conversation {
final String phoneNumber;
final String lastMessage;
final String msgType;
final int time;
final String photoUrl;
final String chatId;
final String name;
final String username;
Conversation({
this.phoneNumber,
this.lastMessage,
this.msgType,
this.time,
this.photoUrl,
this.chatId,
this.name,
this.username,
});
factory Conversation.fromMap(Map map) {
// here map is the map from the sqflite database
return Conversation(
phoneNumber: map["phoneNumber"],
lastMessage: map["msg"],
msgType: map["msgType"],
time: map["time"],
photoUrl: map["photoUrl"],
chatId: map["chatId"],
name: map['name'],
username: map['username'],
);
}
@override
String toString() => "phoneNumber : $phoneNumber,"
"lastMessage : $lastMessage, msgType : $msgType, time : $time, photoUrl : $photoUrl, "
"chatId : $chatId";
}
================================================
FILE: lib/models/MyContact.dart
================================================
import 'package:cloud_firestore/cloud_firestore.dart';
class MyContact {
final String phoneNumber;
final String name;
final String username;
final String photoUrl;
final String chatId;
final int ind;
MyContact(
{this.phoneNumber,
this.name,
this.username,
this.photoUrl,
this.chatId,
this.ind});
factory MyContact.fromFireStore(DocumentSnapshot snapshot) {
var data = snapshot.data;
return MyContact(
phoneNumber: data['phoneNumber'] ?? snapshot.documentID,
name: data['name'],
photoUrl: data['photoUrl'],
username: data['username'],
chatId: data['chatId']);
}
factory MyContact.fromMap(Map data) {
return MyContact(
phoneNumber: data['phoneNumber'],
name: data['name'],
photoUrl: data['photoUrl'],
username: data['username'],
chatId: data['chatId']);
}
@override
String toString() {
return "index : ${this.ind}, phoneNumber : ${this.phoneNumber}, "
"name : ${this.name} photoUrl : ${this.photoUrl}, "
"chatId : ${this.chatId}, username : ${this.username}";
}
}
================================================
FILE: lib/models/NonContact.dart
================================================
import 'package:equatable/equatable.dart';
class NonContact extends Equatable {
final String name;
final String phoneNumber;
NonContact(this.phoneNumber, {this.name});
@override
List<Object> get props => [phoneNumber];
}
================================================
FILE: lib/models/User.dart
================================================
import 'package:cloud_firestore/cloud_firestore.dart';
class User {
String documentId;
String phoneNumber;
String username;
String photoUrl;
User({this.documentId, this.phoneNumber, this.username, this.photoUrl});
factory User.fromFirestore(DocumentSnapshot doc) {
Map data = doc.data;
return User(
documentId: doc.documentID,
phoneNumber: data['phoneNumber'],
username: data['username'],
photoUrl: data['photoUrl']);
}
factory User.fromMap(Map data) {
return User(
documentId: data['uid'],
phoneNumber: data['phoneNumber'],
username: data['username'],
photoUrl: data['photoUrl']);
}
@override
String toString() {
return '{ documentId: $documentId, phoneNumb: $phoneNumber, username: $username, photoUrl: $photoUrl }';
}
}
================================================
FILE: lib/screens/ContactsHelpPage.dart
================================================
import 'package:coocoo/constants.dart';
import 'package:flutter/material.dart';
class ContactsHelpPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final double screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
appBar: AppBar(
title: Text('Contacts Help'),
),
body: Container(
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
" If some of your friends don't appear in\n the contacts"
" list, we recommend\n the following steps:",
style: TextStyle(
fontSize: (screenWidth / perfectWidth) * 18.0,
fontWeight: FontWeight.w400,
),
),
SizedBox(height: 8.0),
Text(
"1. Click on the Refresh Button on the\n "
" Top right hand side of the page and "
"\n check for the contact again.",
style: TextStyle(
fontSize: (screenWidth / perfectWidth) * 18.0,
fontWeight: FontWeight.w400,
),
),
SizedBox(height: 8.0),
Text(
"2. Make sure that your friend is using\n HitUp Messenger",
style: TextStyle(
fontSize: (screenWidth / perfectWidth) * 18.0,
fontWeight: FontWeight.w400,
),
),
SizedBox(height: 8.0),
Text(
"3. Make sure that your friend's phone number\n is in your "
"address book",
style: TextStyle(
fontSize: (screenWidth / perfectWidth) * 18.0,
fontWeight: FontWeight.w400,
),
),
],
),
),
);
}
}
================================================
FILE: lib/screens/account_screen.dart
================================================
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:coocoo/screens/profile_screen.dart';
import 'package:coocoo/config/Constants.dart';
import 'package:coocoo/config/Paths.dart';
import 'package:coocoo/managers/db_manager.dart';
import 'package:coocoo/utils/SharedObjects.dart';
import 'package:coocoo/widgets/DangerCard.dart';
import 'package:coocoo/widgets/SettingsTile.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import '../splashscreen.dart';
class AccountScreen extends StatefulWidget {
@override
_AccountScreenState createState() => _AccountScreenState();
}
class _AccountScreenState extends State<AccountScreen> {
final Firestore _firestore = Firestore.instance;
FirebaseAuth _auth = FirebaseAuth.instance;
bool loading = false;
Future<bool> _showDialogBox() async {
return (await showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Are you sure?'),
content: Text('You want to delete your HitUp account?'),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.of(context).pop(false),
child: Text('No'),
),
FlatButton(
onPressed: () async {
setState(() {
loading = true;
});
String userPhone =
SharedObjects.prefs.getString(Constants.sessionUid);
try {
_firestore
.collection(Paths.usersPath)
.document(userPhone)
.delete();
} catch (e) {
print(e);
}
DBManager.db.deleteTable();
await SharedObjects.prefs.clearAll();
Navigator.push(context,
MaterialPageRoute(builder: (context) => SplashScreen()));
setState(() {
loading = false;
});
},
child: Text('Yes Delete'),
),
],
),
)) ??
false;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Account'),
),
body: !loading
? Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SettingsTile(
icon: Icons.account_circle,
title: 'My Account',
onPress: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProfileScreen()));
},
),
DangerCard(Colors.red, 'Delete Account', () {
_showDialogBox();
}),
],
),
)
: Center(child: CircularProgressIndicator()),
);
}
}
================================================
FILE: lib/screens/addFriends_screen.dart
================================================
import 'dart:ui';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:coocoo/blocs/AddFriends/add_friends_bloc.dart';
import 'package:coocoo/config/Constants.dart';
import 'package:coocoo/config/Paths.dart';
import 'package:coocoo/constants.dart';
import 'package:coocoo/functions/BaseFunctions.dart';
import 'package:coocoo/models/MyContact.dart';
import 'package:coocoo/utils/SharedObjects.dart';
import 'package:coocoo/widgets/AddFriendCard.dart';
import 'package:coocoo/widgets/FriendRequestCard.dart';
import 'package:coocoo/widgets/NoRequestsCard.dart';
import 'package:coocoo/widgets/SentRequestCard.dart';
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
enum RequestsType { FriendRequests, SentRequests }
class AddFriendsScreen extends StatefulWidget {
@override
_AddFriendsScreenState createState() => _AddFriendsScreenState();
}
class _AddFriendsScreenState extends State<AddFriendsScreen> {
final TextEditingController hitupIdController = TextEditingController();
Firestore _firestore = Firestore.instance;
String uid = SharedObjects.prefs.getString(Constants.sessionUid);
AddFriendsBloc addFriendsBloc;
final _formKey = GlobalKey<FormState>();
Widget _buildRequestsStreamBuilder(
double algo, RequestsType requestsType, BuildContext contex) {
return StreamBuilder<QuerySnapshot>(
stream: _firestore
.collection(Paths.usersPath)
.document(uid)
.collection(requestsType == RequestsType.SentRequests
? Paths.sentRequestsPath
: Paths.friendRequestsPath)
.snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
Widget toShow;
if (snapshot.hasError) {
toShow = HitUpIdTextWidget(
algo: algo, text: 'Sorry! Not able to retrieve Data');
} else {
switch (snapshot.connectionState) {
case ConnectionState.none:
toShow = HitUpIdTextWidget(
algo: algo, text: 'Sorry! Not able to retrieve Data');
break;
case ConnectionState.waiting:
toShow = Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Center(
child: SizedBox(
child: CircularProgressIndicator(),
height: 60,
width: 60,
),
),
);
break;
case ConnectionState.active:
case ConnectionState.done:
if (snapshot.data.documents.isEmpty) {
toShow = NoRequestsCard(
algo: algo,
text: requestsType == RequestsType.SentRequests
? 'You h'
'ave not sent any Friend Requests'
: 'You have No '
'Friend Requests');
} else {
toShow = Column(
children: snapshot.data.documents
.map((e) => requestsType == RequestsType.SentRequests
? SentRequestCard(MyContact.fromFireStore(e))
: FriendRequestCard(MyContact.fromFireStore(e),
addFriendsBloc, contex))
.toList(),
);
}
break;
}
}
return toShow;
},
);
}
@override
void initState() {
addFriendsBloc = BlocProvider.of<AddFriendsBloc>(context);
super.initState();
}
@override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
double algo = width / perfectWidth;
return Form(
key: _formKey,
child: Padding(
padding: EdgeInsets.only(top: 12.0, right: 10.0, left: 10.0),
child: ListView(
children: [
Row(
children: [
GestureDetector(
child: Icon(
Icons.arrow_back,
color: Colors.black,
),
onTap: () {
Navigator.pop(context);
},
),
SizedBox(width: 5.0),
Expanded(
child: TextFormField(
inputFormatters: [
FilteringTextInputFormatter.deny(
RegExp(r'\s+')) // no spaces allowed
],
validator: (value) {
if (value.isEmpty) {
return "Please enter a valid username";
}
return null;
},
controller: hitupIdController,
style: TextStyle(
fontSize: algo * 18.0,
),
autocorrect: false,
cursorColor: Colors.blueGrey,
decoration: kHitUpIdTextFieldDecoration,
)),
SizedBox(width: algo * 10.0),
GestureDetector(
onTap: () {
if (_formKey.currentState.validate()) {
addFriendsBloc
.add(SearchHitUpIdEvent(hitupIdController.text));
}
hitupIdController.clear();
},
child: Text(
'Search',
style: TextStyle(
letterSpacing: 0.5,
fontSize: algo * 21.0,
fontWeight: FontWeight.bold,
),
),
),
],
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: BlocBuilder<AddFriendsBloc, AddFriendsState>(
builder: (context, state) {
if (state is SearchingHitUpIdState) {
return SearchingCard(algo: algo);
}
if (state is HitUpIdAlreadyThere) {
if (state.hitUpIdLocation == HitUpIdLocation.InLocalDb) {
return HitUpIdTextWidget(
algo: algo,
text:
'@${state.hitUpId} already exists in your contacts!');
} else if (state.hitUpIdLocation ==
HitUpIdLocation.InFriendRequests) {
return HitUpIdTextWidget(
algo: algo,
text:
'You have already received a friend request from @${state.hitUpId}. Please'
' check your Friend Requests List');
} else if (state.hitUpIdLocation ==
HitUpIdLocation.InSentRequests) {
return HitUpIdTextWidget(
algo: algo,
text:
'You have already sent a friend request to @${state.hitUpId}');
}
}
if (state is SendingFriendRequestState) {
return SearchingCard(algo: algo);
}
if (state is FriendRequestSentState) {
return SentRequestCard(state.friend);
}
if (state is HitUpIdExistsState) {
// return Text(state.friend.name);
return AddFriendCard(state.friend, () async {
// print(state.friend.phoneNumber);
addFriendsBloc
.add(AddButtonClickEvent(context, state.friend));
});
}
if (state is HitUpIdNotExistsState) {
return HitUpIdTextWidget(
algo: algo,
text: 'HitUp Id @${state.hitupId} not found!',
);
}
return SizedBox(height: 10.0);
},
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Friend Requests',
style: kRequestTitleStyle,
),
SizedBox(height: 6.0),
BlocBuilder<AddFriendsBloc, AddFriendsState>(
builder: (context, state) {
if (state is AcceptingFriendRequestState ||
state is DecliningFriendRequestState) {
return SearchingCard(algo: algo);
}
return _buildRequestsStreamBuilder(
algo, RequestsType.FriendRequests, context);
},
),
],
),
SizedBox(height: 30.0),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Your Sent Requests',
style: kRequestTitleStyle,
),
SizedBox(height: 6.0),
_buildRequestsStreamBuilder(
algo,
RequestsType.SentRequests,
context,
),
],
),
],
),
),
);
}
@override
void dispose() {
super.dispose();
hitupIdController.dispose();
// addFriendsBloc.close();
}
}
class SearchingCard extends StatelessWidget {
const SearchingCard({
Key key,
@required this.algo,
}) : super(key: key);
final double algo;
@override
Widget build(BuildContext context) {
return Card(
elevation: 5.0,
child: Container(
padding: EdgeInsets.symmetric(vertical: 3.0),
height: algo * 50.0,
child: Center(
child: CircularProgressIndicator(),
),
),
);
}
}
class HitUpIdTextWidget extends StatelessWidget {
final double algo;
final String text;
HitUpIdTextWidget({
@required this.algo,
@required this.text,
});
@override
Widget build(BuildContext context) {
return Card(
elevation: 5.0,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 6.0, horizontal: 8.0),
child: Center(
child: Text(text,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: algo * 20.0,
color: Constants.textStuffColor,
)),
),
),
);
}
}
================================================
FILE: lib/screens/chat_screen.dart
================================================
import 'dart:async';
import 'dart:io';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:coocoo/screens/friend_profile_screen.dart';
import 'package:coocoo/blocs/chats/chat_bloc.dart';
import 'package:coocoo/constants.dart';
import 'package:coocoo/functions/UserDataFunction.dart';
import 'package:coocoo/models/ChatMessage.dart';
import 'package:coocoo/models/MyContact.dart';
import 'package:coocoo/stateProviders/profilePicUrlState.dart';
import 'package:coocoo/widgets/ChatItemWidget.dart';
import 'package:coocoo/widgets/GradientSnackBar.dart';
import 'package:coocoo/widgets/ImageFullScreenWidget.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_emoji/flutter_emoji.dart' as emj;
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
import 'package:image_picker/image_picker.dart';
import 'package:provider/provider.dart';
class ChatScreen extends StatefulWidget {
final MyContact toContact;
ChatScreen(this.toContact);
@override
_ChatScreenState createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> {
var parser = emj.EmojiParser();
TextEditingController chatTextController = TextEditingController();
ChatBloc chatBloc;
UserDataFunction userDataFunction = UserDataFunction();
List<ChatMessage> allMessages = [];
ScrollController _scrollController;
final picker = ImagePicker();
Widget _buildSendButton(double algo) {
return Expanded(
child: InkWell(
onTap: () {
String tempChatId = widget.toContact.chatId;
String msgToSend = parser.unemojify(chatTextController.text);
chatBloc.add(SendMessageEvent(context, msgToSend, tempChatId));
userDataFunction.sendNotification(
toUid: widget.toContact.phoneNumber,
title: "${widget.toContact.name}",
content: msgToSend,
);
chatTextController.clear();
},
child: Neumorphic(
style: kCircleNeumorphicStyle,
child: CircleAvatar(
backgroundColor: Colors.white,
radius: algo * 33.0,
child: Neumorphic(
style: NeumorphicStyle(
shadowDarkColor: Colors.blueGrey,
boxShape: NeumorphicBoxShape.circle(),
depth: 4,
intensity: 0.7,
surfaceIntensity: 0.6,
),
child: CircleAvatar(
radius: algo * 23.0,
backgroundColor: Colors.white,
child:
Icon(Icons.send, color: Colors.blueGrey, size: algo * 26.0),
),
),
),
),
),
);
}
Widget _buildTypeMessageTextField() {
return Expanded(
flex: 5,
child: Row(
children: [
Expanded(
child: Neumorphic(
margin: EdgeInsets.only(left: 6, right: 5, top: 2, bottom: 4),
style: NeumorphicStyle(
depth: -15,
boxShape: NeumorphicBoxShape.stadium(),
shadowDarkColorEmboss: Colors.black,
shadowLightColor: Colors.white,
intensity: 0.6,
),
padding: EdgeInsets.symmetric(vertical: 14, horizontal: 18),
child: TextField(
onTap: () {
// scroll to the bottom of the list when keyboard appears
Timer(
Duration(milliseconds: 200),
() => _scrollController.animateTo(
_scrollController.position.maxScrollExtent,
duration: Duration(milliseconds: 500),
curve: Curves.easeIn));
},
focusNode: FocusNode(),
cursorColor: Colors.blueGrey,
controller: chatTextController,
style: TextStyle(
fontSize: 21.0,
),
decoration:
InputDecoration.collapsed(hintText: "Type a message"),
),
),
),
],
),
);
}
Widget _buildContactProfilePicture(double algo) {
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ImageFullScreen(
url: widget.toContact.photoUrl,
tag: 'dash${widget.toContact.ind}')));
},
child: Hero(
tag: 'dash${widget.toContact.ind}',
child: Neumorphic(
style: kCircleNeumorphicStyle,
child: CircleAvatar(
radius: algo * 23.5,
backgroundImage:
CachedNetworkImageProvider(widget.toContact.photoUrl),
),
),
),
);
}
@override
void initState() {
super.initState();
chatBloc = BlocProvider.of<ChatBloc>(context);
chatBloc.add(LoadInitialMessagesEvent(widget.toContact.chatId));
_scrollController = ScrollController();
}
@override
void dispose() {
chatTextController.dispose();
_scrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final double screenWidth = MediaQuery.of(context).size.width;
final double algo = screenWidth / perfectWidth;
return Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
titleSpacing: 0.0,
automaticallyImplyLeading: false,
leading: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(
Icons.arrow_back,
color: Colors.blueGrey[700],
),
),
backgroundColor: Colors.white,
title: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
_buildContactProfilePicture(algo),
SizedBox(width: algo * 13.0),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
FriendProfileScreen(widget.toContact)));
},
child: Text(
widget.toContact.name,
style: TextStyle(
color: Colors.blueGrey[700],
fontSize: algo * 20.0,
fontWeight: FontWeight.w600,
),
),
),
],
),
actions: <Widget>[
GestureDetector(
onTap: () {
pickImage();
},
child: Icon(
Icons.attach_file,
color: Colors.blueGrey[700],
size: 30.0,
),
),
SizedBox(width: 5.0),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
FriendProfileScreen(widget.toContact)));
},
child: Icon(
Icons.more_vert_sharp,
size: 30.0,
),
),
SizedBox(width: algo * 15.0),
],
),
body: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: BlocListener<ChatBloc, ChatState>(
listener: (context, state) {
if (state is ReceivedMessageState) {
if (state.chatMessages[0].chatId ==
widget.toContact.chatId) {
setState(() {
allMessages = state.chatMessages;
});
}
}
if (state is InitialMessagesLoadedState) {
setState(() {
allMessages = state.chatMessages;
});
}
// jump to the bottom of the screen when a new message arrives
// also using a timer because we need to jump to the bottom
// only after the new message is updated in the listview
Timer(
Duration(milliseconds: 600),
() => _scrollController.animateTo(
_scrollController.position.maxScrollExtent,
duration: Duration(milliseconds: 200),
curve: Curves.easeIn));
},
child: Padding(
padding: EdgeInsets.symmetric(vertical: algo * 8.0),
child: ListView.builder(
controller: _scrollController,
itemCount: allMessages.length,
itemBuilder: (context, index) {
return ChatItemWidget(allMessages[index]);
}),
),
),
),
Row(
children: [
_buildTypeMessageTextField(),
_buildSendButton(algo),
],
),
],
),
),
);
}
Future pickImage() async {
final pickedFile = await picker.getImage(source: ImageSource.gallery);
if (pickedFile != null) {
File tempFile = File(pickedFile.path);
chatBloc.add(SendImageEvent(context, tempFile, widget.toContact.chatId));
GradientSnackBar.showMessage(
context, "Sending Your Beautiful Image...", 2);
userDataFunction.sendNotification(
toUid: widget.toContact.phoneNumber,
title: "You have New Messages",
content: "Click To View",
);
}
}
}
================================================
FILE: lib/screens/contacts_screen.dart
================================================
import 'package:animated_bottom_navigation_bar/animated_bottom_navigation_bar.dart';
import 'package:coocoo/screens/ContactsHelpPage.dart';
import 'package:coocoo/screens/addFriends_screen.dart';
import 'package:coocoo/blocs/contacts/contacts_bloc.dart';
import 'package:coocoo/functions/UserDataFunction.dart';
import 'package:coocoo/models/MyContact.dart';
import 'package:coocoo/widgets/ContactRowWidget.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import '../constants.dart';
class ContactListPage extends StatefulWidget {
@override
State<StatefulWidget> createState() => _ContactListPageState();
const ContactListPage();
}
class _ContactListPageState extends State<ContactListPage>
with SingleTickerProviderStateMixin {
ContactsBloc contactsBloc;
final TextEditingController usernameController = TextEditingController();
List<MyContact> contacts = [];
UserDataFunction userDataFunction;
bool refreshing = false;
Color stuffColor = Colors.blueGrey[700];
bool showSearchBar = false;
int _selectedIndex = 0;
AnimationController _animationController;
Animation<double> animation;
CurvedAnimation curve;
final iconList = <IconData>[
FontAwesomeIcons.addressBook,
// Icons.contacts,
// FontAwesomeIcons.solidAddressBook,
FontAwesomeIcons.userFriends,
];
@override
void dispose() {
usernameController.dispose();
_animationController.dispose();
// contactsBloc.close();
super.dispose();
}
@override
void initState() {
userDataFunction = UserDataFunction();
contactsBloc = BlocProvider.of<ContactsBloc>(context);
contactsBloc.add(FetchContactsEvent());
super.initState();
final systemTheme = SystemUiOverlayStyle.light.copyWith(
systemNavigationBarColor: Colors.black,
systemNavigationBarIconBrightness: Brightness.light,
);
SystemChrome.setSystemUIOverlayStyle(systemTheme);
_animationController = AnimationController(
duration: Duration(seconds: 1),
vsync: this,
);
curve = CurvedAnimation(
parent: _animationController,
curve: Interval(
0.5,
1.0,
curve: Curves.fastOutSlowIn,
),
);
animation = Tween<double>(
begin: 0,
end: 1,
).animate(curve);
Future.delayed(
Duration(seconds: 1),
() => _animationController.forward(),
);
}
Widget _buildRefreshButton() {
return InkWell(
child: Icon(
Icons.refresh,
color: stuffColor,
),
onTap: () async {
setState(() {
refreshing = true;
});
await userDataFunction.loadPhoneContactsV2(context);
await Future.delayed(Duration(seconds: 8));
contactsBloc.add(FetchContactsEvent());
setState(() {
refreshing = false;
});
},
);
}
Widget _buildRefreshing() {
return Container(
width: 20.0,
padding: EdgeInsets.symmetric(vertical: 18.0),
child: CircularProgressIndicator(
strokeWidth: 2.5,
backgroundColor: Colors.white,
),
);
}
Widget _buildNormalAppBar(double screenWidth) {
return AppBar(
automaticallyImplyLeading: false,
leading: IconButton(
icon: Icon(
Icons.arrow_back,
color: stuffColor,
),
onPressed: () {
Navigator.pop(context);
},
),
backgroundColor: Colors.white,
title: Text(
'Select Contact',
style: TextStyle(
fontSize: (screenWidth / perfectWidth) * 22.0, color: stuffColor),
),
actions: <Widget>[
refreshing ? _buildRefreshing() : _buildRefreshButton(),
SizedBox(width: 25.0),
],
);
}
void _onItemTapped(int ind) {
setState(() {
_selectedIndex = ind;
});
}
@override
Widget build(BuildContext context) {
final double screenWidth = MediaQuery.of(context).size.width;
return SafeArea(
child: Scaffold(
backgroundColor: Colors.grey[200],
appBar: _selectedIndex == 0 ? _buildNormalAppBar(screenWidth) : null,
floatingActionButton: FloatingActionButton(
elevation: 8,
backgroundColor: Colors.white,
child: Icon(
Icons.favorite,
size: 40.0,
color: Colors.black,
),
onPressed: () {
_animationController.reset();
_animationController.forward();
},
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
bottomNavigationBar: AnimatedBottomNavigationBar(
elevation: 30.0,
activeColor: Colors.black,
splashColor: Colors.blueAccent,
backgroundColor: Colors.white,
icons: iconList,
iconSize: 30.0,
activeIndex: _selectedIndex,
inactiveColor: Colors.grey,
notchAndCornersAnimation: animation,
splashSpeedInMilliseconds: 300,
notchSmoothness: NotchSmoothness.softEdge,
gapLocation: GapLocation.center,
leftCornerRadius: 20,
rightCornerRadius: 20,
onTap: _onItemTapped,
),
body: _selectedIndex == 0
? BlocBuilder<ContactsBloc, ContactsState>(
builder: (context, state) {
if (state is FetchingContactsState) {
print("Fetching Contacts");
return SizedBox(
height: (MediaQuery.of(context).size.height),
child: Center(child: CircularProgressIndicator()),
);
}
if (state is FetchedContactsState) {
contacts = state.contacts;
}
return ListView(
children: <Widget>[
Column(
children: List.generate(
contacts.length,
(index) => ContactRowWidget(
contact: contacts[index],
)),
),
Divider(thickness: 1.5),
SizedBox(height: (screenWidth / perfectWidth) * 20.0),
ListTile(
leading: Icon(
Icons.share,
color: Colors.black,
),
title: Text(
'Invite Friends',
style: TextStyle(
fontSize: (screenWidth / perfectWidth) * 20.0,
fontWeight: FontWeight.w400,
),
),
onTap: () => userDataFunction.onShare(context),
),
ListTile(
leading: Icon(
Icons.help,
color: Colors.black,
),
title: Text(
'Contacts Help',
style: TextStyle(
fontSize: (screenWidth / perfectWidth) * 20.0,
fontWeight: FontWeight.w400,
),
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ContactsHelpPage()));
},
),
],
);
})
: AddFriendsScreen(),
),
);
}
}
================================================
FILE: lib/screens/enter_name_screen.dart
================================================
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:coocoo/screens/update_profile.dart';
import 'package:coocoo/config/Constants.dart';
import 'package:coocoo/config/Paths.dart';
import 'package:coocoo/utils/SharedObjects.dart';
import 'package:coocoo/widgets/NameTextField.dart';
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
class EnterName extends StatefulWidget {
@override
_EnterNameState createState() => _EnterNameState();
}
class _EnterNameState extends State<EnterName> {
final TextEditingController firstNameController = TextEditingController();
final TextEditingController lastNameController = TextEditingController();
final _formKey = GlobalKey<FormState>();
Firestore firestore = Firestore.instance;
bool isLoading = false;
Future<void> saveFullName(String firstname, String lastname) async {
String uid = SharedObjects.prefs.getString(Constants.sessionUid);
String fullName = '$firstname $lastname';
DocumentReference ref = firestore.collection(Paths.usersPath).document(
uid); //reference of the user's document node in database/users. This node is created using uid
var data = {'name': fullName};
await ref.setData(data, merge: true); // set the photourl, age and username
await SharedObjects.prefs.setString(Constants.fullName, fullName);
}
Widget buildLoadingScreen() {
return Center(
child: CircularProgressIndicator(),
);
}
Widget buildEnterNameScreen() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 35.0, vertical: 40.0),
child: Form(
key: _formKey,
child: ListView(
children: [
Center(
child: Text("What's your name?",
style: TextStyle(
fontSize: 25.0,
fontWeight: FontWeight.w600,
)),
),
SizedBox(height: 8.0),
Column(
children: [
NameTextField(
hintText: 'FIRST NAME',
controller: firstNameController,
),
NameTextField(
hintText: 'LAST NAME',
controller: lastNameController,
),
SizedBox(height: 10.0),
Text("This name will appear when someone searches for you "
"on HitUp")
],
),
SizedBox(height: 40.0),
RaisedButton(
padding: EdgeInsets.symmetric(vertical: 8.0),
onPressed: () async {
if (_formKey.currentState.validate()) {
setState(() {
isLoading = true;
});
await saveFullName(
firstNameController.text, lastNameController.text);
Navigator.push(context,
MaterialPageRoute(builder: (context) => UpdateProfile()));
isLoading = false;
}
},
elevation: 10.0,
color: Colors.blueAccent[400],
child: Text(
"NEXT",
style: TextStyle(
color: Colors.white, fontSize: 25.0, letterSpacing: 1.0),
),
),
],
),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: isLoading ? buildLoadingScreen() : buildEnterNameScreen(),
);
}
@override
void dispose() {
firstNameController.dispose();
lastNameController.dispose();
super.dispose();
}
}
================================================
FILE: lib/screens/friend_profile_screen.dart
================================================
import 'package:cached_network_image/cached_network_image.dart';
import 'package:coocoo/blocs/chats/chat_bloc.dart';
import 'package:coocoo/blocs/home/home_bloc.dart';
import 'package:coocoo/config/Constants.dart';
import 'package:coocoo/constants.dart';
import 'package:coocoo/managers/db_manager.dart';
import 'package:coocoo/models/MyContact.dart';
import 'package:coocoo/widgets/DangerCard.dart';
import 'package:coocoo/widgets/ImageFullScreenWidget.dart';
import 'package:coocoo/widgets/ListTileProfile.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class FriendProfileScreen extends StatefulWidget {
final MyContact friend;
FriendProfileScreen(this.friend);
@override
_FriendProfileScreenState createState() => _FriendProfileScreenState();
}
class _FriendProfileScreenState extends State<FriendProfileScreen> {
ChatBloc chatBloc;
bool isBlocked = false;
TextEditingController changeNameController = TextEditingController();
final _formKey = GlobalKey<FormState>();
HomeBloc homeBloc;
Future<bool> _showPrompt(BuildContext context) async {
return (await showDialog(
context: context,
builder: (context) => AlertDialog(
title:
Text('Are you sure you want to block ${widget.friend.name}?'),
content:
Text("You won't be able to send or receive any messages from"
" ${widget.friend.name}."),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.of(context).pop(false),
child: Text(
'NO',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
FlatButton(
onPressed: () {
chatBloc.add(BlockUserEvent(context, widget.friend.chatId));
Navigator.of(context).pop(false);
},
child: Text(
'YES',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
],
),
)) ??
false;
}
void updateIsBlocked() async {
bool temp = await DBManager.db.isBlocked(widget.friend.chatId);
setState(() {
isBlocked = temp;
print(isBlocked);
});
}
@override
void initState() {
chatBloc = BlocProvider.of<ChatBloc>(context);
updateIsBlocked();
super.initState();
}
@override
Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
double algo = screenWidth / perfectWidth;
return Scaffold(
appBar: AppBar(
title: Text("Profile"),
),
body: Container(
width: double.infinity,
padding: EdgeInsets.symmetric(
vertical: algo * 10.0, horizontal: algo * 15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ImageFullScreen(url: widget.friend.photoUrl)));
},
child: CircleAvatar(
radius: algo * 120.0,
backgroundColor: Colors.white,
backgroundImage:
CachedNetworkImageProvider(widget.friend.photoUrl),
),
),
Spacer(
flex: 2,
),
ListTileProfile(
iconData: FontAwesomeIcons.book,
title: 'Full Name',
subTitle: widget.friend.name,
trailingWidget: GestureDetector(
onTap: () {
showModalBottomSheet(
context: context,
isScrollControlled: true,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.vertical(top: Radius.circular(20.0))),
builder: (BuildContext context) {
return Form(
key: _formKey,
child: Container(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
top: 10.0,
left: 15.0,
right: 15.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Edit Name',
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w500,
),
),
SizedBox(height: algo * 12.0),
TextFormField(
validator: (value) {
if (value.trim().isEmpty) {
return "Please enter a valid Name";
}
return null;
},
controller: changeNameController,
style: TextStyle(
fontSize: algo * 18.0,
),
autocorrect: false,
cursorColor: Colors.blueGrey,
decoration:
kHitUpIdTextFieldDecoration.copyWith(
hintText: 'New Name',
),
),
SizedBox(height: algo * 8.0),
FlatButton(
onPressed: () async {
if (_formKey.currentState.validate()) {
Navigator.popUntil(
context, (route) => route.isFirst);
await DBManager.db.updateName(
changeNameController.text,
widget.friend.chatId);
homeBloc =
BlocProvider.of<HomeBloc>(context);
homeBloc.add(FetchHomeChatsEvent());
}
},
color: Constants.stuffColor,
child: Text(
'DONE',
style: TextStyle(
color: Colors.white,
fontSize: algo * 22.0,
letterSpacing: 0.5,
),
),
),
],
),
),
);
},
);
},
child: Icon(
Icons.edit,
color: Constants.stuffColor,
),
),
),
ListTileProfile(
iconData: FontAwesomeIcons.solidUser,
title: "Username",
subTitle: widget.friend.username,
),
Spacer(
flex: 5,
),
BlocListener<ChatBloc, ChatState>(
listener: (context, state) {
if (state is BlockedUserState) {
setState(() {
isBlocked = true;
});
} else {
setState(() {
isBlocked = false;
});
}
},
child: isBlocked
? DangerCard(Colors.green, 'UnBlock', () async {
chatBloc
.add(UnblockUserEvent(context, widget.friend.chatId));
})
: DangerCard(Colors.red, 'Block', () async {
_showPrompt(context);
}),
),
],
),
),
);
}
}
================================================
FILE: lib/screens/help_screen.dart
================================================
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class HelpScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Help"),
),
body: Container(
padding: const EdgeInsets.symmetric(vertical: 15.0, horizontal: 8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"For help with any issues, bugs or feature requests please write a review "
"on Google Play Store or directly contact us "
"at: ",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w400,
),
),
Column(
children: [
ContactMeCard(
iconData: FontAwesomeIcons.envelope,
title: 'digantakalita.ai@gmail.com',
),
ContactMeCard(
iconData: FontAwesomeIcons.instagram,
title: '@digantakalita_real',
),
ContactMeCard(
iconData: FontAwesomeIcons.twitter,
title: '@realdiganta',
),
ContactMeCard(
iconData: FontAwesomeIcons.whatsapp,
title: '+91 1111111111',
),
SizedBox(height: 10.0),
Text(
"If your messages are not being sent, just check your "
"internet connection or restart the app,"
" and it will start working fine af",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 17.0,
),
)
],
),
SizedBox(height: 20.0),
Text(
"We typically reply within 4 hours",
style: TextStyle(
fontSize: 18.0,
color: Colors.teal,
fontWeight: FontWeight.bold,
),
),
],
),
),
);
}
}
class ContactMeCard extends StatelessWidget {
final IconData iconData;
final String title;
ContactMeCard({this.iconData, this.title});
@override
Widget build(BuildContext context) {
return Card(
elevation: 5.0,
child: ListTile(
leading: FaIcon(
iconData,
color: Colors.pinkAccent,
),
title: Text(
title,
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 19.0,
letterSpacing: 0.8,
),
),
),
);
}
}
================================================
FILE: lib/screens/home_screen.dart
================================================
import 'dart:async';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:coocoo/screens/contacts_screen.dart';
import 'package:coocoo/screens/profile_screen.dart';
import 'package:coocoo/screens/settings_screen.dart';
import 'package:coocoo/blocs/home/home_bloc.dart';
import 'package:coocoo/config/Constants.dart';
import 'package:coocoo/config/Paths.dart';
import 'package:coocoo/constants.dart';
import 'package:coocoo/models/Conversation.dart';
import 'package:coocoo/stateProviders/profilePicUrlState.dart';
import 'package:coocoo/utils/SharedObjects.dart';
import 'package:coocoo/widgets/ChatCard.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
import 'package:onesignal_flutter/onesignal_flutter.dart';
import 'package:provider/provider.dart';
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> with WidgetsBindingObserver {
HomeBloc homeBloc;
List<Conversation> conversations;
void setUserNameAndNameIfNull() {
Firestore _firestore = Firestore.instance;
String uid = SharedObjects.prefs.getString(Constants.sessionUid);
String username = SharedObjects.prefs.getString(Constants.sessionUsername);
String fullName = SharedObjects.prefs.getString(Constants.fullName);
if (username == null || fullName == null) {
_firestore.collection(Paths.usersPath).document(uid).get().then((doc) {
SharedObjects.prefs
.setString(Constants.sessionUsername, doc.data["username"]);
SharedObjects.prefs.setString(Constants.fullName, doc.data["name"]);
SharedObjects.prefs.setString(
Constants.sessionProfilePictureUrl, doc.data["photoUrl"]);
});
}
}
Future<bool> _onWillPop() async {
return (await showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Are you sure?'),
content: Text('Do you want to exit the App'),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.of(context).pop(false),
child: Text('No'),
),
FlatButton(
onPressed: () =>
SystemChannels.platform.invokeMethod('SystemNavigator.pop'),
child: Text('Yes'),
),
],
),
)) ??
false;
}
void initOneSignal() async {
await OneSignal.shared.init("98194ba4-9b9a-416b-ab0c-74b851af4f1a",
iOSSettings: {
OSiOSSettings.autoPrompt: false,
OSiOSSettings.inAppLaunchUrl: false
});
await OneSignal.shared
.setInFocusDisplayType(OSNotificationDisplayType.notification);
final String myUid = SharedObjects.prefs.getString(Constants.sessionUid);
await OneSignal.shared.setExternalUserId(myUid);
OneSignal.shared.addTrigger('update', '1');
}
@override
void initState() {
WidgetsBinding.instance.addObserver(this);
initOneSignal();
homeBloc = BlocProvider.of<HomeBloc>(context);
super.initState();
// connecting to the mqtt server in the home page
homeBloc.add(ConnectToServerEvent(context));
setUserNameAndNameIfNull();
print("Home Screen Opened");
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
if (state == AppLifecycleState.paused) {
homeBloc.add(DisconnectEvent());
}
if (state == AppLifecycleState.resumed) {
homeBloc.add(ConnectToServerEvent(context));
}
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
Widget build(BuildContext context) {
final double screenWidth = MediaQuery.of(context).size.width;
return WillPopScope(
onWillPop: _onWillPop,
child: Scaffold(
backgroundColor: Colors.grey[200],
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => ContactListPage()));
},
backgroundColor: Colors.blueGrey[600],
elevation: 15.0,
child: Icon(
Icons.message,
),
),
body: SafeArea(
child: Container(
padding: EdgeInsets.only(top: 15.0, left: 15.0, right: 15.0),
child: Column(
children: <Widget>[
Row(
children: [
Text(
'Chats',
style: TextStyle(
color: Colors.blueGrey[700],
fontSize: (screenWidth / perfectWidth) * 30.0,
fontWeight: FontWeight.w600,
),
),
Spacer(
flex: 10,
),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProfileScreen()));
},
child: Padding(
padding: EdgeInsets.symmetric(
vertical: 3.0, horizontal: 15.0),
child: Hero(
tag: 'myProfile',
child: Neumorphic(
style: kCircleNeumorphicStyle,
child: CircleAvatar(
backgroundColor: Colors.white,
radius: (screenWidth / perfectWidth) * 33.0,
backgroundImage: CachedNetworkImageProvider(
context
.watch<ProfilePicUrlState>()
.profilePicUrl),
),
),
),
),
),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SettingsScreen()));
},
child: Icon(
Icons.more_vert,
size: (screenWidth / perfectWidth) * 30.0,
),
),
],
),
SizedBox(height: 10.0),
Expanded(
flex: 3,
child: BlocBuilder<HomeBloc, HomeState>(
builder: (context, state) {
conversations = state.conversations;
if (conversations.length > 0 &&
conversations.isNotEmpty) {
return ListView.builder(
itemCount: conversations.length,
itemBuilder: (context, index) {
return ChatCard(conversations[index], index);
});
} else {
return Center(child: Text("You have No Messages"));
}
},
))
],
),
),
),
),
);
}
}
================================================
FILE: lib/screens/login_screen.dart
================================================
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:coocoo/screens/otp_screen.dart';
import 'package:coocoo/config/Constants.dart';
import 'package:coocoo/functions/UserDataFunction.dart';
import 'package:coocoo/stateProviders/number_state.dart';
import 'package:coocoo/utils/SharedObjects.dart';
import 'package:country_pickers/country.dart';
import 'package:country_pickers/country_pickers.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
class Login extends StatefulWidget {
@override
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
final _formKey = GlobalKey<FormState>();
Firestore _firestore = Firestore.instance;
TextEditingController mobileNumberController = TextEditingController();
final FirebaseAuth _auth = FirebaseAuth.instance;
UserDataFunction userDataFunction = UserDataFunction();
String countryCode = '91';
// TODO: Handle the exception nicely here instead of just printing out the error
final PhoneVerificationFailed _verificationFailed =
(AuthException authException) {
print(authException.message);
};
Future<bool> _showContinueDialog() async {
return (await showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text(
'We will be verifying the phone number: +$countryCode ${mobileNumberController.text}'),
content: Text('Is this OK, or would you like to edit the number?'),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.of(context).pop(false),
child: Text('EDIT'),
),
FlatButton(
onPressed: () async {
context.read<NumberState>().setPhoneNumber(
"$countryCode${mobileNumberController.text}");
await SharedObjects.prefs
.setString(Constants.sessionCountryCode, countryCode);
await userDataFunction.verifyPhoneNumber(
context,
'+$countryCode' + mobileNumberController.text.toString(),
_verificationFailed);
Navigator.push(context,
MaterialPageRoute(builder: (context) => OTPScreen()));
},
child: Text('OK'),
),
],
),
)) ??
false;
}
Widget _buildDropdownItem(Country country) => Container(
child: Row(
children: <Widget>[
CountryPickerUtils.getDefaultFlagImage(country),
SizedBox(
width: 8.0,
),
Text("+${country.phoneCode} ${country.isoCode}"),
],
),
);
@override
void dispose() {
mobileNumberController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: ChangeNotifierProvider<NumberState>(
create: (context) => NumberState(),
child: Form(
key: _formKey,
child: SafeArea(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 35.0, horizontal: 22.0),
child: ListView(
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
children: <Widget>[
Text(
'Verify your phone number',
style: TextStyle(
color: Constants.textStuffColor,
fontSize: 22.0,
fontWeight: FontWeight.w600,
),
),
SizedBox(height: 30.0),
Text(
'HitUp Messenger will send and SMS message (carrier charges may apply) to verify'
' your phone number. Enter your phone number.',
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.w400,
),
textAlign: TextAlign.center,
),
SizedBox(height: 20.0),
CountryPickerDropdown(
initialValue: 'IN',
itemBuilder: _buildDropdownItem,
// itemFilter: ['AR', 'DE', 'GB', 'CN'].contains(c.isoCode),
sortComparator: (Country a, Country b) =>
a.isoCode.compareTo(b.isoCode),
onValuePicked: (Country country) {
setState(() {
countryCode = country.phoneCode;
});
},
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 50.0),
child: TextFormField(
controller: mobileNumberController,
maxLengthEnforced: true,
maxLength: 10,
cursorColor: Constants.stuffColor,
style: TextStyle(fontSize: 20.0),
keyboardType: TextInputType.number,
textAlign: TextAlign.center,
decoration: InputDecoration(
hintText: 'Phone Number',
),
inputFormatters: [
FilteringTextInputFormatter.deny(
RegExp(r'\s+')) // no spaces allowed
],
validator: (value) {
if (value.length != 10) {
return 'Please enter 10 digits';
}
return null;
},
),
),
],
),
RaisedButton(
padding: EdgeInsets.symmetric(
vertical: 8.0, horizontal: 30.0),
color: Constants.stuffColor,
child: Text(
'NEXT',
style: TextStyle(
color: Colors.white,
fontSize: 18.0,
letterSpacing: 1.0,
),
),
onPressed: () async {
if (_formKey.currentState.validate()) {
await _showContinueDialog();
}
},
),
],
),
],
),
),
),
),
),
);
}
}
================================================
FILE: lib/screens/otp_screen.dart
================================================
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:coocoo/screens/enter_name_screen.dart';
import 'package:coocoo/blocs/timer/timer_bloc.dart';
import 'package:coocoo/config/Constants.dart';
import 'package:coocoo/functions/MQTTFunction.dart';
import 'package:coocoo/functions/UserDataFunction.dart';
import 'package:coocoo/screens/home_screen.dart';
import 'package:coocoo/stateProviders/number_state.dart';
import 'package:coocoo/utils/SharedObjects.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
class OTPScreen extends StatefulWidget {
@override
_OTPScreenState createState() => _OTPScreenState();
}
class _OTPScreenState extends State<OTPScreen> {
final _formKey = GlobalKey<FormState>();
TextEditingController otpController = TextEditingController();
FirebaseAuth _auth = FirebaseAuth.instance;
Firestore _firestore = Firestore.instance;
SharedPreferences loginData;
bool isVerifying = false;
UserDataFunction userDataFunction;
MQTTFunction mqttFunction;
bool showSpinner = false;
TimerBloc timerBLoc;
String minutesStr = '00';
String secondsStr = Constants.resendOtpTime.toString();
bool resendOtpSwitch = false;
// TODO: Handle the exception nicely here instead of just printing out the error
final PhoneVerificationFailed _verificationFailed =
(AuthException authException) {
print(authException.message);
};
Future<bool> _showWrongOTPDialog() async {
return (await showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('The code you entered was not correct'),
content: Text('Please enter the correct code!'),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.of(context).pop(false),
child: Tex
gitextract_qp4kc1fo/
├── .gitignore
├── .metadata
├── LICENSE
├── README.md
├── android/
│ ├── .gitignore
│ ├── app/
│ │ ├── build.gradle
│ │ ├── google-services.json
│ │ └── src/
│ │ ├── debug/
│ │ │ └── AndroidManifest.xml
│ │ ├── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── digantakalita/
│ │ │ │ └── coocoo/
│ │ │ │ └── MainActivity.kt
│ │ │ └── res/
│ │ │ ├── drawable/
│ │ │ │ ├── ic_launcher_background.xml
│ │ │ │ └── launch_background.xml
│ │ │ ├── mipmap-anydpi-v26/
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ └── values/
│ │ │ └── styles.xml
│ │ └── profile/
│ │ └── AndroidManifest.xml
│ ├── build.gradle
│ ├── gradle/
│ │ └── wrapper/
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ └── settings.gradle
├── ios/
│ ├── .gitignore
│ ├── Flutter/
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Runner/
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets/
│ │ │ ├── AppIcon.appiconset/
│ │ │ │ └── Contents.json
│ │ │ └── LaunchImage.imageset/
│ │ │ ├── Contents.json
│ │ │ └── README.md
│ │ ├── Base.lproj/
│ │ │ ├── LaunchScreen.storyboard
│ │ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── Runner-Bridging-Header.h
│ ├── Runner.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ └── Runner.xcscheme
│ └── Runner.xcworkspace/
│ ├── contents.xcworkspacedata
│ └── xcshareddata/
│ ├── IDEWorkspaceChecks.plist
│ └── WorkspaceSettings.xcsettings
├── lib/
│ ├── blocs/
│ │ ├── AddFriends/
│ │ │ ├── add_friends_bloc.dart
│ │ │ ├── add_friends_event.dart
│ │ │ └── add_friends_state.dart
│ │ ├── chats/
│ │ │ ├── chat_bloc.dart
│ │ │ ├── chat_event.dart
│ │ │ └── chat_state.dart
│ │ ├── contacts/
│ │ │ ├── contacts_bloc.dart
│ │ │ ├── contacts_event.dart
│ │ │ └── contacts_state.dart
│ │ ├── home/
│ │ │ ├── home_bloc.dart
│ │ │ ├── home_event.dart
│ │ │ └── home_state.dart
│ │ └── timer/
│ │ ├── timer_bloc.dart
│ │ ├── timer_event.dart
│ │ └── timer_state.dart
│ ├── config/
│ │ ├── Constants.dart
│ │ └── Paths.dart
│ ├── constants.dart
│ ├── functions/
│ │ ├── AddFriendsFunction.dart
│ │ ├── BaseFunctions.dart
│ │ ├── ChatFunction.dart
│ │ ├── MQTTFunction.dart
│ │ └── UserDataFunction.dart
│ ├── main.dart
│ ├── managers/
│ │ ├── db_manager.dart
│ │ └── mqtt_manager.dart
│ ├── models/
│ │ ├── ChatMessage.dart
│ │ ├── Conversation.dart
│ │ ├── MyContact.dart
│ │ ├── NonContact.dart
│ │ └── User.dart
│ ├── screens/
│ │ ├── ContactsHelpPage.dart
│ │ ├── account_screen.dart
│ │ ├── addFriends_screen.dart
│ │ ├── chat_screen.dart
│ │ ├── contacts_screen.dart
│ │ ├── enter_name_screen.dart
│ │ ├── friend_profile_screen.dart
│ │ ├── help_screen.dart
│ │ ├── home_screen.dart
│ │ ├── login_screen.dart
│ │ ├── otp_screen.dart
│ │ ├── profile_screen.dart
│ │ ├── settings_screen.dart
│ │ └── update_profile.dart
│ ├── splashscreen.dart
│ ├── stateProviders/
│ │ ├── mqtt_state.dart
│ │ ├── number_state.dart
│ │ └── profilePicUrlState.dart
│ ├── utils/
│ │ ├── Exceptions.dart
│ │ └── SharedObjects.dart
│ └── widgets/
│ ├── AddFriendCard.dart
│ ├── ChatCard.dart
│ ├── ChatItemWidget.dart
│ ├── ContactCard.dart
│ ├── ContactRowWidget.dart
│ ├── DangerCard.dart
│ ├── FriendRequestCard.dart
│ ├── GradientSnackBar.dart
│ ├── ImageFullScreenWidget.dart
│ ├── ListTileProfile.dart
│ ├── NameTextField.dart
│ ├── NoRequestsCard.dart
│ ├── NonContactCard.dart
│ ├── SentRequestCard.dart
│ └── SettingsTile.dart
├── pubspec.yaml
└── test/
└── widget_test.dart
SYMBOL INDEX (363 symbols across 66 files)
FILE: lib/blocs/AddFriends/add_friends_bloc.dart
class AddFriendsBloc (line 21) | class AddFriendsBloc extends Bloc<AddFriendsEvent, AddFriendsState> {
method mapEventToState (line 31) | Stream<AddFriendsState> mapEventToState(
method mapDeclineFriendRequestEventToState (line 48) | Stream<AddFriendsState> mapDeclineFriendRequestEventToState(
method mapAcceptFriendRequestEventToState (line 57) | Stream<AddFriendsState> mapAcceptFriendRequestEventToState(
method mapAddButtonClickEventToState (line 73) | Stream<AddFriendsState> mapAddButtonClickEventToState(
method mapSearchHitUpIdEventToState (line 85) | Stream<AddFriendsState> mapSearchHitUpIdEventToState(
FILE: lib/blocs/AddFriends/add_friends_event.dart
class AddFriendsEvent (line 3) | abstract class AddFriendsEvent extends Equatable {
class SearchHitUpIdEvent (line 7) | class SearchHitUpIdEvent extends AddFriendsEvent {
class AddButtonClickEvent (line 16) | class AddButtonClickEvent extends AddFriendsEvent {
class AcceptFriendRequestEvent (line 26) | class AcceptFriendRequestEvent extends AddFriendsEvent {
class DeclineFriendRequestEvent (line 36) | class DeclineFriendRequestEvent extends AddFriendsEvent{
FILE: lib/blocs/AddFriends/add_friends_state.dart
class AddFriendsState (line 3) | abstract class AddFriendsState extends Equatable {
class AddFriendsInitial (line 7) | class AddFriendsInitial extends AddFriendsState {
class SearchingHitUpIdState (line 12) | class SearchingHitUpIdState extends AddFriendsState {
class HitUpIdExistsState (line 17) | class HitUpIdExistsState extends AddFriendsState {
class HitUpIdNotExistsState (line 26) | class HitUpIdNotExistsState extends AddFriendsState {
class HitUpIdAlreadyThere (line 34) | class HitUpIdAlreadyThere extends AddFriendsState {
class SendingFriendRequestState (line 44) | class SendingFriendRequestState extends AddFriendsState {
class FriendRequestSentState (line 49) | class FriendRequestSentState extends AddFriendsState {
class AcceptingFriendRequestState (line 58) | class AcceptingFriendRequestState extends AddFriendsState {
class FriendRequestAcceptedState (line 63) | class FriendRequestAcceptedState extends AddFriendsState {
class DecliningFriendRequestState (line 68) | class DecliningFriendRequestState extends AddFriendsState{
class FriendRequestDeclinedState (line 73) | class FriendRequestDeclinedState extends AddFriendsState{
FILE: lib/blocs/chats/chat_bloc.dart
class ChatBloc (line 14) | class ChatBloc extends Bloc<ChatEvent, ChatState> {
method mapEventToState (line 20) | Stream<ChatState> mapEventToState(
FILE: lib/blocs/chats/chat_event.dart
class ChatEvent (line 3) | abstract class ChatEvent extends Equatable {
class SendMessageEvent (line 7) | class SendMessageEvent extends ChatEvent {
class SendImageEvent (line 18) | class SendImageEvent extends ChatEvent {
class ReceivedMessageEvent (line 29) | class ReceivedMessageEvent extends ChatEvent {
class LoadInitialMessagesEvent (line 38) | class LoadInitialMessagesEvent extends ChatEvent {
class BlockUserEvent (line 47) | class BlockUserEvent extends ChatEvent{
class UnblockUserEvent (line 56) | class UnblockUserEvent extends ChatEvent{
FILE: lib/blocs/chats/chat_state.dart
class ChatState (line 3) | abstract class ChatState extends Equatable {
class ChatInitial (line 9) | class ChatInitial extends ChatState {
class ReceivedMessageState (line 15) | class ReceivedMessageState extends ChatState {
class InitialMessagesLoadedState (line 24) | class InitialMessagesLoadedState extends ChatState {
class BlockedUserState (line 33) | class BlockedUserState extends ChatState {
class UnblockedUserState (line 39) | class UnblockedUserState extends ChatState {
FILE: lib/blocs/contacts/contacts_bloc.dart
class ContactsBloc (line 11) | class ContactsBloc extends Bloc<ContactsEvent, ContactsState> {
method mapEventToState (line 17) | Stream<ContactsState> mapEventToState(
FILE: lib/blocs/contacts/contacts_event.dart
class ContactsEvent (line 3) | abstract class ContactsEvent extends Equatable {
class FetchContactsEvent (line 7) | class FetchContactsEvent extends ContactsEvent {
method toString (line 9) | String toString()
class ReceivedContactsEvent (line 15) | class ReceivedContactsEvent extends ContactsEvent {
method toString (line 21) | String toString()
FILE: lib/blocs/contacts/contacts_state.dart
class ContactsState (line 3) | abstract class ContactsState extends Equatable {
class InitialContactsState (line 7) | class InitialContactsState extends ContactsState {
method toString (line 9) | String toString()
class FetchingContactsState (line 15) | class FetchingContactsState extends ContactsState {
method toString (line 17) | String toString()
class FetchedContactsState (line 23) | class FetchedContactsState extends ContactsState {
method toString (line 29) | String toString()
class ErrorState (line 35) | class ErrorState extends ContactsState {
FILE: lib/blocs/home/home_bloc.dart
class HomeBloc (line 13) | class HomeBloc extends Bloc<HomeEvent, HomeState> {
method mapEventToState (line 19) | Stream<HomeState> mapEventToState(
method mapFetchHomeChatsEventToState (line 38) | Stream<HomeState> mapFetchHomeChatsEventToState()
FILE: lib/blocs/home/home_event.dart
class HomeEvent (line 3) | abstract class HomeEvent extends Equatable {
class FetchHomeChatsEvent (line 7) | class FetchHomeChatsEvent extends HomeEvent {
class ConnectToServerEvent (line 12) | class ConnectToServerEvent extends HomeEvent {
class DisconnectEvent (line 21) | class DisconnectEvent extends HomeEvent {
FILE: lib/blocs/home/home_state.dart
class HomeState (line 3) | abstract class HomeState extends Equatable {
class HomeInitial (line 8) | class HomeInitial extends HomeState {
class FetchedHomeChatsState (line 15) | class FetchedHomeChatsState extends HomeState {
FILE: lib/blocs/timer/timer_bloc.dart
class TimerBloc (line 10) | class TimerBloc extends Bloc<TimerEvent, TimerState> {
method mapEventToState (line 17) | Stream<TimerState> mapEventToState(
method stopWatchStream (line 37) | Stream<int> stopWatchStream()
method stopTimer (line 43) | void stopTimer()
method tick (line 52) | void tick(_)
method startTimer (line 60) | void startTimer()
FILE: lib/blocs/timer/timer_event.dart
class TimerEvent (line 3) | abstract class TimerEvent extends Equatable {
class StartTimerEvent (line 7) | class StartTimerEvent extends TimerEvent {
class TimerTickedEvent (line 12) | class TimerTickedEvent extends TimerEvent {
class StopTimerEvent (line 21) | class StopTimerEvent extends TimerEvent {
FILE: lib/blocs/timer/timer_state.dart
class TimerState (line 3) | abstract class TimerState extends Equatable {
class TimerInitial (line 7) | class TimerInitial extends TimerState {
class TimerRunInProgressState (line 12) | class TimerRunInProgressState extends TimerState {
class TimerStoppedState (line 21) | class TimerStoppedState extends TimerState {
FILE: lib/config/Constants.dart
class Constants (line 3) | class Constants {
FILE: lib/config/Paths.dart
class Paths (line 1) | class Paths {
FILE: lib/functions/AddFriendsFunction.dart
class AddFriendsFunction (line 13) | class AddFriendsFunction extends BaseAddFriendsFunction {
method dispose (line 19) | void dispose()
method addToFriendRequestsCollection (line 22) | Future<void> addToFriendRequestsCollection(String phoneNumber)
method addToLocalDBAndSubscribe (line 42) | Future<String> addToLocalDBAndSubscribe(
method addToSentRequestsCollection (line 67) | Future<void> addToSentRequestsCollection(String phoneNumber)
method checkHitUpId (line 87) | Future<HitUpIdLocation> checkHitUpId(String hitUpId)
method removeFromFriendRequestsCollection (line 127) | Future<void> removeFromFriendRequestsCollection(String phoneNumber)
method removeFromSentRequestsCollection (line 139) | void removeFromSentRequestsCollection(String phoneNumber)
FILE: lib/functions/BaseFunctions.dart
type HitUpIdLocation (line 9) | enum HitUpIdLocation {
class BaseFunction (line 16) | abstract class BaseFunction {
method dispose (line 17) | void dispose()
class BaseUserDataFunction (line 20) | abstract class BaseUserDataFunction extends BaseFunction {
method getContactsFromDB (line 21) | Future<List<MyContact>> getContactsFromDB()
method loadPhoneContactsV2 (line 22) | Future<void> loadPhoneContactsV2(BuildContext context)
method loadNonContactsV2 (line 23) | Future<List<NonContact>> loadNonContactsV2()
method askContactPermissions (line 24) | Future<PermissionStatus> askContactPermissions()
method onShare (line 25) | void onShare(BuildContext context)
method sendNotification (line 26) | void sendNotification({String toUid, String title, String content})
method verifyPhoneNumber (line 27) | Future<void> verifyPhoneNumber(
class BaseChatFunction (line 31) | abstract class BaseChatFunction extends BaseFunction {
method createChatIdForContact (line 32) | Future<void> createChatIdForContact(String contactPhoneNumber)
method sendMessageToServer (line 33) | void sendMessageToServer(BuildContext context, String msg, String chatId)
method sendImageToServer (line 34) | void sendImageToServer(BuildContext context, File imageFile, String ch...
method sendServiceMsgToServer (line 35) | void sendServiceMsgToServer(BuildContext context, String msg, String c...
method getAllMsgsFromMessagesTable (line 36) | Future<List<ChatMessage>> getAllMsgsFromMessagesTable(String chatId)
method blockUser (line 37) | void blockUser(BuildContext context, String chatId)
method unBlockUser (line 38) | void unBlockUser(BuildContext context, String chatId)
class BaseMQTTFunction (line 41) | abstract class BaseMQTTFunction extends BaseFunction {
method connect (line 42) | Future<void> connect(BuildContext context)
method disconnect (line 43) | void disconnect()
class BaseUIFunction (line 46) | abstract class BaseUIFunction extends BaseFunction {
method cleanValue (line 47) | double cleanValue(double screenWidth, double value)
class BaseAddFriendsFunction (line 50) | abstract class BaseAddFriendsFunction extends BaseFunction {
method addToLocalDBAndSubscribe (line 51) | Future<String> addToLocalDBAndSubscribe(
method addToFriendRequestsCollection (line 53) | Future<void> addToFriendRequestsCollection(String phoneNumber)
method addToSentRequestsCollection (line 54) | Future<void> addToSentRequestsCollection(String phoneNumber)
method checkHitUpId (line 55) | Future<HitUpIdLocation> checkHitUpId(String hitUpId)
method removeFromFriendRequestsCollection (line 56) | Future<void> removeFromFriendRequestsCollection(String phoneNumber)
method removeFromSentRequestsCollection (line 57) | void removeFromSentRequestsCollection(String phoneNumber)
FILE: lib/functions/ChatFunction.dart
class ChatFunction (line 19) | class ChatFunction extends BaseChatFunction {
method createChatIdForContact (line 25) | Future<String> createChatIdForContact(String contactPhoneNumber)
method createChatId (line 53) | String createChatId()
method dispose (line 63) | void dispose()
method sendMessageToServer (line 66) | void sendMessageToServer(BuildContext context, String msg, String chatId)
method getAllMsgsFromMessagesTable (line 77) | Future<List<ChatMessage>> getAllMsgsFromMessagesTable(String chatId)
method testCompressAndGetFile (line 82) | Future<File> testCompressAndGetFile(File file)
method sendImageToServer (line 96) | void sendImageToServer(
method sendServiceMsgToServer (line 120) | void sendServiceMsgToServer(BuildContext context, String msg, String c...
method blockUser (line 128) | void blockUser(BuildContext context, String chatId)
method unBlockUser (line 137) | void unBlockUser(BuildContext context, String chatId)
FILE: lib/functions/MQTTFunction.dart
class MQTTFunction (line 9) | class MQTTFunction extends BaseMQTTFunction {
method connect (line 14) | Future<void> connect(BuildContext context)
method dispose (line 39) | void dispose()
method disconnect (line 42) | void disconnect()
FILE: lib/functions/UserDataFunction.dart
class UserDataFunction (line 23) | class UserDataFunction extends BaseUserDataFunction {
method dispose (line 28) | void dispose()
method loadNonContactsV2 (line 31) | Future<List<NonContact>> loadNonContactsV2()
method loadPhoneContactsV2 (line 57) | Future<void> loadPhoneContactsV2(BuildContext context)
method removeUninstalledUserFromDB (line 87) | void removeUninstalledUserFromDB(BuildContext context, String tempNum)
method addInstalledUserToDBANDSubscribe (line 98) | Future<void> addInstalledUserToDBANDSubscribe(
method cleanNumber (line 130) | dynamic cleanNumber(Contact dirtyNumber, String countryCode)
method askContactPermissions (line 148) | Future<PermissionStatus> askContactPermissions()
method _getContactPermission (line 153) | Future<PermissionStatus> _getContactPermission()
method getContactsFromDB (line 168) | Future<List<MyContact>> getContactsFromDB()
method onShare (line 181) | void onShare(BuildContext context)
method sendNotification (line 198) | void sendNotification({String toUid, String title, String content})
method verifyPhoneNumber (line 224) | Future<void> verifyPhoneNumber(BuildContext context, String phoneNum,
FILE: lib/main.dart
function main (line 17) | void main()
class MyApp (line 42) | class MyApp extends StatelessWidget {
method build (line 44) | Widget build(BuildContext context)
FILE: lib/managers/db_manager.dart
class DBManager (line 5) | class DBManager {
method updateMessageToChatTable (line 65) | Future<void> updateMessageToChatTable(
method addNewMessageToMessagesTable (line 76) | Future<void> addNewMessageToMessagesTable(String chatId, String newMsg,
method readMessageFromChatTable (line 93) | Future<ChatMessage> readMessageFromChatTable(String chatId)
method readAllMessagesfromMessagesTable (line 113) | Future<List<ChatMessage>> readAllMessagesfromMessagesTable(
method getAlConversationsFromChatTable (line 124) | Future<List<Map<dynamic, dynamic>>> getAlConversationsFromChatTable()
method updateProfilePicInChatsTable (line 133) | Future<void> updateProfilePicInChatsTable(
method getAllContacts (line 143) | Future<List<Map<dynamic, dynamic>>> getAllContacts()
method createRow (line 163) | Future<void> createRow(String phoneNum, String chatId, String contactN...
method deleteContact (line 185) | Future<void> deleteContact(String phoneNum)
method checkIfContactExistsInDb (line 192) | Future<bool> checkIfContactExistsInDb(String phoneNumber)
method checkIfUsernameExistsInDb (line 202) | Future<bool> checkIfUsernameExistsInDb(String username)
method deleteTable (line 211) | Future<void> deleteTable()
method isBlocked (line 218) | Future<bool> isBlocked(String chatId)
method updateBlockStatus (line 229) | Future<void> updateBlockStatus(int newStatus, String chatId)
method updateName (line 238) | Future<void> updateName(String newName, String chatId)
FILE: lib/managers/mqtt_manager.dart
class MQTTManager (line 16) | class MQTTManager {
method initializeMQTTClient (line 31) | void initializeMQTTClient()
method disconnect (line 55) | void disconnect()
method getConnectionStatus (line 59) | bool getConnectionStatus()
method connect (line 67) | Future<void> connect(String username, String password)
method subscribeTopic (line 76) | void subscribeTopic(String topic)
method unSubscribeTopic (line 83) | void unSubscribeTopic(String topic)
method publish (line 90) | void publish(String myMessage, String topic)
method onDisconnected (line 97) | void onDisconnected()
method onConnect (line 101) | void onConnect()
FILE: lib/models/ChatMessage.dart
class ChatMessage (line 1) | class ChatMessage {
method toString (line 22) | String toString()
FILE: lib/models/Conversation.dart
class Conversation (line 1) | class Conversation {
method toString (line 37) | String toString()
FILE: lib/models/MyContact.dart
class MyContact (line 3) | class MyContact {
method toString (line 40) | String toString()
FILE: lib/models/NonContact.dart
class NonContact (line 3) | class NonContact extends Equatable {
FILE: lib/models/User.dart
class User (line 3) | class User {
method toString (line 27) | String toString()
FILE: lib/screens/ContactsHelpPage.dart
class ContactsHelpPage (line 4) | class ContactsHelpPage extends StatelessWidget {
method build (line 6) | Widget build(BuildContext context)
FILE: lib/screens/account_screen.dart
class AccountScreen (line 14) | class AccountScreen extends StatefulWidget {
method createState (line 16) | _AccountScreenState createState()
class _AccountScreenState (line 19) | class _AccountScreenState extends State<AccountScreen> {
method _showDialogBox (line 24) | Future<bool> _showDialogBox()
method build (line 68) | Widget build(BuildContext context)
FILE: lib/screens/addFriends_screen.dart
type RequestsType (line 21) | enum RequestsType { FriendRequests, SentRequests }
class AddFriendsScreen (line 23) | class AddFriendsScreen extends StatefulWidget {
method createState (line 25) | _AddFriendsScreenState createState()
class _AddFriendsScreenState (line 28) | class _AddFriendsScreenState extends State<AddFriendsScreen> {
method _buildRequestsStreamBuilder (line 35) | Widget _buildRequestsStreamBuilder(
method initState (line 97) | void initState()
method build (line 103) | Widget build(BuildContext context)
method dispose (line 259) | void dispose()
class SearchingCard (line 266) | class SearchingCard extends StatelessWidget {
method build (line 275) | Widget build(BuildContext context)
class HitUpIdTextWidget (line 289) | class HitUpIdTextWidget extends StatelessWidget {
method build (line 299) | Widget build(BuildContext context)
FILE: lib/screens/chat_screen.dart
class ChatScreen (line 22) | class ChatScreen extends StatefulWidget {
method createState (line 26) | _ChatScreenState createState()
class _ChatScreenState (line 29) | class _ChatScreenState extends State<ChatScreen> {
method _buildSendButton (line 38) | Widget _buildSendButton(double algo)
method _buildTypeMessageTextField (line 79) | Widget _buildTypeMessageTextField()
method _buildContactProfilePicture (line 121) | Widget _buildContactProfilePicture(double algo)
method initState (line 146) | void initState()
method dispose (line 154) | void dispose()
method build (line 161) | Widget build(BuildContext context)
method pickImage (line 285) | Future pickImage()
FILE: lib/screens/contacts_screen.dart
class ContactListPage (line 16) | class ContactListPage extends StatefulWidget {
method createState (line 18) | State<StatefulWidget> createState()
class _ContactListPageState (line 23) | class _ContactListPageState extends State<ContactListPage>
method dispose (line 46) | void dispose()
method initState (line 54) | void initState()
method _buildRefreshButton (line 89) | Widget _buildRefreshButton()
method _buildRefreshing (line 109) | Widget _buildRefreshing()
method _buildNormalAppBar (line 120) | Widget _buildNormalAppBar(double screenWidth)
method _onItemTapped (line 145) | void _onItemTapped(int ind)
method build (line 152) | Widget build(BuildContext context)
FILE: lib/screens/enter_name_screen.dart
class EnterName (line 10) | class EnterName extends StatefulWidget {
method createState (line 12) | _EnterNameState createState()
class _EnterNameState (line 15) | class _EnterNameState extends State<EnterName> {
method saveFullName (line 22) | Future<void> saveFullName(String firstname, String lastname)
method buildLoadingScreen (line 33) | Widget buildLoadingScreen()
method buildEnterNameScreen (line 39) | Widget buildEnterNameScreen()
method build (line 99) | Widget build(BuildContext context)
method dispose (line 106) | void dispose()
FILE: lib/screens/friend_profile_screen.dart
class FriendProfileScreen (line 15) | class FriendProfileScreen extends StatefulWidget {
method createState (line 20) | _FriendProfileScreenState createState()
class _FriendProfileScreenState (line 23) | class _FriendProfileScreenState extends State<FriendProfileScreen> {
method _showPrompt (line 30) | Future<bool> _showPrompt(BuildContext context)
method updateIsBlocked (line 67) | void updateIsBlocked()
method initState (line 76) | void initState()
method build (line 83) | Widget build(BuildContext context)
FILE: lib/screens/help_screen.dart
class HelpScreen (line 4) | class HelpScreen extends StatelessWidget {
method build (line 6) | Widget build(BuildContext context)
class ContactMeCard (line 72) | class ContactMeCard extends StatelessWidget {
method build (line 79) | Widget build(BuildContext context)
FILE: lib/screens/home_screen.dart
class HomeScreen (line 23) | class HomeScreen extends StatefulWidget {
method createState (line 25) | _HomeScreenState createState()
class _HomeScreenState (line 28) | class _HomeScreenState extends State<HomeScreen> with WidgetsBindingObse...
method setUserNameAndNameIfNull (line 33) | void setUserNameAndNameIfNull()
method _onWillPop (line 50) | Future<bool> _onWillPop()
method initOneSignal (line 72) | void initOneSignal()
method initState (line 88) | void initState()
method didChangeAppLifecycleState (line 101) | void didChangeAppLifecycleState(AppLifecycleState state)
method dispose (line 112) | void dispose()
method build (line 118) | Widget build(BuildContext context)
FILE: lib/screens/login_screen.dart
class Login (line 14) | class Login extends StatefulWidget {
method createState (line 16) | _LoginState createState()
class _LoginState (line 19) | class _LoginState extends State<Login> {
method _showContinueDialog (line 34) | Future<bool> _showContinueDialog()
method _buildDropdownItem (line 67) | Widget _buildDropdownItem(Country country)
method dispose (line 80) | void dispose()
method build (line 86) | Widget build(BuildContext context)
FILE: lib/screens/otp_screen.dart
class OTPScreen (line 17) | class OTPScreen extends StatefulWidget {
method createState (line 19) | _OTPScreenState createState()
class _OTPScreenState (line 22) | class _OTPScreenState extends State<OTPScreen> {
method _showWrongOTPDialog (line 45) | Future<bool> _showWrongOTPDialog()
method _signInWithPhoneNumber (line 62) | Future<void> _signInWithPhoneNumber(String smsCode)
method _buildOTPScreen (line 120) | Widget _buildOTPScreen()
method _loadingScreen (line 251) | Widget _loadingScreen()
method initState (line 258) | void initState()
method dispose (line 266) | void dispose()
method build (line 273) | Widget build(BuildContext context)
FILE: lib/screens/profile_screen.dart
class ProfileScreen (line 21) | class ProfileScreen extends StatefulWidget {
method createState (line 23) | _ProfileScreenState createState()
class _ProfileScreenState (line 26) | class _ProfileScreenState extends State<ProfileScreen> {
method build (line 36) | Widget build(BuildContext context)
method pickImage (line 124) | Future pickImage(BuildContext context)
method saveProfilePicture (line 141) | Future<void> saveProfilePicture(
method testCompressAndGetFile (line 169) | Future<File> testCompressAndGetFile(File file, String username)
method uploadFile (line 182) | Future<String> uploadFile(File file, String path)
FILE: lib/screens/settings_screen.dart
class SettingsScreen (line 7) | class SettingsScreen extends StatelessWidget {
method build (line 11) | Widget build(BuildContext context)
FILE: lib/screens/update_profile.dart
type PageState (line 21) | enum PageState { initial, updating }
class UpdateProfile (line 23) | class UpdateProfile extends StatefulWidget {
method createState (line 25) | _UpdateProfileState createState()
class _UpdateProfileState (line 28) | class _UpdateProfileState extends State<UpdateProfile> {
method dispose (line 44) | void dispose()
method build (line 50) | Widget build(BuildContext context)
method buildUpdateProfilePage (line 59) | Widget buildUpdateProfilePage(BuildContext context)
method saveProfileDetails (line 193) | Future<void> saveProfileDetails(
method testCompressAndGetFile (line 212) | Future<File> testCompressAndGetFile(File file, String username)
method uploadFile (line 225) | Future<String> uploadFile(File file, String path, String username)
method pickImage (line 243) | Future pickImage()
FILE: lib/splashscreen.dart
class SplashScreen (line 10) | class SplashScreen extends StatefulWidget {
method createState (line 12) | _SplashScreenState createState()
class _SplashScreenState (line 15) | class _SplashScreenState extends State<SplashScreen> {
method checkIfAlreadyLogin (line 21) | void checkIfAlreadyLogin(BuildContext context)
method initState (line 45) | void initState()
method build (line 52) | Widget build(BuildContext context)
FILE: lib/stateProviders/mqtt_state.dart
class MQTTState (line 4) | class MQTTState with ChangeNotifier {
method getLastSender (line 11) | String getLastSender(String chatId)
method getLastMsg (line 15) | String getLastMsg(String chatId)
method setLastSender (line 19) | void setLastSender(String chatId, String newSender)
method setLastMsg (line 23) | void setLastMsg(String chatId, String newMsg)
method setNewManager (line 27) | void setNewManager(MQTTManager newManager)
FILE: lib/stateProviders/number_state.dart
class NumberState (line 3) | class NumberState with ChangeNotifier {
method setOTP (line 12) | void setOTP(String newValue)
method setPhoneNumber (line 17) | void setPhoneNumber(String newphoneNumber)
FILE: lib/stateProviders/profilePicUrlState.dart
class ProfilePicUrlState (line 8) | class ProfilePicUrlState with ChangeNotifier {
method setProfilePicUrl (line 15) | void setProfilePicUrl(String newUrl)
FILE: lib/utils/Exceptions.dart
class CooCooException (line 1) | abstract class CooCooException implements Exception {
method errorMessage (line 2) | String errorMessage()
class UserNotFoundException (line 5) | class UserNotFoundException extends CooCooException {
method errorMessage (line 7) | String errorMessage()
class UsernameMappingUndefinedException (line 10) | class UsernameMappingUndefinedException extends CooCooException {
method errorMessage (line 12) | String errorMessage()
class ContactAlreadyExistsException (line 15) | class ContactAlreadyExistsException extends CooCooException {
method errorMessage (line 17) | String errorMessage()
FILE: lib/utils/SharedObjects.dart
class SharedObjects (line 4) | class SharedObjects {
class CachedSharedPreferences (line 8) | class CachedSharedPreferences {
method getInstance (line 32) | Future<CachedSharedPreferences> getInstance()
method getString (line 47) | String getString(String key)
method getBool (line 54) | bool getBool(String key)
method setString (line 61) | Future<bool> setString(String key, String value)
method setBool (line 67) | Future<bool> setBool(String key, bool value)
method clearAll (line 73) | Future<void> clearAll()
method clearSession (line 78) | Future<void> clearSession()
FILE: lib/widgets/AddFriendCard.dart
class AddFriendCard (line 11) | class AddFriendCard extends StatelessWidget {
method build (line 19) | Widget build(BuildContext context)
FILE: lib/widgets/ChatCard.dart
class ChatCard (line 13) | class ChatCard extends StatelessWidget {
method buildMessage (line 20) | Widget buildMessage(String msgType, TextStyle chatTextStyle)
method build (line 39) | Widget build(BuildContext context)
FILE: lib/widgets/ChatItemWidget.dart
class ChatItemWidget (line 11) | class ChatItemWidget extends StatelessWidget {
method build (line 24) | Widget build(BuildContext context)
method buildMessageBody (line 36) | Widget buildMessageBody(
method buildMessageContainer (line 89) | Row buildMessageContainer(
method buildTimeStamp (line 122) | Row buildTimeStamp(BuildContext context, bool isSelf, String timeStamp)
FILE: lib/widgets/ContactCard.dart
class ContactCard (line 7) | class ContactCard extends StatelessWidget {
method build (line 20) | Widget build(BuildContext context)
FILE: lib/widgets/ContactRowWidget.dart
class ContactRowWidget (line 7) | class ContactRowWidget extends StatelessWidget {
method build (line 15) | Widget build(BuildContext context)
FILE: lib/widgets/DangerCard.dart
class DangerCard (line 4) | class DangerCard extends StatelessWidget {
method build (line 12) | Widget build(BuildContext context)
FILE: lib/widgets/FriendRequestCard.dart
class FriendRequestCard (line 11) | class FriendRequestCard extends StatelessWidget {
method _showPrompt (line 19) | Future<bool> _showPrompt(BuildContext context)
method build (line 56) | Widget build(BuildContext context)
FILE: lib/widgets/GradientSnackBar.dart
class GradientSnackBar (line 5) | class GradientSnackBar {
method showMessage (line 6) | void showMessage(
method showError (line 26) | void showError(BuildContext context, String error)
FILE: lib/widgets/ImageFullScreenWidget.dart
class ImageFullScreen (line 6) | class ImageFullScreen extends StatelessWidget {
method _buildImage (line 12) | Widget _buildImage()
method build (line 27) | Widget build(BuildContext context)
FILE: lib/widgets/ListTileProfile.dart
class ListTileProfile (line 3) | class ListTileProfile extends StatelessWidget {
method build (line 13) | Widget build(BuildContext context)
FILE: lib/widgets/NameTextField.dart
class NameTextField (line 4) | class NameTextField extends StatelessWidget {
method build (line 11) | Widget build(BuildContext context)
FILE: lib/widgets/NoRequestsCard.dart
class NoRequestsCard (line 4) | class NoRequestsCard extends StatelessWidget {
method build (line 14) | Widget build(BuildContext context)
FILE: lib/widgets/NonContactCard.dart
class NonContactCard (line 4) | class NonContactCard extends StatelessWidget {
method build (line 12) | Widget build(BuildContext context)
FILE: lib/widgets/SentRequestCard.dart
class SentRequestCard (line 11) | class SentRequestCard extends StatelessWidget {
method _showContinueDialog (line 17) | Future<bool> _showContinueDialog(BuildContext context)
method build (line 41) | Widget build(BuildContext context)
FILE: lib/widgets/SettingsTile.dart
class SettingsTile (line 3) | class SettingsTile extends StatelessWidget {
method build (line 11) | Widget build(BuildContext context)
FILE: test/widget_test.dart
function main (line 13) | void main()
Condensed preview — 108 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (275K chars).
[
{
"path": ".gitignore",
"chars": 722,
"preview": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*.ipr\n*.i"
},
{
"path": ".metadata",
"chars": 305,
"preview": "# This file tracks properties of this Flutter project.\n# Used by Flutter tool to assess capabilities and perform upgrade"
},
{
"path": "LICENSE",
"chars": 1071,
"preview": "MIT License\n\nCopyright (c) 2020 Diganta Kalita\n\nPermission is hereby granted, free of charge, to any person obtaining a "
},
{
"path": "README.md",
"chars": 7069,
"preview": "<p align=\"center\"><a href=\"https://github.com/realdiganta/hitup-messenger\"><img src=\"https://user-images.githubuserconte"
},
{
"path": "android/.gitignore",
"chars": 262,
"preview": "gradle-wrapper.jar\n/.gradle\n/captures/\n/gradlew\n/gradlew.bat\n/local.properties\nGeneratedPluginRegistrant.java\n\n# Remembe"
},
{
"path": "android/app/build.gradle",
"chars": 2411,
"preview": "buildscript {\n repositories {\n // ...\n maven { url 'https://plugins.gradle.org/m2/' } // Gradle Plugin "
},
{
"path": "android/app/google-services.json",
"chars": 2210,
"preview": "{\n \"project_info\": {\n \"project_number\": \"754179280048\",\n \"firebase_url\": \"https://coocoo-private-fc1e0.firebaseio"
},
{
"path": "android/app/src/debug/AndroidManifest.xml",
"chars": 332,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package=\"com.digantakalita.coocoo\">\n <!-- Fl"
},
{
"path": "android/app/src/main/AndroidManifest.xml",
"chars": 2786,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package=\"com.digantakalita.coocoo\">\n <!-- io"
},
{
"path": "android/app/src/main/kotlin/com/digantakalita/coocoo/MainActivity.kt",
"chars": 129,
"preview": "package com.digantakalita.coocoo\n\nimport io.flutter.embedding.android.FlutterActivity\n\nclass MainActivity: FlutterActivi"
},
{
"path": "android/app/src/main/res/drawable/ic_launcher_background.xml",
"chars": 4867,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector\n android:height=\"108dp\"\n android:width=\"108dp\"\n android:viewport"
},
{
"path": "android/app/src/main/res/drawable/launch_background.xml",
"chars": 434,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Modify this file to customize your launch splash screen -->\n<layer-list xmln"
},
{
"path": "android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
"chars": 268,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <b"
},
{
"path": "android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
"chars": 268,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <b"
},
{
"path": "android/app/src/main/res/values/styles.xml",
"chars": 951,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <!-- Theme applied to the Android Window while the process is sta"
},
{
"path": "android/app/src/profile/AndroidManifest.xml",
"chars": 332,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package=\"com.digantakalita.coocoo\">\n <!-- Fl"
},
{
"path": "android/build.gradle",
"chars": 639,
"preview": "buildscript {\n ext.kotlin_version = '1.3.50'\n repositories {\n google()\n jcenter()\n }\n\n depende"
},
{
"path": "android/gradle/wrapper/gradle-wrapper.properties",
"chars": 233,
"preview": "#Fri Jun 23 08:50:38 CEST 2017\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER"
},
{
"path": "android/gradle.properties",
"chars": 104,
"preview": "org.gradle.jvmargs=-Xmx1536M\nandroid.enableR8=true\nandroid.useAndroidX=true\nandroid.enableJetifier=true\n"
},
{
"path": "android/settings.gradle",
"chars": 462,
"preview": "include ':app'\n\ndef localPropertiesFile = new File(rootProject.projectDir, \"local.properties\")\ndef properties = new Prop"
},
{
"path": "ios/.gitignore",
"chars": 542,
"preview": "*.mode1v3\n*.mode2v3\n*.moved-aside\n*.pbxuser\n*.perspectivev3\n**/*sync/\n.sconsign.dblite\n.tags*\n**/.vagrant/\n**/DerivedDat"
},
{
"path": "ios/Flutter/AppFrameworkInfo.plist",
"chars": 794,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "ios/Flutter/Debug.xcconfig",
"chars": 30,
"preview": "#include \"Generated.xcconfig\"\n"
},
{
"path": "ios/Flutter/Release.xcconfig",
"chars": 30,
"preview": "#include \"Generated.xcconfig\"\n"
},
{
"path": "ios/Runner/AppDelegate.swift",
"chars": 404,
"preview": "import UIKit\nimport Flutter\n\n@UIApplicationMain\n@objc class AppDelegate: FlutterAppDelegate {\n override func applicatio"
},
{
"path": "ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json",
"chars": 2519,
"preview": "{\n \"images\" : [\n {\n \"size\" : \"20x20\",\n \"idiom\" : \"iphone\",\n \"filename\" : \"Icon-App-20x20@2x.png\",\n "
},
{
"path": "ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json",
"chars": 391,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"LaunchImage.png\",\n \"scale\" : \"1x\"\n },\n "
},
{
"path": "ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md",
"chars": 336,
"preview": "# Launch Screen Assets\n\nYou can customize the launch screen with your own desired assets by replacing the image files in"
},
{
"path": "ios/Runner/Base.lproj/LaunchScreen.storyboard",
"chars": 2377,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard"
},
{
"path": "ios/Runner/Base.lproj/Main.storyboard",
"chars": 1605,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard"
},
{
"path": "ios/Runner/Info.plist",
"chars": 1525,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "ios/Runner/Runner-Bridging-Header.h",
"chars": 38,
"preview": "#import \"GeneratedPluginRegistrant.h\"\n"
},
{
"path": "ios/Runner.xcodeproj/project.pbxproj",
"chars": 18978,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 152,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"group:Runner.xcodepr"
},
{
"path": "ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
"chars": 226,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme",
"chars": 3291,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"1020\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "ios/Runner.xcworkspace/contents.xcworkspacedata",
"chars": 152,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"group:Runner.xcodepr"
},
{
"path": "ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
"chars": 226,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "lib/blocs/AddFriends/add_friends_bloc.dart",
"chars": 4343,
"preview": "import 'dart:async';\nimport 'dart:convert';\n\nimport 'package:bloc/bloc.dart';\nimport 'package:cloud_firestore/cloud_fire"
},
{
"path": "lib/blocs/AddFriends/add_friends_event.dart",
"chars": 938,
"preview": "part of 'add_friends_bloc.dart';\n\nabstract class AddFriendsEvent extends Equatable {\n const AddFriendsEvent();\n}\n\nclass"
},
{
"path": "lib/blocs/AddFriends/add_friends_state.dart",
"chars": 1604,
"preview": "part of 'add_friends_bloc.dart';\n\nabstract class AddFriendsState extends Equatable {\n const AddFriendsState();\n}\n\nclass"
},
{
"path": "lib/blocs/chats/chat_bloc.dart",
"chars": 1585,
"preview": "import 'dart:async';\nimport 'dart:io';\n\nimport 'package:bloc/bloc.dart';\nimport 'package:coocoo/functions/ChatFunction.d"
},
{
"path": "lib/blocs/chats/chat_event.dart",
"chars": 1311,
"preview": "part of 'chat_bloc.dart';\n\nabstract class ChatEvent extends Equatable {\n const ChatEvent();\n}\n\nclass SendMessageEvent e"
},
{
"path": "lib/blocs/chats/chat_state.dart",
"chars": 958,
"preview": "part of 'chat_bloc.dart';\n\nabstract class ChatState extends Equatable {\n final List<ChatMessage> chatMessages;\n\n const"
},
{
"path": "lib/blocs/contacts/contacts_bloc.dart",
"chars": 909,
"preview": "import 'dart:async';\n\nimport 'package:bloc/bloc.dart';\nimport 'package:coocoo/functions/UserDataFunction.dart';\nimport '"
},
{
"path": "lib/blocs/contacts/contacts_event.dart",
"chars": 505,
"preview": "part of 'contacts_bloc.dart';\n\nabstract class ContactsEvent extends Equatable {\n const ContactsEvent();\n}\n\nclass FetchC"
},
{
"path": "lib/blocs/contacts/contacts_state.dart",
"chars": 783,
"preview": "part of 'contacts_bloc.dart';\n\nabstract class ContactsState extends Equatable {\n const ContactsState();\n}\n\nclass Initia"
},
{
"path": "lib/blocs/home/home_bloc.dart",
"chars": 1420,
"preview": "import 'dart:async';\n\nimport 'package:bloc/bloc.dart';\nimport 'package:coocoo/functions/MQTTFunction.dart';\nimport 'pack"
},
{
"path": "lib/blocs/home/home_event.dart",
"chars": 448,
"preview": "part of 'home_bloc.dart';\n\nabstract class HomeEvent extends Equatable {\n const HomeEvent();\n}\n\nclass FetchHomeChatsEven"
},
{
"path": "lib/blocs/home/home_state.dart",
"chars": 489,
"preview": "part of 'home_bloc.dart';\n\nabstract class HomeState extends Equatable {\n final List<Conversation> conversations;\n cons"
},
{
"path": "lib/blocs/timer/timer_bloc.dart",
"chars": 1730,
"preview": "import 'dart:async';\n\nimport 'package:bloc/bloc.dart';\nimport 'package:coocoo/config/Constants.dart';\nimport 'package:eq"
},
{
"path": "lib/blocs/timer/timer_event.dart",
"chars": 432,
"preview": "part of 'timer_bloc.dart';\n\nabstract class TimerEvent extends Equatable {\n const TimerEvent();\n}\n\nclass StartTimerEvent"
},
{
"path": "lib/blocs/timer/timer_state.dart",
"chars": 446,
"preview": "part of 'timer_bloc.dart';\n\nabstract class TimerState extends Equatable {\n const TimerState();\n}\n\nclass TimerInitial ex"
},
{
"path": "lib/config/Constants.dart",
"chars": 737,
"preview": "import 'package:flutter/material.dart';\n\nclass Constants {\n static final Color stuffColor = Colors.blueAccent[400];\n s"
},
{
"path": "lib/config/Paths.dart",
"chars": 1003,
"preview": "class Paths {\n /*\n Firebase paths\n */\n static const String profilePicturePath = 'profile_pictures';\n static const "
},
{
"path": "lib/constants.dart",
"chars": 1809,
"preview": "import 'package:flutter/material.dart';\nimport 'package:flutter/painting.dart';\nimport 'package:flutter_neumorphic/flutt"
},
{
"path": "lib/functions/AddFriendsFunction.dart",
"chars": 4944,
"preview": "import 'package:cloud_firestore/cloud_firestore.dart';\nimport 'package:coocoo/config/Constants.dart';\nimport 'package:co"
},
{
"path": "lib/functions/BaseFunctions.dart",
"chars": 2143,
"preview": "import 'dart:io';\n\nimport 'package:coocoo/models/ChatMessage.dart';\nimport 'package:coocoo/models/MyContact.dart';\nimpor"
},
{
"path": "lib/functions/ChatFunction.dart",
"chars": 4661,
"preview": "import 'dart:convert';\nimport 'dart:io';\nimport 'dart:math';\n\nimport 'package:cloud_firestore/cloud_firestore.dart';\nimp"
},
{
"path": "lib/functions/MQTTFunction.dart",
"chars": 1281,
"preview": "import 'package:coocoo/config/Constants.dart';\nimport 'package:coocoo/functions/BaseFunctions.dart';\nimport 'package:coo"
},
{
"path": "lib/functions/UserDataFunction.dart",
"chars": 8305,
"preview": "import 'dart:convert';\n\nimport 'package:cloud_firestore/cloud_firestore.dart';\nimport 'package:contacts_service/contacts"
},
{
"path": "lib/main.dart",
"chars": 2425,
"preview": "import 'package:coocoo/blocs/AddFriends/add_friends_bloc.dart';\nimport 'package:coocoo/blocs/chats/chat_bloc.dart';\nimpo"
},
{
"path": "lib/managers/db_manager.dart",
"chars": 7563,
"preview": "import 'package:coocoo/models/ChatMessage.dart';\nimport 'package:path/path.dart';\nimport 'package:sqflite/sqflite.dart';"
},
{
"path": "lib/managers/mqtt_manager.dart",
"chars": 5296,
"preview": "import 'dart:convert';\n\nimport 'package:coocoo/blocs/chats/chat_bloc.dart';\nimport 'package:coocoo/blocs/home/home_bloc."
},
{
"path": "lib/models/ChatMessage.dart",
"chars": 598,
"preview": "class ChatMessage {\n final String msg;\n final int time;\n final String msgType;\n // final int msgStatus;\n final Stri"
},
{
"path": "lib/models/Conversation.dart",
"chars": 949,
"preview": "class Conversation {\n final String phoneNumber;\n final String lastMessage;\n final String msgType;\n final int time;\n "
},
{
"path": "lib/models/MyContact.dart",
"chars": 1144,
"preview": "import 'package:cloud_firestore/cloud_firestore.dart';\n\nclass MyContact {\n final String phoneNumber;\n final String nam"
},
{
"path": "lib/models/NonContact.dart",
"chars": 234,
"preview": "import 'package:equatable/equatable.dart';\n\nclass NonContact extends Equatable {\n final String name;\n final String pho"
},
{
"path": "lib/models/User.dart",
"chars": 830,
"preview": "import 'package:cloud_firestore/cloud_firestore.dart';\n\nclass User {\n String documentId;\n String phoneNumber;\n String"
},
{
"path": "lib/screens/ContactsHelpPage.dart",
"chars": 1946,
"preview": "import 'package:coocoo/constants.dart';\nimport 'package:flutter/material.dart';\n\nclass ContactsHelpPage extends Stateles"
},
{
"path": "lib/screens/account_screen.dart",
"chars": 3244,
"preview": "import 'package:cloud_firestore/cloud_firestore.dart';\nimport 'package:coocoo/screens/profile_screen.dart';\nimport 'pack"
},
{
"path": "lib/screens/addFriends_screen.dart",
"chars": 10910,
"preview": "import 'dart:ui';\n\nimport 'package:cloud_firestore/cloud_firestore.dart';\nimport 'package:coocoo/blocs/AddFriends/add_fr"
},
{
"path": "lib/screens/chat_screen.dart",
"chars": 9914,
"preview": "import 'dart:async';\nimport 'dart:io';\n\nimport 'package:cached_network_image/cached_network_image.dart';\nimport 'package"
},
{
"path": "lib/screens/contacts_screen.dart",
"chars": 7846,
"preview": "import 'package:animated_bottom_navigation_bar/animated_bottom_navigation_bar.dart';\nimport 'package:coocoo/screens/Cont"
},
{
"path": "lib/screens/enter_name_screen.dart",
"chars": 3672,
"preview": "import 'package:cloud_firestore/cloud_firestore.dart';\nimport 'package:coocoo/screens/update_profile.dart';\nimport 'pack"
},
{
"path": "lib/screens/friend_profile_screen.dart",
"chars": 8796,
"preview": "import 'package:cached_network_image/cached_network_image.dart';\nimport 'package:coocoo/blocs/chats/chat_bloc.dart';\nimp"
},
{
"path": "lib/screens/help_screen.dart",
"chars": 2848,
"preview": "import 'package:flutter/material.dart';\nimport 'package:font_awesome_flutter/font_awesome_flutter.dart';\n\nclass HelpScre"
},
{
"path": "lib/screens/home_screen.dart",
"chars": 7814,
"preview": "import 'dart:async';\n\nimport 'package:cached_network_image/cached_network_image.dart';\nimport 'package:cloud_firestore/c"
},
{
"path": "lib/screens/login_screen.dart",
"chars": 7473,
"preview": "import 'package:cloud_firestore/cloud_firestore.dart';\nimport 'package:coocoo/screens/otp_screen.dart';\nimport 'package:"
},
{
"path": "lib/screens/otp_screen.dart",
"chars": 10487,
"preview": "import 'package:cloud_firestore/cloud_firestore.dart';\nimport 'package:coocoo/screens/enter_name_screen.dart';\nimport 'p"
},
{
"path": "lib/screens/profile_screen.dart",
"chars": 7212,
"preview": "import 'dart:io';\n\nimport 'package:cached_network_image/cached_network_image.dart';\nimport 'package:cloud_firestore/clou"
},
{
"path": "lib/screens/settings_screen.dart",
"chars": 1266,
"preview": "import 'package:coocoo/screens/account_screen.dart';\nimport 'package:coocoo/screens/help_screen.dart';\nimport 'package:c"
},
{
"path": "lib/screens/update_profile.dart",
"chars": 10015,
"preview": "import 'dart:io';\n\nimport 'package:cloud_firestore/cloud_firestore.dart';\nimport 'package:coocoo/config/Constants.dart';"
},
{
"path": "lib/splashscreen.dart",
"chars": 2903,
"preview": "import 'package:coocoo/screens/login_screen.dart';\nimport 'package:coocoo/functions/MQTTFunction.dart';\nimport 'package:"
},
{
"path": "lib/stateProviders/mqtt_state.dart",
"chars": 762,
"preview": "import 'package:coocoo/managers/mqtt_manager.dart';\nimport 'package:flutter/material.dart';\n\nclass MQTTState with Change"
},
{
"path": "lib/stateProviders/number_state.dart",
"chars": 438,
"preview": "import 'package:flutter/material.dart';\n\nclass NumberState with ChangeNotifier {\n String _otp;\n String _phoneNumber;\n "
},
{
"path": "lib/stateProviders/profilePicUrlState.dart",
"chars": 618,
"preview": "import 'package:coocoo/config/Constants.dart';\nimport 'package:coocoo/utils/SharedObjects.dart';\nimport 'package:flutter"
},
{
"path": "lib/utils/Exceptions.dart",
"chars": 479,
"preview": "abstract class CooCooException implements Exception {\n String errorMessage();\n}\n\nclass UserNotFoundException extends Co"
},
{
"path": "lib/utils/SharedObjects.dart",
"chars": 2674,
"preview": "import 'package:coocoo/config/Constants.dart';\nimport 'package:shared_preferences/shared_preferences.dart';\n\nclass Share"
},
{
"path": "lib/widgets/AddFriendCard.dart",
"chars": 2831,
"preview": "import 'package:cached_network_image/cached_network_image.dart';\nimport 'package:coocoo/config/Constants.dart';\nimport '"
},
{
"path": "lib/widgets/ChatCard.dart",
"chars": 4083,
"preview": "import 'package:cached_network_image/cached_network_image.dart';\nimport 'package:coocoo/constants.dart';\nimport 'package"
},
{
"path": "lib/widgets/ChatItemWidget.dart",
"chars": 4591,
"preview": "import 'dart:convert';\n\nimport 'package:coocoo/config/Constants.dart';\nimport 'package:coocoo/models/ChatMessage.dart';\n"
},
{
"path": "lib/widgets/ContactCard.dart",
"chars": 1180,
"preview": "import 'package:cached_network_image/cached_network_image.dart';\nimport 'package:coocoo/constants.dart';\nimport 'package"
},
{
"path": "lib/widgets/ContactRowWidget.dart",
"chars": 822,
"preview": "import 'package:coocoo/models/MyContact.dart';\nimport 'package:coocoo/screens/chat_screen.dart';\nimport 'package:coocoo/"
},
{
"path": "lib/widgets/DangerCard.dart",
"chars": 680,
"preview": "import 'package:flutter/material.dart';\nimport 'package:font_awesome_flutter/font_awesome_flutter.dart';\n\nclass DangerCa"
},
{
"path": "lib/widgets/FriendRequestCard.dart",
"chars": 4250,
"preview": "import 'package:cached_network_image/cached_network_image.dart';\nimport 'package:coocoo/blocs/AddFriends/add_friends_blo"
},
{
"path": "lib/widgets/GradientSnackBar.dart",
"chars": 1293,
"preview": "import 'package:flushbar/flushbar.dart';\nimport 'package:flutter/cupertino.dart';\nimport 'package:flutter/material.dart'"
},
{
"path": "lib/widgets/ImageFullScreenWidget.dart",
"chars": 1258,
"preview": "import 'dart:convert';\n\nimport 'package:cached_network_image/cached_network_image.dart';\nimport 'package:flutter/materia"
},
{
"path": "lib/widgets/ListTileProfile.dart",
"chars": 857,
"preview": "import 'package:flutter/material.dart';\n\nclass ListTileProfile extends StatelessWidget {\n final IconData iconData;\n fi"
},
{
"path": "lib/widgets/NameTextField.dart",
"chars": 1087,
"preview": "import 'package:flutter/material.dart';\nimport 'package:flutter/services.dart';\n\nclass NameTextField extends StatelessWi"
},
{
"path": "lib/widgets/NoRequestsCard.dart",
"chars": 709,
"preview": "import 'package:coocoo/config/Constants.dart';\nimport 'package:flutter/material.dart';\n\nclass NoRequestsCard extends Sta"
},
{
"path": "lib/widgets/NonContactCard.dart",
"chars": 1553,
"preview": "import 'package:flutter/material.dart';\nimport 'package:share/share.dart';\n\nclass NonContactCard extends StatelessWidget"
},
{
"path": "lib/widgets/SentRequestCard.dart",
"chars": 3988,
"preview": "import 'package:cached_network_image/cached_network_image.dart';\nimport 'package:coocoo/config/Constants.dart';\nimport '"
},
{
"path": "lib/widgets/SettingsTile.dart",
"chars": 577,
"preview": "import 'package:flutter/material.dart';\n\nclass SettingsTile extends StatelessWidget {\n final IconData icon;\n final Str"
},
{
"path": "pubspec.yaml",
"chars": 3484,
"preview": "name: coocoo\ndescription: A Private Chat Messenger\n\n# The following line prevents the package from being accidentally pu"
},
{
"path": "test/widget_test.dart",
"chars": 1045,
"preview": "// This is a basic Flutter widget test.\n//\n// To perform an interaction with a widget in your test, use the WidgetTester"
}
]
About this extraction
This page contains the full source code of the realdiganta/hitup-messenger GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 108 files (251.3 KB), approximately 61.4k tokens, and a symbol index with 363 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.