├── linux ├── .gitignore ├── main.cc ├── flutter │ ├── generated_plugin_registrant.cc │ ├── generated_plugin_registrant.h │ ├── generated_plugins.cmake │ └── CMakeLists.txt ├── my_application.h ├── my_application.cc └── CMakeLists.txt ├── nodejs_socket_server ├── .gitignore ├── models │ ├── Messages.js │ └── index.js ├── dist │ ├── models │ │ ├── Messages.js │ │ └── index.js │ ├── routes │ │ └── Message.js │ ├── ecosystem.config.js │ ├── controllers │ │ └── Message.js │ ├── common │ │ └── connectDb.js │ └── index.js ├── routes │ └── Message.js ├── ecosystem.config.js ├── common │ └── connectDb.js ├── controllers │ └── Message.js ├── package.json └── index.js ├── ios ├── Flutter │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── AppFrameworkInfo.plist ├── Runner │ ├── Runner-Bridging-Header.h │ ├── Assets.xcassets │ │ ├── LaunchImage.imageset │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ ├── README.md │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ └── Contents.json │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ └── Info.plist ├── Runner.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ └── project.pbxproj ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── WorkspaceSettings.xcsettings │ │ └── IDEWorkspaceChecks.plist └── .gitignore ├── web ├── favicon.png ├── icons │ ├── Icon-192.png │ └── Icon-512.png ├── manifest.json └── index.html ├── screenshots └── socket.gif ├── android ├── gradle.properties ├── app │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── drawable │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable-v21 │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── values │ │ │ │ │ └── styles.xml │ │ │ │ └── values-night │ │ │ │ │ └── styles.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── flutter_chat_socket │ │ │ │ │ └── MainActivity.kt │ │ │ └── AndroidManifest.xml │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ └── profile │ │ │ └── AndroidManifest.xml │ └── build.gradle ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore ├── settings.gradle └── build.gradle ├── lib ├── src │ ├── common │ │ ├── app_initializer.dart │ │ ├── dependecy_injection.dart │ │ └── styles.dart │ ├── shared │ │ └── logger │ │ │ └── logger_utils.dart │ ├── events │ │ └── socket_event.dart │ ├── app.dart │ ├── repository │ │ ├── friend_repository.dart │ │ └── group_repository.dart │ ├── pages │ │ ├── drawer │ │ │ ├── widgets │ │ │ │ └── friend_card.dart │ │ │ └── drawer.dart │ │ └── home │ │ │ └── home_page.dart │ └── services │ │ └── socket_service.dart └── main.dart ├── .metadata ├── integration_test ├── driver.dart └── app_test.dart ├── .gitignore ├── README.md ├── test └── widget_test.dart ├── LICENSE ├── pubspec.yaml └── pubspec.lock /linux/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral 2 | -------------------------------------------------------------------------------- /nodejs_socket_server/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/web/favicon.png -------------------------------------------------------------------------------- /screenshots/socket.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/screenshots/socket.gif -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/web/icons/Icon-512.png -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /lib/src/common/app_initializer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_simple_dependency_injection/injector.dart'; 2 | 3 | class AppInitializer { 4 | initialise(Injector injector) async {} 5 | } 6 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /nodejs_socket_server/models/Messages.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | msg: { type: String, default: '' }, 3 | id: { type: String, default: '' }, 4 | room: { type: String, default: '' }, 5 | } -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /nodejs_socket_server/dist/models/Messages.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | msg: { type: String, default: '' }, 3 | id: { type: String, default: '' }, 4 | room: { type: String, default: '' } 5 | }; -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /lib/src/shared/logger/logger_utils.dart: -------------------------------------------------------------------------------- 1 | class Logger { 2 | static void write(String text, {bool isError = false}) { 3 | Future.microtask(() => print('** $text. isError: [$isError]')); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lambiengcode/flutter_chat_realtime/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /linux/main.cc: -------------------------------------------------------------------------------- 1 | #include "my_application.h" 2 | 3 | int main(int argc, char** argv) { 4 | g_autoptr(MyApplication) app = my_application_new(); 5 | return g_application_run(G_APPLICATION(app), argc, argv); 6 | } 7 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | #include "generated_plugin_registrant.h" 6 | 7 | 8 | void fl_register_plugins(FlPluginRegistry* registry) { 9 | } 10 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/flutter_chat_socket/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.flutter_chat_socket 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /nodejs_socket_server/routes/Message.js: -------------------------------------------------------------------------------- 1 | const routes = require('express').Router(); 2 | const {getAllMessages} = require('../controllers/Message'); 3 | 4 | routes.get('/getMessageByRoom', getAllMessages); 5 | 6 | module.exports = routes; -------------------------------------------------------------------------------- /nodejs_socket_server/dist/routes/Message.js: -------------------------------------------------------------------------------- 1 | const routes = require('express').Router(); 2 | const { getAllMessages } = require('../controllers/Message'); 3 | 4 | routes.get('/getMessageByRoom', getAllMessages); 5 | 6 | module.exports = routes; -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip 7 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/src/events/socket_event.dart: -------------------------------------------------------------------------------- 1 | const List SOCKET_EVENTS = [ 2 | 'connect', 3 | 'connect_error', 4 | 'connect_timeout', 5 | 'connecting', 6 | 'disconnect', 7 | 'error', 8 | 'reconnect', 9 | 'reconnect_attempt', 10 | 'reconnect_failed', 11 | 'reconnect_error', 12 | 'reconnecting', 13 | 'ping', 14 | 'pong' 15 | ]; 16 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: b7f6d9bcb2333bae29e55e98befdad3723a97f2b 8 | channel: master 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /integration_test/driver.dart: -------------------------------------------------------------------------------- 1 | // This file is provided as a convenience for running integration tests via the 2 | // flutter drive command. 3 | // 4 | // flutter drive --driver integration_test/driver.dart --target integration_test/app_test.dart 5 | 6 | import 'package:integration_test/integration_test_driver.dart'; 7 | 8 | Future main() => integrationDriver(); 9 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 6 | #define GENERATED_PLUGIN_REGISTRANT_ 7 | 8 | #include 9 | 10 | // Registers Flutter plugins. 11 | void fl_register_plugins(FlPluginRegistry* registry); 12 | 13 | #endif // GENERATED_PLUGIN_REGISTRANT_ 14 | -------------------------------------------------------------------------------- /lib/src/common/dependecy_injection.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_chat_socket/src/services/socket_service.dart'; 2 | import 'package:flutter_simple_dependency_injection/injector.dart'; 3 | 4 | class DependencyInjection { 5 | Injector initialise(Injector injector) { 6 | injector.map((i) => SocketService(), isSingleton: true); 7 | return injector; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /nodejs_socket_server/dist/models/index.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const MessageSchema = require('./Messages'); 3 | 4 | const Schema = mongoose.Schema; 5 | 6 | const createSchema = schema => { 7 | const model = new Schema(schema, { timestamps: true }); 8 | return model; 9 | }; 10 | 11 | const Messages = mongoose.model('Messages', createSchema(MessageSchema)); 12 | 13 | module.exports = { 14 | Messages 15 | }; -------------------------------------------------------------------------------- /nodejs_socket_server/models/index.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const MessageSchema = require('./Messages') 3 | 4 | const Schema = mongoose.Schema 5 | 6 | const createSchema = (schema) => { 7 | const model = new Schema(schema, { timestamps: true }) 8 | return model 9 | } 10 | 11 | const Messages = mongoose.model('Messages', createSchema(MessageSchema)) 12 | 13 | 14 | module.exports = { 15 | Messages, 16 | } -------------------------------------------------------------------------------- /nodejs_socket_server/dist/ecosystem.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | apps: [{ 3 | name: 'realtime-chat', 4 | script: 'dist/index.js', 5 | args: 'index.js', 6 | wait_ready: true, 7 | watch: true, 8 | error_file: './logs/err.log', 9 | out_file: './logs/out.log', 10 | log_file: './logs/combined.log', 11 | log_date_format: 'YYYY-MM-DD HH:mm:ss:SSSS', 12 | min_uptime: 10000, 13 | max_restarts: 3 14 | }] 15 | }; -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/src/app.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_chat_socket/src/pages/home/home_page.dart'; 3 | 4 | class App extends StatefulWidget { 5 | @override 6 | State createState() => _AppState(); 7 | } 8 | 9 | class _AppState extends State { 10 | @override 11 | void initState() { 12 | super.initState(); 13 | } 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | return HomePage(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /linux/my_application.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUTTER_MY_APPLICATION_H_ 2 | #define FLUTTER_MY_APPLICATION_H_ 3 | 4 | #include 5 | 6 | G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, 7 | GtkApplication) 8 | 9 | /** 10 | * my_application_new: 11 | * 12 | * Creates a new Flutter-based application. 13 | * 14 | * Returns: a new #MyApplication. 15 | */ 16 | MyApplication* my_application_new(); 17 | 18 | #endif // FLUTTER_MY_APPLICATION_H_ 19 | -------------------------------------------------------------------------------- /nodejs_socket_server/ecosystem.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | apps: [ 3 | { 4 | name: 'realtime-chat', 5 | script: 'dist/index.js', 6 | args: 'index.js', 7 | wait_ready: true, 8 | watch: true, 9 | error_file: './logs/err.log', 10 | out_file: './logs/out.log', 11 | log_file: './logs/combined.log', 12 | log_date_format: 'YYYY-MM-DD HH:mm:ss:SSSS', 13 | min_uptime: 10000, 14 | max_restarts: 3, 15 | }, 16 | ], 17 | }; -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /nodejs_socket_server/dist/controllers/Message.js: -------------------------------------------------------------------------------- 1 | const { Messages } = require("../models/index"); 2 | 3 | async function getAllMessages(roomInfo) { 4 | const payload = await Messages.find({ 5 | room: roomInfo 6 | }); 7 | return payload; 8 | } 9 | 10 | async function addMessage(message, roomInfo) { 11 | const payload = await Messages.create({ 12 | msg: message.msg, 13 | id: message.id, 14 | room: roomInfo 15 | }); 16 | return payload; 17 | } 18 | 19 | module.exports = { 20 | getAllMessages, 21 | addMessage 22 | }; -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/src/repository/friend_repository.dart: -------------------------------------------------------------------------------- 1 | var friends = [ 2 | { 3 | 'name': 'Selena', 4 | 'image': 5 | 'https://images.unsplash.com/photo-1516726817505-f5ed825624d8?ixid=MXwxMjA3fDB8MHxzZWFyY2h8Mnx8bW9kZWx8ZW58MHx8MHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60', 6 | }, 7 | { 8 | 'name': 'Victoria Kim', 9 | 'image': 10 | 'https://images.unsplash.com/photo-1529626455594-4ff0802cfb7e?ixid=MXwxMjA3fDB8MHxzZWFyY2h8M3x8bW9kZWx8ZW58MHx8MHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60', 11 | }, 12 | ]; 13 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | ) 7 | 8 | set(PLUGIN_BUNDLED_LIBRARIES) 9 | 10 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 11 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) 12 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 13 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 14 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 15 | endforeach(plugin) 16 | -------------------------------------------------------------------------------- /nodejs_socket_server/dist/common/connectDb.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | connectDatabase = () => { 4 | mongoose.connect(`${process.env.DB_URL}`, { 5 | //mongoose.connect(`mongodb://${process.env.DB_URL}/${process.env.DB_NAME}`, { 6 | useUnifiedTopology: true, 7 | useFindAndModify: false, 8 | useNewUrlParser: true, 9 | useCreateIndex: true 10 | }).then(async () => { 11 | console.log('Connect Db successfully'); 12 | }).catch(err => { 13 | console.log(err); 14 | }); 15 | }; 16 | 17 | module.exports = connectDatabase; -------------------------------------------------------------------------------- /nodejs_socket_server/common/connectDb.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | connectDatabase = () => { 4 | mongoose.connect(`${process.env.DB_URL}`, { 5 | //mongoose.connect(`mongodb://${process.env.DB_URL}/${process.env.DB_NAME}`, { 6 | useUnifiedTopology: true, 7 | useFindAndModify: false, 8 | useNewUrlParser: true, 9 | useCreateIndex: true 10 | }) 11 | .then(async () => { 12 | console.log('Connect Db successfully') 13 | }).catch((err) => { 14 | console.log(err) 15 | }) 16 | } 17 | 18 | module.exports = connectDatabase; -------------------------------------------------------------------------------- /nodejs_socket_server/controllers/Message.js: -------------------------------------------------------------------------------- 1 | const {Messages} = require("../models/index"); 2 | 3 | async function getAllMessages(roomInfo) { 4 | const payload = await Messages.find({ 5 | room: roomInfo, 6 | }); 7 | return payload; 8 | } 9 | 10 | async function addMessage(message, roomInfo) { 11 | const payload = await Messages.create( 12 | { 13 | msg: message.msg, 14 | id: message.id, 15 | room: roomInfo, 16 | } 17 | ); 18 | return payload; 19 | } 20 | 21 | module.exports = { 22 | getAllMessages, 23 | addMessage, 24 | }; 25 | -------------------------------------------------------------------------------- /lib/src/repository/group_repository.dart: -------------------------------------------------------------------------------- 1 | var groups = [ 2 | { 3 | 'name': 'Flutter Vietnam', 4 | 'image': 5 | 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ4cgMB0VWcC4iJbuyTuONHRB7uachIF99E7A&usqp=CAU', 6 | }, 7 | { 8 | 'name': 'Google Play Console', 9 | 'image': 10 | 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRugdNYgdaILmDlR4oJ5iGJrvzGhsfuKpQXjg&usqp=CAU', 11 | }, 12 | { 13 | 'name': 'Sexy Girl', 14 | 'image': 15 | 'https://images.unsplash.com/flagged/photo-1578985355557-d6c2342fed0c?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxzZWFyY2h8MjF8fHNleHl8ZW58MHx8MHw%3D&auto=format&fit=crop&w=500&q=60', 16 | }, 17 | ]; 18 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flutter_chat_socket", 3 | "short_name": "flutter_chat_socket", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:4.1.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /nodejs_socket_server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodejs_socket_server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "start": "index.js", 7 | "scripts": { 8 | "build": "rimraf dist/ && babel ./ --out-dir dist/ --ignore ./node_modules,./.babelrc,./package.json,./npm-console.log.log --copy-files", 9 | "start": "npm run build && node dist/index.js", 10 | "dev": "nodemon --exec babel-node index.js", 11 | "pm2": "yarn build && yarn pm2:start", 12 | "pm2:start": "pm2 start ecosystem.config.js" 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "ISC", 17 | "dependencies": { 18 | "babel-cli": "^6.26.0", 19 | "dotenv": "^8.2.0", 20 | "express": "^4.17.1", 21 | "http": "^0.0.1-security", 22 | "mongoose": "^5.12.3", 23 | "socket.io": "^2.3.0" 24 | }, 25 | "devDependencies": { 26 | "nodemon": "^2.0.7" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Flutter Chat Socket 2 | 3 | ### Description: 4 | - 🚀 This application using Flutter for develop a realtime chat app 5 | 6 | ### How I can run it? 7 | - 🚀 Clone this repository 8 | - 🚀 Run below code in terminal of project 9 | 10 | - start socket server 11 | ```terminal 12 | cd nodejs_socket_server/ 13 | npm install 14 | npm start 15 | ``` 16 | - start flutter app (Support Linux, Web and Mobile) 17 | ```terminal 18 | flutter pub get 19 | flutter run 20 | ``` 21 | 22 | ### How I can extends project? 23 | - 🚀 Write extend channel in socket server ***nodejs_socket_server folder*** 24 | - 🚀 Listen and emit new channel in ***socket_service.dart*** file in flutter project 25 | 26 | ### Author: lambiengcode 27 | 28 | ### Screenshots 29 | - 🚀 Below is video demo between linux desktop app and web platform 30 | 31 | 32 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | void main() { 12 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 13 | // Build our app and trigger a frame. 14 | 15 | // Verify that our counter starts at 0. 16 | expect(find.text('0'), findsOneWidget); 17 | expect(find.text('1'), findsNothing); 18 | 19 | // Tap the '+' icon and trigger a frame. 20 | await tester.tap(find.byIcon(Icons.add)); 21 | await tester.pump(); 22 | 23 | // Verify that our counter has incremented. 24 | expect(find.text('0'), findsNothing); 25 | expect(find.text('1'), findsOneWidget); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_chat_socket/src/app.dart'; 3 | import 'package:flutter_chat_socket/src/common/app_initializer.dart'; 4 | import 'package:flutter_chat_socket/src/common/dependecy_injection.dart'; 5 | import 'package:flutter_chat_socket/src/services/socket_service.dart'; 6 | import 'package:flutter_chat_socket/src/shared/logger/logger_utils.dart'; 7 | import 'package:flutter_simple_dependency_injection/injector.dart'; 8 | import 'package:get/get_navigation/get_navigation.dart'; 9 | 10 | Injector injector = Injector(); 11 | 12 | void main() async { 13 | DependencyInjection().initialise(injector); 14 | //injector = injector; 15 | await AppInitializer().initialise(injector); 16 | final SocketService socketService = injector.get(); 17 | socketService.createSocketConnection(); 18 | runApp( 19 | GetMaterialApp( 20 | enableLog: true, 21 | logWriterCallback: Logger.write, 22 | debugShowCheckedModeBanner: false, 23 | title: 'Flutter Chat Realtime', 24 | home: App(), 25 | ), 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Dao Hong Vinh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /integration_test/app_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter integration test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | import 'package:integration_test/integration_test.dart'; 11 | 12 | import 'package:flutter_chat_socket/main.dart' as app; 13 | 14 | void main() => run(_testMain); 15 | 16 | void _testMain() { 17 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 18 | // Build our app and trigger a frame. 19 | app.main(); 20 | 21 | // Trigger a frame. 22 | await tester.pumpAndSettle(); 23 | 24 | // Verify that our counter starts at 0. 25 | expect(find.text('0'), findsOneWidget); 26 | expect(find.text('1'), findsNothing); 27 | 28 | // Tap the '+' icon and trigger a frame. 29 | await tester.tap(find.byIcon(Icons.add)); 30 | await tester.pump(); 31 | 32 | // Verify that our counter has incremented. 33 | expect(find.text('0'), findsNothing); 34 | expect(find.text('1'), findsOneWidget); 35 | }); 36 | } 37 | -------------------------------------------------------------------------------- /nodejs_socket_server/dist/index.js: -------------------------------------------------------------------------------- 1 | require("dotenv").config(); 2 | const express = require("express"); 3 | const app = express(); 4 | const server = require("http").Server(app); 5 | const io = require("socket.io")(server); 6 | const connectDatabase = require("./common/connectDb"); 7 | const { getAllMessages, addMessage } = require("./controllers/Message"); 8 | 9 | connectDatabase(); 10 | 11 | io.on("connection", function (socket) { 12 | var id; 13 | 14 | socket.on("join", function (msg) { 15 | id = msg; 16 | }); 17 | 18 | socket.on("subscribe", async function (roomInfo) { 19 | socket.join(roomInfo); 20 | const history = await getAllMessages(roomInfo); 21 | io.emit(`${id}-${roomInfo}-history`, history); 22 | 23 | socket.on(roomInfo, async function (msg) { 24 | socket.broadcast.to(roomInfo).emit(roomInfo, { 25 | msg: msg, 26 | id: id 27 | }); 28 | await addMessage({ msg: msg, id: id }, roomInfo); 29 | }); 30 | 31 | socket.on(`${roomInfo}-typing`, function (typing) { 32 | socket.broadcast.to(roomInfo).emit(`${roomInfo}-typing`, { 33 | id: id, 34 | name: typing.name, 35 | isTyping: typing.isTyping 36 | }); 37 | }); 38 | }); 39 | 40 | socket.on("unsubscribe", function (roomInfo) { 41 | socket.leave(roomInfo); 42 | socket.removeAllListeners(roomInfo); 43 | }); 44 | }); 45 | 46 | server.listen(process.env.PORT, "0.0.0.0", function () { 47 | console.log("Server is running on port: " + process.env.PORT); 48 | }); -------------------------------------------------------------------------------- /nodejs_socket_server/index.js: -------------------------------------------------------------------------------- 1 | require("dotenv").config(); 2 | const express = require("express"); 3 | const app = express(); 4 | const server = require("http").Server(app); 5 | const io = require("socket.io")(server); 6 | const connectDatabase = require("./common/connectDb"); 7 | const { getAllMessages, addMessage } = require("./controllers/Message"); 8 | 9 | connectDatabase(); 10 | 11 | io.on("connection", function (socket) { 12 | var id; 13 | 14 | socket.on("join", function (msg) { 15 | id = msg; 16 | }); 17 | 18 | socket.on("subscribe", async function (roomInfo) { 19 | socket.join(roomInfo); 20 | const history = await getAllMessages(roomInfo); 21 | io.emit(`${id}-${roomInfo}-history`, history); 22 | 23 | socket.on(roomInfo, async function (msg) { 24 | socket.broadcast.to(roomInfo).emit(roomInfo, { 25 | msg: msg, 26 | id: id, 27 | }); 28 | await addMessage({ msg: msg, id: id }, roomInfo); 29 | }); 30 | 31 | socket.on(`${roomInfo}-typing`, function (typing) { 32 | socket.broadcast.to(roomInfo).emit(`${roomInfo}-typing`, { 33 | id: id, 34 | name: typing.name, 35 | isTyping: typing.isTyping, 36 | }); 37 | }); 38 | }); 39 | 40 | socket.on("unsubscribe", function (roomInfo) { 41 | socket.leave(roomInfo); 42 | socket.removeAllListeners(roomInfo); 43 | }); 44 | }); 45 | 46 | server.listen(process.env.PORT, "0.0.0.0", function () { 47 | console.log("Server is running on port: " + process.env.PORT); 48 | }); 49 | -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | flutter_chat_socket 30 | 31 | 32 | 33 | 36 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | flutter_chat_socket 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 30 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | defaultConfig { 36 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 37 | applicationId "com.example.flutter_chat_socket" 38 | minSdkVersion 16 39 | targetSdkVersion 30 40 | versionCode flutterVersionCode.toInteger() 41 | versionName flutterVersionName 42 | } 43 | 44 | buildTypes { 45 | release { 46 | // TODO: Add your own signing config for the release build. 47 | // Signing with the debug keys for now, so `flutter run --release` works. 48 | signingConfig signingConfigs.debug 49 | } 50 | } 51 | } 52 | 53 | flutter { 54 | source '../..' 55 | } 56 | 57 | dependencies { 58 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 59 | } 60 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 14 | 18 | 22 | 27 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /lib/src/pages/drawer/widgets/friend_card.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_chat_socket/main.dart'; 3 | import 'package:flutter_chat_socket/src/common/styles.dart'; 4 | import 'package:flutter_chat_socket/src/services/socket_service.dart'; 5 | import 'package:flutter_icons/flutter_icons.dart'; 6 | import 'package:get/get.dart'; 7 | 8 | class FriendCard extends StatefulWidget { 9 | final String name; 10 | final String image; 11 | FriendCard({this.name, this.image}); 12 | @override 13 | State createState() => _FriendCardState(); 14 | } 15 | 16 | class _FriendCardState extends State { 17 | final SocketService socketService = injector.get(); 18 | @override 19 | Widget build(BuildContext context) { 20 | return Container( 21 | margin: EdgeInsets.only(bottom: 16.0), 22 | padding: EdgeInsets.symmetric(horizontal: 12.0), 23 | child: Row( 24 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 25 | children: [ 26 | Row( 27 | children: [ 28 | Container( 29 | height: 46.0, 30 | width: 46.0, 31 | decoration: BoxDecoration( 32 | shape: BoxShape.circle, 33 | image: DecorationImage( 34 | image: NetworkImage(widget.image), 35 | fit: BoxFit.cover, 36 | ), 37 | ), 38 | ), 39 | SizedBox(width: 12.0), 40 | Column( 41 | crossAxisAlignment: CrossAxisAlignment.start, 42 | children: [ 43 | Text( 44 | widget.name, 45 | style: TextStyle( 46 | color: colorTitle, 47 | fontSize: 16.5, 48 | fontWeight: FontWeight.w600, 49 | ), 50 | ), 51 | SizedBox(height: 4.0), 52 | Text( 53 | 'Active Now', 54 | style: TextStyle( 55 | color: Colors.green.shade400, 56 | fontSize: 14.0, 57 | fontWeight: FontWeight.w400, 58 | ), 59 | ), 60 | ], 61 | ), 62 | ], 63 | ), 64 | IconButton( 65 | onPressed: () { 66 | socketService.setUserInfo( 67 | { 68 | 'name': widget.name, 69 | 'image': widget.image, 70 | }, 71 | ); 72 | Get.back(); 73 | }, 74 | icon: Icon( 75 | Feather.message_square, 76 | color: colorPrimary, 77 | size: 20.0, 78 | ), 79 | ), 80 | ], 81 | ), 82 | ); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /lib/src/common/styles.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:get/get.dart'; 3 | 4 | var myId = GetPlatform.isWeb.toString(); 5 | var height = Get.height; 6 | var width = Get.width; 7 | 8 | var colorBlack1 = Color(0xFF191414); 9 | var colorBlack2 = Color(0xFF14171A); 10 | var colorDarkGrey = Color(0xFF657786); 11 | var colorPrimary = Color(0xFF1DA1F2); 12 | var colorTitle = Color(0xFF2C3D50); 13 | var colorPrimaryTextOpacity = Colors.greenAccent.withOpacity(.96); 14 | var colorStar = Colors.amber.shade300; 15 | var colorHigh = Colors.redAccent; 16 | var colorMedium = Colors.amber.shade700; 17 | var colorLow = colorPrimary; 18 | var colorCompleted = Colors.green; 19 | var colorFailed = colorDarkGrey; 20 | var colorActive = Color(0xFF00D72F); 21 | 22 | Color mC = Colors.grey.shade100; 23 | Color mCL = Colors.white; 24 | Color mCM = Colors.grey.shade200; 25 | Color mCH = Colors.grey.shade400; 26 | Color mCD = Colors.black.withOpacity(0.075); 27 | Color mCC = Colors.green.withOpacity(0.65); 28 | Color fCD = Colors.grey.shade700; 29 | Color fCL = Colors.grey; 30 | 31 | BoxDecoration nMbox = BoxDecoration( 32 | borderRadius: BorderRadius.circular(15), 33 | color: mC, 34 | boxShadow: [ 35 | BoxShadow( 36 | color: mCD, 37 | offset: Offset(10, 10), 38 | blurRadius: 10, 39 | ), 40 | BoxShadow( 41 | color: mCL, 42 | offset: Offset(-10, -10), 43 | blurRadius: 10, 44 | ), 45 | ], 46 | ); 47 | 48 | BoxDecoration nMboxCategoryOff = BoxDecoration( 49 | shape: BoxShape.circle, 50 | color: mC, 51 | boxShadow: [ 52 | BoxShadow( 53 | color: mCD, 54 | offset: Offset(10, 10), 55 | blurRadius: 10, 56 | ), 57 | BoxShadow( 58 | color: mCL, 59 | offset: Offset(-10, -10), 60 | blurRadius: 10, 61 | ), 62 | ], 63 | ); 64 | 65 | BoxDecoration nMboxCategoryOn = BoxDecoration( 66 | shape: BoxShape.circle, 67 | color: mCD, 68 | boxShadow: [ 69 | BoxShadow( 70 | color: mCL, offset: Offset(3, 3), blurRadius: 3, spreadRadius: -3), 71 | ], 72 | ); 73 | 74 | BoxDecoration nMboxInvert = BoxDecoration( 75 | borderRadius: BorderRadius.circular(15), 76 | color: mCD, 77 | boxShadow: [ 78 | BoxShadow( 79 | color: mCL, offset: Offset(3, 3), blurRadius: 3, spreadRadius: -3), 80 | ]); 81 | 82 | BoxDecoration nMboxInvertActive = nMboxInvert.copyWith(color: mCC); 83 | 84 | BoxDecoration nMbtn = BoxDecoration( 85 | borderRadius: BorderRadius.circular(10), 86 | color: mC, 87 | boxShadow: [ 88 | BoxShadow( 89 | color: mCD, 90 | offset: Offset(2, 2), 91 | blurRadius: 2, 92 | ) 93 | ], 94 | ); 95 | 96 | class NMButton extends StatelessWidget { 97 | final bool down; 98 | final IconData icon; 99 | const NMButton({this.down, this.icon}); 100 | @override 101 | Widget build(BuildContext context) { 102 | return Container( 103 | width: 55, 104 | height: 55, 105 | decoration: down ? nMboxInvert : nMbox, 106 | child: Icon( 107 | icon, 108 | color: down ? fCD : fCL, 109 | ), 110 | ); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /linux/flutter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | 3 | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") 4 | 5 | # Configuration provided via flutter tool. 6 | include(${EPHEMERAL_DIR}/generated_config.cmake) 7 | 8 | # TODO: Move the rest of this into files in ephemeral. See 9 | # https://github.com/flutter/flutter/issues/57146. 10 | 11 | # Serves the same purpose as list(TRANSFORM ... PREPEND ...), 12 | # which isn't available in 3.10. 13 | function(list_prepend LIST_NAME PREFIX) 14 | set(NEW_LIST "") 15 | foreach(element ${${LIST_NAME}}) 16 | list(APPEND NEW_LIST "${PREFIX}${element}") 17 | endforeach(element) 18 | set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) 19 | endfunction() 20 | 21 | # === Flutter Library === 22 | # System-level dependencies. 23 | find_package(PkgConfig REQUIRED) 24 | pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) 25 | pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) 26 | pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) 27 | pkg_check_modules(BLKID REQUIRED IMPORTED_TARGET blkid) 28 | pkg_check_modules(LZMA REQUIRED IMPORTED_TARGET liblzma) 29 | 30 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") 31 | 32 | # Published to parent scope for install step. 33 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) 34 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) 35 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) 36 | set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) 37 | 38 | list(APPEND FLUTTER_LIBRARY_HEADERS 39 | "fl_basic_message_channel.h" 40 | "fl_binary_codec.h" 41 | "fl_binary_messenger.h" 42 | "fl_dart_project.h" 43 | "fl_engine.h" 44 | "fl_json_message_codec.h" 45 | "fl_json_method_codec.h" 46 | "fl_message_codec.h" 47 | "fl_method_call.h" 48 | "fl_method_channel.h" 49 | "fl_method_codec.h" 50 | "fl_method_response.h" 51 | "fl_plugin_registrar.h" 52 | "fl_plugin_registry.h" 53 | "fl_standard_message_codec.h" 54 | "fl_standard_method_codec.h" 55 | "fl_string_codec.h" 56 | "fl_value.h" 57 | "fl_view.h" 58 | "flutter_linux.h" 59 | ) 60 | list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") 61 | add_library(flutter INTERFACE) 62 | target_include_directories(flutter INTERFACE 63 | "${EPHEMERAL_DIR}" 64 | ) 65 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") 66 | target_link_libraries(flutter INTERFACE 67 | PkgConfig::GTK 68 | PkgConfig::GLIB 69 | PkgConfig::GIO 70 | PkgConfig::BLKID 71 | PkgConfig::LZMA 72 | ) 73 | add_dependencies(flutter flutter_assemble) 74 | 75 | # === Flutter tool backend === 76 | # _phony_ is a non-existent file to force this command to run every time, 77 | # since currently there's no way to get a full input/output list from the 78 | # flutter tool. 79 | add_custom_command( 80 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} 81 | ${CMAKE_CURRENT_BINARY_DIR}/_phony_ 82 | COMMAND ${CMAKE_COMMAND} -E env 83 | ${FLUTTER_TOOL_ENVIRONMENT} 84 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" 85 | linux-x64 ${CMAKE_BUILD_TYPE} 86 | VERBATIM 87 | ) 88 | add_custom_target(flutter_assemble DEPENDS 89 | "${FLUTTER_LIBRARY}" 90 | ${FLUTTER_LIBRARY_HEADERS} 91 | ) 92 | -------------------------------------------------------------------------------- /lib/src/services/socket_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_chat_socket/src/common/styles.dart'; 3 | import 'package:flutter_chat_socket/src/repository/friend_repository.dart'; 4 | import 'package:socket_io_client/socket_io_client.dart' as IO; 5 | import 'dart:async'; 6 | 7 | class SocketService { 8 | final _socketResponse = StreamController>(); 9 | final _typingController = StreamController(); 10 | final _userController = StreamController(); 11 | final _scrollController = ScrollController(); 12 | var _userInfo, _room = 'Selena'; 13 | List _allMessage = []; 14 | IO.Socket socket; 15 | 16 | createSocketConnection() { 17 | _userController.add(friends[0]); 18 | _userInfo = friends[0]; 19 | this.socket = IO.io('http://localhost:3000/', 20 | IO.OptionBuilder().setTransports(['websocket']).build()); 21 | this.socket.connect(); 22 | this.socket.onConnect((_) { 23 | this.socket.emit('join', myId); 24 | // Join room 25 | this.socket.emit('subscribe', _room); 26 | 27 | subscribe(); 28 | }); 29 | 30 | this.socket.onDisconnect((_) => print('disconnect')); 31 | } 32 | 33 | subscribe() { 34 | this.socket.on('$myId-$_room-history', (data) { 35 | _allMessage.clear(); 36 | _allMessage.addAll(data); 37 | _allMessage = _allMessage.reversed.toList(); 38 | _socketResponse.add(_allMessage); 39 | scrollToBottom(); 40 | }); 41 | 42 | this.socket.on(_room, (data) { 43 | _allMessage.insert(0, data); 44 | _socketResponse.add(_allMessage); 45 | scrollToBottom(); 46 | }); 47 | 48 | this.socket.on('$_room-typing', (data) { 49 | _typingController.add(data); 50 | }); 51 | } 52 | 53 | sendMessage(msg) { 54 | _allMessage.insert(0, { 55 | 'msg': msg, 56 | 'id': myId, 57 | }); 58 | this.socket.emit(_room, msg.toString()); 59 | } 60 | 61 | isTyping(isTyping) { 62 | this.socket.emit('$_room-typing', { 63 | 'id': myId, 64 | 'isTyping': isTyping, 65 | 'name': 'lambiengcode', 66 | }); 67 | } 68 | 69 | void Function(List) get addResponse => _socketResponse.sink.add; 70 | 71 | Stream> get getResponse => _socketResponse.stream; 72 | 73 | Stream get getTyping => _typingController.stream; 74 | 75 | ScrollController get getScrollController => _scrollController; 76 | 77 | void setUserInfo(dynamic info) { 78 | _userController.add(info); 79 | _userInfo = info; 80 | _allMessage.clear(); 81 | _socketResponse.add(_allMessage); 82 | this.socket.emit('unsubscribe', _room); 83 | _room = info['name']; 84 | this.socket.emit('subscribe', _room); 85 | subscribe(); 86 | } 87 | 88 | Stream get getUserInfo => _userController.stream; 89 | 90 | void scrollToBottom() { 91 | if (_scrollController.hasClients) { 92 | _scrollController.animateTo( 93 | 0.0, 94 | curve: Curves.easeOut, 95 | duration: Duration(milliseconds: 100), 96 | ); 97 | } 98 | } 99 | 100 | void dispose() { 101 | _socketResponse.close(); 102 | _typingController.close(); 103 | _userController.close(); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_chat_socket 2 | description: A new Flutter project. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 1.0.0+1 19 | 20 | environment: 21 | sdk: ">=2.7.0 <3.0.0" 22 | 23 | dependencies: 24 | flutter: 25 | sdk: flutter 26 | 27 | 28 | # The following adds the Cupertino Icons font to your application. 29 | # Use with the CupertinoIcons class for iOS style icons. 30 | cupertino_icons: ^1.0.2 31 | get: ^3.13.0 32 | socket_io_client: ^0.9.12 33 | flutter_icons: 34 | flutter_simple_dependency_injection: ^1.0.1 35 | 36 | dev_dependencies: 37 | flutter_test: 38 | sdk: flutter 39 | integration_test: 40 | sdk: flutter 41 | 42 | # For information on the generic Dart part of this file, see the 43 | # following page: https://dart.dev/tools/pub/pubspec 44 | 45 | # The following section is specific to Flutter. 46 | flutter: 47 | 48 | # The following line ensures that the Material Icons font is 49 | # included with your application, so that you can use the icons in 50 | # the material Icons class. 51 | uses-material-design: true 52 | 53 | # To add assets to your application, add an assets section, like this: 54 | # assets: 55 | # - images/a_dot_burr.jpeg 56 | # - images/a_dot_ham.jpeg 57 | 58 | # An image asset can refer to one or more resolution-specific "variants", see 59 | # https://flutter.dev/assets-and-images/#resolution-aware. 60 | 61 | # For details regarding adding assets from package dependencies, see 62 | # https://flutter.dev/assets-and-images/#from-packages 63 | 64 | # To add custom fonts to your application, add a fonts section here, 65 | # in this "flutter" section. Each entry in this list should have a 66 | # "family" key with the font family name, and a "fonts" key with a 67 | # list giving the asset and other descriptors for the font. For 68 | # example: 69 | # fonts: 70 | # - family: Schyler 71 | # fonts: 72 | # - asset: fonts/Schyler-Regular.ttf 73 | # - asset: fonts/Schyler-Italic.ttf 74 | # style: italic 75 | # - family: Trajan Pro 76 | # fonts: 77 | # - asset: fonts/TrajanPro.ttf 78 | # - asset: fonts/TrajanPro_Bold.ttf 79 | # weight: 700 80 | # 81 | # For details regarding fonts from package dependencies, 82 | # see https://flutter.dev/custom-fonts/#from-packages 83 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /linux/my_application.cc: -------------------------------------------------------------------------------- 1 | #include "my_application.h" 2 | 3 | #include 4 | #ifdef GDK_WINDOWING_X11 5 | #include 6 | #endif 7 | 8 | #include "flutter/generated_plugin_registrant.h" 9 | 10 | struct _MyApplication { 11 | GtkApplication parent_instance; 12 | char** dart_entrypoint_arguments; 13 | }; 14 | 15 | G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) 16 | 17 | // Implements GApplication::activate. 18 | static void my_application_activate(GApplication* application) { 19 | MyApplication* self = MY_APPLICATION(application); 20 | GtkWindow* window = 21 | GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); 22 | 23 | // Use a header bar when running in GNOME as this is the common style used 24 | // by applications and is the setup most users will be using (e.g. Ubuntu 25 | // desktop). 26 | // If running on X and not using GNOME then just use a traditional title bar 27 | // in case the window manager does more exotic layout, e.g. tiling. 28 | // If running on Wayland assume the header bar will work (may need changing 29 | // if future cases occur). 30 | gboolean use_header_bar = TRUE; 31 | #ifdef GDK_WINDOWING_X11 32 | GdkScreen *screen = gtk_window_get_screen(window); 33 | if (GDK_IS_X11_SCREEN(screen)) { 34 | const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); 35 | if (g_strcmp0(wm_name, "GNOME Shell") != 0) { 36 | use_header_bar = FALSE; 37 | } 38 | } 39 | #endif 40 | if (use_header_bar) { 41 | GtkHeaderBar *header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); 42 | gtk_widget_show(GTK_WIDGET(header_bar)); 43 | gtk_header_bar_set_title(header_bar, "Realtime Chat App"); 44 | gtk_header_bar_set_show_close_button(header_bar, TRUE); 45 | gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); 46 | } 47 | else { 48 | gtk_window_set_title(window, "Realtime Chat App"); 49 | } 50 | 51 | gtk_window_set_default_size(window, 1400, 820); 52 | gtk_widget_show(GTK_WIDGET(window)); 53 | 54 | g_autoptr(FlDartProject) project = fl_dart_project_new(); 55 | fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); 56 | 57 | FlView* view = fl_view_new(project); 58 | gtk_widget_show(GTK_WIDGET(view)); 59 | gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); 60 | 61 | fl_register_plugins(FL_PLUGIN_REGISTRY(view)); 62 | 63 | gtk_widget_grab_focus(GTK_WIDGET(view)); 64 | } 65 | 66 | // Implements GApplication::local_command_line. 67 | static gboolean my_application_local_command_line(GApplication* application, gchar ***arguments, int *exit_status) { 68 | MyApplication* self = MY_APPLICATION(application); 69 | // Strip out the first argument as it is the binary name. 70 | self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); 71 | 72 | g_autoptr(GError) error = nullptr; 73 | if (!g_application_register(application, nullptr, &error)) { 74 | g_warning("Failed to register: %s", error->message); 75 | *exit_status = 1; 76 | return TRUE; 77 | } 78 | 79 | g_application_activate(application); 80 | *exit_status = 0; 81 | 82 | return TRUE; 83 | } 84 | 85 | // Implements GObject::dispose. 86 | static void my_application_dispose(GObject *object) { 87 | MyApplication* self = MY_APPLICATION(object); 88 | g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); 89 | G_OBJECT_CLASS(my_application_parent_class)->dispose(object); 90 | } 91 | 92 | static void my_application_class_init(MyApplicationClass* klass) { 93 | G_APPLICATION_CLASS(klass)->activate = my_application_activate; 94 | G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; 95 | G_OBJECT_CLASS(klass)->dispose = my_application_dispose; 96 | } 97 | 98 | static void my_application_init(MyApplication* self) {} 99 | 100 | MyApplication* my_application_new() { 101 | return MY_APPLICATION(g_object_new(my_application_get_type(), 102 | "application-id", APPLICATION_ID, 103 | nullptr)); 104 | } 105 | -------------------------------------------------------------------------------- /linux/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | project(runner LANGUAGES CXX) 3 | 4 | set(BINARY_NAME "flutter_chat_socket") 5 | set(APPLICATION_ID "com.example.flutter_chat_socket") 6 | 7 | cmake_policy(SET CMP0063 NEW) 8 | 9 | set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") 10 | 11 | # Configure build options. 12 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) 13 | set(CMAKE_BUILD_TYPE "Debug" CACHE 14 | STRING "Flutter build mode" FORCE) 15 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS 16 | "Debug" "Profile" "Release") 17 | endif() 18 | 19 | # Compilation settings that should be applied to most targets. 20 | function(APPLY_STANDARD_SETTINGS TARGET) 21 | target_compile_features(${TARGET} PUBLIC cxx_std_14) 22 | target_compile_options(${TARGET} PRIVATE -Wall -Werror) 23 | target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") 24 | target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") 25 | endfunction() 26 | 27 | set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") 28 | 29 | # Flutter library and tool build rules. 30 | add_subdirectory(${FLUTTER_MANAGED_DIR}) 31 | 32 | # System-level dependencies. 33 | find_package(PkgConfig REQUIRED) 34 | pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) 35 | 36 | add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") 37 | 38 | # Application build 39 | add_executable(${BINARY_NAME} 40 | "main.cc" 41 | "my_application.cc" 42 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" 43 | ) 44 | apply_standard_settings(${BINARY_NAME}) 45 | target_link_libraries(${BINARY_NAME} PRIVATE flutter) 46 | target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) 47 | add_dependencies(${BINARY_NAME} flutter_assemble) 48 | # Only the install-generated bundle's copy of the executable will launch 49 | # correctly, since the resources must in the right relative locations. To avoid 50 | # people trying to run the unbundled copy, put it in a subdirectory instead of 51 | # the default top-level location. 52 | set_target_properties(${BINARY_NAME} 53 | PROPERTIES 54 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" 55 | ) 56 | 57 | # Generated plugin build rules, which manage building the plugins and adding 58 | # them to the application. 59 | include(flutter/generated_plugins.cmake) 60 | 61 | 62 | # === Installation === 63 | # By default, "installing" just makes a relocatable bundle in the build 64 | # directory. 65 | set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") 66 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 67 | set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) 68 | endif() 69 | 70 | # Start with a clean build bundle directory every time. 71 | install(CODE " 72 | file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") 73 | " COMPONENT Runtime) 74 | 75 | set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") 76 | set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") 77 | 78 | install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" 79 | COMPONENT Runtime) 80 | 81 | install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" 82 | COMPONENT Runtime) 83 | 84 | install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 85 | COMPONENT Runtime) 86 | 87 | if(PLUGIN_BUNDLED_LIBRARIES) 88 | install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" 89 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 90 | COMPONENT Runtime) 91 | endif() 92 | 93 | # Fully re-copy the assets directory on each build to avoid having stale files 94 | # from a previous install. 95 | set(FLUTTER_ASSET_DIR_NAME "flutter_assets") 96 | install(CODE " 97 | file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") 98 | " COMPONENT Runtime) 99 | install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" 100 | DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) 101 | 102 | # Install the AOT library on non-Debug builds only. 103 | if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") 104 | install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 105 | COMPONENT Runtime) 106 | endif() 107 | -------------------------------------------------------------------------------- /lib/src/pages/drawer/drawer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_chat_socket/src/common/styles.dart'; 3 | import 'package:flutter_chat_socket/src/pages/drawer/widgets/friend_card.dart'; 4 | import 'package:flutter_chat_socket/src/repository/friend_repository.dart'; 5 | import 'package:flutter_chat_socket/src/repository/group_repository.dart'; 6 | import 'package:flutter_icons/flutter_icons.dart'; 7 | 8 | class DrawerLayout extends StatefulWidget { 9 | @override 10 | State createState() => _DrawerLayoutState(); 11 | } 12 | 13 | class _DrawerLayoutState extends State { 14 | @override 15 | Widget build(BuildContext context) { 16 | return Container( 17 | padding: EdgeInsets.symmetric(vertical: 20.0), 18 | child: ListView( 19 | children: [ 20 | Padding( 21 | padding: EdgeInsets.symmetric(horizontal: 12.0), 22 | child: Row( 23 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 24 | children: [ 25 | Row( 26 | children: [ 27 | Container( 28 | height: 46.0, 29 | width: 46.0, 30 | decoration: BoxDecoration( 31 | shape: BoxShape.circle, 32 | image: DecorationImage( 33 | image: NetworkImage( 34 | 'https://avatars.githubusercontent.com/u/60530946?v=4'), 35 | fit: BoxFit.cover, 36 | ), 37 | ), 38 | ), 39 | SizedBox(width: 12.0), 40 | Column( 41 | crossAxisAlignment: CrossAxisAlignment.start, 42 | children: [ 43 | Text( 44 | 'lambiengcode', 45 | style: TextStyle( 46 | color: colorTitle, 47 | fontSize: 16.5, 48 | fontWeight: FontWeight.w600, 49 | ), 50 | ), 51 | SizedBox(height: 4.0), 52 | Text( 53 | 'I\'m a Mobile App Developer', 54 | style: TextStyle( 55 | color: colorDarkGrey, 56 | fontSize: 14.0, 57 | fontWeight: FontWeight.w400, 58 | ), 59 | ), 60 | ], 61 | ), 62 | ], 63 | ), 64 | IconButton( 65 | onPressed: () => null, 66 | icon: Icon( 67 | Feather.sun, 68 | color: colorPrimary, 69 | size: 20.0, 70 | ), 71 | ), 72 | ], 73 | ), 74 | ), 75 | SizedBox(height: 16.0), 76 | Divider( 77 | thickness: .2, 78 | height: .2, 79 | color: colorDarkGrey, 80 | ), 81 | SizedBox(height: 16.0), 82 | _buildTitle('Active Friends'), 83 | SizedBox(height: 16.0), 84 | ListView.builder( 85 | shrinkWrap: true, 86 | itemCount: friends.length, 87 | itemBuilder: (context, index) { 88 | return FriendCard( 89 | name: friends[index]['name'], 90 | image: friends[index]['image'], 91 | ); 92 | }, 93 | ), 94 | Padding( 95 | padding: EdgeInsets.symmetric(horizontal: 8.0, vertical: 12.0), 96 | child: Divider( 97 | thickness: .1, 98 | height: .1, 99 | color: colorDarkGrey, 100 | ), 101 | ), 102 | _buildTitle('Groups'), 103 | SizedBox(height: 16.0), 104 | ListView.builder( 105 | shrinkWrap: true, 106 | itemCount: groups.length, 107 | itemBuilder: (context, index) { 108 | return FriendCard( 109 | name: groups[index]['name'], 110 | image: groups[index]['image'], 111 | ); 112 | }, 113 | ), 114 | ], 115 | ), 116 | ); 117 | } 118 | 119 | Widget _buildTitle(title) { 120 | return Padding( 121 | padding: EdgeInsets.symmetric(horizontal: 12.0), 122 | child: Row( 123 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 124 | children: [ 125 | Text( 126 | title, 127 | style: TextStyle( 128 | color: colorTitle, 129 | fontSize: 16.0, 130 | fontWeight: FontWeight.w600, 131 | ), 132 | ), 133 | Text( 134 | 'View All', 135 | style: TextStyle( 136 | color: colorPrimary, 137 | fontSize: 15.0, 138 | fontWeight: FontWeight.w400, 139 | ), 140 | ), 141 | ], 142 | ), 143 | ); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | _fe_analyzer_shared: 5 | dependency: transitive 6 | description: 7 | name: _fe_analyzer_shared 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "12.0.0" 11 | analyzer: 12 | dependency: transitive 13 | description: 14 | name: analyzer 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "0.40.6" 18 | archive: 19 | dependency: transitive 20 | description: 21 | name: archive 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "2.0.13" 25 | args: 26 | dependency: transitive 27 | description: 28 | name: args 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "1.6.0" 32 | async: 33 | dependency: transitive 34 | description: 35 | name: async 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "2.5.0-nullsafety.3" 39 | boolean_selector: 40 | dependency: transitive 41 | description: 42 | name: boolean_selector 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "2.1.0-nullsafety.3" 46 | characters: 47 | dependency: transitive 48 | description: 49 | name: characters 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "1.1.0-nullsafety.5" 53 | charcode: 54 | dependency: transitive 55 | description: 56 | name: charcode 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "1.2.0-nullsafety.3" 60 | cli_util: 61 | dependency: transitive 62 | description: 63 | name: cli_util 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "0.2.0" 67 | clock: 68 | dependency: transitive 69 | description: 70 | name: clock 71 | url: "https://pub.dartlang.org" 72 | source: hosted 73 | version: "1.1.0-nullsafety.3" 74 | collection: 75 | dependency: transitive 76 | description: 77 | name: collection 78 | url: "https://pub.dartlang.org" 79 | source: hosted 80 | version: "1.15.0-nullsafety.5" 81 | convert: 82 | dependency: transitive 83 | description: 84 | name: convert 85 | url: "https://pub.dartlang.org" 86 | source: hosted 87 | version: "2.1.1" 88 | coverage: 89 | dependency: transitive 90 | description: 91 | name: coverage 92 | url: "https://pub.dartlang.org" 93 | source: hosted 94 | version: "0.14.2" 95 | crypto: 96 | dependency: transitive 97 | description: 98 | name: crypto 99 | url: "https://pub.dartlang.org" 100 | source: hosted 101 | version: "2.1.5" 102 | cupertino_icons: 103 | dependency: "direct main" 104 | description: 105 | name: cupertino_icons 106 | url: "https://pub.dartlang.org" 107 | source: hosted 108 | version: "1.0.2" 109 | fake_async: 110 | dependency: transitive 111 | description: 112 | name: fake_async 113 | url: "https://pub.dartlang.org" 114 | source: hosted 115 | version: "1.2.0-nullsafety.3" 116 | file: 117 | dependency: transitive 118 | description: 119 | name: file 120 | url: "https://pub.dartlang.org" 121 | source: hosted 122 | version: "6.0.0-nullsafety.4" 123 | flutter: 124 | dependency: "direct main" 125 | description: flutter 126 | source: sdk 127 | version: "0.0.0" 128 | flutter_driver: 129 | dependency: transitive 130 | description: flutter 131 | source: sdk 132 | version: "0.0.0" 133 | flutter_icons: 134 | dependency: "direct main" 135 | description: 136 | name: flutter_icons 137 | url: "https://pub.dartlang.org" 138 | source: hosted 139 | version: "1.1.0" 140 | flutter_simple_dependency_injection: 141 | dependency: "direct main" 142 | description: 143 | name: flutter_simple_dependency_injection 144 | url: "https://pub.dartlang.org" 145 | source: hosted 146 | version: "1.0.4" 147 | flutter_test: 148 | dependency: "direct dev" 149 | description: flutter 150 | source: sdk 151 | version: "0.0.0" 152 | fuchsia_remote_debug_protocol: 153 | dependency: transitive 154 | description: flutter 155 | source: sdk 156 | version: "0.0.0" 157 | get: 158 | dependency: "direct main" 159 | description: 160 | name: get 161 | url: "https://pub.dartlang.org" 162 | source: hosted 163 | version: "3.26.0" 164 | glob: 165 | dependency: transitive 166 | description: 167 | name: glob 168 | url: "https://pub.dartlang.org" 169 | source: hosted 170 | version: "1.2.0" 171 | integration_test: 172 | dependency: "direct dev" 173 | description: flutter 174 | source: sdk 175 | version: "0.9.2+2" 176 | io: 177 | dependency: transitive 178 | description: 179 | name: io 180 | url: "https://pub.dartlang.org" 181 | source: hosted 182 | version: "0.3.4" 183 | js: 184 | dependency: transitive 185 | description: 186 | name: js 187 | url: "https://pub.dartlang.org" 188 | source: hosted 189 | version: "0.6.3-nullsafety.3" 190 | json_rpc_2: 191 | dependency: transitive 192 | description: 193 | name: json_rpc_2 194 | url: "https://pub.dartlang.org" 195 | source: hosted 196 | version: "2.2.2" 197 | logging: 198 | dependency: transitive 199 | description: 200 | name: logging 201 | url: "https://pub.dartlang.org" 202 | source: hosted 203 | version: "0.11.4" 204 | matcher: 205 | dependency: transitive 206 | description: 207 | name: matcher 208 | url: "https://pub.dartlang.org" 209 | source: hosted 210 | version: "0.12.10-nullsafety.3" 211 | meta: 212 | dependency: transitive 213 | description: 214 | name: meta 215 | url: "https://pub.dartlang.org" 216 | source: hosted 217 | version: "1.3.0-nullsafety.6" 218 | node_interop: 219 | dependency: transitive 220 | description: 221 | name: node_interop 222 | url: "https://pub.dartlang.org" 223 | source: hosted 224 | version: "1.2.1" 225 | node_io: 226 | dependency: transitive 227 | description: 228 | name: node_io 229 | url: "https://pub.dartlang.org" 230 | source: hosted 231 | version: "1.1.1" 232 | package_config: 233 | dependency: transitive 234 | description: 235 | name: package_config 236 | url: "https://pub.dartlang.org" 237 | source: hosted 238 | version: "1.9.3" 239 | path: 240 | dependency: transitive 241 | description: 242 | name: path 243 | url: "https://pub.dartlang.org" 244 | source: hosted 245 | version: "1.8.0-nullsafety.3" 246 | pedantic: 247 | dependency: transitive 248 | description: 249 | name: pedantic 250 | url: "https://pub.dartlang.org" 251 | source: hosted 252 | version: "1.10.0-nullsafety.3" 253 | platform: 254 | dependency: transitive 255 | description: 256 | name: platform 257 | url: "https://pub.dartlang.org" 258 | source: hosted 259 | version: "3.0.0-nullsafety.4" 260 | pool: 261 | dependency: transitive 262 | description: 263 | name: pool 264 | url: "https://pub.dartlang.org" 265 | source: hosted 266 | version: "1.5.0-nullsafety.3" 267 | process: 268 | dependency: transitive 269 | description: 270 | name: process 271 | url: "https://pub.dartlang.org" 272 | source: hosted 273 | version: "4.0.0-nullsafety.4" 274 | pub_semver: 275 | dependency: transitive 276 | description: 277 | name: pub_semver 278 | url: "https://pub.dartlang.org" 279 | source: hosted 280 | version: "1.4.4" 281 | sky_engine: 282 | dependency: transitive 283 | description: flutter 284 | source: sdk 285 | version: "0.0.99" 286 | socket_io_client: 287 | dependency: "direct main" 288 | description: 289 | name: socket_io_client 290 | url: "https://pub.dartlang.org" 291 | source: hosted 292 | version: "0.9.12" 293 | socket_io_common: 294 | dependency: transitive 295 | description: 296 | name: socket_io_common 297 | url: "https://pub.dartlang.org" 298 | source: hosted 299 | version: "0.9.2" 300 | source_map_stack_trace: 301 | dependency: transitive 302 | description: 303 | name: source_map_stack_trace 304 | url: "https://pub.dartlang.org" 305 | source: hosted 306 | version: "2.1.0-nullsafety.4" 307 | source_maps: 308 | dependency: transitive 309 | description: 310 | name: source_maps 311 | url: "https://pub.dartlang.org" 312 | source: hosted 313 | version: "0.10.10-nullsafety.3" 314 | source_span: 315 | dependency: transitive 316 | description: 317 | name: source_span 318 | url: "https://pub.dartlang.org" 319 | source: hosted 320 | version: "1.8.0-nullsafety.4" 321 | stack_trace: 322 | dependency: transitive 323 | description: 324 | name: stack_trace 325 | url: "https://pub.dartlang.org" 326 | source: hosted 327 | version: "1.10.0-nullsafety.6" 328 | stream_channel: 329 | dependency: transitive 330 | description: 331 | name: stream_channel 332 | url: "https://pub.dartlang.org" 333 | source: hosted 334 | version: "2.1.0-nullsafety.3" 335 | string_scanner: 336 | dependency: transitive 337 | description: 338 | name: string_scanner 339 | url: "https://pub.dartlang.org" 340 | source: hosted 341 | version: "1.1.0-nullsafety.3" 342 | sync_http: 343 | dependency: transitive 344 | description: 345 | name: sync_http 346 | url: "https://pub.dartlang.org" 347 | source: hosted 348 | version: "0.2.0" 349 | term_glyph: 350 | dependency: transitive 351 | description: 352 | name: term_glyph 353 | url: "https://pub.dartlang.org" 354 | source: hosted 355 | version: "1.2.0-nullsafety.3" 356 | test_api: 357 | dependency: transitive 358 | description: 359 | name: test_api 360 | url: "https://pub.dartlang.org" 361 | source: hosted 362 | version: "0.2.19-nullsafety.6" 363 | test_core: 364 | dependency: transitive 365 | description: 366 | name: test_core 367 | url: "https://pub.dartlang.org" 368 | source: hosted 369 | version: "0.3.12-nullsafety.9" 370 | typed_data: 371 | dependency: transitive 372 | description: 373 | name: typed_data 374 | url: "https://pub.dartlang.org" 375 | source: hosted 376 | version: "1.3.0-nullsafety.5" 377 | vector_math: 378 | dependency: transitive 379 | description: 380 | name: vector_math 381 | url: "https://pub.dartlang.org" 382 | source: hosted 383 | version: "2.1.0-nullsafety.5" 384 | vm_service: 385 | dependency: transitive 386 | description: 387 | name: vm_service 388 | url: "https://pub.dartlang.org" 389 | source: hosted 390 | version: "5.5.0" 391 | watcher: 392 | dependency: transitive 393 | description: 394 | name: watcher 395 | url: "https://pub.dartlang.org" 396 | source: hosted 397 | version: "0.9.7+15" 398 | web_socket_channel: 399 | dependency: transitive 400 | description: 401 | name: web_socket_channel 402 | url: "https://pub.dartlang.org" 403 | source: hosted 404 | version: "1.1.0" 405 | webdriver: 406 | dependency: transitive 407 | description: 408 | name: webdriver 409 | url: "https://pub.dartlang.org" 410 | source: hosted 411 | version: "2.1.2" 412 | yaml: 413 | dependency: transitive 414 | description: 415 | name: yaml 416 | url: "https://pub.dartlang.org" 417 | source: hosted 418 | version: "2.2.1" 419 | sdks: 420 | dart: ">=2.12.0-0.0 <3.0.0" 421 | -------------------------------------------------------------------------------- /lib/src/pages/home/home_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/services.dart'; 3 | import 'package:flutter_chat_socket/main.dart'; 4 | import 'package:flutter_chat_socket/src/common/styles.dart'; 5 | import 'package:flutter_chat_socket/src/pages/drawer/drawer.dart'; 6 | import 'package:flutter_chat_socket/src/services/socket_service.dart'; 7 | import 'package:flutter_icons/flutter_icons.dart'; 8 | 9 | class HomePage extends StatefulWidget { 10 | @override 11 | State createState() => _HomePageState(); 12 | } 13 | 14 | class _HomePageState extends State { 15 | final SocketService socketService = injector.get(); 16 | final _scaffoldKey = GlobalKey(); 17 | TextEditingController _msgController = new TextEditingController(); 18 | FocusNode _focusNode = new FocusNode(); 19 | String _msg = ''; 20 | bool _flagTyping = false; 21 | 22 | submitMsg(msg) { 23 | if (msg == 'exit') { 24 | SystemNavigator.pop(); 25 | } else if (msg != '') { 26 | socketService.sendMessage(msg); 27 | socketService.isTyping(false); 28 | } 29 | setState(() { 30 | _msgController.text = ''; 31 | _msg = ''; 32 | _flagTyping = false; 33 | }); 34 | _focusNode.requestFocus(); 35 | } 36 | 37 | openDrawer() { 38 | _scaffoldKey.currentState.openEndDrawer(); 39 | } 40 | 41 | @override 42 | void initState() { 43 | super.initState(); 44 | _msgController.text = ''; 45 | } 46 | 47 | @override 48 | Widget build(BuildContext context) { 49 | return Scaffold( 50 | key: _scaffoldKey, 51 | endDrawer: Container( 52 | width: 400.0, 53 | child: Drawer( 54 | child: DrawerLayout(), 55 | ), 56 | ), 57 | appBar: AppBar( 58 | elevation: 1.0, 59 | backgroundColor: mC, 60 | centerTitle: false, 61 | automaticallyImplyLeading: false, 62 | leading: IconButton( 63 | onPressed: () => null, 64 | icon: Icon( 65 | Feather.arrow_left, 66 | color: colorPrimary, 67 | size: 22.5, 68 | ), 69 | ), 70 | title: StreamBuilder( 71 | stream: socketService.getUserInfo, 72 | builder: (context, AsyncSnapshot snapshot) { 73 | if (!snapshot.hasData) { 74 | return Container(); 75 | } 76 | 77 | return Row( 78 | children: [ 79 | Container( 80 | height: 40.0, 81 | width: 40.0, 82 | decoration: BoxDecoration( 83 | shape: BoxShape.circle, 84 | image: DecorationImage( 85 | image: NetworkImage(snapshot.data['image']), 86 | fit: BoxFit.cover, 87 | ), 88 | ), 89 | ), 90 | SizedBox(width: 12.0), 91 | Column( 92 | crossAxisAlignment: CrossAxisAlignment.start, 93 | children: [ 94 | Text( 95 | snapshot.data['name'], 96 | style: TextStyle( 97 | color: colorTitle, 98 | fontSize: 16.5, 99 | fontWeight: FontWeight.w600, 100 | ), 101 | ), 102 | SizedBox(height: 4.0), 103 | Text( 104 | 'Active Now', 105 | style: TextStyle( 106 | color: Colors.green.shade400, 107 | fontSize: 14.0, 108 | fontWeight: FontWeight.w400, 109 | ), 110 | ), 111 | ], 112 | ), 113 | ], 114 | ); 115 | }, 116 | ), 117 | actions: [ 118 | IconButton( 119 | onPressed: () => null, 120 | icon: Icon( 121 | Feather.phone, 122 | size: 22.5, 123 | color: colorPrimary, 124 | ), 125 | ), 126 | SizedBox(width: 8.0), 127 | IconButton( 128 | onPressed: () => null, 129 | icon: Icon( 130 | Feather.video, 131 | size: 22.5, 132 | color: colorPrimary, 133 | ), 134 | ), 135 | SizedBox(width: 8.0), 136 | IconButton( 137 | onPressed: () => openDrawer(), 138 | icon: Icon( 139 | Feather.sidebar, 140 | size: 22.5, 141 | color: colorPrimary, 142 | ), 143 | ), 144 | ], 145 | ), 146 | body: Container( 147 | color: mC, 148 | child: Column( 149 | children: [ 150 | Expanded( 151 | child: StreamBuilder( 152 | stream: socketService.getResponse, 153 | builder: (context, AsyncSnapshot snapshot) { 154 | if (!snapshot.hasData) { 155 | return Container(); 156 | } 157 | 158 | return ListView.builder( 159 | //shrinkWrap: true, 160 | reverse: true, 161 | padding: EdgeInsets.only(bottom: 4.0), 162 | controller: socketService.getScrollController, 163 | itemCount: snapshot.data.length, 164 | itemBuilder: (context, index) { 165 | return Container( 166 | padding: EdgeInsets.symmetric(horizontal: 8.0), 167 | child: Row( 168 | mainAxisAlignment: snapshot.data[index]['id'] == myId 169 | ? MainAxisAlignment.end 170 | : MainAxisAlignment.start, 171 | children: [ 172 | _buildMsgLine( 173 | snapshot.data[index]['msg'], 174 | snapshot.data[index]['id'] == myId, 175 | ), 176 | ], 177 | ), 178 | ); 179 | }, 180 | ); 181 | }, 182 | ), 183 | ), 184 | Container( 185 | padding: EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0), 186 | alignment: Alignment.centerLeft, 187 | child: StreamBuilder( 188 | stream: socketService.getTyping, 189 | builder: (context, AsyncSnapshot snapshot) { 190 | if (!snapshot.hasData) { 191 | return Container(); 192 | } 193 | 194 | return snapshot.data['isTyping'] 195 | ? Text( 196 | '${snapshot.data['name']} is typing...', 197 | style: TextStyle( 198 | color: colorPrimary, 199 | fontSize: 15.0, 200 | fontWeight: FontWeight.w400, 201 | ), 202 | ) 203 | : Container(); 204 | }, 205 | ), 206 | ), 207 | Divider( 208 | height: .1, 209 | thickness: .1, 210 | color: colorDarkGrey, 211 | ), 212 | Container( 213 | height: 75.0, 214 | child: Row( 215 | children: [ 216 | Expanded( 217 | child: Container( 218 | margin: EdgeInsets.symmetric( 219 | horizontal: 16.0, 220 | vertical: 12.0, 221 | ), 222 | decoration: BoxDecoration( 223 | borderRadius: BorderRadius.circular( 224 | 30.0, 225 | ), 226 | color: mC, 227 | boxShadow: [ 228 | BoxShadow( 229 | color: mCD, 230 | offset: Offset(2, 2), 231 | blurRadius: 2, 232 | ), 233 | BoxShadow( 234 | color: mCL, 235 | offset: Offset(-2, -2), 236 | blurRadius: 2, 237 | ), 238 | ], 239 | ), 240 | alignment: Alignment.center, 241 | child: TextFormField( 242 | autofocus: true, 243 | focusNode: _focusNode, 244 | controller: _msgController, 245 | onFieldSubmitted: (val) => submitMsg(val), 246 | cursorColor: fCL, 247 | cursorRadius: Radius.circular(30.0), 248 | keyboardType: TextInputType.text, 249 | style: TextStyle( 250 | color: fCL, 251 | fontSize: 15.0, 252 | fontWeight: FontWeight.w400, 253 | ), 254 | onChanged: (val) { 255 | setState(() { 256 | if (val.length == 0) { 257 | if (_flagTyping) { 258 | socketService.isTyping(false); 259 | _flagTyping = false; 260 | } 261 | } else { 262 | if (_flagTyping == false) { 263 | socketService.isTyping(true); 264 | _flagTyping = true; 265 | } 266 | } 267 | _msg = val.trim(); 268 | }); 269 | }, 270 | textAlign: TextAlign.start, 271 | decoration: InputDecoration( 272 | contentPadding: EdgeInsets.only( 273 | bottom: .0, 274 | left: 24.0, 275 | ), 276 | border: InputBorder.none, 277 | hintText: "Type a message...", 278 | hintStyle: TextStyle( 279 | color: fCL, 280 | fontSize: 15.0, 281 | fontWeight: FontWeight.w400, 282 | ), 283 | ), 284 | ), 285 | ), 286 | ), 287 | IconButton( 288 | onPressed: () => submitMsg(_msg), 289 | icon: Icon( 290 | Feather.send, 291 | color: _msg.length == 0 ? fCD : colorPrimary, 292 | size: 30.0, 293 | ), 294 | ), 295 | SizedBox(width: 20.0), 296 | ], 297 | ), 298 | ), 299 | ], 300 | ), 301 | ), 302 | ); 303 | } 304 | 305 | Widget _buildMsgLine(msg, isMe) { 306 | return Container( 307 | padding: EdgeInsets.symmetric( 308 | horizontal: 26.0, 309 | vertical: 14.0, 310 | ), 311 | margin: EdgeInsets.only(top: 8.0), 312 | decoration: BoxDecoration( 313 | color: isMe ? colorPrimary : mC, 314 | borderRadius: BorderRadius.circular(30.0), 315 | boxShadow: [ 316 | BoxShadow( 317 | color: mCD, 318 | offset: Offset(2, 2), 319 | blurRadius: 2, 320 | ), 321 | BoxShadow( 322 | color: mCL, 323 | offset: Offset(-2, -2), 324 | blurRadius: 2, 325 | ), 326 | ], 327 | ), 328 | child: Row( 329 | children: [ 330 | Text( 331 | msg, 332 | style: TextStyle( 333 | color: isMe ? mCL : colorTitle, 334 | fontSize: 15.0, 335 | fontWeight: FontWeight.w400, 336 | ), 337 | ), 338 | ], 339 | ), 340 | ); 341 | } 342 | } 343 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXCopyFilesBuildPhase section */ 19 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 20 | isa = PBXCopyFilesBuildPhase; 21 | buildActionMask = 2147483647; 22 | dstPath = ""; 23 | dstSubfolderSpec = 10; 24 | files = ( 25 | ); 26 | name = "Embed Frameworks"; 27 | runOnlyForDeploymentPostprocessing = 0; 28 | }; 29 | /* End PBXCopyFilesBuildPhase section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 33 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 34 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 35 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 36 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 37 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 38 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 39 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 40 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 42 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 43 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 44 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXFrameworksBuildPhase section */ 56 | 57 | /* Begin PBXGroup section */ 58 | 9740EEB11CF90186004384FC /* Flutter */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 62 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 63 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 64 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 65 | ); 66 | name = Flutter; 67 | sourceTree = ""; 68 | }; 69 | 97C146E51CF9000F007C117D = { 70 | isa = PBXGroup; 71 | children = ( 72 | 9740EEB11CF90186004384FC /* Flutter */, 73 | 97C146F01CF9000F007C117D /* Runner */, 74 | 97C146EF1CF9000F007C117D /* Products */, 75 | ); 76 | sourceTree = ""; 77 | }; 78 | 97C146EF1CF9000F007C117D /* Products */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 97C146EE1CF9000F007C117D /* Runner.app */, 82 | ); 83 | name = Products; 84 | sourceTree = ""; 85 | }; 86 | 97C146F01CF9000F007C117D /* Runner */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 90 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 91 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 92 | 97C147021CF9000F007C117D /* Info.plist */, 93 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 94 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 95 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 96 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 97 | ); 98 | path = Runner; 99 | sourceTree = ""; 100 | }; 101 | /* End PBXGroup section */ 102 | 103 | /* Begin PBXNativeTarget section */ 104 | 97C146ED1CF9000F007C117D /* Runner */ = { 105 | isa = PBXNativeTarget; 106 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 107 | buildPhases = ( 108 | 9740EEB61CF901F6004384FC /* Run Script */, 109 | 97C146EA1CF9000F007C117D /* Sources */, 110 | 97C146EB1CF9000F007C117D /* Frameworks */, 111 | 97C146EC1CF9000F007C117D /* Resources */, 112 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 113 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 114 | ); 115 | buildRules = ( 116 | ); 117 | dependencies = ( 118 | ); 119 | name = Runner; 120 | productName = Runner; 121 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 122 | productType = "com.apple.product-type.application"; 123 | }; 124 | /* End PBXNativeTarget section */ 125 | 126 | /* Begin PBXProject section */ 127 | 97C146E61CF9000F007C117D /* Project object */ = { 128 | isa = PBXProject; 129 | attributes = { 130 | LastUpgradeCheck = 1020; 131 | ORGANIZATIONNAME = ""; 132 | TargetAttributes = { 133 | 97C146ED1CF9000F007C117D = { 134 | CreatedOnToolsVersion = 7.3.1; 135 | LastSwiftMigration = 1100; 136 | }; 137 | }; 138 | }; 139 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 140 | compatibilityVersion = "Xcode 9.3"; 141 | developmentRegion = en; 142 | hasScannedForEncodings = 0; 143 | knownRegions = ( 144 | en, 145 | Base, 146 | ); 147 | mainGroup = 97C146E51CF9000F007C117D; 148 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 149 | projectDirPath = ""; 150 | projectRoot = ""; 151 | targets = ( 152 | 97C146ED1CF9000F007C117D /* Runner */, 153 | ); 154 | }; 155 | /* End PBXProject section */ 156 | 157 | /* Begin PBXResourcesBuildPhase section */ 158 | 97C146EC1CF9000F007C117D /* Resources */ = { 159 | isa = PBXResourcesBuildPhase; 160 | buildActionMask = 2147483647; 161 | files = ( 162 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 163 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 164 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 165 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | /* End PBXResourcesBuildPhase section */ 170 | 171 | /* Begin PBXShellScriptBuildPhase section */ 172 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 173 | isa = PBXShellScriptBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | ); 177 | inputPaths = ( 178 | ); 179 | name = "Thin Binary"; 180 | outputPaths = ( 181 | ); 182 | runOnlyForDeploymentPostprocessing = 0; 183 | shellPath = /bin/sh; 184 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 185 | }; 186 | 9740EEB61CF901F6004384FC /* Run Script */ = { 187 | isa = PBXShellScriptBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | ); 191 | inputPaths = ( 192 | ); 193 | name = "Run Script"; 194 | outputPaths = ( 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | shellPath = /bin/sh; 198 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 199 | }; 200 | /* End PBXShellScriptBuildPhase section */ 201 | 202 | /* Begin PBXSourcesBuildPhase section */ 203 | 97C146EA1CF9000F007C117D /* Sources */ = { 204 | isa = PBXSourcesBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 208 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 209 | ); 210 | runOnlyForDeploymentPostprocessing = 0; 211 | }; 212 | /* End PBXSourcesBuildPhase section */ 213 | 214 | /* Begin PBXVariantGroup section */ 215 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 216 | isa = PBXVariantGroup; 217 | children = ( 218 | 97C146FB1CF9000F007C117D /* Base */, 219 | ); 220 | name = Main.storyboard; 221 | sourceTree = ""; 222 | }; 223 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 224 | isa = PBXVariantGroup; 225 | children = ( 226 | 97C147001CF9000F007C117D /* Base */, 227 | ); 228 | name = LaunchScreen.storyboard; 229 | sourceTree = ""; 230 | }; 231 | /* End PBXVariantGroup section */ 232 | 233 | /* Begin XCBuildConfiguration section */ 234 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 235 | isa = XCBuildConfiguration; 236 | buildSettings = { 237 | ALWAYS_SEARCH_USER_PATHS = NO; 238 | CLANG_ANALYZER_NONNULL = YES; 239 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 240 | CLANG_CXX_LIBRARY = "libc++"; 241 | CLANG_ENABLE_MODULES = YES; 242 | CLANG_ENABLE_OBJC_ARC = YES; 243 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 244 | CLANG_WARN_BOOL_CONVERSION = YES; 245 | CLANG_WARN_COMMA = YES; 246 | CLANG_WARN_CONSTANT_CONVERSION = YES; 247 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 249 | CLANG_WARN_EMPTY_BODY = YES; 250 | CLANG_WARN_ENUM_CONVERSION = YES; 251 | CLANG_WARN_INFINITE_RECURSION = YES; 252 | CLANG_WARN_INT_CONVERSION = YES; 253 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 254 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 255 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 257 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 258 | CLANG_WARN_STRICT_PROTOTYPES = YES; 259 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 260 | CLANG_WARN_UNREACHABLE_CODE = YES; 261 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 262 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 263 | COPY_PHASE_STRIP = NO; 264 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 265 | ENABLE_NS_ASSERTIONS = NO; 266 | ENABLE_STRICT_OBJC_MSGSEND = YES; 267 | GCC_C_LANGUAGE_STANDARD = gnu99; 268 | GCC_NO_COMMON_BLOCKS = YES; 269 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 270 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 271 | GCC_WARN_UNDECLARED_SELECTOR = YES; 272 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 273 | GCC_WARN_UNUSED_FUNCTION = YES; 274 | GCC_WARN_UNUSED_VARIABLE = YES; 275 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 276 | MTL_ENABLE_DEBUG_INFO = NO; 277 | SDKROOT = iphoneos; 278 | SUPPORTED_PLATFORMS = iphoneos; 279 | TARGETED_DEVICE_FAMILY = "1,2"; 280 | VALIDATE_PRODUCT = YES; 281 | }; 282 | name = Profile; 283 | }; 284 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 285 | isa = XCBuildConfiguration; 286 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 287 | buildSettings = { 288 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 289 | CLANG_ENABLE_MODULES = YES; 290 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 291 | ENABLE_BITCODE = NO; 292 | INFOPLIST_FILE = Runner/Info.plist; 293 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 294 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterChatSocket; 295 | PRODUCT_NAME = "$(TARGET_NAME)"; 296 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 297 | SWIFT_VERSION = 5.0; 298 | VERSIONING_SYSTEM = "apple-generic"; 299 | }; 300 | name = Profile; 301 | }; 302 | 97C147031CF9000F007C117D /* Debug */ = { 303 | isa = XCBuildConfiguration; 304 | buildSettings = { 305 | ALWAYS_SEARCH_USER_PATHS = NO; 306 | CLANG_ANALYZER_NONNULL = YES; 307 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 308 | CLANG_CXX_LIBRARY = "libc++"; 309 | CLANG_ENABLE_MODULES = YES; 310 | CLANG_ENABLE_OBJC_ARC = YES; 311 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 312 | CLANG_WARN_BOOL_CONVERSION = YES; 313 | CLANG_WARN_COMMA = YES; 314 | CLANG_WARN_CONSTANT_CONVERSION = YES; 315 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 316 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 317 | CLANG_WARN_EMPTY_BODY = YES; 318 | CLANG_WARN_ENUM_CONVERSION = YES; 319 | CLANG_WARN_INFINITE_RECURSION = YES; 320 | CLANG_WARN_INT_CONVERSION = YES; 321 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 322 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 323 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 324 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 325 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 326 | CLANG_WARN_STRICT_PROTOTYPES = YES; 327 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 328 | CLANG_WARN_UNREACHABLE_CODE = YES; 329 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 330 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 331 | COPY_PHASE_STRIP = NO; 332 | DEBUG_INFORMATION_FORMAT = dwarf; 333 | ENABLE_STRICT_OBJC_MSGSEND = YES; 334 | ENABLE_TESTABILITY = YES; 335 | GCC_C_LANGUAGE_STANDARD = gnu99; 336 | GCC_DYNAMIC_NO_PIC = NO; 337 | GCC_NO_COMMON_BLOCKS = YES; 338 | GCC_OPTIMIZATION_LEVEL = 0; 339 | GCC_PREPROCESSOR_DEFINITIONS = ( 340 | "DEBUG=1", 341 | "$(inherited)", 342 | ); 343 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 344 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 345 | GCC_WARN_UNDECLARED_SELECTOR = YES; 346 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 347 | GCC_WARN_UNUSED_FUNCTION = YES; 348 | GCC_WARN_UNUSED_VARIABLE = YES; 349 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 350 | MTL_ENABLE_DEBUG_INFO = YES; 351 | ONLY_ACTIVE_ARCH = YES; 352 | SDKROOT = iphoneos; 353 | TARGETED_DEVICE_FAMILY = "1,2"; 354 | }; 355 | name = Debug; 356 | }; 357 | 97C147041CF9000F007C117D /* Release */ = { 358 | isa = XCBuildConfiguration; 359 | buildSettings = { 360 | ALWAYS_SEARCH_USER_PATHS = NO; 361 | CLANG_ANALYZER_NONNULL = YES; 362 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 363 | CLANG_CXX_LIBRARY = "libc++"; 364 | CLANG_ENABLE_MODULES = YES; 365 | CLANG_ENABLE_OBJC_ARC = YES; 366 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 367 | CLANG_WARN_BOOL_CONVERSION = YES; 368 | CLANG_WARN_COMMA = YES; 369 | CLANG_WARN_CONSTANT_CONVERSION = YES; 370 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 371 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 372 | CLANG_WARN_EMPTY_BODY = YES; 373 | CLANG_WARN_ENUM_CONVERSION = YES; 374 | CLANG_WARN_INFINITE_RECURSION = YES; 375 | CLANG_WARN_INT_CONVERSION = YES; 376 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 377 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 378 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 379 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 380 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 381 | CLANG_WARN_STRICT_PROTOTYPES = YES; 382 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 383 | CLANG_WARN_UNREACHABLE_CODE = YES; 384 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 385 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 386 | COPY_PHASE_STRIP = NO; 387 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 388 | ENABLE_NS_ASSERTIONS = NO; 389 | ENABLE_STRICT_OBJC_MSGSEND = YES; 390 | GCC_C_LANGUAGE_STANDARD = gnu99; 391 | GCC_NO_COMMON_BLOCKS = YES; 392 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 393 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 394 | GCC_WARN_UNDECLARED_SELECTOR = YES; 395 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 396 | GCC_WARN_UNUSED_FUNCTION = YES; 397 | GCC_WARN_UNUSED_VARIABLE = YES; 398 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 399 | MTL_ENABLE_DEBUG_INFO = NO; 400 | SDKROOT = iphoneos; 401 | SUPPORTED_PLATFORMS = iphoneos; 402 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 403 | TARGETED_DEVICE_FAMILY = "1,2"; 404 | VALIDATE_PRODUCT = YES; 405 | }; 406 | name = Release; 407 | }; 408 | 97C147061CF9000F007C117D /* Debug */ = { 409 | isa = XCBuildConfiguration; 410 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 411 | buildSettings = { 412 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 413 | CLANG_ENABLE_MODULES = YES; 414 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 415 | ENABLE_BITCODE = NO; 416 | INFOPLIST_FILE = Runner/Info.plist; 417 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 418 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterChatSocket; 419 | PRODUCT_NAME = "$(TARGET_NAME)"; 420 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 421 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 422 | SWIFT_VERSION = 5.0; 423 | VERSIONING_SYSTEM = "apple-generic"; 424 | }; 425 | name = Debug; 426 | }; 427 | 97C147071CF9000F007C117D /* Release */ = { 428 | isa = XCBuildConfiguration; 429 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 430 | buildSettings = { 431 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 432 | CLANG_ENABLE_MODULES = YES; 433 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 434 | ENABLE_BITCODE = NO; 435 | INFOPLIST_FILE = Runner/Info.plist; 436 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 437 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterChatSocket; 438 | PRODUCT_NAME = "$(TARGET_NAME)"; 439 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 440 | SWIFT_VERSION = 5.0; 441 | VERSIONING_SYSTEM = "apple-generic"; 442 | }; 443 | name = Release; 444 | }; 445 | /* End XCBuildConfiguration section */ 446 | 447 | /* Begin XCConfigurationList section */ 448 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 449 | isa = XCConfigurationList; 450 | buildConfigurations = ( 451 | 97C147031CF9000F007C117D /* Debug */, 452 | 97C147041CF9000F007C117D /* Release */, 453 | 249021D3217E4FDB00AE95B9 /* Profile */, 454 | ); 455 | defaultConfigurationIsVisible = 0; 456 | defaultConfigurationName = Release; 457 | }; 458 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 459 | isa = XCConfigurationList; 460 | buildConfigurations = ( 461 | 97C147061CF9000F007C117D /* Debug */, 462 | 97C147071CF9000F007C117D /* Release */, 463 | 249021D4217E4FDB00AE95B9 /* Profile */, 464 | ); 465 | defaultConfigurationIsVisible = 0; 466 | defaultConfigurationName = Release; 467 | }; 468 | /* End XCConfigurationList section */ 469 | }; 470 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 471 | } 472 | --------------------------------------------------------------------------------