mirror of
https://github.com/Linloir/Simple-TCP-Client.git
synced 2025-12-17 00:38:11 +08:00
Bug Fix
This commit is contained in:
parent
e7f690159c
commit
84fe935fcd
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-13 14:03:56
|
* @Date : 2022-10-13 14:03:56
|
||||||
* @LastEditTime : 2022-10-17 17:43:55
|
* @LastEditTime : 2022-10-18 11:25:04
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -9,7 +9,6 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:open_file/open_file.dart';
|
import 'package:open_file/open_file.dart';
|
||||||
import 'package:path/path.dart';
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:tcp_client/chat/cubit/chat_state.dart';
|
import 'package:tcp_client/chat/cubit/chat_state.dart';
|
||||||
import 'package:tcp_client/chat/model/chat_history.dart';
|
import 'package:tcp_client/chat/model/chat_history.dart';
|
||||||
@ -158,7 +157,6 @@ class ChatCubit extends Cubit<ChatState> {
|
|||||||
response as ForwardMessageResponse;
|
response as ForwardMessageResponse;
|
||||||
if(response.message.senderID == userID || response.message.recieverID == userID) {
|
if(response.message.senderID == userID || response.message.recieverID == userID) {
|
||||||
// Message storage will be handled by home bloc listener
|
// Message storage will be handled by home bloc listener
|
||||||
// addMessage(response.message);
|
|
||||||
//Emit new state
|
//Emit new state
|
||||||
var newHistory = ChatHistory(
|
var newHistory = ChatHistory(
|
||||||
message: response.message,
|
message: response.message,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-14 21:57:05
|
* @Date : 2022-10-14 21:57:05
|
||||||
* @LastEditTime : 2022-10-14 22:55:16
|
* @LastEditTime : 2022-10-18 11:25:09
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -12,8 +12,6 @@ import 'package:tcp_client/chat/cubit/chat_cubit.dart';
|
|||||||
import 'package:tcp_client/chat/view/input_box/cubit/input_state.dart';
|
import 'package:tcp_client/chat/view/input_box/cubit/input_state.dart';
|
||||||
import 'package:tcp_client/chat/view/input_box/model/input.dart';
|
import 'package:tcp_client/chat/view/input_box/model/input.dart';
|
||||||
import 'package:tcp_client/repositories/common_models/message.dart';
|
import 'package:tcp_client/repositories/common_models/message.dart';
|
||||||
import 'package:tcp_client/repositories/local_service_repository/local_service_repository.dart';
|
|
||||||
import 'package:tcp_client/repositories/tcp_repository/tcp_repository.dart';
|
|
||||||
|
|
||||||
class MessageInputCubit extends Cubit<MessageInputState> {
|
class MessageInputCubit extends Cubit<MessageInputState> {
|
||||||
MessageInputCubit({
|
MessageInputCubit({
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-14 17:54:30
|
* @Date : 2022-10-14 17:54:30
|
||||||
* @LastEditTime : 2022-10-15 00:27:39
|
* @LastEditTime : 2022-10-18 11:25:12
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -16,7 +16,6 @@ import 'package:tcp_client/chat/view/input_box/cubit/input_cubit.dart';
|
|||||||
import 'package:tcp_client/chat/view/input_box/cubit/input_state.dart';
|
import 'package:tcp_client/chat/view/input_box/cubit/input_state.dart';
|
||||||
import 'package:tcp_client/chat/view/input_box/model/input.dart';
|
import 'package:tcp_client/chat/view/input_box/model/input.dart';
|
||||||
import 'package:tcp_client/repositories/common_models/message.dart';
|
import 'package:tcp_client/repositories/common_models/message.dart';
|
||||||
import 'package:tcp_client/repositories/tcp_repository/models/tcp_request.dart';
|
|
||||||
|
|
||||||
class InputBox extends StatelessWidget {
|
class InputBox extends StatelessWidget {
|
||||||
InputBox({super.key});
|
InputBox({super.key});
|
||||||
@ -29,9 +28,11 @@ class InputBox extends StatelessWidget {
|
|||||||
create:(context) => MessageInputCubit(
|
create:(context) => MessageInputCubit(
|
||||||
chatCubit: context.read<ChatCubit>()
|
chatCubit: context.read<ChatCubit>()
|
||||||
),
|
),
|
||||||
child: SizedBox(
|
child: Container(
|
||||||
height: 64,
|
// height: 64,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 16.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: BlocListener<MessageInputCubit, MessageInputState>(
|
child: BlocListener<MessageInputCubit, MessageInputState>(
|
||||||
@ -39,16 +40,29 @@ class InputBox extends StatelessWidget {
|
|||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
_controller.clear();
|
_controller.clear();
|
||||||
},
|
},
|
||||||
child: Builder(
|
child: Container(
|
||||||
|
constraints: const BoxConstraints(maxHeight: 120),
|
||||||
|
child: Builder(
|
||||||
builder: (context) => TextField(
|
builder: (context) => TextField(
|
||||||
controller: _controller,
|
controller: _controller,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
context.read<MessageInputCubit>().onInputChange(MessageInput.dirty(value));
|
context.read<MessageInputCubit>().onInputChange(MessageInput.dirty(value));
|
||||||
},
|
},
|
||||||
|
maxLines: null,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
border: UnderlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
width: 1.0
|
||||||
|
)
|
||||||
|
),
|
||||||
|
hintText: 'Input message here'
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(width: 8.0,),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
var chatCubit = context.read<ChatCubit>();
|
var chatCubit = context.read<ChatCubit>();
|
||||||
@ -66,8 +80,9 @@ class InputBox extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.attach_file_rounded)
|
icon: Icon(Icons.attach_file_rounded, color: Colors.grey[700],)
|
||||||
),
|
),
|
||||||
|
const SizedBox(width: 8.0,),
|
||||||
BlocBuilder<MessageInputCubit, MessageInputState>(
|
BlocBuilder<MessageInputCubit, MessageInputState>(
|
||||||
builder:(context, state) {
|
builder:(context, state) {
|
||||||
return IconButton(
|
return IconButton(
|
||||||
@ -75,6 +90,7 @@ class InputBox extends StatelessWidget {
|
|||||||
context.read<MessageInputCubit>().onSubmission();
|
context.read<MessageInputCubit>().onSubmission();
|
||||||
} : null,
|
} : null,
|
||||||
icon: const Icon(Icons.send_rounded),
|
icon: const Icon(Icons.send_rounded),
|
||||||
|
color: state.status == FormzStatus.valid ? Colors.blue : Colors.grey[400],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,14 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-13 14:02:28
|
* @Date : 2022-10-13 14:02:28
|
||||||
* @LastEditTime : 2022-10-17 17:00:45
|
* @LastEditTime : 2022-10-17 19:26:13
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:tcp_client/home/cubit/home_state.dart';
|
import 'package:tcp_client/home/cubit/home_state.dart';
|
||||||
import 'package:tcp_client/repositories/local_service_repository/local_service_repository.dart';
|
import 'package:tcp_client/repositories/local_service_repository/local_service_repository.dart';
|
||||||
|
import 'package:tcp_client/repositories/tcp_repository/models/tcp_response.dart';
|
||||||
import 'package:tcp_client/repositories/tcp_repository/tcp_repository.dart';
|
import 'package:tcp_client/repositories/tcp_repository/tcp_repository.dart';
|
||||||
|
|
||||||
class HomeCubit extends Cubit<HomeState> {
|
class HomeCubit extends Cubit<HomeState> {
|
||||||
@ -20,11 +23,13 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
pageController.addListener(() {
|
pageController.addListener(() {
|
||||||
emit(state.copyWith(page: HomePagePosition.fromValue((pageController.page ?? 0).round())));
|
emit(state.copyWith(page: HomePagePosition.fromValue((pageController.page ?? 0).round())));
|
||||||
});
|
});
|
||||||
|
subscription = tcpRepository.responseStreamBroadcast.listen(_onTCPResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
final LocalServiceRepository localServiceRepository;
|
final LocalServiceRepository localServiceRepository;
|
||||||
final TCPRepository tcpRepository;
|
final TCPRepository tcpRepository;
|
||||||
final PageController pageController;
|
final PageController pageController;
|
||||||
|
late final StreamSubscription subscription;
|
||||||
|
|
||||||
void switchPage(HomePagePosition newPage) {
|
void switchPage(HomePagePosition newPage) {
|
||||||
pageController.animateToPage(
|
pageController.animateToPage(
|
||||||
@ -33,4 +38,28 @@ class HomeCubit extends Cubit<HomeState> {
|
|||||||
curve: Curves.easeInOutCubicEmphasized
|
curve: Curves.easeInOutCubicEmphasized
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onTCPResponse(TCPResponse response) {
|
||||||
|
switch(response.type) {
|
||||||
|
case TCPResponseType.forwardMessage: {
|
||||||
|
response as ForwardMessageResponse;
|
||||||
|
localServiceRepository.storeMessages([response.message]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TCPResponseType.fetchMessage: {
|
||||||
|
response as FetchMessageResponse;
|
||||||
|
localServiceRepository.storeMessages(response.messages);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> close() {
|
||||||
|
subscription.cancel();
|
||||||
|
return super.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-12 23:36:07
|
* @Date : 2022-10-12 23:36:07
|
||||||
* @LastEditTime : 2022-10-17 17:35:05
|
* @LastEditTime : 2022-10-18 11:25:18
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -18,39 +18,37 @@ class ContactPage extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return BlocBuilder<ContactCubit, ContactState>(
|
||||||
child: BlocBuilder<ContactCubit, ContactState>(
|
builder: (context, state) {
|
||||||
builder: (context, state) {
|
var indexedData = state.indexedData;
|
||||||
var indexedData = state.indexedData;
|
return AzListView(
|
||||||
return AzListView(
|
data: indexedData,
|
||||||
data: indexedData,
|
itemCount: indexedData.length,
|
||||||
itemCount: indexedData.length,
|
itemBuilder: (context, index) {
|
||||||
itemBuilder: (context, index) {
|
return ContactTile(
|
||||||
return ContactTile(
|
userInfo: (indexedData[index] as ContactModel).userInfo,
|
||||||
userInfo: (indexedData[index] as ContactModel).userInfo,
|
);
|
||||||
);
|
},
|
||||||
},
|
physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
|
||||||
physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
|
susItemBuilder: (context, index) {
|
||||||
susItemBuilder: (context, index) {
|
return Container(
|
||||||
return Container(
|
height: 40,
|
||||||
height: 40,
|
width: MediaQuery.of(context).size.width,
|
||||||
width: MediaQuery.of(context).size.width,
|
padding: const EdgeInsets.only(left: 16.0),
|
||||||
padding: const EdgeInsets.only(left: 16.0),
|
color: Colors.grey[200],
|
||||||
color: Colors.grey[200],
|
alignment: Alignment.centerLeft,
|
||||||
alignment: Alignment.centerLeft,
|
child: Text(
|
||||||
child: Text(
|
indexedData[index].getSuspensionTag(),
|
||||||
indexedData[index].getSuspensionTag(),
|
softWrap: false,
|
||||||
softWrap: false,
|
style: TextStyle(
|
||||||
style: TextStyle(
|
fontSize: 14.0,
|
||||||
fontSize: 14.0,
|
color: Colors.grey[700],
|
||||||
color: Colors.grey[700],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
},
|
);
|
||||||
);
|
},
|
||||||
},
|
);
|
||||||
),
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-13 14:02:00
|
* @Date : 2022-10-13 14:02:00
|
||||||
* @LastEditTime : 2022-10-17 17:19:50
|
* @LastEditTime : 2022-10-18 11:25:32
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:tcp_client/chat/chat_page.dart';
|
import 'package:tcp_client/chat/chat_page.dart';
|
||||||
|
|||||||
@ -1,13 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-12 23:48:54
|
* @Date : 2022-10-12 23:48:54
|
||||||
* @LastEditTime : 2022-10-15 01:01:48
|
* @LastEditTime : 2022-10-18 11:25:36
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:tcp_client/repositories/common_models/message.dart';
|
import 'package:tcp_client/repositories/common_models/message.dart';
|
||||||
import 'package:tcp_client/repositories/common_models/userinfo.dart';
|
|
||||||
|
|
||||||
class MessageInfo extends Equatable {
|
class MessageInfo extends Equatable {
|
||||||
final Message? message;
|
final Message? message;
|
||||||
|
|||||||
@ -1,19 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-13 13:17:52
|
* @Date : 2022-10-13 13:17:52
|
||||||
* @LastEditTime : 2022-10-17 17:18:22
|
* @LastEditTime : 2022-10-18 11:25:40
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:tcp_client/chat/chat_page.dart';
|
import 'package:tcp_client/chat/chat_page.dart';
|
||||||
import 'package:tcp_client/common/avatar/avatar.dart';
|
import 'package:tcp_client/common/avatar/avatar.dart';
|
||||||
import 'package:tcp_client/common/username/username.dart';
|
import 'package:tcp_client/common/username/username.dart';
|
||||||
import 'package:tcp_client/repositories/common_models/message.dart';
|
import 'package:tcp_client/repositories/common_models/message.dart';
|
||||||
import 'package:tcp_client/repositories/common_models/userinfo.dart';
|
|
||||||
import 'package:tcp_client/repositories/local_service_repository/local_service_repository.dart';
|
import 'package:tcp_client/repositories/local_service_repository/local_service_repository.dart';
|
||||||
import 'package:tcp_client/repositories/tcp_repository/tcp_repository.dart';
|
import 'package:tcp_client/repositories/tcp_repository/tcp_repository.dart';
|
||||||
import 'package:tcp_client/repositories/user_repository/user_repository.dart';
|
import 'package:tcp_client/repositories/user_repository/user_repository.dart';
|
||||||
@ -110,6 +107,8 @@ class MessageTile extends StatelessWidget {
|
|||||||
child: IgnorePointer(
|
child: IgnorePointer(
|
||||||
child: Text(
|
child: Text(
|
||||||
message?.contentDecoded ?? '',
|
message?.contentDecoded ?? '',
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-14 10:54:57
|
* @Date : 2022-10-14 10:54:57
|
||||||
* @LastEditTime : 2022-10-14 11:44:12
|
* @LastEditTime : 2022-10-17 20:51:45
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -36,6 +36,7 @@ class LogOutCubit extends Cubit<LogOutStatus> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onLogout() async {
|
void onLogout() async {
|
||||||
|
emit(LogOutStatus.processing);
|
||||||
tcpRepository.pushRequest(LogoutRequest(token: (await SharedPreferences.getInstance()).getInt('token')));
|
tcpRepository.pushRequest(LogoutRequest(token: (await SharedPreferences.getInstance()).getInt('token')));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-12 09:56:04
|
* @Date : 2022-10-12 09:56:04
|
||||||
* @LastEditTime : 2022-10-14 16:47:04
|
* @LastEditTime : 2022-10-17 21:11:30
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -22,7 +22,11 @@ class InitializationCubit extends Cubit<InitializationState> {
|
|||||||
TCPRepository? tcpRepository;
|
TCPRepository? tcpRepository;
|
||||||
LocalServiceRepository? localServiceRepository;
|
LocalServiceRepository? localServiceRepository;
|
||||||
Future(() async {
|
Future(() async {
|
||||||
localServiceRepository = await LocalServiceRepository.create(databaseFilePath: '${(await getApplicationDocumentsDirectory()).path}/.data/database.db');
|
localServiceRepository = await LocalServiceRepository.create(
|
||||||
|
databaseFilePath: '${
|
||||||
|
(await getApplicationDocumentsDirectory()).path
|
||||||
|
}/LChatClient/.data/database.db'
|
||||||
|
);
|
||||||
}).then((_) {
|
}).then((_) {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
databaseStatus: InitializationStatus.done,
|
databaseStatus: InitializationStatus.done,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-11 10:56:02
|
* @Date : 2022-10-11 10:56:02
|
||||||
* @LastEditTime : 2022-10-17 13:01:35
|
* @LastEditTime : 2022-10-18 11:27:15
|
||||||
* @Description : Local Service Repository
|
* @Description : Local Service Repository
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -133,20 +133,30 @@ class LocalServiceRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Message>> findMessages({required String pattern}) async {
|
Future<List<Message>> findMessages({required String pattern}) async {
|
||||||
|
if(pattern.isEmpty) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
// Obtain shared preferences.
|
// Obtain shared preferences.
|
||||||
final pref = await SharedPreferences.getInstance();
|
final pref = await SharedPreferences.getInstance();
|
||||||
// Get user info from preferences
|
// Get user info from preferences
|
||||||
var currentUserID = pref.getInt('userid');
|
var currentUserID = pref.getInt('userid');
|
||||||
var alikeMessages = await _database.query(
|
var rawMessages = await _database.query(
|
||||||
'msgs',
|
'msgs',
|
||||||
where: 'userid = ? or targetid = ?',
|
where: '(userid = ? or targetid = ?)',
|
||||||
whereArgs: [
|
whereArgs: [
|
||||||
currentUserID, currentUserID
|
currentUserID, currentUserID
|
||||||
],
|
],
|
||||||
orderBy: 'timestamp desc',
|
orderBy: 'timestamp desc',
|
||||||
limit: 100
|
limit: 100
|
||||||
);
|
);
|
||||||
return alikeMessages.map((e) => Message.fromJSONObject(jsonObject: e)).toList();
|
List<Message> alikeMessages = [];
|
||||||
|
for(var rawMessage in rawMessages) {
|
||||||
|
var message = Message.fromJSONObject(jsonObject: rawMessage);
|
||||||
|
if(message.contentDecoded.contains(pattern)) {
|
||||||
|
alikeMessages.add(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return alikeMessages;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Find the most recent message of given users
|
//Find the most recent message of given users
|
||||||
@ -266,7 +276,7 @@ class LocalServiceRepository {
|
|||||||
conflictAlgorithm: ConflictAlgorithm.replace
|
conflictAlgorithm: ConflictAlgorithm.replace
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
print(err);
|
//TODO: Log the err
|
||||||
}
|
}
|
||||||
//Clear temp file
|
//Clear temp file
|
||||||
tempFile.file.delete();
|
tempFile.file.delete();
|
||||||
@ -318,7 +328,19 @@ class LocalServiceRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<UserInfo?> fetchUserInfoViaUsername({required String username}) async {
|
Future<UserInfo?> fetchUserInfoViaUsername({required String username}) async {
|
||||||
|
var result = await _database.query(
|
||||||
|
'users',
|
||||||
|
where: 'username = ?',
|
||||||
|
whereArgs: [
|
||||||
|
username
|
||||||
|
]
|
||||||
|
);
|
||||||
|
if(result.isEmpty) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return UserInfo.fromJSONObject(jsonObject: result[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Message?> fetchMessage({required String msgmd5}) async {
|
Future<Message?> fetchMessage({required String msgmd5}) async {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-11 09:42:05
|
* @Date : 2022-10-11 09:42:05
|
||||||
* @LastEditTime : 2022-10-15 16:50:16
|
* @LastEditTime : 2022-10-18 11:27:46
|
||||||
* @Description : TCP repository
|
* @Description : TCP repository
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -25,13 +25,26 @@ class TCPRepository {
|
|||||||
required String remoteAddress,
|
required String remoteAddress,
|
||||||
required int remotePort
|
required int remotePort
|
||||||
}): _socket = socket, _remoteAddress = remoteAddress, _remotePort = remotePort {
|
}): _socket = socket, _remoteAddress = remoteAddress, _remotePort = remotePort {
|
||||||
_socket.listen(_pullResponse);
|
Future(() async {
|
||||||
|
try{
|
||||||
|
await for(var response in _socket) {
|
||||||
|
_pullResponse(response);
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
_socket.close();
|
||||||
|
}
|
||||||
|
// _responseRawStreamController.close();
|
||||||
|
// _payloadPullStreamController.close();
|
||||||
|
// _payloadRawStreamController.close();
|
||||||
|
// _responseStreamController.close();
|
||||||
|
// _requestStreamController.close();
|
||||||
|
});
|
||||||
//This future never ends, would that be bothersome?
|
//This future never ends, would that be bothersome?
|
||||||
Future(() async {
|
Future(() async {
|
||||||
await for(var request in _requestStreamController.stream) {
|
await for(var request in _requestStreamController.stream) {
|
||||||
await _socket.addStream(request.stream);
|
await _socket.addStream(request.stream);
|
||||||
}
|
}
|
||||||
});
|
}).onError((error, stackTrace) {_socket.close();});
|
||||||
Future(() async {
|
Future(() async {
|
||||||
var responseQueue = StreamQueue(_responseRawStreamController.stream);
|
var responseQueue = StreamQueue(_responseRawStreamController.stream);
|
||||||
var payloadQueue = StreamQueue(_payloadRawStreamController.stream);
|
var payloadQueue = StreamQueue(_payloadRawStreamController.stream);
|
||||||
@ -42,7 +55,7 @@ class TCPRepository {
|
|||||||
}
|
}
|
||||||
responseQueue.cancel();
|
responseQueue.cancel();
|
||||||
payloadQueue.cancel();
|
payloadQueue.cancel();
|
||||||
});
|
}).onError((error, stackTrace) {_socket.close();});
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<TCPRepository> create({
|
static Future<TCPRepository> create({
|
||||||
@ -75,6 +88,9 @@ class TCPRepository {
|
|||||||
//Byte length for subsequent data of the json object
|
//Byte length for subsequent data of the json object
|
||||||
int payloadLength = 0;
|
int payloadLength = 0;
|
||||||
|
|
||||||
|
//Temp filename counter
|
||||||
|
int _fileCounter = 0;
|
||||||
|
|
||||||
//Construct a stream which emits events on intact requests
|
//Construct a stream which emits events on intact requests
|
||||||
final StreamController<List<int>> _responseRawStreamController = StreamController();
|
final StreamController<List<int>> _responseRawStreamController = StreamController();
|
||||||
final StreamController<File> _payloadRawStreamController = StreamController();
|
final StreamController<File> _payloadRawStreamController = StreamController();
|
||||||
@ -147,9 +163,11 @@ class TCPRepository {
|
|||||||
Future(() async {
|
Future(() async {
|
||||||
var documentDirectory = await getApplicationDocumentsDirectory();
|
var documentDirectory = await getApplicationDocumentsDirectory();
|
||||||
//Create temp file to read payload (might be huge)
|
//Create temp file to read payload (might be huge)
|
||||||
Directory('${documentDirectory.path}/ChatClient').createSync();
|
Directory('${documentDirectory.path}/LChatClient').createSync();
|
||||||
Directory('${documentDirectory.path}/ChatClient/.tmp').createSync();
|
Directory('${documentDirectory.path}/LChatClient/.tmp').createSync();
|
||||||
var tempFile = File('${documentDirectory.path}/ChatClient/.tmp/${DateTime.now().microsecondsSinceEpoch}')..createSync();
|
var tempFile = File('${documentDirectory.path}/LChatClient/.tmp/${DateTime.now().microsecondsSinceEpoch}$_fileCounter')..createSync();
|
||||||
|
_fileCounter += 1;
|
||||||
|
_fileCounter %= 10;
|
||||||
await for(var data in payloadPullStream) {
|
await for(var data in payloadPullStream) {
|
||||||
await tempFile.writeAsBytes(data, mode: FileMode.append, flush: true);
|
await tempFile.writeAsBytes(data, mode: FileMode.append, flush: true);
|
||||||
}
|
}
|
||||||
@ -342,10 +360,5 @@ class TCPRepository {
|
|||||||
void dispose() async {
|
void dispose() async {
|
||||||
await _socket.flush();
|
await _socket.flush();
|
||||||
await _socket.close();
|
await _socket.close();
|
||||||
_responseRawStreamController.close();
|
|
||||||
_payloadPullStreamController.close();
|
|
||||||
_payloadRawStreamController.close();
|
|
||||||
_responseStreamController.close();
|
|
||||||
_requestStreamController.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-13 21:41:49
|
* @Date : 2022-10-13 21:41:49
|
||||||
* @LastEditTime : 2022-10-14 10:38:31
|
* @LastEditTime : 2022-10-17 22:23:46
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -36,6 +36,7 @@ class HistoryTile extends StatelessWidget {
|
|||||||
const SizedBox(width: 12,),
|
const SizedBox(width: 12,),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
@ -51,6 +52,8 @@ class HistoryTile extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
message.contentDecoded,
|
message.contentDecoded,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,19 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-13 21:41:41
|
* @Date : 2022-10-13 21:41:41
|
||||||
* @LastEditTime : 2022-10-14 12:04:26
|
* @LastEditTime : 2022-10-18 11:28:17
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:tcp_client/common/avatar/avatar.dart';
|
import 'package:tcp_client/common/avatar/avatar.dart';
|
||||||
import 'package:tcp_client/common/username/username.dart';
|
import 'package:tcp_client/common/username/username.dart';
|
||||||
import 'package:tcp_client/profile/user_profile_page.dart';
|
import 'package:tcp_client/profile/user_profile_page.dart';
|
||||||
import 'package:tcp_client/repositories/common_models/userinfo.dart';
|
import 'package:tcp_client/repositories/common_models/userinfo.dart';
|
||||||
import 'package:tcp_client/repositories/local_service_repository/local_service_repository.dart';
|
|
||||||
import 'package:tcp_client/repositories/user_repository/user_repository.dart';
|
import 'package:tcp_client/repositories/user_repository/user_repository.dart';
|
||||||
import 'package:tcp_client/search/cubit/search_cubit.dart';
|
import 'package:tcp_client/search/cubit/search_cubit.dart';
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ project(runner LANGUAGES CXX)
|
|||||||
set(BINARY_NAME "tcp_client")
|
set(BINARY_NAME "tcp_client")
|
||||||
# The unique GTK application identifier for this application. See:
|
# The unique GTK application identifier for this application. See:
|
||||||
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
|
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
|
||||||
set(APPLICATION_ID "com.example.tcp_client")
|
set(APPLICATION_ID "com.linloir.tcp_client")
|
||||||
|
|
||||||
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
|
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
|
||||||
# versions of CMake.
|
# versions of CMake.
|
||||||
|
|||||||
@ -4,7 +4,7 @@ project(tcp_client LANGUAGES CXX)
|
|||||||
|
|
||||||
# The name of the executable created for the application. Change this to change
|
# The name of the executable created for the application. Change this to change
|
||||||
# the on-disk name of your application.
|
# the on-disk name of your application.
|
||||||
set(BINARY_NAME "tcp_client")
|
set(BINARY_NAME "LChatClient")
|
||||||
|
|
||||||
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
|
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
|
||||||
# versions of CMake.
|
# versions of CMake.
|
||||||
|
|||||||
@ -89,13 +89,13 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
BLOCK "040904e4"
|
BLOCK "040904e4"
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "com.example" "\0"
|
VALUE "CompanyName", "com.linloir" "\0"
|
||||||
VALUE "FileDescription", "tcp_client" "\0"
|
VALUE "FileDescription", "LChatClient" "\0"
|
||||||
VALUE "FileVersion", VERSION_AS_STRING "\0"
|
VALUE "FileVersion", VERSION_AS_STRING "\0"
|
||||||
VALUE "InternalName", "tcp_client" "\0"
|
VALUE "InternalName", "LChatClient" "\0"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2022 com.example. All rights reserved." "\0"
|
VALUE "LegalCopyright", "Copyright (C) 2022 com.linloir. All rights reserved." "\0"
|
||||||
VALUE "OriginalFilename", "tcp_client.exe" "\0"
|
VALUE "OriginalFilename", "LCatClient.exe" "\0"
|
||||||
VALUE "ProductName", "tcp_client" "\0"
|
VALUE "ProductName", "LCatClient" "\0"
|
||||||
VALUE "ProductVersion", VERSION_AS_STRING "\0"
|
VALUE "ProductVersion", VERSION_AS_STRING "\0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user