Browse Source

ios 消息保存,socket消息发送

dart3_last
zsw 4 months ago
parent
commit
6817afca8b
  1. 26
      ios/Podfile.lock
  2. 15
      ios/Runner.xcodeproj/project.pbxproj
  3. 61
      lib/im/SocketClient.dart
  4. 1
      lib/im/chat_details_page.dart
  5. 18
      lib/im/database/hx_database.dart
  6. 144
      lib/im/database/hx_database.g.dart
  7. 61
      lib/im/database/message.dart
  8. 17
      lib/im/database/message_dao.dart
  9. 297
      lib/im/im_view/im_page.dart
  10. 7
      lib/main.dart
  11. 21
      lib/main_page.dart
  12. 3
      lib/message/mine_message.dart
  13. 366
      pubspec.lock
  14. 2
      pubspec.yaml

26
ios/Podfile.lock

@ -22,6 +22,9 @@ PODS:
- fluwx (0.0.1): - fluwx (0.0.1):
- Flutter - Flutter
- "OpenWeChatSDK (~> 1.9.2+1)" - "OpenWeChatSDK (~> 1.9.2+1)"
- FMDB (2.7.11):
- FMDB/standard (= 2.7.11)
- FMDB/standard (2.7.11)
- geolocator (6.2.0): - geolocator (6.2.0):
- Flutter - Flutter
- image_gallery_saver (2.0.2): - image_gallery_saver (2.0.2):
@ -56,7 +59,7 @@ PODS:
- "OpenWeChatSDK (1.9.9+1)" - "OpenWeChatSDK (1.9.9+1)"
- package_info (0.0.1): - package_info (0.0.1):
- Flutter - Flutter
- path_provider (0.0.1): - path_provider_ios (0.0.1):
- Flutter - Flutter
- "permission_handler (5.1.0+2)": - "permission_handler (5.1.0+2)":
- Flutter - Flutter
@ -76,6 +79,9 @@ PODS:
- mob_sharesdk/ShareSDKPlatforms/Line - mob_sharesdk/ShareSDKPlatforms/Line
- mob_sharesdk/ShareSDKPlatforms/WeChat_Lite - mob_sharesdk/ShareSDKPlatforms/WeChat_Lite
- mob_sharesdk/ShareSDKUI - mob_sharesdk/ShareSDKUI
- sqflite (0.0.3):
- Flutter
- FMDB (>= 2.7.5)
- SSZipArchive (2.4.3) - SSZipArchive (2.4.3)
- tobias (0.0.1): - tobias (0.0.1):
- Flutter - Flutter
@ -111,11 +117,12 @@ DEPENDENCIES:
- image_pickers (from `.symlinks/plugins/image_pickers/ios`) - image_pickers (from `.symlinks/plugins/image_pickers/ios`)
- number_precision (from `.symlinks/plugins/number_precision/ios`) - number_precision (from `.symlinks/plugins/number_precision/ios`)
- package_info (from `.symlinks/plugins/package_info/ios`) - package_info (from `.symlinks/plugins/package_info/ios`)
- path_provider (from `.symlinks/plugins/path_provider/ios`) - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
- permission_handler (from `.symlinks/plugins/permission_handler/ios`) - permission_handler (from `.symlinks/plugins/permission_handler/ios`)
- scan (from `.symlinks/plugins/scan/ios`) - scan (from `.symlinks/plugins/scan/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`)
- sharesdk_plugin (from `.symlinks/plugins/sharesdk_plugin/ios`) - sharesdk_plugin (from `.symlinks/plugins/sharesdk_plugin/ios`)
- sqflite (from `.symlinks/plugins/sqflite/ios`)
- SSZipArchive (~> 2.4.2) - SSZipArchive (~> 2.4.2)
- tobias (from `.symlinks/plugins/tobias/ios`) - tobias (from `.symlinks/plugins/tobias/ios`)
- tpns_flutter_plugin (from `.symlinks/plugins/tpns_flutter_plugin/ios`) - tpns_flutter_plugin (from `.symlinks/plugins/tpns_flutter_plugin/ios`)
@ -128,6 +135,7 @@ DEPENDENCIES:
SPEC REPOS: SPEC REPOS:
https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git: https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git:
- AFNetworking - AFNetworking
- FMDB
- mob_sharesdk - mob_sharesdk
- MOBFoundation - MOBFoundation
- OpenWeChatSDK - OpenWeChatSDK
@ -157,8 +165,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/number_precision/ios" :path: ".symlinks/plugins/number_precision/ios"
package_info: package_info:
:path: ".symlinks/plugins/package_info/ios" :path: ".symlinks/plugins/package_info/ios"
path_provider: path_provider_ios:
:path: ".symlinks/plugins/path_provider/ios" :path: ".symlinks/plugins/path_provider_ios/ios"
permission_handler: permission_handler:
:path: ".symlinks/plugins/permission_handler/ios" :path: ".symlinks/plugins/permission_handler/ios"
scan: scan:
@ -167,6 +175,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/shared_preferences_foundation/ios" :path: ".symlinks/plugins/shared_preferences_foundation/ios"
sharesdk_plugin: sharesdk_plugin:
:path: ".symlinks/plugins/sharesdk_plugin/ios" :path: ".symlinks/plugins/sharesdk_plugin/ios"
sqflite:
:path: ".symlinks/plugins/sqflite/ios"
tobias: tobias:
:path: ".symlinks/plugins/tobias/ios" :path: ".symlinks/plugins/tobias/ios"
tpns_flutter_plugin: tpns_flutter_plugin:
@ -188,6 +198,7 @@ SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_pdfview: 25f53dd6097661e6395b17de506e6060585946bd flutter_pdfview: 25f53dd6097661e6395b17de506e6060585946bd
fluwx: 79c66b6d795ab8208262ada215d9e60388cfe492 fluwx: 79c66b6d795ab8208262ada215d9e60388cfe492
FMDB: 57486c1117fd8e0e6b947b2f54c3f42bf8e57a4e
geolocator: f5e3de65e241caba7ce3e8a618803387bda73384 geolocator: f5e3de65e241caba7ce3e8a618803387bda73384
image_gallery_saver: cb43cc43141711190510e92c460eb1655cd343cb image_gallery_saver: cb43cc43141711190510e92c460eb1655cd343cb
image_pickers: 25c8916d358bc9d2707cb470ba3d57497f105773 image_pickers: 25c8916d358bc9d2707cb470ba3d57497f105773
@ -196,12 +207,13 @@ SPEC CHECKSUMS:
number_precision: 26fa2be2212f9d1429f92d667d6b0aa4df0058d8 number_precision: 26fa2be2212f9d1429f92d667d6b0aa4df0058d8
OpenWeChatSDK: ea48e9db20645f78128db9091893910280b8e4b1 OpenWeChatSDK: ea48e9db20645f78128db9091893910280b8e4b1
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0 permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0
scan: aea35bb4aa59ccc8839c576a18cd57c7d492cc86 scan: aea35bb4aa59ccc8839c576a18cd57c7d492cc86
SDWebImage: e5cc87bf736e60f49592f307bdf9e157189298a3 SDWebImage: e5cc87bf736e60f49592f307bdf9e157189298a3
shared_preferences_foundation: 986fc17f3d3251412d18b0265f9c64113a8c2472 shared_preferences_foundation: 986fc17f3d3251412d18b0265f9c64113a8c2472
sharesdk_plugin: f29a6f471ae1c253e96636d62106c3f8d793948c sharesdk_plugin: f29a6f471ae1c253e96636d62106c3f8d793948c
sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
tobias: 2aded9b83e3663b907360a800d8e3c13284f25c5 tobias: 2aded9b83e3663b907360a800d8e3c13284f25c5
TPNS-iOS: 36c335eff80670de6ede780ab827f679d78f64ff TPNS-iOS: 36c335eff80670de6ede780ab827f679d78f64ff
@ -209,8 +221,8 @@ SPEC CHECKSUMS:
UMCommon: 47e0b53f6a36568e958a5abd005ed7577fcac9ad UMCommon: 47e0b53f6a36568e958a5abd005ed7577fcac9ad
UMDevice: 9ef8045b59e0479cff7062915c879a1af46fa094 UMDevice: 9ef8045b59e0479cff7062915c879a1af46fa094
umeng_common_sdk: a8abd7f86dfd013dbbeeae587ee143760c6582f2 umeng_common_sdk: a8abd7f86dfd013dbbeeae587ee143760c6582f2
url_launcher: a1c0cc845906122c4784c542523d8cacbded5626 url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
video_player_avfoundation: 6d971a232d72e6ee25368378d48a079dea01f1cf video_player_avfoundation: 81e49bb3d9fb63dccf9fa0f6d877dc3ddbeac126
wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f
webview_flutter: 5fb4def2bbd4339889ee14d045b605cefc5bc232 webview_flutter: 5fb4def2bbd4339889ee14d045b605cefc5bc232
ZLPhotoBrowser-objc: c7657d3bc85ae231884e058d0e3638f619164736 ZLPhotoBrowser-objc: c7657d3bc85ae231884e058d0e3638f619164736

