mirror of
https://github.com/StarCitizenToolBox/app.git
synced 2026-02-06 15:10:20 +00:00
feat: use rust rqbit to replace aria2c
This commit is contained in:
@@ -2,6 +2,7 @@ import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:starcitizen_doctor/widgets/widgets.dart';
|
||||
import 'package:file_sizes/file_sizes.dart';
|
||||
import 'package:starcitizen_doctor/common/rust/api/downloader_api.dart';
|
||||
|
||||
import 'home_downloader_ui_model.dart';
|
||||
|
||||
@@ -13,59 +14,51 @@ class HomeDownloaderUI extends HookConsumerWidget {
|
||||
final state = ref.watch(homeDownloaderUIModelProvider);
|
||||
final model = ref.read(homeDownloaderUIModelProvider.notifier);
|
||||
|
||||
return makeDefaultPage(context,
|
||||
content: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
const Spacer(),
|
||||
const SizedBox(width: 24),
|
||||
const SizedBox(width: 12),
|
||||
for (final item in <MapEntry<String, IconData>, String>{
|
||||
const MapEntry("settings", FluentIcons.settings):
|
||||
S.current.downloader_speed_limit_settings,
|
||||
if (state.tasks.isNotEmpty)
|
||||
const MapEntry("pause_all", FluentIcons.pause):
|
||||
S.current.downloader_action_pause_all,
|
||||
if (state.waitingTasks.isNotEmpty)
|
||||
const MapEntry("resume_all", FluentIcons.download):
|
||||
S.current.downloader_action_resume_all,
|
||||
if (state.tasks.isNotEmpty || state.waitingTasks.isNotEmpty)
|
||||
const MapEntry("cancel_all", FluentIcons.cancel):
|
||||
S.current.downloader_action_cancel_all,
|
||||
}.entries)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 6, right: 6),
|
||||
child: Button(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(4),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(item.key.value),
|
||||
const SizedBox(width: 6),
|
||||
Text(item.value),
|
||||
],
|
||||
),
|
||||
),
|
||||
onPressed: () =>
|
||||
model.onTapButton(context, item.key.key)),
|
||||
return makeDefaultPage(
|
||||
context,
|
||||
content: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
const Spacer(),
|
||||
const SizedBox(width: 24),
|
||||
const SizedBox(width: 12),
|
||||
for (final item in <MapEntry<String, IconData>, String>{
|
||||
const MapEntry("settings", FluentIcons.settings): S.current.downloader_speed_limit_settings,
|
||||
if (state.activeTasks.isNotEmpty)
|
||||
const MapEntry("pause_all", FluentIcons.pause): S.current.downloader_action_pause_all,
|
||||
if (state.waitingTasks.isNotEmpty)
|
||||
const MapEntry("resume_all", FluentIcons.download): S.current.downloader_action_resume_all,
|
||||
if (state.activeTasks.isNotEmpty || state.waitingTasks.isNotEmpty)
|
||||
const MapEntry("cancel_all", FluentIcons.cancel): S.current.downloader_action_cancel_all,
|
||||
}.entries)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 6, right: 6),
|
||||
child: Button(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(4),
|
||||
child: Row(children: [Icon(item.key.value), const SizedBox(width: 6), Text(item.value)]),
|
||||
),
|
||||
onPressed: () => model.onTapButton(context, item.key.key),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
],
|
||||
),
|
||||
if (model.getTasksLen() == 0)
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: Text(S.current.downloader_info_no_download_tasks),
|
||||
))
|
||||
else
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
],
|
||||
),
|
||||
if (model.getTasksLen() == 0)
|
||||
Expanded(child: Center(child: Text(S.current.downloader_info_no_download_tasks)))
|
||||
else
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final (task, type, isFirstType) = model.getTaskAndType(index);
|
||||
final nt = HomeDownloaderUIModel.getTaskTypeAndName(task);
|
||||
final statusStr = model.getStatusString(task.status);
|
||||
final isActive = task.status == DownloadTaskStatus.live;
|
||||
final isPaused = task.status == DownloadTaskStatus.paused;
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -73,39 +66,30 @@ class HomeDownloaderUI extends HookConsumerWidget {
|
||||
Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.only(
|
||||
left: 24,
|
||||
right: 24,
|
||||
top: index == 0 ? 0 : 12,
|
||||
bottom: 12),
|
||||
padding: EdgeInsets.only(left: 24, right: 24, top: index == 0 ? 0 : 12, bottom: 12),
|
||||
margin: const EdgeInsets.only(top: 6, bottom: 6),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
"${model.listHeaderStatusMap[type]}",
|
||||
style: const TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
)),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
"${model.listHeaderStatusMap[type]}",
|
||||
style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 12, right: 12, top: 12, bottom: 12),
|
||||
margin: const EdgeInsets.only(
|
||||
left: 12, right: 12, top: 6, bottom: 6),
|
||||
padding: const EdgeInsets.only(left: 12, right: 12, top: 12, bottom: 12),
|
||||
margin: const EdgeInsets.only(left: 12, right: 12, top: 6, bottom: 6),
|
||||
decoration: BoxDecoration(
|
||||
color: FluentTheme.of(context)
|
||||
.cardColor
|
||||
.withValues(alpha: .06),
|
||||
color: FluentTheme.of(context).cardColor.withValues(alpha: .06),
|
||||
borderRadius: BorderRadius.circular(7),
|
||||
),
|
||||
child: Row(
|
||||
@@ -113,47 +97,26 @@ class HomeDownloaderUI extends HookConsumerWidget {
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
nt.value,
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(nt.value, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
||||
const SizedBox(height: 6),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
S.current.downloader_info_total_size(
|
||||
FileSize.getSize(
|
||||
task.totalLength ?? 0)),
|
||||
S.current.downloader_info_total_size(FileSize.getSize(task.totalBytes.toInt())),
|
||||
style: const TextStyle(fontSize: 14),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
if (nt.key == "torrent" &&
|
||||
task.verifiedLength != null &&
|
||||
task.verifiedLength != 0)
|
||||
if (isActive)
|
||||
Text(
|
||||
S.current.downloader_info_verifying(
|
||||
FileSize.getSize(
|
||||
task.verifiedLength)),
|
||||
style: const TextStyle(fontSize: 14),
|
||||
S.current.downloader_info_downloading((task.progress * 100).toStringAsFixed(2)),
|
||||
)
|
||||
else if (task.status == "active")
|
||||
Text(S.current
|
||||
.downloader_info_downloading(
|
||||
((task.completedLength ?? 0) *
|
||||
100 /
|
||||
(task.totalLength ?? 1))
|
||||
.toStringAsFixed(4)))
|
||||
else
|
||||
Text(S.current.downloader_info_status(
|
||||
model.statusMap[task.status] ??
|
||||
"Unknown")),
|
||||
Text(S.current.downloader_info_status(model.statusMap[statusStr] ?? "Unknown")),
|
||||
const SizedBox(width: 24),
|
||||
if (task.status == "active" &&
|
||||
task.verifiedLength == null)
|
||||
if (isActive)
|
||||
Text(
|
||||
"ETA: ${model.formatter.format(DateTime.now().add(Duration(seconds: model.getETA(task))))}"),
|
||||
"ETA: ${model.formatter.format(DateTime.now().add(Duration(seconds: model.getETA(task))))}",
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
@@ -162,20 +125,18 @@ class HomeDownloaderUI extends HookConsumerWidget {
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(S.current.downloader_info_uploaded(
|
||||
FileSize.getSize(task.uploadLength))),
|
||||
Text(S.current.downloader_info_downloaded(
|
||||
FileSize.getSize(task.completedLength))),
|
||||
Text(S.current.downloader_info_uploaded(FileSize.getSize(task.uploadedBytes.toInt()))),
|
||||
Text(
|
||||
S.current.downloader_info_downloaded(FileSize.getSize(task.downloadedBytes.toInt())),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 18),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"↑:${FileSize.getSize(task.uploadSpeed)}/s"),
|
||||
Text(
|
||||
"↓:${FileSize.getSize(task.downloadSpeed)}/s"),
|
||||
Text("↑:${FileSize.getSize(task.uploadSpeed.toInt())}/s"),
|
||||
Text("↓:${FileSize.getSize(task.downloadSpeed.toInt())}/s"),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 32),
|
||||
@@ -184,42 +145,32 @@ class HomeDownloaderUI extends HookConsumerWidget {
|
||||
closeAfterClick: false,
|
||||
title: Padding(
|
||||
padding: const EdgeInsets.all(3),
|
||||
child:
|
||||
Text(S.current.downloader_action_options),
|
||||
child: Text(S.current.downloader_action_options),
|
||||
),
|
||||
items: [
|
||||
if (task.status == "paused")
|
||||
if (isPaused)
|
||||
MenuFlyoutItem(
|
||||
leading:
|
||||
const Icon(FluentIcons.download),
|
||||
text: Text(S.current
|
||||
.downloader_action_continue_download),
|
||||
onPressed: () =>
|
||||
model.resumeTask(task.gid))
|
||||
else if (task.status == "active")
|
||||
leading: const Icon(FluentIcons.download),
|
||||
text: Text(S.current.downloader_action_continue_download),
|
||||
onPressed: () => model.resumeTask(task.id.toInt()),
|
||||
)
|
||||
else if (isActive)
|
||||
MenuFlyoutItem(
|
||||
leading: const Icon(FluentIcons.pause),
|
||||
text: Text(S.current
|
||||
.downloader_action_pause_download),
|
||||
onPressed: () =>
|
||||
model.pauseTask(task.gid)),
|
||||
leading: const Icon(FluentIcons.pause),
|
||||
text: Text(S.current.downloader_action_pause_download),
|
||||
onPressed: () => model.pauseTask(task.id.toInt()),
|
||||
),
|
||||
const MenuFlyoutSeparator(),
|
||||
MenuFlyoutItem(
|
||||
leading: const Icon(
|
||||
FluentIcons.chrome_close,
|
||||
size: 14,
|
||||
),
|
||||
text: Text(S.current
|
||||
.downloader_action_cancel_download),
|
||||
onPressed: () =>
|
||||
model.cancelTask(context, task.gid)),
|
||||
leading: const Icon(FluentIcons.chrome_close, size: 14),
|
||||
text: Text(S.current.downloader_action_cancel_download),
|
||||
onPressed: () => model.cancelTask(context, task.id.toInt()),
|
||||
),
|
||||
MenuFlyoutItem(
|
||||
leading: const Icon(
|
||||
FluentIcons.folder_open,
|
||||
size: 14,
|
||||
),
|
||||
text: Text(S.current.action_open_folder),
|
||||
onPressed: () => model.openFolder(task)),
|
||||
leading: const Icon(FluentIcons.folder_open, size: 14),
|
||||
text: Text(S.current.action_open_folder),
|
||||
onPressed: () => model.openFolder(task),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
@@ -230,31 +181,36 @@ class HomeDownloaderUI extends HookConsumerWidget {
|
||||
);
|
||||
},
|
||||
itemCount: model.getTasksLen(),
|
||||
)),
|
||||
Container(
|
||||
color: FluentTheme.of(context).cardColor.withValues(alpha: .06),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 12, bottom: 3, top: 3),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 8,
|
||||
height: 8,
|
||||
decoration: BoxDecoration(
|
||||
color: state.isAvailable ? Colors.green : Colors.white,
|
||||
borderRadius: BorderRadius.circular(1000),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Text(S.current.downloader_info_download_upload_speed(
|
||||
FileSize.getSize(state.globalStat?.downloadSpeed ?? 0),
|
||||
FileSize.getSize(state.globalStat?.uploadSpeed ?? 0)))
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
useBodyContainer: true);
|
||||
Container(
|
||||
color: FluentTheme.of(context).cardColor.withValues(alpha: .06),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 12, bottom: 3, top: 3),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 8,
|
||||
height: 8,
|
||||
decoration: BoxDecoration(
|
||||
color: state.isAvailable ? Colors.green : Colors.white,
|
||||
borderRadius: BorderRadius.circular(1000),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
S.current.downloader_info_download_upload_speed(
|
||||
FileSize.getSize((state.globalStat?.downloadSpeed ?? BigInt.zero).toInt()),
|
||||
FileSize.getSize((state.globalStat?.uploadSpeed ?? BigInt.zero).toInt()),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
useBodyContainer: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// ignore_for_file: avoid_build_context_in_providers, avoid_public_notifier_properties
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:aria2/aria2.dart';
|
||||
import 'package:fluent_ui/fluent_ui.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
@@ -9,9 +7,9 @@ import 'package:hive_ce/hive.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:starcitizen_doctor/common/helper/system_helper.dart';
|
||||
import 'package:starcitizen_doctor/common/rust/api/downloader_api.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/log.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/provider.dart';
|
||||
import 'package:starcitizen_doctor/provider/aria2c.dart';
|
||||
import 'package:starcitizen_doctor/provider/download_manager.dart';
|
||||
|
||||
import '../../../widgets/widgets.dart';
|
||||
|
||||
@@ -22,10 +20,10 @@ part 'home_downloader_ui_model.freezed.dart';
|
||||
@freezed
|
||||
abstract class HomeDownloaderUIState with _$HomeDownloaderUIState {
|
||||
factory HomeDownloaderUIState({
|
||||
@Default([]) List<Aria2Task> tasks,
|
||||
@Default([]) List<Aria2Task> waitingTasks,
|
||||
@Default([]) List<Aria2Task> stoppedTasks,
|
||||
Aria2GlobalStat? globalStat,
|
||||
@Default([]) List<DownloadTaskInfo> activeTasks,
|
||||
@Default([]) List<DownloadTaskInfo> waitingTasks,
|
||||
@Default([]) List<DownloadTaskInfo> stoppedTasks,
|
||||
DownloadGlobalStat? globalStat,
|
||||
}) = _HomeDownloaderUIState;
|
||||
}
|
||||
|
||||
@@ -40,12 +38,11 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel {
|
||||
bool _disposed = false;
|
||||
|
||||
final statusMap = {
|
||||
"active": S.current.downloader_info_downloading_status,
|
||||
"waiting": S.current.downloader_info_waiting,
|
||||
"live": S.current.downloader_info_downloading_status,
|
||||
"initializing": S.current.downloader_info_waiting,
|
||||
"paused": S.current.downloader_info_paused,
|
||||
"error": S.current.downloader_info_download_failed,
|
||||
"complete": S.current.downloader_info_download_completed,
|
||||
"removed": S.current.downloader_info_deleted,
|
||||
"finished": S.current.downloader_info_download_completed,
|
||||
};
|
||||
|
||||
final listHeaderStatusMap = {
|
||||
@@ -65,17 +62,17 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel {
|
||||
}
|
||||
|
||||
Future<void> onTapButton(BuildContext context, String key) async {
|
||||
final aria2cState = ref.read(aria2cModelProvider);
|
||||
final downloadManagerState = ref.read(downloadManagerProvider);
|
||||
final downloadManager = ref.read(downloadManagerProvider.notifier);
|
||||
|
||||
switch (key) {
|
||||
case "pause_all":
|
||||
if (!aria2cState.isRunning) return;
|
||||
await aria2cState.aria2c?.pauseAll();
|
||||
await aria2cState.aria2c?.saveSession();
|
||||
if (!downloadManagerState.isRunning) return;
|
||||
await downloadManager.pauseAll();
|
||||
return;
|
||||
case "resume_all":
|
||||
if (!aria2cState.isRunning) return;
|
||||
await aria2cState.aria2c?.unpauseAll();
|
||||
await aria2cState.aria2c?.saveSession();
|
||||
if (!downloadManagerState.isRunning) return;
|
||||
await downloadManager.resumeAll();
|
||||
return;
|
||||
case "cancel_all":
|
||||
final userOK = await showConfirmDialogs(
|
||||
@@ -84,12 +81,12 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel {
|
||||
Text(S.current.downloader_info_manual_file_deletion_note),
|
||||
);
|
||||
if (userOK == true) {
|
||||
if (!aria2cState.isRunning) return;
|
||||
if (!downloadManagerState.isRunning) return;
|
||||
try {
|
||||
for (var value in [...state.tasks, ...state.waitingTasks]) {
|
||||
await aria2cState.aria2c?.remove(value.gid!);
|
||||
final allTasks = [...state.activeTasks, ...state.waitingTasks];
|
||||
for (var task in allTasks) {
|
||||
await downloadManager.removeTask(task.id.toInt(), deleteFiles: false);
|
||||
}
|
||||
await aria2cState.aria2c?.saveSession();
|
||||
} catch (e) {
|
||||
dPrint("DownloadsUIModel cancel_all Error: $e");
|
||||
}
|
||||
@@ -102,91 +99,77 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel {
|
||||
}
|
||||
|
||||
int getTasksLen() {
|
||||
return state.tasks.length + state.waitingTasks.length + state.stoppedTasks.length;
|
||||
return state.activeTasks.length + state.waitingTasks.length + state.stoppedTasks.length;
|
||||
}
|
||||
|
||||
(Aria2Task, String, bool) getTaskAndType(int index) {
|
||||
final tempList = <Aria2Task>[...state.tasks, ...state.waitingTasks, ...state.stoppedTasks];
|
||||
if (index >= 0 && index < state.tasks.length) {
|
||||
(DownloadTaskInfo, String, bool) getTaskAndType(int index) {
|
||||
final tempList = <DownloadTaskInfo>[...state.activeTasks, ...state.waitingTasks, ...state.stoppedTasks];
|
||||
if (index >= 0 && index < state.activeTasks.length) {
|
||||
return (tempList[index], "active", index == 0);
|
||||
}
|
||||
if (index >= state.tasks.length && index < state.tasks.length + state.waitingTasks.length) {
|
||||
return (tempList[index], "waiting", index == state.tasks.length);
|
||||
if (index >= state.activeTasks.length && index < state.activeTasks.length + state.waitingTasks.length) {
|
||||
return (tempList[index], "waiting", index == state.activeTasks.length);
|
||||
}
|
||||
if (index >= state.tasks.length + state.waitingTasks.length && index < tempList.length) {
|
||||
return (tempList[index], "stopped", index == state.tasks.length + state.waitingTasks.length);
|
||||
if (index >= state.activeTasks.length + state.waitingTasks.length && index < tempList.length) {
|
||||
return (tempList[index], "stopped", index == state.activeTasks.length + state.waitingTasks.length);
|
||||
}
|
||||
throw Exception("Index out of range or element is null");
|
||||
}
|
||||
|
||||
static MapEntry<String, String> getTaskTypeAndName(Aria2Task task) {
|
||||
if (task.bittorrent == null) {
|
||||
String uri = task.files?[0]['uris'][0]['uri'] as String;
|
||||
return MapEntry("url", uri.split('/').last);
|
||||
} else if (task.bittorrent != null) {
|
||||
if (task.bittorrent!.containsKey('info')) {
|
||||
var btName = task.bittorrent?["info"]["name"];
|
||||
return MapEntry("torrent", btName ?? 'torrent');
|
||||
} else {
|
||||
return MapEntry("magnet", '[METADATA]${task.infoHash}');
|
||||
}
|
||||
} else {
|
||||
return const MapEntry("metaLink", '==========metaLink============');
|
||||
static MapEntry<String, String> getTaskTypeAndName(DownloadTaskInfo task) {
|
||||
// All tasks in rqbit are torrent-based
|
||||
return MapEntry("torrent", task.name);
|
||||
}
|
||||
|
||||
int getETA(DownloadTaskInfo task) {
|
||||
if (task.downloadSpeed == BigInt.zero) return 0;
|
||||
final remainingBytes = task.totalBytes - task.downloadedBytes;
|
||||
return (remainingBytes ~/ task.downloadSpeed).toInt();
|
||||
}
|
||||
|
||||
String getStatusString(DownloadTaskStatus status) {
|
||||
switch (status) {
|
||||
case DownloadTaskStatus.live:
|
||||
return "live";
|
||||
case DownloadTaskStatus.initializing:
|
||||
return "initializing";
|
||||
case DownloadTaskStatus.paused:
|
||||
return "paused";
|
||||
case DownloadTaskStatus.error:
|
||||
return "error";
|
||||
case DownloadTaskStatus.finished:
|
||||
return "finished";
|
||||
}
|
||||
}
|
||||
|
||||
int getETA(Aria2Task task) {
|
||||
if (task.downloadSpeed == null || task.downloadSpeed == 0) return 0;
|
||||
final remainingBytes = (task.totalLength ?? 0) - (task.completedLength ?? 0);
|
||||
return remainingBytes ~/ (task.downloadSpeed!);
|
||||
Future<void> resumeTask(int taskId) async {
|
||||
final downloadManager = ref.read(downloadManagerProvider.notifier);
|
||||
await downloadManager.resumeTask(taskId);
|
||||
}
|
||||
|
||||
Future<void> resumeTask(String? gid) async {
|
||||
final aria2c = ref.read(aria2cModelProvider).aria2c;
|
||||
if (gid != null) {
|
||||
await aria2c?.unpause(gid);
|
||||
}
|
||||
Future<void> pauseTask(int taskId) async {
|
||||
final downloadManager = ref.read(downloadManagerProvider.notifier);
|
||||
await downloadManager.pauseTask(taskId);
|
||||
}
|
||||
|
||||
Future<void> pauseTask(String? gid) async {
|
||||
final aria2c = ref.read(aria2cModelProvider).aria2c;
|
||||
if (gid != null) {
|
||||
await aria2c?.pause(gid);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> cancelTask(BuildContext context, String? gid) async {
|
||||
Future<void> cancelTask(BuildContext context, int taskId) async {
|
||||
await Future.delayed(const Duration(milliseconds: 300));
|
||||
if (gid != null) {
|
||||
if (!context.mounted) return;
|
||||
final ok = await showConfirmDialogs(
|
||||
context,
|
||||
S.current.downloader_action_confirm_cancel_download,
|
||||
Text(S.current.downloader_info_manual_file_deletion_note),
|
||||
);
|
||||
if (ok == true) {
|
||||
final aria2c = ref.read(aria2cModelProvider).aria2c;
|
||||
await aria2c?.remove(gid);
|
||||
await aria2c?.saveSession();
|
||||
}
|
||||
if (!context.mounted) return;
|
||||
final ok = await showConfirmDialogs(
|
||||
context,
|
||||
S.current.downloader_action_confirm_cancel_download,
|
||||
Text(S.current.downloader_info_manual_file_deletion_note),
|
||||
);
|
||||
if (ok == true) {
|
||||
final downloadManager = ref.read(downloadManagerProvider.notifier);
|
||||
await downloadManager.removeTask(taskId, deleteFiles: false);
|
||||
}
|
||||
}
|
||||
|
||||
List<Aria2File> getFilesFormTask(Aria2Task task) {
|
||||
List<Aria2File> l = [];
|
||||
if (task.files != null) {
|
||||
for (var element in task.files!) {
|
||||
final f = Aria2File.fromJson(element);
|
||||
l.add(f);
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
void openFolder(Aria2Task task) {
|
||||
final f = getFilesFormTask(task).firstOrNull;
|
||||
if (f != null) {
|
||||
SystemHelper.openDir(File(f.path!).absolute.path.replaceAll("/", "\\"));
|
||||
void openFolder(DownloadTaskInfo task) {
|
||||
final outputFolder = task.outputFolder;
|
||||
if (outputFolder.isNotEmpty) {
|
||||
SystemHelper.openDir(outputFolder.replaceAll("/", "\\"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,21 +177,39 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel {
|
||||
try {
|
||||
while (true) {
|
||||
if (_disposed) return;
|
||||
final aria2cState = ref.read(aria2cModelProvider);
|
||||
if (aria2cState.isRunning) {
|
||||
final aria2c = aria2cState.aria2c!;
|
||||
final tasks = await aria2c.tellActive();
|
||||
final waitingTasks = await aria2c.tellWaiting(0, 1000000);
|
||||
final stoppedTasks = await aria2c.tellStopped(0, 1000000);
|
||||
final globalStat = await aria2c.getGlobalStat();
|
||||
final downloadManagerState = ref.read(downloadManagerProvider);
|
||||
if (downloadManagerState.isRunning) {
|
||||
final downloadManager = ref.read(downloadManagerProvider.notifier);
|
||||
final allTasks = await downloadManager.getAllTasks();
|
||||
|
||||
final activeTasks = <DownloadTaskInfo>[];
|
||||
final waitingTasks = <DownloadTaskInfo>[];
|
||||
final stoppedTasks = <DownloadTaskInfo>[];
|
||||
|
||||
for (var task in allTasks) {
|
||||
switch (task.status) {
|
||||
case DownloadTaskStatus.live:
|
||||
activeTasks.add(task);
|
||||
break;
|
||||
case DownloadTaskStatus.initializing:
|
||||
case DownloadTaskStatus.paused:
|
||||
waitingTasks.add(task);
|
||||
break;
|
||||
case DownloadTaskStatus.finished:
|
||||
case DownloadTaskStatus.error:
|
||||
stoppedTasks.add(task);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
state = state.copyWith(
|
||||
tasks: tasks,
|
||||
activeTasks: activeTasks,
|
||||
waitingTasks: waitingTasks,
|
||||
stoppedTasks: stoppedTasks,
|
||||
globalStat: globalStat,
|
||||
globalStat: downloadManagerState.globalStat,
|
||||
);
|
||||
} else {
|
||||
state = state.copyWith(tasks: [], waitingTasks: [], stoppedTasks: [], globalStat: null);
|
||||
state = state.copyWith(activeTasks: [], waitingTasks: [], stoppedTasks: [], globalStat: null);
|
||||
}
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
}
|
||||
@@ -266,22 +267,14 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel {
|
||||
),
|
||||
);
|
||||
if (ok == true) {
|
||||
final aria2cState = ref.read(aria2cModelProvider);
|
||||
final aria2cModel = ref.read(aria2cModelProvider.notifier);
|
||||
await aria2cModel.launchDaemon(appGlobalState.applicationBinaryModuleDir!);
|
||||
final aria2c = aria2cState.aria2c!;
|
||||
final upByte = aria2cModel.textToByte(upCtrl.text.trim());
|
||||
final downByte = aria2cModel.textToByte(downCtrl.text.trim());
|
||||
final r = await aria2c
|
||||
.changeGlobalOption(
|
||||
Aria2Option()
|
||||
..maxOverallUploadLimit = upByte
|
||||
..maxOverallDownloadLimit = downByte,
|
||||
)
|
||||
.unwrap();
|
||||
if (r != null) {
|
||||
await box.put('downloader_up_limit', upCtrl.text.trim());
|
||||
await box.put('downloader_down_limit', downCtrl.text.trim());
|
||||
// Note: rqbit doesn't support dynamic speed limit changes yet
|
||||
// Just save the settings for now
|
||||
await box.put('downloader_up_limit', upCtrl.text.trim());
|
||||
await box.put('downloader_down_limit', downCtrl.text.trim());
|
||||
|
||||
// Show info that speed limits will apply on next restart
|
||||
if (context.mounted) {
|
||||
showToast(context, "Speed limit settings saved. Will apply on next download.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$HomeDownloaderUIState {
|
||||
|
||||
List<Aria2Task> get tasks; List<Aria2Task> get waitingTasks; List<Aria2Task> get stoppedTasks; Aria2GlobalStat? get globalStat;
|
||||
List<DownloadTaskInfo> get activeTasks; List<DownloadTaskInfo> get waitingTasks; List<DownloadTaskInfo> get stoppedTasks; DownloadGlobalStat? get globalStat;
|
||||
/// Create a copy of HomeDownloaderUIState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@@ -25,16 +25,16 @@ $HomeDownloaderUIStateCopyWith<HomeDownloaderUIState> get copyWith => _$HomeDown
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is HomeDownloaderUIState&&const DeepCollectionEquality().equals(other.tasks, tasks)&&const DeepCollectionEquality().equals(other.waitingTasks, waitingTasks)&&const DeepCollectionEquality().equals(other.stoppedTasks, stoppedTasks)&&(identical(other.globalStat, globalStat) || other.globalStat == globalStat));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is HomeDownloaderUIState&&const DeepCollectionEquality().equals(other.activeTasks, activeTasks)&&const DeepCollectionEquality().equals(other.waitingTasks, waitingTasks)&&const DeepCollectionEquality().equals(other.stoppedTasks, stoppedTasks)&&(identical(other.globalStat, globalStat) || other.globalStat == globalStat));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(tasks),const DeepCollectionEquality().hash(waitingTasks),const DeepCollectionEquality().hash(stoppedTasks),globalStat);
|
||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(activeTasks),const DeepCollectionEquality().hash(waitingTasks),const DeepCollectionEquality().hash(stoppedTasks),globalStat);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HomeDownloaderUIState(tasks: $tasks, waitingTasks: $waitingTasks, stoppedTasks: $stoppedTasks, globalStat: $globalStat)';
|
||||
return 'HomeDownloaderUIState(activeTasks: $activeTasks, waitingTasks: $waitingTasks, stoppedTasks: $stoppedTasks, globalStat: $globalStat)';
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ abstract mixin class $HomeDownloaderUIStateCopyWith<$Res> {
|
||||
factory $HomeDownloaderUIStateCopyWith(HomeDownloaderUIState value, $Res Function(HomeDownloaderUIState) _then) = _$HomeDownloaderUIStateCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
List<Aria2Task> tasks, List<Aria2Task> waitingTasks, List<Aria2Task> stoppedTasks, Aria2GlobalStat? globalStat
|
||||
List<DownloadTaskInfo> activeTasks, List<DownloadTaskInfo> waitingTasks, List<DownloadTaskInfo> stoppedTasks, DownloadGlobalStat? globalStat
|
||||
});
|
||||
|
||||
|
||||
@@ -62,13 +62,13 @@ class _$HomeDownloaderUIStateCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of HomeDownloaderUIState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? tasks = null,Object? waitingTasks = null,Object? stoppedTasks = null,Object? globalStat = freezed,}) {
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? activeTasks = null,Object? waitingTasks = null,Object? stoppedTasks = null,Object? globalStat = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
tasks: null == tasks ? _self.tasks : tasks // ignore: cast_nullable_to_non_nullable
|
||||
as List<Aria2Task>,waitingTasks: null == waitingTasks ? _self.waitingTasks : waitingTasks // ignore: cast_nullable_to_non_nullable
|
||||
as List<Aria2Task>,stoppedTasks: null == stoppedTasks ? _self.stoppedTasks : stoppedTasks // ignore: cast_nullable_to_non_nullable
|
||||
as List<Aria2Task>,globalStat: freezed == globalStat ? _self.globalStat : globalStat // ignore: cast_nullable_to_non_nullable
|
||||
as Aria2GlobalStat?,
|
||||
activeTasks: null == activeTasks ? _self.activeTasks : activeTasks // ignore: cast_nullable_to_non_nullable
|
||||
as List<DownloadTaskInfo>,waitingTasks: null == waitingTasks ? _self.waitingTasks : waitingTasks // ignore: cast_nullable_to_non_nullable
|
||||
as List<DownloadTaskInfo>,stoppedTasks: null == stoppedTasks ? _self.stoppedTasks : stoppedTasks // ignore: cast_nullable_to_non_nullable
|
||||
as List<DownloadTaskInfo>,globalStat: freezed == globalStat ? _self.globalStat : globalStat // ignore: cast_nullable_to_non_nullable
|
||||
as DownloadGlobalStat?,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -153,10 +153,10 @@ return $default(_that);case _:
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<Aria2Task> tasks, List<Aria2Task> waitingTasks, List<Aria2Task> stoppedTasks, Aria2GlobalStat? globalStat)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<DownloadTaskInfo> activeTasks, List<DownloadTaskInfo> waitingTasks, List<DownloadTaskInfo> stoppedTasks, DownloadGlobalStat? globalStat)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _HomeDownloaderUIState() when $default != null:
|
||||
return $default(_that.tasks,_that.waitingTasks,_that.stoppedTasks,_that.globalStat);case _:
|
||||
return $default(_that.activeTasks,_that.waitingTasks,_that.stoppedTasks,_that.globalStat);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
@@ -174,10 +174,10 @@ return $default(_that.tasks,_that.waitingTasks,_that.stoppedTasks,_that.globalSt
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<Aria2Task> tasks, List<Aria2Task> waitingTasks, List<Aria2Task> stoppedTasks, Aria2GlobalStat? globalStat) $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<DownloadTaskInfo> activeTasks, List<DownloadTaskInfo> waitingTasks, List<DownloadTaskInfo> stoppedTasks, DownloadGlobalStat? globalStat) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _HomeDownloaderUIState():
|
||||
return $default(_that.tasks,_that.waitingTasks,_that.stoppedTasks,_that.globalStat);case _:
|
||||
return $default(_that.activeTasks,_that.waitingTasks,_that.stoppedTasks,_that.globalStat);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
@@ -194,10 +194,10 @@ return $default(_that.tasks,_that.waitingTasks,_that.stoppedTasks,_that.globalSt
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<Aria2Task> tasks, List<Aria2Task> waitingTasks, List<Aria2Task> stoppedTasks, Aria2GlobalStat? globalStat)? $default,) {final _that = this;
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<DownloadTaskInfo> activeTasks, List<DownloadTaskInfo> waitingTasks, List<DownloadTaskInfo> stoppedTasks, DownloadGlobalStat? globalStat)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _HomeDownloaderUIState() when $default != null:
|
||||
return $default(_that.tasks,_that.waitingTasks,_that.stoppedTasks,_that.globalStat);case _:
|
||||
return $default(_that.activeTasks,_that.waitingTasks,_that.stoppedTasks,_that.globalStat);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
@@ -209,31 +209,31 @@ return $default(_that.tasks,_that.waitingTasks,_that.stoppedTasks,_that.globalSt
|
||||
|
||||
|
||||
class _HomeDownloaderUIState implements HomeDownloaderUIState {
|
||||
_HomeDownloaderUIState({final List<Aria2Task> tasks = const [], final List<Aria2Task> waitingTasks = const [], final List<Aria2Task> stoppedTasks = const [], this.globalStat}): _tasks = tasks,_waitingTasks = waitingTasks,_stoppedTasks = stoppedTasks;
|
||||
_HomeDownloaderUIState({final List<DownloadTaskInfo> activeTasks = const [], final List<DownloadTaskInfo> waitingTasks = const [], final List<DownloadTaskInfo> stoppedTasks = const [], this.globalStat}): _activeTasks = activeTasks,_waitingTasks = waitingTasks,_stoppedTasks = stoppedTasks;
|
||||
|
||||
|
||||
final List<Aria2Task> _tasks;
|
||||
@override@JsonKey() List<Aria2Task> get tasks {
|
||||
if (_tasks is EqualUnmodifiableListView) return _tasks;
|
||||
final List<DownloadTaskInfo> _activeTasks;
|
||||
@override@JsonKey() List<DownloadTaskInfo> get activeTasks {
|
||||
if (_activeTasks is EqualUnmodifiableListView) return _activeTasks;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_tasks);
|
||||
return EqualUnmodifiableListView(_activeTasks);
|
||||
}
|
||||
|
||||
final List<Aria2Task> _waitingTasks;
|
||||
@override@JsonKey() List<Aria2Task> get waitingTasks {
|
||||
final List<DownloadTaskInfo> _waitingTasks;
|
||||
@override@JsonKey() List<DownloadTaskInfo> get waitingTasks {
|
||||
if (_waitingTasks is EqualUnmodifiableListView) return _waitingTasks;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_waitingTasks);
|
||||
}
|
||||
|
||||
final List<Aria2Task> _stoppedTasks;
|
||||
@override@JsonKey() List<Aria2Task> get stoppedTasks {
|
||||
final List<DownloadTaskInfo> _stoppedTasks;
|
||||
@override@JsonKey() List<DownloadTaskInfo> get stoppedTasks {
|
||||
if (_stoppedTasks is EqualUnmodifiableListView) return _stoppedTasks;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_stoppedTasks);
|
||||
}
|
||||
|
||||
@override final Aria2GlobalStat? globalStat;
|
||||
@override final DownloadGlobalStat? globalStat;
|
||||
|
||||
/// Create a copy of HomeDownloaderUIState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -245,16 +245,16 @@ _$HomeDownloaderUIStateCopyWith<_HomeDownloaderUIState> get copyWith => __$HomeD
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _HomeDownloaderUIState&&const DeepCollectionEquality().equals(other._tasks, _tasks)&&const DeepCollectionEquality().equals(other._waitingTasks, _waitingTasks)&&const DeepCollectionEquality().equals(other._stoppedTasks, _stoppedTasks)&&(identical(other.globalStat, globalStat) || other.globalStat == globalStat));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _HomeDownloaderUIState&&const DeepCollectionEquality().equals(other._activeTasks, _activeTasks)&&const DeepCollectionEquality().equals(other._waitingTasks, _waitingTasks)&&const DeepCollectionEquality().equals(other._stoppedTasks, _stoppedTasks)&&(identical(other.globalStat, globalStat) || other.globalStat == globalStat));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_tasks),const DeepCollectionEquality().hash(_waitingTasks),const DeepCollectionEquality().hash(_stoppedTasks),globalStat);
|
||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_activeTasks),const DeepCollectionEquality().hash(_waitingTasks),const DeepCollectionEquality().hash(_stoppedTasks),globalStat);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'HomeDownloaderUIState(tasks: $tasks, waitingTasks: $waitingTasks, stoppedTasks: $stoppedTasks, globalStat: $globalStat)';
|
||||
return 'HomeDownloaderUIState(activeTasks: $activeTasks, waitingTasks: $waitingTasks, stoppedTasks: $stoppedTasks, globalStat: $globalStat)';
|
||||
}
|
||||
|
||||
|
||||
@@ -265,7 +265,7 @@ abstract mixin class _$HomeDownloaderUIStateCopyWith<$Res> implements $HomeDownl
|
||||
factory _$HomeDownloaderUIStateCopyWith(_HomeDownloaderUIState value, $Res Function(_HomeDownloaderUIState) _then) = __$HomeDownloaderUIStateCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
List<Aria2Task> tasks, List<Aria2Task> waitingTasks, List<Aria2Task> stoppedTasks, Aria2GlobalStat? globalStat
|
||||
List<DownloadTaskInfo> activeTasks, List<DownloadTaskInfo> waitingTasks, List<DownloadTaskInfo> stoppedTasks, DownloadGlobalStat? globalStat
|
||||
});
|
||||
|
||||
|
||||
@@ -282,13 +282,13 @@ class __$HomeDownloaderUIStateCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of HomeDownloaderUIState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? tasks = null,Object? waitingTasks = null,Object? stoppedTasks = null,Object? globalStat = freezed,}) {
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? activeTasks = null,Object? waitingTasks = null,Object? stoppedTasks = null,Object? globalStat = freezed,}) {
|
||||
return _then(_HomeDownloaderUIState(
|
||||
tasks: null == tasks ? _self._tasks : tasks // ignore: cast_nullable_to_non_nullable
|
||||
as List<Aria2Task>,waitingTasks: null == waitingTasks ? _self._waitingTasks : waitingTasks // ignore: cast_nullable_to_non_nullable
|
||||
as List<Aria2Task>,stoppedTasks: null == stoppedTasks ? _self._stoppedTasks : stoppedTasks // ignore: cast_nullable_to_non_nullable
|
||||
as List<Aria2Task>,globalStat: freezed == globalStat ? _self.globalStat : globalStat // ignore: cast_nullable_to_non_nullable
|
||||
as Aria2GlobalStat?,
|
||||
activeTasks: null == activeTasks ? _self._activeTasks : activeTasks // ignore: cast_nullable_to_non_nullable
|
||||
as List<DownloadTaskInfo>,waitingTasks: null == waitingTasks ? _self._waitingTasks : waitingTasks // ignore: cast_nullable_to_non_nullable
|
||||
as List<DownloadTaskInfo>,stoppedTasks: null == stoppedTasks ? _self._stoppedTasks : stoppedTasks // ignore: cast_nullable_to_non_nullable
|
||||
as List<DownloadTaskInfo>,globalStat: freezed == globalStat ? _self.globalStat : globalStat // ignore: cast_nullable_to_non_nullable
|
||||
as DownloadGlobalStat?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ final class HomeDownloaderUIModelProvider
|
||||
}
|
||||
|
||||
String _$homeDownloaderUIModelHash() =>
|
||||
r'cb5d0973d56bbf40673afc2a734b49f5d034ab98';
|
||||
r'27e2e4b7a5103eee9d489a347410131edef46be4';
|
||||
|
||||
abstract class _$HomeDownloaderUIModel
|
||||
extends $Notifier<HomeDownloaderUIState> {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// ignore_for_file: avoid_build_context_in_providers, use_build_context_synchronously
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
@@ -14,7 +13,7 @@ import 'package:starcitizen_doctor/common/utils/async.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/base_utils.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/log.dart';
|
||||
import 'package:starcitizen_doctor/common/utils/provider.dart';
|
||||
import 'package:starcitizen_doctor/provider/aria2c.dart';
|
||||
import 'package:starcitizen_doctor/provider/download_manager.dart';
|
||||
import 'package:starcitizen_doctor/ui/home/localization/localization_ui_model.dart';
|
||||
import 'package:starcitizen_doctor/common/rust/api/ort_api.dart' as ort;
|
||||
|
||||
@@ -240,11 +239,10 @@ class InputMethodDialogUIModel extends _$InputMethodDialogUIModel {
|
||||
Future<String> doDownloadTranslateModel() async {
|
||||
state = state.copyWith(isAutoTranslateWorking: true);
|
||||
try {
|
||||
final aria2cManager = ref.read(aria2cModelProvider.notifier);
|
||||
await aria2cManager.launchDaemon(appGlobalState.applicationBinaryModuleDir!);
|
||||
final aria2c = ref.read(aria2cModelProvider).aria2c!;
|
||||
final downloadManager = ref.read(downloadManagerProvider.notifier);
|
||||
await downloadManager.initDownloader();
|
||||
|
||||
if (await aria2cManager.isNameInTask(_localTranslateModelName)) {
|
||||
if (await downloadManager.isNameInTask(_localTranslateModelName)) {
|
||||
throw Exception("Model is already downloading");
|
||||
}
|
||||
|
||||
@@ -259,9 +257,8 @@ class InputMethodDialogUIModel extends _$InputMethodDialogUIModel {
|
||||
}
|
||||
// get torrent Data
|
||||
final data = await RSHttp.get(torrentUrl!);
|
||||
final b64Str = base64Encode(data.data!);
|
||||
final gid = await aria2c.addTorrent(b64Str, extraParams: {"dir": _localTranslateModelDir});
|
||||
return gid;
|
||||
final taskId = await downloadManager.addTorrent(data.data!, outputFolder: _localTranslateModelDir);
|
||||
return taskId.toString();
|
||||
} catch (e) {
|
||||
dPrint("[InputMethodDialogUIModel] doDownloadTranslateModel error: $e");
|
||||
rethrow;
|
||||
@@ -330,8 +327,8 @@ class InputMethodDialogUIModel extends _$InputMethodDialogUIModel {
|
||||
}
|
||||
|
||||
Future<bool> isTranslateModelDownloading() async {
|
||||
final aria2cManager = ref.read(aria2cModelProvider.notifier);
|
||||
return await aria2cManager.isNameInTask(_localTranslateModelName);
|
||||
final downloadManager = ref.read(downloadManagerProvider.notifier);
|
||||
return await downloadManager.isNameInTask(_localTranslateModelName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ final class InputMethodDialogUIModelProvider
|
||||
}
|
||||
|
||||
String _$inputMethodDialogUIModelHash() =>
|
||||
r'bd96c85ef2073d80de6eba71748b41adb8861e1c';
|
||||
r'5c2989faf94d43bb814e5b80e10d68416c8241ec';
|
||||
|
||||
abstract class _$InputMethodDialogUIModel
|
||||
extends $Notifier<InputMethodDialogUIState> {
|
||||
|
||||
Reference in New Issue
Block a user