mirror of
https://github.com/StarCitizenToolBox/app.git
synced 2026-01-13 19:50:28 +00:00
feat: downloader update
This commit is contained in:
parent
8ea5373dec
commit
fbf40580cf
@ -86,6 +86,7 @@ Future<void> downloaderResume({required BigInt taskId}) =>
|
|||||||
RustLib.instance.api.crateApiDownloaderApiDownloaderResume(taskId: taskId);
|
RustLib.instance.api.crateApiDownloaderApiDownloaderResume(taskId: taskId);
|
||||||
|
|
||||||
/// Remove a download task
|
/// Remove a download task
|
||||||
|
/// Handles both active tasks (task_id < 10000) and cached completed tasks (task_id >= 10000)
|
||||||
Future<void> downloaderRemove({
|
Future<void> downloaderRemove({
|
||||||
required BigInt taskId,
|
required BigInt taskId,
|
||||||
required bool deleteFiles,
|
required bool deleteFiles,
|
||||||
@ -100,7 +101,7 @@ Future<DownloadTaskInfo> downloaderGetTaskInfo({required BigInt taskId}) =>
|
|||||||
taskId: taskId,
|
taskId: taskId,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Get all tasks
|
/// Get all tasks (includes both active and completed tasks from cache)
|
||||||
Future<List<DownloadTaskInfo>> downloaderGetAllTasks() =>
|
Future<List<DownloadTaskInfo>> downloaderGetAllTasks() =>
|
||||||
RustLib.instance.api.crateApiDownloaderApiDownloaderGetAllTasks();
|
RustLib.instance.api.crateApiDownloaderApiDownloaderGetAllTasks();
|
||||||
|
|
||||||
@ -109,10 +110,17 @@ Future<DownloadGlobalStat> downloaderGetGlobalStats() =>
|
|||||||
RustLib.instance.api.crateApiDownloaderApiDownloaderGetGlobalStats();
|
RustLib.instance.api.crateApiDownloaderApiDownloaderGetGlobalStats();
|
||||||
|
|
||||||
/// Check if a task with given name exists
|
/// Check if a task with given name exists
|
||||||
Future<bool> downloaderIsNameInTask({required String name}) => RustLib
|
///
|
||||||
.instance
|
/// Parameters:
|
||||||
.api
|
/// - name: Task name to search for
|
||||||
.crateApiDownloaderApiDownloaderIsNameInTask(name: name);
|
/// - downloading_only: If true, only search in active/waiting tasks. If false, include completed tasks (default: true)
|
||||||
|
Future<bool> downloaderIsNameInTask({
|
||||||
|
required String name,
|
||||||
|
bool? downloadingOnly,
|
||||||
|
}) => RustLib.instance.api.crateApiDownloaderApiDownloaderIsNameInTask(
|
||||||
|
name: name,
|
||||||
|
downloadingOnly: downloadingOnly,
|
||||||
|
);
|
||||||
|
|
||||||
/// Pause all tasks
|
/// Pause all tasks
|
||||||
Future<void> downloaderPauseAll() =>
|
Future<void> downloaderPauseAll() =>
|
||||||
|
|||||||
@ -148,6 +148,7 @@ abstract class RustLibApi extends BaseApi {
|
|||||||
|
|
||||||
Future<bool> crateApiDownloaderApiDownloaderIsNameInTask({
|
Future<bool> crateApiDownloaderApiDownloaderIsNameInTask({
|
||||||
required String name,
|
required String name,
|
||||||
|
bool? downloadingOnly,
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<void> crateApiDownloaderApiDownloaderPause({required BigInt taskId});
|
Future<void> crateApiDownloaderApiDownloaderPause({required BigInt taskId});
|
||||||
@ -912,15 +913,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
@override
|
@override
|
||||||
Future<bool> crateApiDownloaderApiDownloaderIsNameInTask({
|
Future<bool> crateApiDownloaderApiDownloaderIsNameInTask({
|
||||||
required String name,
|
required String name,
|
||||||
|
bool? downloadingOnly,
|
||||||
}) {
|
}) {
|
||||||
return handler.executeNormal(
|
return handler.executeNormal(
|
||||||
NormalTask(
|
NormalTask(
|
||||||
callFfi: (port_) {
|
callFfi: (port_) {
|
||||||
var arg0 = cst_encode_String(name);
|
var arg0 = cst_encode_String(name);
|
||||||
|
var arg1 = cst_encode_opt_box_autoadd_bool(downloadingOnly);
|
||||||
return wire
|
return wire
|
||||||
.wire__crate__api__downloader_api__downloader_is_name_in_task(
|
.wire__crate__api__downloader_api__downloader_is_name_in_task(
|
||||||
port_,
|
port_,
|
||||||
arg0,
|
arg0,
|
||||||
|
arg1,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
codec: DcoCodec(
|
codec: DcoCodec(
|
||||||
@ -928,7 +932,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
decodeErrorData: null,
|
decodeErrorData: null,
|
||||||
),
|
),
|
||||||
constMeta: kCrateApiDownloaderApiDownloaderIsNameInTaskConstMeta,
|
constMeta: kCrateApiDownloaderApiDownloaderIsNameInTaskConstMeta,
|
||||||
argValues: [name],
|
argValues: [name, downloadingOnly],
|
||||||
apiImpl: this,
|
apiImpl: this,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -937,7 +941,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
TaskConstMeta get kCrateApiDownloaderApiDownloaderIsNameInTaskConstMeta =>
|
TaskConstMeta get kCrateApiDownloaderApiDownloaderIsNameInTaskConstMeta =>
|
||||||
const TaskConstMeta(
|
const TaskConstMeta(
|
||||||
debugName: "downloader_is_name_in_task",
|
debugName: "downloader_is_name_in_task",
|
||||||
argNames: ["name"],
|
argNames: ["name", "downloadingOnly"],
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@ -1494,10 +1494,12 @@ class RustLibWire implements BaseWire {
|
|||||||
void wire__crate__api__downloader_api__downloader_is_name_in_task(
|
void wire__crate__api__downloader_api__downloader_is_name_in_task(
|
||||||
int port_,
|
int port_,
|
||||||
ffi.Pointer<wire_cst_list_prim_u_8_strict> name,
|
ffi.Pointer<wire_cst_list_prim_u_8_strict> name,
|
||||||
|
ffi.Pointer<ffi.Bool> downloading_only,
|
||||||
) {
|
) {
|
||||||
return _wire__crate__api__downloader_api__downloader_is_name_in_task(
|
return _wire__crate__api__downloader_api__downloader_is_name_in_task(
|
||||||
port_,
|
port_,
|
||||||
name,
|
name,
|
||||||
|
downloading_only,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1507,6 +1509,7 @@ class RustLibWire implements BaseWire {
|
|||||||
ffi.Void Function(
|
ffi.Void Function(
|
||||||
ffi.Int64,
|
ffi.Int64,
|
||||||
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||||
|
ffi.Pointer<ffi.Bool>,
|
||||||
)
|
)
|
||||||
>
|
>
|
||||||
>(
|
>(
|
||||||
@ -1515,7 +1518,11 @@ class RustLibWire implements BaseWire {
|
|||||||
late final _wire__crate__api__downloader_api__downloader_is_name_in_task =
|
late final _wire__crate__api__downloader_api__downloader_is_name_in_task =
|
||||||
_wire__crate__api__downloader_api__downloader_is_name_in_taskPtr
|
_wire__crate__api__downloader_api__downloader_is_name_in_taskPtr
|
||||||
.asFunction<
|
.asFunction<
|
||||||
void Function(int, ffi.Pointer<wire_cst_list_prim_u_8_strict>)
|
void Function(
|
||||||
|
int,
|
||||||
|
ffi.Pointer<wire_cst_list_prim_u_8_strict>,
|
||||||
|
ffi.Pointer<ffi.Bool>,
|
||||||
|
)
|
||||||
>();
|
>();
|
||||||
|
|
||||||
void wire__crate__api__downloader_api__downloader_pause(
|
void wire__crate__api__downloader_api__downloader_pause(
|
||||||
|
|||||||
@ -596,6 +596,9 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"downloader_action_cancel_download": MessageLookupByLibrary.simpleMessage(
|
"downloader_action_cancel_download": MessageLookupByLibrary.simpleMessage(
|
||||||
"Cancel Download",
|
"Cancel Download",
|
||||||
),
|
),
|
||||||
|
"downloader_action_clear_completed": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"Clear Completed",
|
||||||
|
),
|
||||||
"downloader_action_confirm_cancel_all_tasks":
|
"downloader_action_confirm_cancel_all_tasks":
|
||||||
MessageLookupByLibrary.simpleMessage(
|
MessageLookupByLibrary.simpleMessage(
|
||||||
"Confirm cancellation of all tasks?",
|
"Confirm cancellation of all tasks?",
|
||||||
@ -616,6 +619,9 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"downloader_action_pause_download": MessageLookupByLibrary.simpleMessage(
|
"downloader_action_pause_download": MessageLookupByLibrary.simpleMessage(
|
||||||
"Pause Download",
|
"Pause Download",
|
||||||
),
|
),
|
||||||
|
"downloader_action_remove_record": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"Remove Record",
|
||||||
|
),
|
||||||
"downloader_action_restart_later": MessageLookupByLibrary.simpleMessage(
|
"downloader_action_restart_later": MessageLookupByLibrary.simpleMessage(
|
||||||
"Apply Later",
|
"Apply Later",
|
||||||
),
|
),
|
||||||
|
|||||||
@ -539,6 +539,9 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"downloader_action_cancel_download": MessageLookupByLibrary.simpleMessage(
|
"downloader_action_cancel_download": MessageLookupByLibrary.simpleMessage(
|
||||||
"ダウンロードをキャンセル",
|
"ダウンロードをキャンセル",
|
||||||
),
|
),
|
||||||
|
"downloader_action_clear_completed": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"完了をクリア",
|
||||||
|
),
|
||||||
"downloader_action_confirm_cancel_all_tasks":
|
"downloader_action_confirm_cancel_all_tasks":
|
||||||
MessageLookupByLibrary.simpleMessage("すべてのタスクをキャンセルしますか?"),
|
MessageLookupByLibrary.simpleMessage("すべてのタスクをキャンセルしますか?"),
|
||||||
"downloader_action_confirm_cancel_download":
|
"downloader_action_confirm_cancel_download":
|
||||||
@ -553,6 +556,9 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"downloader_action_pause_download": MessageLookupByLibrary.simpleMessage(
|
"downloader_action_pause_download": MessageLookupByLibrary.simpleMessage(
|
||||||
"ダウンロードを一時停止",
|
"ダウンロードを一時停止",
|
||||||
),
|
),
|
||||||
|
"downloader_action_remove_record": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"レコードを削除",
|
||||||
|
),
|
||||||
"downloader_action_restart_later": MessageLookupByLibrary.simpleMessage(
|
"downloader_action_restart_later": MessageLookupByLibrary.simpleMessage(
|
||||||
"後で適用",
|
"後で適用",
|
||||||
),
|
),
|
||||||
|
|||||||
@ -579,6 +579,9 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"downloader_action_cancel_download": MessageLookupByLibrary.simpleMessage(
|
"downloader_action_cancel_download": MessageLookupByLibrary.simpleMessage(
|
||||||
"Отменить загрузку",
|
"Отменить загрузку",
|
||||||
),
|
),
|
||||||
|
"downloader_action_clear_completed": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"Очистить завершённые",
|
||||||
|
),
|
||||||
"downloader_action_confirm_cancel_all_tasks":
|
"downloader_action_confirm_cancel_all_tasks":
|
||||||
MessageLookupByLibrary.simpleMessage("Подтвердите отмену всех задач?"),
|
MessageLookupByLibrary.simpleMessage("Подтвердите отмену всех задач?"),
|
||||||
"downloader_action_confirm_cancel_download":
|
"downloader_action_confirm_cancel_download":
|
||||||
@ -593,6 +596,9 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"downloader_action_pause_download": MessageLookupByLibrary.simpleMessage(
|
"downloader_action_pause_download": MessageLookupByLibrary.simpleMessage(
|
||||||
"Приостановить загрузку",
|
"Приостановить загрузку",
|
||||||
),
|
),
|
||||||
|
"downloader_action_remove_record": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"Удалить запись",
|
||||||
|
),
|
||||||
"downloader_action_restart_later": MessageLookupByLibrary.simpleMessage(
|
"downloader_action_restart_later": MessageLookupByLibrary.simpleMessage(
|
||||||
"Применить позже",
|
"Применить позже",
|
||||||
),
|
),
|
||||||
|
|||||||
@ -528,6 +528,9 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"downloader_action_cancel_download": MessageLookupByLibrary.simpleMessage(
|
"downloader_action_cancel_download": MessageLookupByLibrary.simpleMessage(
|
||||||
"取消下载",
|
"取消下载",
|
||||||
),
|
),
|
||||||
|
"downloader_action_clear_completed": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"清除已完成",
|
||||||
|
),
|
||||||
"downloader_action_confirm_cancel_all_tasks":
|
"downloader_action_confirm_cancel_all_tasks":
|
||||||
MessageLookupByLibrary.simpleMessage("确认取消全部任务?"),
|
MessageLookupByLibrary.simpleMessage("确认取消全部任务?"),
|
||||||
"downloader_action_confirm_cancel_download":
|
"downloader_action_confirm_cancel_download":
|
||||||
@ -540,6 +543,9 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"downloader_action_pause_download": MessageLookupByLibrary.simpleMessage(
|
"downloader_action_pause_download": MessageLookupByLibrary.simpleMessage(
|
||||||
"暂停下载",
|
"暂停下载",
|
||||||
),
|
),
|
||||||
|
"downloader_action_remove_record": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"移除记录",
|
||||||
|
),
|
||||||
"downloader_action_restart_later": MessageLookupByLibrary.simpleMessage(
|
"downloader_action_restart_later": MessageLookupByLibrary.simpleMessage(
|
||||||
"下次启动时生效",
|
"下次启动时生效",
|
||||||
),
|
),
|
||||||
|
|||||||
@ -512,6 +512,9 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"downloader_action_cancel_download": MessageLookupByLibrary.simpleMessage(
|
"downloader_action_cancel_download": MessageLookupByLibrary.simpleMessage(
|
||||||
"取消下載",
|
"取消下載",
|
||||||
),
|
),
|
||||||
|
"downloader_action_clear_completed": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"清除已完成",
|
||||||
|
),
|
||||||
"downloader_action_confirm_cancel_all_tasks":
|
"downloader_action_confirm_cancel_all_tasks":
|
||||||
MessageLookupByLibrary.simpleMessage("確認取消全部任務?"),
|
MessageLookupByLibrary.simpleMessage("確認取消全部任務?"),
|
||||||
"downloader_action_confirm_cancel_download":
|
"downloader_action_confirm_cancel_download":
|
||||||
@ -524,6 +527,9 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"downloader_action_pause_download": MessageLookupByLibrary.simpleMessage(
|
"downloader_action_pause_download": MessageLookupByLibrary.simpleMessage(
|
||||||
"暫停下載",
|
"暫停下載",
|
||||||
),
|
),
|
||||||
|
"downloader_action_remove_record": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"移除記錄",
|
||||||
|
),
|
||||||
"downloader_action_restart_later": MessageLookupByLibrary.simpleMessage(
|
"downloader_action_restart_later": MessageLookupByLibrary.simpleMessage(
|
||||||
"稍後套用",
|
"稍後套用",
|
||||||
),
|
),
|
||||||
|
|||||||
@ -28,10 +28,9 @@ class S {
|
|||||||
static const AppLocalizationDelegate delegate = AppLocalizationDelegate();
|
static const AppLocalizationDelegate delegate = AppLocalizationDelegate();
|
||||||
|
|
||||||
static Future<S> load(Locale locale) {
|
static Future<S> load(Locale locale) {
|
||||||
final name =
|
final name = (locale.countryCode?.isEmpty ?? false)
|
||||||
(locale.countryCode?.isEmpty ?? false)
|
? locale.languageCode
|
||||||
? locale.languageCode
|
: locale.toString();
|
||||||
: locale.toString();
|
|
||||||
final localeName = Intl.canonicalizedLocale(name);
|
final localeName = Intl.canonicalizedLocale(name);
|
||||||
return initializeMessages(localeName).then((_) {
|
return initializeMessages(localeName).then((_) {
|
||||||
Intl.defaultLocale = localeName;
|
Intl.defaultLocale = localeName;
|
||||||
@ -425,6 +424,26 @@ class S {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `Clear Completed`
|
||||||
|
String get downloader_action_clear_completed {
|
||||||
|
return Intl.message(
|
||||||
|
'Clear Completed',
|
||||||
|
name: 'downloader_action_clear_completed',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Remove Record`
|
||||||
|
String get downloader_action_remove_record {
|
||||||
|
return Intl.message(
|
||||||
|
'Remove Record',
|
||||||
|
name: 'downloader_action_remove_record',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// `No download tasks`
|
/// `No download tasks`
|
||||||
String get downloader_info_no_download_tasks {
|
String get downloader_info_no_download_tasks {
|
||||||
return Intl.message(
|
return Intl.message(
|
||||||
|
|||||||
@ -77,6 +77,10 @@
|
|||||||
"@downloader_action_resume_all": {},
|
"@downloader_action_resume_all": {},
|
||||||
"downloader_action_cancel_all": "Cancel All",
|
"downloader_action_cancel_all": "Cancel All",
|
||||||
"@downloader_action_cancel_all": {},
|
"@downloader_action_cancel_all": {},
|
||||||
|
"downloader_action_clear_completed": "Clear Completed",
|
||||||
|
"@downloader_action_clear_completed": {},
|
||||||
|
"downloader_action_remove_record": "Remove Record",
|
||||||
|
"@downloader_action_remove_record": {},
|
||||||
"downloader_info_no_download_tasks": "No download tasks",
|
"downloader_info_no_download_tasks": "No download tasks",
|
||||||
"@downloader_info_no_download_tasks": {},
|
"@downloader_info_no_download_tasks": {},
|
||||||
"downloader_info_total_size": "Total Size: {v1}",
|
"downloader_info_total_size": "Total Size: {v1}",
|
||||||
|
|||||||
@ -77,6 +77,10 @@
|
|||||||
"@downloader_action_resume_all": {},
|
"@downloader_action_resume_all": {},
|
||||||
"downloader_action_cancel_all": "すべてキャンセル",
|
"downloader_action_cancel_all": "すべてキャンセル",
|
||||||
"@downloader_action_cancel_all": {},
|
"@downloader_action_cancel_all": {},
|
||||||
|
"downloader_action_clear_completed": "完了をクリア",
|
||||||
|
"@downloader_action_clear_completed": {},
|
||||||
|
"downloader_action_remove_record": "レコードを削除",
|
||||||
|
"@downloader_action_remove_record": {},
|
||||||
"downloader_info_no_download_tasks": "ダウンロードタスクはありません",
|
"downloader_info_no_download_tasks": "ダウンロードタスクはありません",
|
||||||
"@downloader_info_no_download_tasks": {},
|
"@downloader_info_no_download_tasks": {},
|
||||||
"downloader_info_total_size": "合計サイズ:{v1}",
|
"downloader_info_total_size": "合計サイズ:{v1}",
|
||||||
|
|||||||
@ -77,6 +77,10 @@
|
|||||||
"@downloader_action_resume_all": {},
|
"@downloader_action_resume_all": {},
|
||||||
"downloader_action_cancel_all": "Отменить все",
|
"downloader_action_cancel_all": "Отменить все",
|
||||||
"@downloader_action_cancel_all": {},
|
"@downloader_action_cancel_all": {},
|
||||||
|
"downloader_action_clear_completed": "Очистить завершённые",
|
||||||
|
"@downloader_action_clear_completed": {},
|
||||||
|
"downloader_action_remove_record": "Удалить запись",
|
||||||
|
"@downloader_action_remove_record": {},
|
||||||
"downloader_info_no_download_tasks": "Нет задач загрузки",
|
"downloader_info_no_download_tasks": "Нет задач загрузки",
|
||||||
"@downloader_info_no_download_tasks": {},
|
"@downloader_info_no_download_tasks": {},
|
||||||
"downloader_info_total_size": "Общий размер: {v1}",
|
"downloader_info_total_size": "Общий размер: {v1}",
|
||||||
|
|||||||
@ -76,6 +76,10 @@
|
|||||||
"@downloader_action_resume_all": {},
|
"@downloader_action_resume_all": {},
|
||||||
"downloader_action_cancel_all": "全部取消",
|
"downloader_action_cancel_all": "全部取消",
|
||||||
"@downloader_action_cancel_all": {},
|
"@downloader_action_cancel_all": {},
|
||||||
|
"downloader_action_clear_completed": "清除已完成",
|
||||||
|
"@downloader_action_clear_completed": {},
|
||||||
|
"downloader_action_remove_record": "移除记录",
|
||||||
|
"@downloader_action_remove_record": {},
|
||||||
"downloader_info_no_download_tasks": "无下载任务",
|
"downloader_info_no_download_tasks": "无下载任务",
|
||||||
"@downloader_info_no_download_tasks": {},
|
"@downloader_info_no_download_tasks": {},
|
||||||
"downloader_info_total_size": "总大小:{v1}",
|
"downloader_info_total_size": "总大小:{v1}",
|
||||||
|
|||||||
@ -77,6 +77,10 @@
|
|||||||
"@downloader_action_resume_all": {},
|
"@downloader_action_resume_all": {},
|
||||||
"downloader_action_cancel_all": "全部取消",
|
"downloader_action_cancel_all": "全部取消",
|
||||||
"@downloader_action_cancel_all": {},
|
"@downloader_action_cancel_all": {},
|
||||||
|
"downloader_action_clear_completed": "清除已完成",
|
||||||
|
"@downloader_action_clear_completed": {},
|
||||||
|
"downloader_action_remove_record": "移除記錄",
|
||||||
|
"@downloader_action_remove_record": {},
|
||||||
"downloader_info_no_download_tasks": "無下載任務",
|
"downloader_info_no_download_tasks": "無下載任務",
|
||||||
"@downloader_info_no_download_tasks": {},
|
"@downloader_info_no_download_tasks": {},
|
||||||
"downloader_info_total_size": "總大小:{v1}",
|
"downloader_info_total_size": "總大小:{v1}",
|
||||||
|
|||||||
@ -178,11 +178,11 @@ class DownloadManager extends _$DownloadManager {
|
|||||||
return await downloader_api.downloaderGetAllTasks();
|
return await downloader_api.downloaderGetAllTasks();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> isNameInTask(String name) async {
|
Future<bool> isNameInTask(String name, {bool downloadingOnly = true}) async {
|
||||||
if (!state.isInitialized) {
|
if (!state.isInitialized) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return await downloader_api.downloaderIsNameInTask(name: name);
|
return await downloader_api.downloaderIsNameInTask(name: name, downloadingOnly: downloadingOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> pauseAll() async {
|
Future<void> pauseAll() async {
|
||||||
|
|||||||
@ -41,7 +41,7 @@ final class DownloadManagerProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$downloadManagerHash() => r'55c92224a5eb6bb0f84f0a97fd0585b94f61f711';
|
String _$downloadManagerHash() => r'feed17eda191d6b618b30e01afb75b7245fe0a83';
|
||||||
|
|
||||||
abstract class _$DownloadManager extends $Notifier<DownloadManagerState> {
|
abstract class _$DownloadManager extends $Notifier<DownloadManagerState> {
|
||||||
DownloadManagerState build();
|
DownloadManagerState build();
|
||||||
|
|||||||
@ -33,6 +33,8 @@ class HomeDownloaderUI extends HookConsumerWidget {
|
|||||||
const MapEntry("resume_all", FluentIcons.download): S.current.downloader_action_resume_all,
|
const MapEntry("resume_all", FluentIcons.download): S.current.downloader_action_resume_all,
|
||||||
if (state.activeTasks.isNotEmpty || state.waitingTasks.isNotEmpty)
|
if (state.activeTasks.isNotEmpty || state.waitingTasks.isNotEmpty)
|
||||||
const MapEntry("cancel_all", FluentIcons.cancel): S.current.downloader_action_cancel_all,
|
const MapEntry("cancel_all", FluentIcons.cancel): S.current.downloader_action_cancel_all,
|
||||||
|
if (state.completedTasks.isNotEmpty || state.errorTasks.isNotEmpty)
|
||||||
|
const MapEntry("clear_completed", FluentIcons.clear): S.current.downloader_action_clear_completed,
|
||||||
}.entries)
|
}.entries)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 6, right: 6),
|
padding: const EdgeInsets.only(left: 6, right: 6),
|
||||||
@ -151,7 +153,7 @@ class HomeDownloaderUI extends HookConsumerWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(width: 32),
|
const SizedBox(width: 32),
|
||||||
if (type != "stopped")
|
if (type != "completed" && type != "error")
|
||||||
DropDownButton(
|
DropDownButton(
|
||||||
closeAfterClick: true,
|
closeAfterClick: true,
|
||||||
title: Padding(
|
title: Padding(
|
||||||
@ -183,6 +185,26 @@ class HomeDownloaderUI extends HookConsumerWidget {
|
|||||||
onPressed: () => model.openFolder(task),
|
onPressed: () => model.openFolder(task),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
)
|
||||||
|
else
|
||||||
|
DropDownButton(
|
||||||
|
closeAfterClick: true,
|
||||||
|
title: Padding(
|
||||||
|
padding: const EdgeInsets.all(3),
|
||||||
|
child: Text(S.current.downloader_action_options),
|
||||||
|
),
|
||||||
|
items: [
|
||||||
|
MenuFlyoutItem(
|
||||||
|
leading: const Icon(FluentIcons.chrome_close, size: 14),
|
||||||
|
text: Text(S.current.downloader_action_remove_record),
|
||||||
|
onPressed: () => model.removeTask(task.id.toInt()),
|
||||||
|
),
|
||||||
|
MenuFlyoutItem(
|
||||||
|
leading: const Icon(FluentIcons.folder_open, size: 14),
|
||||||
|
text: Text(S.current.action_open_folder),
|
||||||
|
onPressed: () => model.openFolder(task),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -22,7 +22,8 @@ abstract class HomeDownloaderUIState with _$HomeDownloaderUIState {
|
|||||||
factory HomeDownloaderUIState({
|
factory HomeDownloaderUIState({
|
||||||
@Default([]) List<DownloadTaskInfo> activeTasks,
|
@Default([]) List<DownloadTaskInfo> activeTasks,
|
||||||
@Default([]) List<DownloadTaskInfo> waitingTasks,
|
@Default([]) List<DownloadTaskInfo> waitingTasks,
|
||||||
@Default([]) List<DownloadTaskInfo> stoppedTasks,
|
@Default([]) List<DownloadTaskInfo> completedTasks,
|
||||||
|
@Default([]) List<DownloadTaskInfo> errorTasks,
|
||||||
DownloadGlobalStat? globalStat,
|
DownloadGlobalStat? globalStat,
|
||||||
}) = _HomeDownloaderUIState;
|
}) = _HomeDownloaderUIState;
|
||||||
}
|
}
|
||||||
@ -48,7 +49,8 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel {
|
|||||||
final listHeaderStatusMap = {
|
final listHeaderStatusMap = {
|
||||||
"active": S.current.downloader_title_downloading,
|
"active": S.current.downloader_title_downloading,
|
||||||
"waiting": S.current.downloader_info_waiting,
|
"waiting": S.current.downloader_info_waiting,
|
||||||
"stopped": S.current.downloader_title_ended,
|
"completed": S.current.downloader_title_ended,
|
||||||
|
"error": S.current.downloader_info_download_failed,
|
||||||
};
|
};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -92,6 +94,17 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
case "clear_completed":
|
||||||
|
if (!downloadManagerState.isRunning) return;
|
||||||
|
try {
|
||||||
|
final allTasks = [...state.completedTasks, ...state.errorTasks];
|
||||||
|
for (var task in allTasks) {
|
||||||
|
await downloadManager.removeTask(task.id.toInt(), deleteFiles: false);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
dPrint("DownloadsUIModel clear_completed Error: $e");
|
||||||
|
}
|
||||||
|
return;
|
||||||
case "settings":
|
case "settings":
|
||||||
_showDownloadSpeedSettings(context);
|
_showDownloadSpeedSettings(context);
|
||||||
return;
|
return;
|
||||||
@ -99,19 +112,33 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int getTasksLen() {
|
int getTasksLen() {
|
||||||
return state.activeTasks.length + state.waitingTasks.length + state.stoppedTasks.length;
|
return state.activeTasks.length + state.waitingTasks.length + state.completedTasks.length + state.errorTasks.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
(DownloadTaskInfo, String, bool) getTaskAndType(int index) {
|
(DownloadTaskInfo, String, bool) getTaskAndType(int index) {
|
||||||
final tempList = <DownloadTaskInfo>[...state.activeTasks, ...state.waitingTasks, ...state.stoppedTasks];
|
final tempList = <DownloadTaskInfo>[
|
||||||
|
...state.activeTasks,
|
||||||
|
...state.waitingTasks,
|
||||||
|
...state.completedTasks,
|
||||||
|
...state.errorTasks,
|
||||||
|
];
|
||||||
if (index >= 0 && index < state.activeTasks.length) {
|
if (index >= 0 && index < state.activeTasks.length) {
|
||||||
return (tempList[index], "active", index == 0);
|
return (tempList[index], "active", index == 0);
|
||||||
}
|
}
|
||||||
if (index >= state.activeTasks.length && index < state.activeTasks.length + state.waitingTasks.length) {
|
if (index >= state.activeTasks.length && index < state.activeTasks.length + state.waitingTasks.length) {
|
||||||
return (tempList[index], "waiting", index == state.activeTasks.length);
|
return (tempList[index], "waiting", index == state.activeTasks.length);
|
||||||
}
|
}
|
||||||
if (index >= state.activeTasks.length + state.waitingTasks.length && index < tempList.length) {
|
if (index >= state.activeTasks.length + state.waitingTasks.length &&
|
||||||
return (tempList[index], "stopped", index == state.activeTasks.length + state.waitingTasks.length);
|
index < state.activeTasks.length + state.waitingTasks.length + state.completedTasks.length) {
|
||||||
|
return (tempList[index], "completed", index == state.activeTasks.length + state.waitingTasks.length);
|
||||||
|
}
|
||||||
|
if (index >= state.activeTasks.length + state.waitingTasks.length + state.completedTasks.length &&
|
||||||
|
index < tempList.length) {
|
||||||
|
return (
|
||||||
|
tempList[index],
|
||||||
|
"error",
|
||||||
|
index == state.activeTasks.length + state.waitingTasks.length + state.completedTasks.length,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
throw Exception("Index out of range or element is null");
|
throw Exception("Index out of range or element is null");
|
||||||
}
|
}
|
||||||
@ -172,6 +199,11 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> removeTask(int taskId) async {
|
||||||
|
final downloadManager = ref.read(downloadManagerProvider.notifier);
|
||||||
|
await downloadManager.removeTask(taskId, deleteFiles: false);
|
||||||
|
}
|
||||||
|
|
||||||
void openFolder(DownloadTaskInfo task) {
|
void openFolder(DownloadTaskInfo task) {
|
||||||
final outputFolder = task.outputFolder;
|
final outputFolder = task.outputFolder;
|
||||||
if (outputFolder.isNotEmpty) {
|
if (outputFolder.isNotEmpty) {
|
||||||
@ -190,7 +222,8 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel {
|
|||||||
|
|
||||||
final activeTasks = <DownloadTaskInfo>[];
|
final activeTasks = <DownloadTaskInfo>[];
|
||||||
final waitingTasks = <DownloadTaskInfo>[];
|
final waitingTasks = <DownloadTaskInfo>[];
|
||||||
final stoppedTasks = <DownloadTaskInfo>[];
|
final completedTasks = <DownloadTaskInfo>[];
|
||||||
|
final errorTasks = <DownloadTaskInfo>[];
|
||||||
|
|
||||||
for (var task in allTasks) {
|
for (var task in allTasks) {
|
||||||
switch (task.status) {
|
switch (task.status) {
|
||||||
@ -202,8 +235,10 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel {
|
|||||||
waitingTasks.add(task);
|
waitingTasks.add(task);
|
||||||
break;
|
break;
|
||||||
case DownloadTaskStatus.finished:
|
case DownloadTaskStatus.finished:
|
||||||
|
completedTasks.add(task);
|
||||||
|
break;
|
||||||
case DownloadTaskStatus.error:
|
case DownloadTaskStatus.error:
|
||||||
stoppedTasks.add(task);
|
errorTasks.add(task);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,11 +246,18 @@ class HomeDownloaderUIModel extends _$HomeDownloaderUIModel {
|
|||||||
state = state.copyWith(
|
state = state.copyWith(
|
||||||
activeTasks: activeTasks,
|
activeTasks: activeTasks,
|
||||||
waitingTasks: waitingTasks,
|
waitingTasks: waitingTasks,
|
||||||
stoppedTasks: stoppedTasks,
|
completedTasks: completedTasks,
|
||||||
|
errorTasks: errorTasks,
|
||||||
globalStat: downloadManagerState.globalStat,
|
globalStat: downloadManagerState.globalStat,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
state = state.copyWith(activeTasks: [], waitingTasks: [], stoppedTasks: [], globalStat: null);
|
state = state.copyWith(
|
||||||
|
activeTasks: [],
|
||||||
|
waitingTasks: [],
|
||||||
|
completedTasks: [],
|
||||||
|
errorTasks: [],
|
||||||
|
globalStat: null,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
await Future.delayed(const Duration(seconds: 1));
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ T _$identity<T>(T value) => value;
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$HomeDownloaderUIState {
|
mixin _$HomeDownloaderUIState {
|
||||||
|
|
||||||
List<DownloadTaskInfo> get activeTasks; List<DownloadTaskInfo> get waitingTasks; List<DownloadTaskInfo> get stoppedTasks; DownloadGlobalStat? get globalStat;
|
List<DownloadTaskInfo> get activeTasks; List<DownloadTaskInfo> get waitingTasks; List<DownloadTaskInfo> get completedTasks; List<DownloadTaskInfo> get errorTasks; DownloadGlobalStat? get globalStat;
|
||||||
/// Create a copy of HomeDownloaderUIState
|
/// Create a copy of HomeDownloaderUIState
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@ -25,16 +25,16 @@ $HomeDownloaderUIStateCopyWith<HomeDownloaderUIState> get copyWith => _$HomeDown
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
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));
|
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.completedTasks, completedTasks)&&const DeepCollectionEquality().equals(other.errorTasks, errorTasks)&&(identical(other.globalStat, globalStat) || other.globalStat == globalStat));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(activeTasks),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(completedTasks),const DeepCollectionEquality().hash(errorTasks),globalStat);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'HomeDownloaderUIState(activeTasks: $activeTasks, waitingTasks: $waitingTasks, stoppedTasks: $stoppedTasks, globalStat: $globalStat)';
|
return 'HomeDownloaderUIState(activeTasks: $activeTasks, waitingTasks: $waitingTasks, completedTasks: $completedTasks, errorTasks: $errorTasks, globalStat: $globalStat)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ abstract mixin class $HomeDownloaderUIStateCopyWith<$Res> {
|
|||||||
factory $HomeDownloaderUIStateCopyWith(HomeDownloaderUIState value, $Res Function(HomeDownloaderUIState) _then) = _$HomeDownloaderUIStateCopyWithImpl;
|
factory $HomeDownloaderUIStateCopyWith(HomeDownloaderUIState value, $Res Function(HomeDownloaderUIState) _then) = _$HomeDownloaderUIStateCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
List<DownloadTaskInfo> activeTasks, List<DownloadTaskInfo> waitingTasks, List<DownloadTaskInfo> stoppedTasks, DownloadGlobalStat? globalStat
|
List<DownloadTaskInfo> activeTasks, List<DownloadTaskInfo> waitingTasks, List<DownloadTaskInfo> completedTasks, List<DownloadTaskInfo> errorTasks, DownloadGlobalStat? globalStat
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -62,11 +62,12 @@ class _$HomeDownloaderUIStateCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of HomeDownloaderUIState
|
/// Create a copy of HomeDownloaderUIState
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline') @override $Res call({Object? activeTasks = null,Object? waitingTasks = null,Object? stoppedTasks = null,Object? globalStat = freezed,}) {
|
@pragma('vm:prefer-inline') @override $Res call({Object? activeTasks = null,Object? waitingTasks = null,Object? completedTasks = null,Object? errorTasks = null,Object? globalStat = freezed,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
activeTasks: null == activeTasks ? _self.activeTasks : activeTasks // ignore: cast_nullable_to_non_nullable
|
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>,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>,completedTasks: null == completedTasks ? _self.completedTasks : completedTasks // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<DownloadTaskInfo>,errorTasks: null == errorTasks ? _self.errorTasks : errorTasks // ignore: cast_nullable_to_non_nullable
|
||||||
as List<DownloadTaskInfo>,globalStat: freezed == globalStat ? _self.globalStat : globalStat // ignore: cast_nullable_to_non_nullable
|
as List<DownloadTaskInfo>,globalStat: freezed == globalStat ? _self.globalStat : globalStat // ignore: cast_nullable_to_non_nullable
|
||||||
as DownloadGlobalStat?,
|
as DownloadGlobalStat?,
|
||||||
));
|
));
|
||||||
@ -153,10 +154,10 @@ return $default(_that);case _:
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@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;
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<DownloadTaskInfo> activeTasks, List<DownloadTaskInfo> waitingTasks, List<DownloadTaskInfo> completedTasks, List<DownloadTaskInfo> errorTasks, DownloadGlobalStat? globalStat)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _HomeDownloaderUIState() when $default != null:
|
case _HomeDownloaderUIState() when $default != null:
|
||||||
return $default(_that.activeTasks,_that.waitingTasks,_that.stoppedTasks,_that.globalStat);case _:
|
return $default(_that.activeTasks,_that.waitingTasks,_that.completedTasks,_that.errorTasks,_that.globalStat);case _:
|
||||||
return orElse();
|
return orElse();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -174,10 +175,10 @@ return $default(_that.activeTasks,_that.waitingTasks,_that.stoppedTasks,_that.gl
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<DownloadTaskInfo> activeTasks, List<DownloadTaskInfo> waitingTasks, List<DownloadTaskInfo> stoppedTasks, DownloadGlobalStat? globalStat) $default,) {final _that = this;
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<DownloadTaskInfo> activeTasks, List<DownloadTaskInfo> waitingTasks, List<DownloadTaskInfo> completedTasks, List<DownloadTaskInfo> errorTasks, DownloadGlobalStat? globalStat) $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _HomeDownloaderUIState():
|
case _HomeDownloaderUIState():
|
||||||
return $default(_that.activeTasks,_that.waitingTasks,_that.stoppedTasks,_that.globalStat);case _:
|
return $default(_that.activeTasks,_that.waitingTasks,_that.completedTasks,_that.errorTasks,_that.globalStat);case _:
|
||||||
throw StateError('Unexpected subclass');
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -194,10 +195,10 @@ return $default(_that.activeTasks,_that.waitingTasks,_that.stoppedTasks,_that.gl
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<DownloadTaskInfo> activeTasks, List<DownloadTaskInfo> waitingTasks, List<DownloadTaskInfo> stoppedTasks, DownloadGlobalStat? globalStat)? $default,) {final _that = this;
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<DownloadTaskInfo> activeTasks, List<DownloadTaskInfo> waitingTasks, List<DownloadTaskInfo> completedTasks, List<DownloadTaskInfo> errorTasks, DownloadGlobalStat? globalStat)? $default,) {final _that = this;
|
||||||
switch (_that) {
|
switch (_that) {
|
||||||
case _HomeDownloaderUIState() when $default != null:
|
case _HomeDownloaderUIState() when $default != null:
|
||||||
return $default(_that.activeTasks,_that.waitingTasks,_that.stoppedTasks,_that.globalStat);case _:
|
return $default(_that.activeTasks,_that.waitingTasks,_that.completedTasks,_that.errorTasks,_that.globalStat);case _:
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -209,7 +210,7 @@ return $default(_that.activeTasks,_that.waitingTasks,_that.stoppedTasks,_that.gl
|
|||||||
|
|
||||||
|
|
||||||
class _HomeDownloaderUIState implements HomeDownloaderUIState {
|
class _HomeDownloaderUIState implements HomeDownloaderUIState {
|
||||||
_HomeDownloaderUIState({final List<DownloadTaskInfo> activeTasks = const [], final List<DownloadTaskInfo> waitingTasks = const [], final List<DownloadTaskInfo> stoppedTasks = const [], this.globalStat}): _activeTasks = activeTasks,_waitingTasks = waitingTasks,_stoppedTasks = stoppedTasks;
|
_HomeDownloaderUIState({final List<DownloadTaskInfo> activeTasks = const [], final List<DownloadTaskInfo> waitingTasks = const [], final List<DownloadTaskInfo> completedTasks = const [], final List<DownloadTaskInfo> errorTasks = const [], this.globalStat}): _activeTasks = activeTasks,_waitingTasks = waitingTasks,_completedTasks = completedTasks,_errorTasks = errorTasks;
|
||||||
|
|
||||||
|
|
||||||
final List<DownloadTaskInfo> _activeTasks;
|
final List<DownloadTaskInfo> _activeTasks;
|
||||||
@ -226,11 +227,18 @@ class _HomeDownloaderUIState implements HomeDownloaderUIState {
|
|||||||
return EqualUnmodifiableListView(_waitingTasks);
|
return EqualUnmodifiableListView(_waitingTasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<DownloadTaskInfo> _stoppedTasks;
|
final List<DownloadTaskInfo> _completedTasks;
|
||||||
@override@JsonKey() List<DownloadTaskInfo> get stoppedTasks {
|
@override@JsonKey() List<DownloadTaskInfo> get completedTasks {
|
||||||
if (_stoppedTasks is EqualUnmodifiableListView) return _stoppedTasks;
|
if (_completedTasks is EqualUnmodifiableListView) return _completedTasks;
|
||||||
// ignore: implicit_dynamic_type
|
// ignore: implicit_dynamic_type
|
||||||
return EqualUnmodifiableListView(_stoppedTasks);
|
return EqualUnmodifiableListView(_completedTasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<DownloadTaskInfo> _errorTasks;
|
||||||
|
@override@JsonKey() List<DownloadTaskInfo> get errorTasks {
|
||||||
|
if (_errorTasks is EqualUnmodifiableListView) return _errorTasks;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableListView(_errorTasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override final DownloadGlobalStat? globalStat;
|
@override final DownloadGlobalStat? globalStat;
|
||||||
@ -245,16 +253,16 @@ _$HomeDownloaderUIStateCopyWith<_HomeDownloaderUIState> get copyWith => __$HomeD
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
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));
|
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._completedTasks, _completedTasks)&&const DeepCollectionEquality().equals(other._errorTasks, _errorTasks)&&(identical(other.globalStat, globalStat) || other.globalStat == globalStat));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_activeTasks),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(_completedTasks),const DeepCollectionEquality().hash(_errorTasks),globalStat);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'HomeDownloaderUIState(activeTasks: $activeTasks, waitingTasks: $waitingTasks, stoppedTasks: $stoppedTasks, globalStat: $globalStat)';
|
return 'HomeDownloaderUIState(activeTasks: $activeTasks, waitingTasks: $waitingTasks, completedTasks: $completedTasks, errorTasks: $errorTasks, globalStat: $globalStat)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -265,7 +273,7 @@ abstract mixin class _$HomeDownloaderUIStateCopyWith<$Res> implements $HomeDownl
|
|||||||
factory _$HomeDownloaderUIStateCopyWith(_HomeDownloaderUIState value, $Res Function(_HomeDownloaderUIState) _then) = __$HomeDownloaderUIStateCopyWithImpl;
|
factory _$HomeDownloaderUIStateCopyWith(_HomeDownloaderUIState value, $Res Function(_HomeDownloaderUIState) _then) = __$HomeDownloaderUIStateCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
List<DownloadTaskInfo> activeTasks, List<DownloadTaskInfo> waitingTasks, List<DownloadTaskInfo> stoppedTasks, DownloadGlobalStat? globalStat
|
List<DownloadTaskInfo> activeTasks, List<DownloadTaskInfo> waitingTasks, List<DownloadTaskInfo> completedTasks, List<DownloadTaskInfo> errorTasks, DownloadGlobalStat? globalStat
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -282,11 +290,12 @@ class __$HomeDownloaderUIStateCopyWithImpl<$Res>
|
|||||||
|
|
||||||
/// Create a copy of HomeDownloaderUIState
|
/// Create a copy of HomeDownloaderUIState
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@override @pragma('vm:prefer-inline') $Res call({Object? activeTasks = null,Object? waitingTasks = null,Object? stoppedTasks = null,Object? globalStat = freezed,}) {
|
@override @pragma('vm:prefer-inline') $Res call({Object? activeTasks = null,Object? waitingTasks = null,Object? completedTasks = null,Object? errorTasks = null,Object? globalStat = freezed,}) {
|
||||||
return _then(_HomeDownloaderUIState(
|
return _then(_HomeDownloaderUIState(
|
||||||
activeTasks: null == activeTasks ? _self._activeTasks : activeTasks // ignore: cast_nullable_to_non_nullable
|
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>,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>,completedTasks: null == completedTasks ? _self._completedTasks : completedTasks // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<DownloadTaskInfo>,errorTasks: null == errorTasks ? _self._errorTasks : errorTasks // ignore: cast_nullable_to_non_nullable
|
||||||
as List<DownloadTaskInfo>,globalStat: freezed == globalStat ? _self.globalStat : globalStat // ignore: cast_nullable_to_non_nullable
|
as List<DownloadTaskInfo>,globalStat: freezed == globalStat ? _self.globalStat : globalStat // ignore: cast_nullable_to_non_nullable
|
||||||
as DownloadGlobalStat?,
|
as DownloadGlobalStat?,
|
||||||
));
|
));
|
||||||
|
|||||||
@ -42,7 +42,7 @@ final class HomeDownloaderUIModelProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _$homeDownloaderUIModelHash() =>
|
String _$homeDownloaderUIModelHash() =>
|
||||||
r'bf7d095d761fff078de707562cf311c20db664d9';
|
r'b230746a782b511dd58b0b46def7845c01412762';
|
||||||
|
|
||||||
abstract class _$HomeDownloaderUIModel
|
abstract class _$HomeDownloaderUIModel
|
||||||
extends $Notifier<HomeDownloaderUIState> {
|
extends $Notifier<HomeDownloaderUIState> {
|
||||||
|
|||||||
@ -257,7 +257,7 @@ class InputMethodDialogUIModel extends _$InputMethodDialogUIModel {
|
|||||||
}
|
}
|
||||||
// get torrent Data
|
// get torrent Data
|
||||||
final data = await RSHttp.get(torrentUrl!);
|
final data = await RSHttp.get(torrentUrl!);
|
||||||
final taskId = await downloadManager.addTorrent(data.data!, outputFolder: _localTranslateModelDir);
|
final taskId = await downloadManager.addTorrent(data.data!, outputFolder: "$_localTranslateModelDir/$_localTranslateModelName");
|
||||||
return taskId.toString();
|
return taskId.toString();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
dPrint("[InputMethodDialogUIModel] doDownloadTranslateModel error: $e");
|
dPrint("[InputMethodDialogUIModel] doDownloadTranslateModel error: $e");
|
||||||
|
|||||||
@ -43,7 +43,7 @@ final class InputMethodDialogUIModelProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _$inputMethodDialogUIModelHash() =>
|
String _$inputMethodDialogUIModelHash() =>
|
||||||
r'5c2989faf94d43bb814e5b80e10d68416c8241ec';
|
r'77bf2b02a7b7ea66e9a06be068b791b3a4295a44';
|
||||||
|
|
||||||
abstract class _$InputMethodDialogUIModel
|
abstract class _$InputMethodDialogUIModel
|
||||||
extends $Notifier<InputMethodDialogUIState> {
|
extends $Notifier<InputMethodDialogUIState> {
|
||||||
|
|||||||
@ -27,6 +27,7 @@ static TORRENT_HANDLES: once_cell::sync::Lazy<RwLock<HashMap<usize, ManagedTorre
|
|||||||
once_cell::sync::Lazy::new(|| RwLock::new(HashMap::new()));
|
once_cell::sync::Lazy::new(|| RwLock::new(HashMap::new()));
|
||||||
|
|
||||||
// Store completed tasks info (in-memory cache, cleared on restart)
|
// Store completed tasks info (in-memory cache, cleared on restart)
|
||||||
|
// Task IDs in cache are >= 10000 and are assigned sequentially (10000 + cache_index)
|
||||||
static COMPLETED_TASKS_CACHE: once_cell::sync::Lazy<RwLock<Vec<DownloadTaskInfo>>> =
|
static COMPLETED_TASKS_CACHE: once_cell::sync::Lazy<RwLock<Vec<DownloadTaskInfo>>> =
|
||||||
once_cell::sync::Lazy::new(|| RwLock::new(Vec::new()));
|
once_cell::sync::Lazy::new(|| RwLock::new(Vec::new()));
|
||||||
|
|
||||||
@ -369,7 +370,20 @@ pub async fn downloader_resume(task_id: usize) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Remove a download task
|
/// Remove a download task
|
||||||
|
/// Handles both active tasks (task_id < 10000) and cached completed tasks (task_id >= 10000)
|
||||||
pub async fn downloader_remove(task_id: usize, delete_files: bool) -> Result<()> {
|
pub async fn downloader_remove(task_id: usize, delete_files: bool) -> Result<()> {
|
||||||
|
// Check if this is a cached completed task (ID >= 10000)
|
||||||
|
if task_id >= 10000 {
|
||||||
|
// Remove from completed tasks cache by index (10000 + index)
|
||||||
|
let cache_index = task_id - 10000;
|
||||||
|
let mut cache = COMPLETED_TASKS_CACHE.write();
|
||||||
|
if cache_index < cache.len() {
|
||||||
|
cache.remove(cache_index);
|
||||||
|
}
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, it's an active task
|
||||||
let session = get_session()?;
|
let session = get_session()?;
|
||||||
|
|
||||||
session
|
session
|
||||||
@ -454,12 +468,15 @@ fn get_task_status(stats: &TorrentStats) -> DownloadTaskStatus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get all tasks
|
/// Get all tasks (includes both active and completed tasks from cache)
|
||||||
pub async fn downloader_get_all_tasks() -> Result<Vec<DownloadTaskInfo>> {
|
pub async fn downloader_get_all_tasks() -> Result<Vec<DownloadTaskInfo>> {
|
||||||
let session_guard = SESSION.read();
|
let session_guard = SESSION.read();
|
||||||
let session = match session_guard.as_ref() {
|
let session = match session_guard.as_ref() {
|
||||||
Some(s) => s.clone(),
|
Some(s) => s.clone(),
|
||||||
None => return Ok(vec![]),
|
None => {
|
||||||
|
// If session is not initialized, return only cached completed tasks
|
||||||
|
return Ok(COMPLETED_TASKS_CACHE.read().clone());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
drop(session_guard);
|
drop(session_guard);
|
||||||
|
|
||||||
@ -516,7 +533,18 @@ pub async fn downloader_get_all_tasks() -> Result<Vec<DownloadTaskInfo>> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(tasks.into_inner())
|
// Merge cached completed tasks with IDs based on cache index (10000 + index)
|
||||||
|
let mut result = tasks.into_inner();
|
||||||
|
let completed_tasks_cache = COMPLETED_TASKS_CACHE.read();
|
||||||
|
|
||||||
|
for (cache_index, task) in completed_tasks_cache.iter().enumerate() {
|
||||||
|
let mut task_with_id = task.clone();
|
||||||
|
// Assign ID based on cache index: 10000, 10001, 10002, etc.
|
||||||
|
task_with_id.id = 10000 + cache_index;
|
||||||
|
result.push(task_with_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get global statistics
|
/// Get global statistics
|
||||||
@ -540,9 +568,20 @@ pub async fn downloader_get_global_stats() -> Result<DownloadGlobalStat> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Check if a task with given name exists
|
/// Check if a task with given name exists
|
||||||
pub async fn downloader_is_name_in_task(name: String) -> bool {
|
///
|
||||||
|
/// Parameters:
|
||||||
|
/// - name: Task name to search for
|
||||||
|
/// - downloading_only: If true, only search in active/waiting tasks. If false, include completed tasks (default: true)
|
||||||
|
pub async fn downloader_is_name_in_task(name: String, downloading_only: Option<bool>) -> bool {
|
||||||
|
let downloading_only = downloading_only.unwrap_or(true);
|
||||||
|
|
||||||
if let Ok(tasks) = downloader_get_all_tasks().await {
|
if let Ok(tasks) = downloader_get_all_tasks().await {
|
||||||
for task in tasks {
|
for task in tasks {
|
||||||
|
// If downloading_only is true, skip finished and error tasks
|
||||||
|
if downloading_only && (task.status == DownloadTaskStatus::Finished || task.status == DownloadTaskStatus::Error) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if task.name.contains(&name) {
|
if task.name.contains(&name) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -640,16 +679,17 @@ pub async fn downloader_remove_completed_tasks() -> Result<u32> {
|
|||||||
|
|
||||||
for task in tasks {
|
for task in tasks {
|
||||||
if task.status == DownloadTaskStatus::Finished {
|
if task.status == DownloadTaskStatus::Finished {
|
||||||
// Check if handle exists (drop lock before await)
|
// Only process active tasks (id < 10000)
|
||||||
let has_handle = TORRENT_HANDLES.read().contains_key(&task.id);
|
if task.id < 10000 {
|
||||||
if has_handle {
|
let has_handle = TORRENT_HANDLES.read().contains_key(&task.id);
|
||||||
// Use TorrentIdOrHash::Id for deletion (TorrentId is just usize)
|
if has_handle {
|
||||||
if session.delete(TorrentIdOrHash::Id(task.id), false).await.is_ok() {
|
// Use TorrentIdOrHash::Id for deletion
|
||||||
// Save task info to cache before removing
|
if session.delete(TorrentIdOrHash::Id(task.id), false).await.is_ok() {
|
||||||
COMPLETED_TASKS_CACHE.write().push(task.clone());
|
// Cache the task - it will get ID based on cache length
|
||||||
|
COMPLETED_TASKS_CACHE.write().push(task.clone());
|
||||||
TORRENT_HANDLES.write().remove(&task.id);
|
TORRENT_HANDLES.write().remove(&task.id);
|
||||||
removed_count += 1;
|
removed_count += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -514,6 +514,7 @@ fn wire__crate__api__downloader_api__downloader_is_initialized_impl(
|
|||||||
fn wire__crate__api__downloader_api__downloader_is_name_in_task_impl(
|
fn wire__crate__api__downloader_api__downloader_is_name_in_task_impl(
|
||||||
port_: flutter_rust_bridge::for_generated::MessagePort,
|
port_: flutter_rust_bridge::for_generated::MessagePort,
|
||||||
name: impl CstDecode<String>,
|
name: impl CstDecode<String>,
|
||||||
|
downloading_only: impl CstDecode<Option<bool>>,
|
||||||
) {
|
) {
|
||||||
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::DcoCodec, _, _, _>(
|
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::DcoCodec, _, _, _>(
|
||||||
flutter_rust_bridge::for_generated::TaskInfo {
|
flutter_rust_bridge::for_generated::TaskInfo {
|
||||||
@ -523,11 +524,16 @@ fn wire__crate__api__downloader_api__downloader_is_name_in_task_impl(
|
|||||||
},
|
},
|
||||||
move || {
|
move || {
|
||||||
let api_name = name.cst_decode();
|
let api_name = name.cst_decode();
|
||||||
|
let api_downloading_only = downloading_only.cst_decode();
|
||||||
move |context| async move {
|
move |context| async move {
|
||||||
transform_result_dco::<_, _, ()>(
|
transform_result_dco::<_, _, ()>(
|
||||||
(move || async move {
|
(move || async move {
|
||||||
let output_ok = Result::<_, ()>::Ok(
|
let output_ok = Result::<_, ()>::Ok(
|
||||||
crate::api::downloader_api::downloader_is_name_in_task(api_name).await,
|
crate::api::downloader_api::downloader_is_name_in_task(
|
||||||
|
api_name,
|
||||||
|
api_downloading_only,
|
||||||
|
)
|
||||||
|
.await,
|
||||||
)?;
|
)?;
|
||||||
Ok(output_ok)
|
Ok(output_ok)
|
||||||
})()
|
})()
|
||||||
@ -4200,8 +4206,13 @@ mod io {
|
|||||||
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__downloader_api__downloader_is_name_in_task(
|
pub extern "C" fn frbgen_starcitizen_doctor_wire__crate__api__downloader_api__downloader_is_name_in_task(
|
||||||
port_: i64,
|
port_: i64,
|
||||||
name: *mut wire_cst_list_prim_u_8_strict,
|
name: *mut wire_cst_list_prim_u_8_strict,
|
||||||
|
downloading_only: *mut bool,
|
||||||
) {
|
) {
|
||||||
wire__crate__api__downloader_api__downloader_is_name_in_task_impl(port_, name)
|
wire__crate__api__downloader_api__downloader_is_name_in_task_impl(
|
||||||
|
port_,
|
||||||
|
name,
|
||||||
|
downloading_only,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user