rustdesk/flutter/lib/models/cm_file_model.dart

143 lines
3.9 KiB
Dart
Raw Normal View History

import 'dart:collection';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/models/model.dart';
import 'package:flutter_hbb/models/server_model.dart';
import 'package:get/get.dart';
import 'file_model.dart';
class CmFileModel {
final WeakReference<FFI> parent;
final currentJobTable = RxList<JobProgress>();
final _jobTables = HashMap<int, RxList<JobProgress>>.fromEntries([]);
Stopwatch stopwatch = Stopwatch();
int _lastElapsed = 0;
CmFileModel(this.parent);
void updateCurrentClientId(int id) {
if (_jobTables[id] == null) {
_jobTables[id] = RxList<JobProgress>();
}
Future.delayed(Duration.zero, () {
currentJobTable.value = _jobTables[id]!;
});
}
onFileTransferLog(dynamic log) {
try {
dynamic d = jsonDecode(log);
if (!stopwatch.isRunning) stopwatch.start();
bool calcSpeed = stopwatch.elapsedMilliseconds - _lastElapsed >= 1000;
if (calcSpeed) {
_lastElapsed = stopwatch.elapsedMilliseconds;
}
if (d is List<dynamic>) {
for (var l in d) {
_dealOneJob(l, calcSpeed);
}
} else {
_dealOneJob(d, calcSpeed);
}
currentJobTable.refresh();
} catch (e) {
debugPrint("onFileTransferLog:$e");
}
}
_dealOneJob(dynamic l, bool calcSpeed) {
final data = TransferJobSerdeData.fromJson(l);
Client? client =
gFFI.serverModel.clients.firstWhereOrNull((e) => e.id == data.connId);
var jobTable = _jobTables[data.connId];
if (jobTable == null) {
debugPrint("jobTable should not be null");
return;
}
JobProgress? job = jobTable.firstWhereOrNull((e) => e.id == data.id);
if (job == null) {
job = JobProgress();
jobTable.add(job);
final currentSelectedTab =
gFFI.serverModel.tabController.state.value.selectedTabInfo;
if (!(gFFI.chatModel.isShowCMSidePage &&
currentSelectedTab.key == data.connId.toString())) {
client?.unreadChatMessageCount.value += 1;
}
}
job.id = data.id;
job.isRemoteToLocal = data.isRemote;
job.fileName = data.path;
job.totalSize = data.totalSize;
job.finishedSize = data.finishedSize;
if (job.finishedSize > data.totalSize) {
job.finishedSize = data.totalSize;
}
job.isRemoteToLocal = data.isRemote;
if (job.finishedSize > 0) {
if (job.finishedSize < job.totalSize) {
job.state = JobState.inProgress;
} else {
job.state = JobState.done;
}
}
if (data.done) {
job.state = JobState.done;
} else if (data.cancel || data.error == 'skipped') {
job.state = JobState.done;
job.err = 'skipped';
} else if (data.error.isNotEmpty) {
job.state = JobState.error;
job.err = data.error;
}
if (calcSpeed) {
job.speed = (data.transferred - job.lastTransferredSize) * 1.0;
job.lastTransferredSize = data.transferred;
}
jobTable.refresh();
}
}
class TransferJobSerdeData {
int connId;
int id;
String path;
bool isRemote;
int totalSize;
int finishedSize;
int transferred;
bool done;
bool cancel;
String error;
TransferJobSerdeData({
required this.connId,
required this.id,
required this.path,
required this.isRemote,
required this.totalSize,
required this.finishedSize,
required this.transferred,
required this.done,
required this.cancel,
required this.error,
});
TransferJobSerdeData.fromJson(dynamic d)
: this(
connId: d['connId'] ?? 0,
id: int.tryParse(d['id'].toString()) ?? 0,
path: d['path'] ?? '',
isRemote: d['isRemote'] ?? false,
totalSize: d['totalSize'] ?? 0,
finishedSize: d['finishedSize'] ?? 0,
transferred: d['transferred'] ?? 0,
done: d['done'] ?? false,
cancel: d['cancel'] ?? false,
error: d['error'] ?? '',
);
}