15
ios/Runner.xcodeproj/project.pbxproj

@ -660,12 +660,7 @@
"-ObjC", "-ObjC",
"-l\"c++\"", "-l\"c++\"",
"-l\"image_pickers\"", "-l\"image_pickers\"",
"-l\"path_provider\"",
"-l\"permission_handler\"", "-l\"permission_handler\"",
"-l\"sqlite3\"",
"-l\"wakelock\"",
"-l\"webview_flutter\"",
"-l\"z\"",
"-fcxx-modules", "-fcxx-modules",
"-fmodules", "-fmodules",
"-ld64", "-ld64",
@ -864,12 +859,7 @@
"-ObjC", "-ObjC",
"-l\"c++\"", "-l\"c++\"",
"-l\"image_pickers\"", "-l\"image_pickers\"",
"-l\"path_provider\"",
"-l\"permission_handler\"", "-l\"permission_handler\"",
"-l\"sqlite3\"",
"-l\"wakelock\"",
"-l\"webview_flutter\"",
"-l\"z\"",
"-fcxx-modules", "-fcxx-modules",
"-fmodules", "-fmodules",
"-ld64", "-ld64",
@ -954,12 +944,7 @@
"-ObjC", "-ObjC",
"-l\"c++\"", "-l\"c++\"",
"-l\"image_pickers\"", "-l\"image_pickers\"",
"-l\"path_provider\"",
"-l\"permission_handler\"", "-l\"permission_handler\"",
"-l\"sqlite3\"",
"-l\"wakelock\"",
"-l\"webview_flutter\"",
"-l\"z\"",
"-fcxx-modules", "-fcxx-modules",
"-fmodules", "-fmodules",
"-ld64", "-ld64",

