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
|
||||
* @Date : 2022-10-11 11:05:08
|
||||
* @LastEditTime : 2022-10-17 16:57:57
|
||||
* @LastEditTime : 2022-10-19 11:08:50
|
||||
* @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/user_repository/user_repository.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({
|
||||
required this.userID,
|
||||
required this.localServiceRepository,
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
/*
|
||||
* @Author : Linloir
|
||||
* @Date : 2022-10-10 08:04:53
|
||||
* @LastEditTime : 2022-10-17 13:03:55
|
||||
* @LastEditTime : 2022-10-19 11:17:44
|
||||
* @Description :
|
||||
*/
|
||||
import 'package:easy_debounce/easy_debounce.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.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/initialization_page.dart';
|
||||
import 'package:tcp_client/login/login_page.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
|
||||
void main() {
|
||||
void main() async {
|
||||
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());
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
class MyApp extends StatefulWidget {
|
||||
const MyApp({super.key});
|
||||
|
||||
@override
|
||||
State<MyApp> createState() => MyAppState();
|
||||
}
|
||||
|
||||
class MyAppState extends State<MyApp> with WindowListener {
|
||||
// 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
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* @Author : Linloir
|
||||
* @Date : 2022-10-12 17:36:38
|
||||
* @LastEditTime : 2022-10-14 11:22:38
|
||||
* @LastEditTime : 2022-10-19 11:14:06
|
||||
* @Description :
|
||||
*/
|
||||
/*
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* @Author : Linloir
|
||||
* @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
|
||||
*/
|
||||
|
||||
@ -239,13 +239,13 @@ class LocalServiceRepository {
|
||||
var fileExt = fileName.substring(fileName.lastIndexOf('.'));
|
||||
var duplicate = 0;
|
||||
//Rename target file
|
||||
await Directory('$documentPath/files').create();
|
||||
await Directory('$documentPath/files/$userID').create();
|
||||
var targetFilePath = '$documentPath/files/$userID/$fileBaseName$fileExt';
|
||||
await Directory('$documentPath/LChatClient/files').create();
|
||||
await Directory('$documentPath/LChatClient/files/$userID').create();
|
||||
var targetFilePath = '$documentPath/LChatClient/files/$userID/$fileBaseName$fileExt';
|
||||
var targetFile = File(targetFilePath);
|
||||
while(await targetFile.exists()) {
|
||||
duplicate += 1;
|
||||
targetFilePath = '$documentPath/files/$userID/$fileBaseName($duplicate)$fileExt';
|
||||
targetFilePath = '$documentPath/LChatClient/files/$userID/$fileBaseName($duplicate)$fileExt';
|
||||
targetFile = File(targetFilePath);
|
||||
}
|
||||
targetFile = await file.copy(targetFilePath);
|
||||
@ -271,9 +271,9 @@ class LocalServiceRepository {
|
||||
}) async {
|
||||
//Write to file library
|
||||
var documentPath = (await getApplicationDocumentsDirectory()).path;
|
||||
await Directory('$documentPath/files').create();
|
||||
await Directory('$documentPath/files/.lib').create();
|
||||
var permanentFilePath = '$documentPath/files/.lib/${tempFile.filemd5}';
|
||||
await Directory('$documentPath/LChatClient/files').create();
|
||||
await Directory('$documentPath/LChatClient/files/.lib').create();
|
||||
var permanentFilePath = '$documentPath/LChatClient/files/.lib/${tempFile.filemd5}';
|
||||
await tempFile.file.copy(permanentFilePath);
|
||||
try{
|
||||
await _database.insert(
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* @Author : Linloir
|
||||
* @Date : 2022-10-11 09:42:05
|
||||
* @LastEditTime : 2022-10-19 00:57:05
|
||||
* @LastEditTime : 2022-10-19 10:41:43
|
||||
* @Description : TCP repository
|
||||
*/
|
||||
|
||||
@ -170,7 +170,7 @@ class TCPRepository {
|
||||
_fileCounter += 1;
|
||||
_fileCounter %= 10;
|
||||
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);
|
||||
});
|
||||
@ -206,7 +206,7 @@ class TCPRepository {
|
||||
if(buffer.length >= payloadLength) {
|
||||
//Last few bytes to emit
|
||||
//Send the last few bytes to stream
|
||||
_payloadPullStreamController.add(Uint8List.fromList(buffer.sublist(0, payloadLength)));
|
||||
_payloadPullStreamController.add(buffer.sublist(0, payloadLength));
|
||||
//Clear buffer
|
||||
buffer.removeRange(0, payloadLength);
|
||||
//Set payload length to zero
|
||||
@ -217,7 +217,7 @@ class TCPRepository {
|
||||
else {
|
||||
//Part of payload
|
||||
//Transmit all to stream
|
||||
_payloadPullStreamController.add(Uint8List.fromList(buffer));
|
||||
_payloadPullStreamController.add([...buffer]);
|
||||
//Reduce payload bytes left
|
||||
payloadLength -= buffer.length;
|
||||
//Clear buffer
|
||||
|
||||
@ -6,6 +6,14 @@
|
||||
|
||||
#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) {
|
||||
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
|
||||
screen_retriever
|
||||
window_manager
|
||||
)
|
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||
|
||||
@ -6,11 +6,15 @@ import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import path_provider_macos
|
||||
import screen_retriever
|
||||
import shared_preferences_macos
|
||||
import sqflite
|
||||
import window_manager
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
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"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -492,6 +499,13 @@ packages:
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@ -56,6 +56,7 @@ dependencies:
|
||||
lpinyin: ^2.0.3
|
||||
easy_debounce: ^2.0.2+1
|
||||
path: ^1.8.2
|
||||
window_manager: ^0.2.7
|
||||
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
|
||||
@ -6,6 +6,12 @@
|
||||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <screen_retriever/screen_retriever_plugin.h>
|
||||
#include <window_manager/window_manager_plugin.h>
|
||||
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
ScreenRetrieverPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("ScreenRetrieverPlugin"));
|
||||
WindowManagerPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("WindowManagerPlugin"));
|
||||
}
|
||||
|
||||
@ -3,6 +3,8 @@
|
||||
#
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
screen_retriever
|
||||
window_manager
|
||||
)
|
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user