mirror of
https://github.com/Linloir/Simple-TCP-Client.git
synced 2025-12-17 00:38:11 +08:00
Bug Fix & Improvements
- Fix bug when receiving file: passing a to-be-cleared buffer by referrence - Improve experience: remember window size & position
This commit is contained in:
parent
2a6dc0d97f
commit
70dd97a9df
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-11 11:05:08
|
* @Date : 2022-10-11 11:05:08
|
||||||
* @LastEditTime : 2022-10-17 16:57:57
|
* @LastEditTime : 2022-10-19 11:08:50
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -18,8 +18,9 @@ import 'package:tcp_client/repositories/local_service_repository/local_service_r
|
|||||||
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';
|
||||||
import 'package:tcp_client/search/search_page.dart';
|
import 'package:tcp_client/search/search_page.dart';
|
||||||
|
import 'package:window_manager/window_manager.dart';
|
||||||
|
|
||||||
class HomePage extends StatelessWidget {
|
class HomePage extends StatelessWidget with WindowListener {
|
||||||
const HomePage({
|
const HomePage({
|
||||||
required this.userID,
|
required this.userID,
|
||||||
required this.localServiceRepository,
|
required this.localServiceRepository,
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-10 08:04:53
|
* @Date : 2022-10-10 08:04:53
|
||||||
* @LastEditTime : 2022-10-17 13:03:55
|
* @LastEditTime : 2022-10-19 11:17:44
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
|
import 'package:easy_debounce/easy_debounce.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -14,16 +15,87 @@ import 'package:tcp_client/initialization/cubit/initialization_cubit.dart';
|
|||||||
import 'package:tcp_client/initialization/cubit/initialization_state.dart';
|
import 'package:tcp_client/initialization/cubit/initialization_state.dart';
|
||||||
import 'package:tcp_client/initialization/initialization_page.dart';
|
import 'package:tcp_client/initialization/initialization_page.dart';
|
||||||
import 'package:tcp_client/login/login_page.dart';
|
import 'package:tcp_client/login/login_page.dart';
|
||||||
|
import 'package:window_manager/window_manager.dart';
|
||||||
|
|
||||||
void main() {
|
void main() async {
|
||||||
sqfliteFfiInit();
|
sqfliteFfiInit();
|
||||||
|
|
||||||
|
//The code below is for desktop platforms only-------------------------
|
||||||
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
// Must add this line.
|
||||||
|
await windowManager.ensureInitialized();
|
||||||
|
|
||||||
|
//Get preferred window size
|
||||||
|
var pref = await SharedPreferences.getInstance();
|
||||||
|
var width = pref.getDouble('windowWidth');
|
||||||
|
var height = pref.getDouble('windowHeight');
|
||||||
|
var posX = pref.getDouble('windowPosX');
|
||||||
|
var posY = pref.getDouble('windowPosY');
|
||||||
|
WindowOptions windowOptions = WindowOptions(
|
||||||
|
size: Size(width ?? 800, height ?? 600),
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
skipTaskbar: false,
|
||||||
|
titleBarStyle: TitleBarStyle.normal
|
||||||
|
);
|
||||||
|
windowManager.waitUntilReadyToShow(windowOptions, () async {
|
||||||
|
await windowManager.show();
|
||||||
|
await windowManager.focus();
|
||||||
|
if(posX != null && posY != null) {
|
||||||
|
await windowManager.setPosition(Offset(posX, posY));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
runApp(const MyApp());
|
runApp(const MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyApp extends StatelessWidget {
|
class MyApp extends StatefulWidget {
|
||||||
const MyApp({super.key});
|
const MyApp({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MyApp> createState() => MyAppState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyAppState extends State<MyApp> with WindowListener {
|
||||||
// This widget is the root of your application.
|
// This widget is the root of your application.
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
windowManager.addListener(this);
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onWindowMove() {
|
||||||
|
EasyDebounce.debounce(
|
||||||
|
'WindowMove',
|
||||||
|
const Duration(milliseconds: 50),
|
||||||
|
() async {
|
||||||
|
var pref = await SharedPreferences.getInstance();
|
||||||
|
var pos = await windowManager.getPosition();
|
||||||
|
pref.setDouble('windowPosX', pos.dx);
|
||||||
|
pref.setDouble('windowPosY', pos.dy);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
super.onWindowMove();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onWindowResize() {
|
||||||
|
EasyDebounce.debounce(
|
||||||
|
'WindowResize',
|
||||||
|
const Duration(milliseconds: 50),
|
||||||
|
() async {
|
||||||
|
var pref = await SharedPreferences.getInstance();
|
||||||
|
var size = await windowManager.getSize();
|
||||||
|
pref.setDouble('windowWidth', size.width);
|
||||||
|
pref.setDouble('windowHeight', size.height);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
super.onWindowResize();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* @Author : Linloir
|
* @Author : Linloir
|
||||||
* @Date : 2022-10-12 17:36:38
|
* @Date : 2022-10-12 17:36:38
|
||||||
* @LastEditTime : 2022-10-14 11:22:38
|
* @LastEditTime : 2022-10-19 11:14:06
|
||||||
* @Description :
|
* @Description :
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -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-18 15:13:27
|
* @LastEditTime : 2022-10-19 10:28:21
|
||||||
* @Description : Local Service Repository
|
* @Description : Local Service Repository
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -239,13 +239,13 @@ class LocalServiceRepository {
|
|||||||
var fileExt = fileName.substring(fileName.lastIndexOf('.'));
|
var fileExt = fileName.substring(fileName.lastIndexOf('.'));
|
||||||
var duplicate = 0;
|
var duplicate = 0;
|
||||||
//Rename target file
|
//Rename target file
|
||||||
await Directory('$documentPath/files').create();
|
await Directory('$documentPath/LChatClient/files').create();
|
||||||
await Directory('$documentPath/files/$userID').create();
|
await Directory('$documentPath/LChatClient/files/$userID').create();
|
||||||
var targetFilePath = '$documentPath/files/$userID/$fileBaseName$fileExt';
|
var targetFilePath = '$documentPath/LChatClient/files/$userID/$fileBaseName$fileExt';
|
||||||
var targetFile = File(targetFilePath);
|
var targetFile = File(targetFilePath);
|
||||||
while(await targetFile.exists()) {
|
while(await targetFile.exists()) {
|
||||||
duplicate += 1;
|
duplicate += 1;
|
||||||
targetFilePath = '$documentPath/files/$userID/$fileBaseName($duplicate)$fileExt';
|
targetFilePath = '$documentPath/LChatClient/files/$userID/$fileBaseName($duplicate)$fileExt';
|
||||||
targetFile = File(targetFilePath);
|
targetFile = File(targetFilePath);
|
||||||
}
|
}
|
||||||
targetFile = await file.copy(targetFilePath);
|
targetFile = await file.copy(targetFilePath);
|
||||||
@ -271,9 +271,9 @@ class LocalServiceRepository {
|
|||||||
}) async {
|
}) async {
|
||||||
//Write to file library
|
//Write to file library
|
||||||
var documentPath = (await getApplicationDocumentsDirectory()).path;
|
var documentPath = (await getApplicationDocumentsDirectory()).path;
|
||||||
await Directory('$documentPath/files').create();
|
await Directory('$documentPath/LChatClient/files').create();
|
||||||
await Directory('$documentPath/files/.lib').create();
|
await Directory('$documentPath/LChatClient/files/.lib').create();
|
||||||
var permanentFilePath = '$documentPath/files/.lib/${tempFile.filemd5}';
|
var permanentFilePath = '$documentPath/LChatClient/files/.lib/${tempFile.filemd5}';
|
||||||
await tempFile.file.copy(permanentFilePath);
|
await tempFile.file.copy(permanentFilePath);
|
||||||
try{
|
try{
|
||||||
await _database.insert(
|
await _database.insert(
|
||||||
|
|||||||
@ -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-19 00:57:05
|
* @LastEditTime : 2022-10-19 10:41:43
|
||||||
* @Description : TCP repository
|
* @Description : TCP repository
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ class TCPRepository {
|
|||||||
_fileCounter += 1;
|
_fileCounter += 1;
|
||||||
_fileCounter %= 10;
|
_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);
|
||||||
}
|
}
|
||||||
_payloadRawStreamController.add(tempFile);
|
_payloadRawStreamController.add(tempFile);
|
||||||
});
|
});
|
||||||
@ -206,7 +206,7 @@ class TCPRepository {
|
|||||||
if(buffer.length >= payloadLength) {
|
if(buffer.length >= payloadLength) {
|
||||||
//Last few bytes to emit
|
//Last few bytes to emit
|
||||||
//Send the last few bytes to stream
|
//Send the last few bytes to stream
|
||||||
_payloadPullStreamController.add(Uint8List.fromList(buffer.sublist(0, payloadLength)));
|
_payloadPullStreamController.add(buffer.sublist(0, payloadLength));
|
||||||
//Clear buffer
|
//Clear buffer
|
||||||
buffer.removeRange(0, payloadLength);
|
buffer.removeRange(0, payloadLength);
|
||||||
//Set payload length to zero
|
//Set payload length to zero
|
||||||
@ -217,7 +217,7 @@ class TCPRepository {
|
|||||||
else {
|
else {
|
||||||
//Part of payload
|
//Part of payload
|
||||||
//Transmit all to stream
|
//Transmit all to stream
|
||||||
_payloadPullStreamController.add(Uint8List.fromList(buffer));
|
_payloadPullStreamController.add([...buffer]);
|
||||||
//Reduce payload bytes left
|
//Reduce payload bytes left
|
||||||
payloadLength -= buffer.length;
|
payloadLength -= buffer.length;
|
||||||
//Clear buffer
|
//Clear buffer
|
||||||
|
|||||||
@ -6,6 +6,14 @@
|
|||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <screen_retriever/screen_retriever_plugin.h>
|
||||||
|
#include <window_manager/window_manager_plugin.h>
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
|
g_autoptr(FlPluginRegistrar) screen_retriever_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin");
|
||||||
|
screen_retriever_plugin_register_with_registrar(screen_retriever_registrar);
|
||||||
|
g_autoptr(FlPluginRegistrar) window_manager_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "WindowManagerPlugin");
|
||||||
|
window_manager_plugin_register_with_registrar(window_manager_registrar);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,8 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
screen_retriever
|
||||||
|
window_manager
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
|||||||
@ -6,11 +6,15 @@ import FlutterMacOS
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
import path_provider_macos
|
import path_provider_macos
|
||||||
|
import screen_retriever
|
||||||
import shared_preferences_macos
|
import shared_preferences_macos
|
||||||
import sqflite
|
import sqflite
|
||||||
|
import window_manager
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
|
ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin"))
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||||
|
WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin"))
|
||||||
}
|
}
|
||||||
|
|||||||
14
pubspec.lock
14
pubspec.lock
@ -319,6 +319,13 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
|
screen_retriever:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: screen_retriever
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.4"
|
||||||
scrollable_positioned_list:
|
scrollable_positioned_list:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -492,6 +499,13 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.0"
|
version: "3.0.0"
|
||||||
|
window_manager:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: window_manager
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.7"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@ -56,6 +56,7 @@ dependencies:
|
|||||||
lpinyin: ^2.0.3
|
lpinyin: ^2.0.3
|
||||||
easy_debounce: ^2.0.2+1
|
easy_debounce: ^2.0.2+1
|
||||||
path: ^1.8.2
|
path: ^1.8.2
|
||||||
|
window_manager: ^0.2.7
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
|
|||||||
@ -6,6 +6,12 @@
|
|||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <screen_retriever/screen_retriever_plugin.h>
|
||||||
|
#include <window_manager/window_manager_plugin.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
|
ScreenRetrieverPluginRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("ScreenRetrieverPlugin"));
|
||||||
|
WindowManagerPluginRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("WindowManagerPlugin"));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,8 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
screen_retriever
|
||||||
|
window_manager
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user