61
lib/im/SocketClient.dart

@ -6,27 +6,45 @@ import 'dart:io';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:huixiang/im/Proto.dart'; import 'package:huixiang/im/Proto.dart';
import 'package:huixiang/im/database/message.dart';
import 'package:huixiang/im/out/auth.pb.dart'; import 'package:huixiang/im/out/auth.pb.dart';
import 'package:huixiang/im/out/message.pb.dart'; import 'package:huixiang/im/out/message.pb.dart';
import 'package:huixiang/main.dart';
import 'package:shared_preferences/shared_preferences.dart';
class SocketClient { class SocketClient {
Socket _socket; Socket _socket;
SharedPreferences shared;
connect() async { connect() async {
_socket = await Socket.connect('192.168.10.129', 9090); shared = await SharedPreferences.getInstance();
_socket.listen((data) {
print(data); await Socket.connect('192.168.10.129', 9090).then((value) {
print("socket-listen"); debugPrint("socket-connect");
Proto proto = Proto.fromBytes(data); _socket = value;
print("socket-listen: $proto"); _socket.listen((data) {
MsgData data1 = MsgData.fromBuffer(proto.body); print(data);
print('收到来自:${data1.from},消息内容: ${utf8.decode(data1.data)} '); print("socket-listen");
Proto proto = Proto.fromBytes(data);
callbacks.forEach((callback) { print("socket-listen: $proto");
callback.call(data1); MsgData data1 = MsgData.fromBuffer(proto.body);
print('收到来自:${data1.from},消息内容: ${utf8.decode(data1.data)} ');
hxDatabase.messageDao.insertMessage(createMessage(mobile, utf8.decode(data1.data), userId: data1.from));
callbacks.forEach((callback) {
callback.call(data1);
});
}, onError: (Object error, StackTrace stackTrace) {
debugPrint("socket-error: $error, stackTrace: ${stackTrace}");
}); });
authRequest(shared.getString("token"));
}).catchError((error) {
debugPrint("socket-connect-error: $error");
}); });
} }
@ -40,27 +58,35 @@ class SocketClient {
callbacks.remove(callback); callbacks.remove(callback);
} }
dispose() {
_socket.close();
}
authRequest(String token) { authRequest(String token) {
if (!checkSocket()) { if (!checkSocket()) {
return; return;
} }
final authReq = AuthReq() final authReq = AuthReq()
..uid = 1 ..uid = mobile
..token = '123456'; ..token = token;
final authReqBytes = authReq.writeToBuffer(); final authReqBytes = authReq.writeToBuffer();
final proto = Proto(1, 1, authReqBytes); // operation seqId 1 final proto = Proto(1, 1, authReqBytes); // operation seqId 1
final protoBytes = proto.toBytes(); final protoBytes = proto.toBytes();
_socket.add(protoBytes); _socket.add(protoBytes);
} }
sendMessage(var to, String content) { sendMessage(int toId, String content) {
if (!checkSocket()) { if (!checkSocket()) {
return; return;
} }
Uint8List data = utf8.encode(content); Uint8List data = utf8.encode(content);
MsgData msgData = MsgData(to: to,from: 2,type: MsgType.SINGLE_TEXT,data: data); MsgData msgData = MsgData(to: toId, from: mobile, type: MsgType.SINGLE_TEXT,data: data);
final proto2 = Proto(5,1,msgData.writeToBuffer()); final proto2 = Proto(5, 1, msgData.writeToBuffer());
_socket.add(proto2.toBytes()); _socket.add(proto2.toBytes());
hxDatabase.messageDao.insertMessage(createMessage(toId, content, userId: mobile)).catchError((error) {
debugPrint("insertMessage: $error");
});
debugPrint("insertMessage: end");
} }
checkSocket() { checkSocket() {
@ -71,4 +97,7 @@ class SocketClient {
return true; return true;
} }
get mobile => 123456;
} }

