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

15
ios/Runner.xcodeproj/project.pbxproj

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

61
lib/im/SocketClient.dart

@ -6,27 +6,45 @@ import 'dart:io';
import 'package:flutter/foundation.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/message.pb.dart';
import 'package:huixiang/main.dart';
import 'package:shared_preferences/shared_preferences.dart';
class SocketClient {
Socket _socket;
SharedPreferences shared;
connect() async {
_socket = await Socket.connect('192.168.10.129', 9090);
_socket.listen((data) {
print(data);
print("socket-listen");
Proto proto = Proto.fromBytes(data);
print("socket-listen: $proto");
MsgData data1 = MsgData.fromBuffer(proto.body);
print('收到来自:${data1.from},消息内容: ${utf8.decode(data1.data)} ');
callbacks.forEach((callback) {
callback.call(data1);
shared = await SharedPreferences.getInstance();
await Socket.connect('192.168.10.129', 9090).then((value) {
debugPrint("socket-connect");
_socket = value;
_socket.listen((data) {
print(data);
print("socket-listen");
Proto proto = Proto.fromBytes(data);
print("socket-listen: $proto");
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);
}
dispose() {
_socket.close();
}
authRequest(String token) {
if (!checkSocket()) {
return;
}
final authReq = AuthReq()
..uid = 1
..token = '123456';
..uid = mobile
..token = token;
final authReqBytes = authReq.writeToBuffer();
final proto = Proto(1, 1, authReqBytes); // operation seqId 1
final protoBytes = proto.toBytes();
_socket.add(protoBytes);
}
sendMessage(var to, String content) {
sendMessage(int toId, String content) {
if (!checkSocket()) {
return;
}
Uint8List data = utf8.encode(content);
MsgData msgData = MsgData(to: to,from: 2,type: MsgType.SINGLE_TEXT,data: data);
final proto2 = Proto(5,1,msgData.writeToBuffer());
MsgData msgData = MsgData(to: toId, from: mobile, type: MsgType.SINGLE_TEXT,data: data);
final proto2 = Proto(5, 1, msgData.writeToBuffer());
_socket.add(proto2.toBytes());
hxDatabase.messageDao.insertMessage(createMessage(toId, content, userId: mobile)).catchError((error) {
debugPrint("insertMessage: $error");
});
debugPrint("insertMessage: end");
}
checkSocket() {
@ -71,4 +97,7 @@ class SocketClient {
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_screenutil/flutter_screenutil.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/view_widget/my_appbar.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:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.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/message.dart';
import 'package:huixiang/retrofit/data/msg_stats.dart';
import 'package:huixiang/retrofit/data/page.dart';
import 'package:huixiang/retrofit/retrofit_api.dart';
@ -18,8 +21,8 @@ import 'on_chat_message.dart';
import 'on_chat_msg_instance.dart';
class IMPage extends StatefulWidget {
IMPage(Key key) : super(key: key);
IMPage(Key key): super(key: key);
@override
State<StatefulWidget> createState() {
return _IMPage();
@ -42,7 +45,7 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
final TextEditingController imEditingController = TextEditingController();
@override
void onMessage(txt){
void onMessage(txt) {
// SmartDialog.showToast("列表 $txt", alignment: Alignment.center);
}
@ -57,57 +60,87 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
super.initState();
OnChatMsgInstance.instance.onChatMessage = this;
loadMessageList();
SharedPreferences.getInstance().then((value) {
apiService =
ApiService(Dio(), token: value.getString("token"), context: context);
queryMessage();
queryMsgStats();
});
}
_refresh() {
pageNum = 1;
queryMessage();
loadMessageList();
queryMsgStats();
}
queryMessage() async {
BaseData<PageInfo<Message>> baseData = await apiService.msgList({
"pageNum": pageNum,
"pageSize": 10,
"searchKey": "",
"state": "",
"typed": ""
}).catchError((onError) {
_refreshController.loadFailed();
_refreshController.refreshFailed();
List<int> userIds = [];
Stream streamSubscription ;
loadMessageList() async {
int userId = 123456;
hxDatabase.changeListener.stream.listen((event) {
debugPrint("messages: 1111");
}, onError: (Object error, stackTrace) {
debugPrint("messages: 3333");
});
hxDatabase.changeListener.onListen = () {
debugPrint("messages: 2222");
};
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();
messages = await hxDatabase.messageDao.findMessageByGroup(userId);
messages.forEach((element) {
debugPrint("messages: $element");
});
userIds = messages
.map((e) => e.toId != userId ? e.toId : e.fromId)
.toSet()
.toList();
if (mounted) {
setState(() {});
}
}
// 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 {
if (apiService == null) {
SharedPreferences value = await SharedPreferences.getInstance();
@ -164,20 +197,16 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
// color: Colors.white,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xFFD9FFDE),
Color(0xFFD9FFDE),
Color(0xFFFFFFFF),
Color(0xFFFFFFFF),
],
stops: [
0,
0.2,
0.4,
1
]),
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xFFD9FFDE),
Color(0xFFD9FFDE),
Color(0xFFFFFFFF),
Color(0xFFFFFFFF),
],
stops: [0, 0.2, 0.4, 1],
),
),
child: SingleChildScrollView(
physics: BouncingScrollPhysics(),
@ -188,24 +217,28 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
Container(
padding: EdgeInsets.only(
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(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Text(
S.of(context).xiaoxi,
style: TextStyle(
color: Colors.black,
fontSize: 18.sp,
fontWeight: MyFontWeight.bold,
),
)),
child: Text(
S.of(context).xiaoxi,
style: TextStyle(
color: Colors.black,
fontSize: 18.sp,
fontWeight: MyFontWeight.bold,
),
),
),
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
Navigator.of(context).pushNamed('/router/chat_friend_group');
Navigator.of(context)
.pushNamed('/router/chat_friend_group');
},
child: Container(
padding: EdgeInsets.all(12),
@ -216,7 +249,8 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
child: Image.asset(
"assets/image/friend_grouping.webp",
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() {
return Container(
margin: EdgeInsets.fromLTRB(16.w, 0, 16.w, 0),
padding: EdgeInsets.symmetric(vertical:13.h),
padding: EdgeInsets.symmetric(vertical: 13.h),
decoration: BoxDecoration(
color: Color(0xFFFFFFFF),
borderRadius: BorderRadius.circular(4),
@ -255,6 +289,7 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
child: TextField(
textInputAction: TextInputAction.search,
onEditingComplete: () {
socketClient.sendMessage(654321, "hello~");
FocusScope.of(context).requestFocus(FocusNode());
},
controller: imEditingController,
@ -285,29 +320,30 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
}
///
Widget chatList(){
Widget chatList() {
return Container(
child: ListView.builder(
padding: EdgeInsets.only(top: 16),
itemCount: 6,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, position) {
return GestureDetector(
behavior:HitTestBehavior.opaque,
onTap: () {
Navigator.of(context).pushNamed('/router/chat_details_page');
},
child: chatItem(),
);
}),
padding: EdgeInsets.only(top: 16),
itemCount: userIds.length,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, position) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
Navigator.of(context).pushNamed('/router/chat_details_page');
},
child: chatItem(userIds[position]),
);
},
),
);
}
Widget chatItem(){
Widget chatItem(userId) {
return Container(
padding: EdgeInsets.only(left: 16.w,right: 17.w,bottom:18.h),
child: Row(
padding: EdgeInsets.only(left: 16.w, right: 17.w, bottom: 18.h),
child: Row(
children: [
// MImage(
// "",
@ -320,49 +356,58 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
// ),
Image.asset(
"assets/image/fuka_zj.webp",
height:54.h,
width:54.h,
height: 54.h,
width: 54.h,
),
SizedBox(width: 12.w,),
Expanded(child:
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(child: Text(
"喽哈",
overflow: TextOverflow.ellipsis,
maxLines: 1,
SizedBox(
width: 12.w,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
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(
fontSize: 16.sp,
color: Color(0xFF060606),
fontWeight: MyFontWeight.semi_bold,
)),),
Text(
"2021.03.08 13:22",
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFFA29E9E),
fontWeight: MyFontWeight.regular,
fontSize: 12.sp,
color: Color(0xFFA29E9E),
fontWeight: MyFontWeight.regular,
),
),
),
],
),
SizedBox(height: 7.h,),
Row(
children: [
Expanded(child:Text(
"新开的火锅店好吃得很",
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFF353535),
fontWeight: MyFontWeight.regular,
],
),
SizedBox(
height: 7.h,
),
Row(
children: [
Expanded(
child: Text(
"新开的火锅店好吃得很",
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 12.sp,
color: Color(0xFF353535),
fontWeight: MyFontWeight.regular,
),
),
),
)),
Container(
Container(
width: 16,
height: 16,
decoration: BoxDecoration(
@ -370,17 +415,19 @@ class _IMPage extends State<IMPage> implements OnChatMessage {
color: Color(0xFFFF441A),
),
child: RoundButton(
text:"99",
text: "99",
textColor: Colors.white,
fontWeight: MyFontWeight.regular,
backgroup: Color(0xFFFF441A),
fontSize: 10.sp,
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/home/founder_story_page.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_page.dart';
import 'package:huixiang/integral_store/integral_store_details_page.dart';
@ -207,6 +208,8 @@ void main() async {
// initSdk();
bool isFirst = sharedPreferences.getBool("isFirst");
initDatabase();
runApp(MyApp(locale, isFirst));
// FlutterBugly.postCatchedException((){
// });
@ -215,7 +218,11 @@ void main() async {
// final XgFlutterPlugin xgFlutterPlugin = XgFlutterPlugin();
HxDatabase hxDatabase;
initDatabase() async {
hxDatabase = await $FloorHxDatabase.databaseBuilder('huixiang_database.db').build();
}
final SocketClient socketClient = new SocketClient();
EventBus eventBus = EventBus(sync: true);

21
lib/main_page.dart

@ -68,6 +68,7 @@ class _MainPage extends State<MainPage> with WidgetsBindingObserver {
@override
void dispose() {
super.dispose();
socketClient.dispose();
WidgetsBinding.instance.removeObserver(this);
}
@ -92,25 +93,9 @@ class _MainPage extends State<MainPage> with WidgetsBindingObserver {
}
}
//socket服务
connectSocket() async {
final socket = await Socket.connect('192.168.10.129', 9090);
//
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();
});
socketClient.connect();
}
@override

3
lib/message/mine_message.dart

@ -36,7 +36,8 @@ class _MineMessagePage extends State<MineMessagePage> {
spreadRadius: 0,
)
],
borderRadius: BorderRadius.circular(8.w)),
borderRadius: BorderRadius.circular(8.w),
),
child: ListView.builder(
itemCount: 1,
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
widgetpicker: ^0.1.1
floor: ^1.4.2
syncfusion_flutter_datepicker: ^19.4.38
protobuf: ^3.1.0

Loading…
Cancel
Save