1
lib/im/chat_details_page.dart

@ -7,6 +7,7 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:huixiang/main.dart';
import 'package:huixiang/retrofit/retrofit_api.dart'; import 'package:huixiang/retrofit/retrofit_api.dart';
import 'package:huixiang/view_widget/my_appbar.dart'; import 'package:huixiang/view_widget/my_appbar.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';

18
lib/im/database/hx_database.dart

@ -0,0 +1,18 @@
import 'dart:async';
import 'package:floor/floor.dart';
import 'package:flutter/cupertino.dart';
import 'package:huixiang/im/database/message_dao.dart';
import 'package:huixiang/im/database/message.dart';
import 'package:sqflite/sqflite.dart' as sqflite;
part 'hx_database.g.dart';
@Database(version: 1, entities: [Message])
abstract class HxDatabase extends FloorDatabase {
MessageDao get messageDao;
}

144
lib/im/database/hx_database.g.dart

@ -0,0 +1,144 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'hx_database.dart';
// **************************************************************************
// FloorGenerator
// **************************************************************************
// ignore: avoid_classes_with_only_static_members
class $FloorHxDatabase {
/// Creates a database builder for a persistent database.
/// Once a database is built, you should keep a reference to it and re-use it.
static _$HxDatabaseBuilder databaseBuilder(String name) =>
_$HxDatabaseBuilder(name);
/// Creates a database builder for an in memory database.
/// Information stored in an in memory database disappears when the process is killed.
/// Once a database is built, you should keep a reference to it and re-use it.
static _$HxDatabaseBuilder inMemoryDatabaseBuilder() =>
_$HxDatabaseBuilder(null);
}
class _$HxDatabaseBuilder {
_$HxDatabaseBuilder(this.name);
final String name;
final List<Migration> _migrations = [];
Callback _callback;
/// Adds migrations to the builder.
_$HxDatabaseBuilder addMigrations(List<Migration> migrations) {
_migrations.addAll(migrations);
return this;
}
/// Adds a database [Callback] to the builder.
_$HxDatabaseBuilder addCallback(Callback callback) {
_callback = callback;
return this;
}
/// Creates the database and initializes it.
Future<HxDatabase> build() async {
final path = name != null
? await sqfliteDatabaseFactory.getDatabasePath(name)
: ':memory:';
final database = _$HxDatabase();
database.database = await database.open(
path,
_migrations,
_callback,
);
return database;
}
}
class _$HxDatabase extends HxDatabase {
_$HxDatabase([StreamController<String> listener]) {
changeListener = listener ?? StreamController<String>.broadcast();
}
MessageDao _messageDaoInstance;
Future<sqflite.Database> open(
String path,
List<Migration> migrations, [
Callback callback,
]) async {
final databaseOptions = sqflite.OpenDatabaseOptions(
version: 1,
onConfigure: (database) async {
await database.execute('PRAGMA foreign_keys = ON');
await callback?.onConfigure?.call(database);
},
onOpen: (database) async {
await callback?.onOpen?.call(database);
},
onUpgrade: (database, startVersion, endVersion) async {
await MigrationAdapter.runMigrations(
database, startVersion, endVersion, migrations);
await callback?.onUpgrade?.call(database, startVersion, endVersion);
},
onCreate: (database, version) async {
await database.execute(
'CREATE TABLE IF NOT EXISTS `Message` (`id` INTEGER, `fromId` INTEGER, `toId` INTEGER, `content` TEXT, `attach` TEXT, `msgType` INTEGER, `time` INTEGER, `state` INTEGER, `isDelete` INTEGER, PRIMARY KEY (`id`))');
await callback?.onCreate?.call(database, version);
},
);
return sqfliteDatabaseFactory.openDatabase(path, options: databaseOptions);
}
@override
MessageDao get messageDao {
return _messageDaoInstance ??= _$MessageDao(database, changeListener);
}
}
class _$MessageDao extends MessageDao {
_$MessageDao(
this.database,
this.changeListener,
) : _queryAdapter = QueryAdapter(database, changeListener),
_messageInsertionAdapter = InsertionAdapter(
database,
'Message',
(Message item) => item.toJson(),
changeListener);
final sqflite.DatabaseExecutor database;
final StreamController<String> changeListener;
final QueryAdapter _queryAdapter;
final InsertionAdapter<Message> _messageInsertionAdapter;
@override
Stream<List<Message>> findMessageByToId(int toId) {
return _queryAdapter.queryListStream(
'SELECT * FROM Message WHERE toId = ?1',
mapper: (Map<String, Object> row) => Message.fromJson(row),
arguments: [toId],
queryableName: 'Message',
isView: false);
}
@override
Future<List<Message>> findMessageByGroup(int userId) {
debugPrint("findMessageByGroup: $userId");
return _queryAdapter.queryList(
'SELECT * FROM Message WHERE toId = ?1 OR fromId = ?2 GROUP BY toId,fromId ORDER BY time DESC',
mapper: (Map<String, Object> row) => Message.fromJson(row),
arguments: [userId, userId]);
}
@override
Future<void> insertMessage(Message message) async {
await _messageInsertionAdapter.insert(message, OnConflictStrategy.abort);
}
}

61
lib/im/database/message.dart

@ -0,0 +1,61 @@
import 'package:floor/floor.dart';
@entity
class Message {
@primaryKey
int id;
int fromId;
int toId;
String content;
String attach;
int msgType;
int time;
int state;
int isDelete;
Message(id, fromId, toId, content, attach, msgType, time, state, isDelete);
factory Message.fromJson(Map<String, dynamic> json) => Message(
json["id"],
json["fromId"],
json["toId"],
json["content"],
json["attach"],
json["msgType"],
json["time"],
json["state"],
json["isDelete"]);
Map<String, dynamic> toJson() => <String, dynamic>{
"id": id,
"fromId": fromId,
"toId": toId,
"content": content,
"attach": attach,
"msgType": msgType,
"time": time,
"state": state,
"isDelete": isDelete == null ? 0 : isDelete
};
}
createMessage(var toId, String content, {String attach, int msgType, userId}) {
return Message.fromJson(<String, dynamic>{
"fromId": userId,
"toId": toId,
"content": content,
"attach": attach,
"msgType": msgType ?? 0,
"time": DateTime.now().millisecondsSinceEpoch,
"state": 0,
"isDelete": 0
});
}

17
lib/im/database/message_dao.dart

@ -0,0 +1,17 @@
import 'package:floor/floor.dart';
import 'package:huixiang/im/database/message.dart';
@dao
abstract class MessageDao {
@Query('SELECT * FROM Message WHERE toId = :toId')
Stream<List<Message>> findMessageByToId(int toId);
@insert
Future<void> insertMessage(Message message);
@Query('SELECT * FROM Message WHERE toId = :userId OR fromId = :userId GROUP BY toId,fromId ORDER BY time DESC')
Future<List<Message>> findMessageByGroup(int userId);
}

297
lib/im/im_view/im_page.dart

@ -1,9 +1,12 @@
import 'dart:async';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:huixiang/generated/l10n.dart'; import 'package:huixiang/generated/l10n.dart';
import 'package:huixiang/im/database/message.dart';
import 'package:huixiang/main.dart';
import 'package:huixiang/retrofit/data/base_data.dart'; import 'package:huixiang/retrofit/data/base_data.dart';
import 'package:huixiang/retrofit/data/message.dart';
import 'package:huixiang/retrofit/data/msg_stats.dart'; import 'package:huixiang/retrofit/data/msg_stats.dart';
import 'package:huixiang/retrofit/data/page.dart'; import 'package:huixiang/retrofit/data/page.dart';
import 'package:huixiang/retrofit/retrofit_api.dart'; import 'package:huixiang/retrofit/retrofit_api.dart';
@ -18,8 +21,8 @@ import 'on_chat_message.dart';
import 'on_chat_msg_instance.dart'; import 'on_chat_msg_instance.dart';
class IMPage extends StatefulWidget { class IMPage extends StatefulWidget {
IMPage(Key key) : super(key: key);
IMPage(Key key): super(key: key);
@override @override
State<StatefulWidget> createState() { State<StatefulWidget> createState() {
return _IMPage(); return _IMPage();
@ -42,7 +45,7 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
final TextEditingController imEditingController = TextEditingController(); final TextEditingController imEditingController = TextEditingController();
@override @override
void onMessage(txt){ void onMessage(txt) {
// SmartDialog.showToast("列表 $txt", alignment: Alignment.center); // SmartDialog.showToast("列表 $txt", alignment: Alignment.center);
} }
@ -57,57 +60,87 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
super.initState(); super.initState();
OnChatMsgInstance.instance.onChatMessage = this; OnChatMsgInstance.instance.onChatMessage = this;
loadMessageList();
SharedPreferences.getInstance().then((value) { SharedPreferences.getInstance().then((value) {
apiService = apiService =
ApiService(Dio(), token: value.getString("token"), context: context); ApiService(Dio(), token: value.getString("token"), context: context);
queryMessage();
queryMsgStats(); queryMsgStats();
}); });
} }
_refresh() { _refresh() {
pageNum = 1; pageNum = 1;
queryMessage(); loadMessageList();
queryMsgStats(); queryMsgStats();
} }
queryMessage() async { List<int> userIds = [];
BaseData<PageInfo<Message>> baseData = await apiService.msgList({
"pageNum": pageNum, Stream streamSubscription ;
"pageSize": 10,
"searchKey": "", loadMessageList() async {
"state": "", int userId = 123456;
"typed": ""
}).catchError((onError) { hxDatabase.changeListener.stream.listen((event) {
_refreshController.loadFailed(); debugPrint("messages: 1111");
_refreshController.refreshFailed(); }, onError: (Object error, stackTrace) {
debugPrint("messages: 3333");
}); });
hxDatabase.changeListener.onListen = () {
debugPrint("messages: 2222");
};
if (baseData != null && baseData.isSuccess) { messages = await hxDatabase.messageDao.findMessageByGroup(userId);
if (pageNum == 1) { messages.forEach((element) {
messages.clear(); debugPrint("messages: $element");
} });
List<Message> message = []; userIds = messages
message.addAll(baseData.data.list); .map((e) => e.toId != userId ? e.toId : e.fromId)
message.forEach((element) { .toSet()
if (element.typed == 2 || element.typed == 3) { .toList();
messages.add(element); if (mounted) {
} setState(() {});
});
_refreshController.loadComplete();
_refreshController.refreshCompleted();
if (mounted) setState(() {});
if (pageNum * 10 > int.tryParse(baseData.data.total)) {
_refreshController.loadNoData();
} else {
pageNum += 1;
}
} else {
_refreshController.loadFailed();
_refreshController.refreshFailed();
} }
} }
// queryMessage() async {
// BaseData<PageInfo<Message>> baseData = await apiService.msgList({
// "pageNum": pageNum,
// "pageSize": 10,
// "searchKey": "",
// "state": "",
// "typed": ""
// }).catchError((onError) {
// _refreshController.loadFailed();
// _refreshController.refreshFailed();
// });
//
// if (baseData != null && baseData.isSuccess) {
// if (pageNum == 1) {
// messages.clear();
// }
// List<Message> message = [];
// message.addAll(baseData.data.list);
// message.forEach((element) {
// if (element.typed == 2 || element.typed == 3) {
// messages.add(element);
// }
// });
// _refreshController.loadComplete();
// _refreshController.refreshCompleted();
// if (mounted) setState(() {});
// if (pageNum * 10 > int.tryParse(baseData.data.total)) {
// _refreshController.loadNoData();
// } else {
// pageNum += 1;
// }
// } else {
// _refreshController.loadFailed();
// _refreshController.refreshFailed();
// }
// }
queryMsgStats() async { queryMsgStats() async {
if (apiService == null) { if (apiService == null) {
SharedPreferences value = await SharedPreferences.getInstance(); SharedPreferences value = await SharedPreferences.getInstance();
@ -164,20 +197,16 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
// color: Colors.white, // color: Colors.white,
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient( gradient: LinearGradient(
begin: Alignment.topCenter, begin: Alignment.topCenter,
end: Alignment.bottomCenter, end: Alignment.bottomCenter,
colors: [ colors: [
Color(0xFFD9FFDE), Color(0xFFD9FFDE),
Color(0xFFD9FFDE), Color(0xFFD9FFDE),
Color(0xFFFFFFFF), Color(0xFFFFFFFF),
Color(0xFFFFFFFF), Color(0xFFFFFFFF),
], ],
stops: [ stops: [0, 0.2, 0.4, 1],
0, ),
0.2,
0.4,
1
]),
), ),
child: SingleChildScrollView( child: SingleChildScrollView(
physics: BouncingScrollPhysics(), physics: BouncingScrollPhysics(),
@ -188,24 +217,28 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
Container( Container(
padding: EdgeInsets.only( padding: EdgeInsets.only(
top: MediaQuery.of(context).padding.top + 12.h, top: MediaQuery.of(context).padding.top + 12.h,
bottom: 15.h,right: 16.w,left: 16.w), bottom: 15.h,
right: 16.w,
left: 16.w),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Expanded( Expanded(
child: Text( child: Text(
S.of(context).xiaoxi, S.of(context).xiaoxi,
style: TextStyle( style: TextStyle(
color: Colors.black, color: Colors.black,
fontSize: 18.sp, fontSize: 18.sp,
fontWeight: MyFontWeight.bold, fontWeight: MyFontWeight.bold,
), ),
)), ),
),
GestureDetector( GestureDetector(
behavior: HitTestBehavior.opaque, behavior: HitTestBehavior.opaque,
onTap: () { onTap: () {
Navigator.of(context).pushNamed('/router/chat_friend_group'); Navigator.of(context)
.pushNamed('/router/chat_friend_group');
}, },
child: Container( child: Container(
padding: EdgeInsets.all(12), padding: EdgeInsets.all(12),
@ -216,7 +249,8 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
child: Image.asset( child: Image.asset(
"assets/image/friend_grouping.webp", "assets/image/friend_grouping.webp",
fit: BoxFit.fill, fit: BoxFit.fill,
height: 14.h,width: 14.h, height: 14.h,
width: 14.h,
), ),
), ),
), ),
@ -239,7 +273,7 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
Widget imSearchItem() { Widget imSearchItem() {
return Container( return Container(
margin: EdgeInsets.fromLTRB(16.w, 0, 16.w, 0), margin: EdgeInsets.fromLTRB(16.w, 0, 16.w, 0),
padding: EdgeInsets.symmetric(vertical:13.h), padding: EdgeInsets.symmetric(vertical: 13.h),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Color(0xFFFFFFFF), color: Color(0xFFFFFFFF),
borderRadius: BorderRadius.circular(4), borderRadius: BorderRadius.circular(4),
@ -255,6 +289,7 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
child: TextField( child: TextField(
textInputAction: TextInputAction.search, textInputAction: TextInputAction.search,
onEditingComplete: () { onEditingComplete: () {
socketClient.sendMessage(654321, "hello~");
FocusScope.of(context).requestFocus(FocusNode()); FocusScope.of(context).requestFocus(FocusNode());
}, },
controller: imEditingController, controller: imEditingController,
@ -285,29 +320,30 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
} }
/// ///
Widget chatList(){ Widget chatList() {
return Container( return Container(
child: ListView.builder( child: ListView.builder(
padding: EdgeInsets.only(top: 16), padding: EdgeInsets.only(top: 16),
itemCount: 6, itemCount: userIds.length,
shrinkWrap: true, shrinkWrap: true,
physics: NeverScrollableScrollPhysics(), physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, position) { itemBuilder: (context, position) {
return GestureDetector( return GestureDetector(
behavior:HitTestBehavior.opaque, behavior: HitTestBehavior.opaque,
onTap: () { onTap: () {
Navigator.of(context).pushNamed('/router/chat_details_page'); Navigator.of(context).pushNamed('/router/chat_details_page');
}, },
child: chatItem(), child: chatItem(userIds[position]),
); );
}), },
),
); );
} }
Widget chatItem(){ Widget chatItem(userId) {
return Container( return Container(
padding: EdgeInsets.only(left: 16.w,right: 17.w,bottom:18.h), padding: EdgeInsets.only(left: 16.w, right: 17.w, bottom: 18.h),
child: Row( child: Row(
children: [ children: [
// MImage( // MImage(
// "", // "",
@ -320,49 +356,58 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
// ), // ),
Image.asset( Image.asset(
"assets/image/fuka_zj.webp", "assets/image/fuka_zj.webp",
height:54.h, height: 54.h,
width:54.h, width: 54.h,
), ),
SizedBox(width: 12.w,), SizedBox(
Expanded(child: width: 12.w,
Column( ),
crossAxisAlignment: CrossAxisAlignment.start, Expanded(
children: [ child: Column(
Row( crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Expanded(child: Text( Row(
"喽哈", children: [
overflow: TextOverflow.ellipsis, Expanded(
maxLines: 1, child: Text(
"喽哈$userId",
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: TextStyle(
fontSize: 16.sp,
color: Color(0xFF060606),
fontWeight: MyFontWeight.semi_bold,
),
),
),
Text(
"2021.03.08 13:22",
style: TextStyle( style: TextStyle(
fontSize: 16.sp, fontSize: 12.sp,
color: Color(0xFF060606), color: Color(0xFFA29E9E),
fontWeight: MyFontWeight.semi_bold, fontWeight: MyFontWeight.regular,
)),), ),
Text(
"2021.03.08 13:22",
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFFA29E9E),
fontWeight: MyFontWeight.regular,
), ),
), ],
], ),
), SizedBox(
SizedBox(height: 7.h,), height: 7.h,
Row( ),
children: [ Row(
Expanded(child:Text( children: [
"新开的火锅店好吃得很", Expanded(
maxLines: 1, child: Text(
overflow: TextOverflow.ellipsis, "新开的火锅店好吃得很",
style: TextStyle( maxLines: 1,
fontSize: 12.sp, overflow: TextOverflow.ellipsis,
color: Color(0xFF353535), style: TextStyle(
fontWeight: MyFontWeight.regular, fontSize: 12.sp,
color: Color(0xFF353535),
fontWeight: MyFontWeight.regular,
),
),
), ),
)), Container(
Container(
width: 16, width: 16,
height: 16, height: 16,
decoration: BoxDecoration( decoration: BoxDecoration(
@ -370,17 +415,19 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
color: Color(0xFFFF441A), color: Color(0xFFFF441A),
), ),
child: RoundButton( child: RoundButton(
text:"99", text: "99",
textColor: Colors.white, textColor: Colors.white,
fontWeight: MyFontWeight.regular, fontWeight: MyFontWeight.regular,
backgroup: Color(0xFFFF441A), backgroup: Color(0xFFFF441A),
fontSize: 10.sp, fontSize: 10.sp,
radius: 100, radius: 100,
)) ),
], ),
) ],
], ),
)), ],
),
),
], ],
), ),
); );

7
lib/main.dart

@ -15,6 +15,7 @@ import 'package:huixiang/community/release_dynamic.dart';
import 'package:huixiang/generated/l10n.dart'; import 'package:huixiang/generated/l10n.dart';
import 'package:huixiang/home/founder_story_page.dart'; import 'package:huixiang/home/founder_story_page.dart';
import 'package:huixiang/im/SocketClient.dart'; import 'package:huixiang/im/SocketClient.dart';
import 'package:huixiang/im/database/hx_database.dart';
import 'package:huixiang/integral/integral_detailed_page.dart'; import 'package:huixiang/integral/integral_detailed_page.dart';
import 'package:huixiang/integral/integral_page.dart'; import 'package:huixiang/integral/integral_page.dart';
import 'package:huixiang/integral_store/integral_store_details_page.dart'; import 'package:huixiang/integral_store/integral_store_details_page.dart';
@ -207,6 +208,8 @@ void main() async {
// initSdk(); // initSdk();
bool isFirst = sharedPreferences.getBool("isFirst"); bool isFirst = sharedPreferences.getBool("isFirst");
initDatabase();
runApp(MyApp(locale, isFirst)); runApp(MyApp(locale, isFirst));
// FlutterBugly.postCatchedException((){ // FlutterBugly.postCatchedException((){
// }); // });
@ -215,7 +218,11 @@ void main() async {
// final XgFlutterPlugin xgFlutterPlugin = XgFlutterPlugin(); // final XgFlutterPlugin xgFlutterPlugin = XgFlutterPlugin();
HxDatabase hxDatabase;
initDatabase() async {
hxDatabase = await $FloorHxDatabase.databaseBuilder('huixiang_database.db').build();
}
final SocketClient socketClient = new SocketClient(); final SocketClient socketClient = new SocketClient();
EventBus eventBus = EventBus(sync: true); EventBus eventBus = EventBus(sync: true);

21
lib/main_page.dart

@ -68,6 +68,7 @@ class _MainPage extends State<MainPage> with WidgetsBindingObserver {
@override @override
void dispose() { void dispose() {
super.dispose(); super.dispose();
socketClient.dispose();
WidgetsBinding.instance.removeObserver(this); WidgetsBinding.instance.removeObserver(this);
} }
@ -92,25 +93,9 @@ class _MainPage extends State<MainPage> with WidgetsBindingObserver {
} }
} }
//socket服务
connectSocket() async { connectSocket() async {
final socket = await Socket.connect('192.168.10.129', 9090); socketClient.connect();
//
socket.listen((Uint8List data) {
print("123");
Proto proto = Proto.fromBytes(data);
print("1234,$proto");
MsgData data1 = MsgData.fromBuffer(proto.body);
print('收到来自:${data1.from},消息内容: ${utf8.decode(data1.data)} ');
}, onDone: () {
print('Server closed connection');
socket.destroy();
}, onError: (error) {
print('Error: $error');
socket.destroy();
});
} }
@override @override

3
lib/message/mine_message.dart

@ -36,7 +36,8 @@ class _MineMessagePage extends State<MineMessagePage> {
spreadRadius: 0, spreadRadius: 0,
) )
], ],
borderRadius: BorderRadius.circular(8.w)), borderRadius: BorderRadius.circular(8.w),
),
child: ListView.builder( child: ListView.builder(
itemCount: 1, itemCount: 1,
shrinkWrap: true, shrinkWrap: true,

366
pubspec.lock

File diff suppressed because it is too large Load Diff

2
pubspec.yaml

@ -123,7 +123,7 @@ dependencies:
flutter_datetime_picker: ^1.5.1 flutter_datetime_picker: ^1.5.1
widgetpicker: ^0.1.1 widgetpicker: ^0.1.1
floor: ^1.4.2
syncfusion_flutter_datepicker: ^19.4.38 syncfusion_flutter_datepicker: ^19.4.38
protobuf: ^3.1.0 protobuf: ^3.1.0

Loading…
Cancel
Save