Skip to content

Commit

Permalink
Update task manager
Browse files Browse the repository at this point in the history
  • Loading branch information
lifegpc committed May 24, 2024
1 parent e560edf commit 4237de5
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 3 deletions.
7 changes: 7 additions & 0 deletions lib/api/eh.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:json_annotation/json_annotation.dart';
import 'api_result.dart';
import '../globals.dart';

part 'eh.g.dart';

Expand Down Expand Up @@ -75,6 +76,12 @@ class GalleryMetadataSingle {
factory GalleryMetadataSingle.fromJson(Map<String, dynamic> json) =>
_$GalleryMetadataSingleFromJson(json);
Map<String, dynamic> toJson() => _$GalleryMetadataSingleToJson(this);

String get preferredTitle => prefs.getBool("useTitleJpn") == true
? titleJpn.isEmpty
? title
: titleJpn
: title;
}

class EHMetaInfo {
Expand Down
98 changes: 98 additions & 0 deletions lib/components/task.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:percent_indicator/linear_percent_indicator.dart';
import '../api/task.dart';
import '../globals.dart';

class TaskView extends StatefulWidget {
const TaskView(this.task, {super.key});
final TaskDetail task;

@override
State<StatefulWidget> createState() => _TaskView();
}

class _TaskView extends State<TaskView> {
@override
void initState() {
listener.on("task_meta_updated", _onStateChanged);
listener.on("task_progress_updated", _onProgressUpdated);
super.initState();
}

void _onStateChanged(dynamic _) {
setState(() {});
}

void _onProgressUpdated(dynamic arg) {
final id = arg as int;
if (id != widget.task.base.id) return;
setState(() {});
}

double get percent {
if (widget.task.status == TaskStatus.finished) return 1;
if (widget.task.status != TaskStatus.running) return 0;
if (widget.task.progress == null) return 0;
switch (widget.task.base.type) {
case TaskType.download:
final progress = widget.task.progress as TaskDownloadProgess;
return progress.downloadedPage / progress.totalPage;
case TaskType.exportZip:
final progress = widget.task.progress as TaskExportZipProgress;
return progress.addedPage / progress.totalPage;
case TaskType.fixGalleryPage:
final progress = widget.task.progress as TaskFixGalleryPageProgress;
return progress.checkedGallery / progress.totalGallery;
case TaskType.updateMeiliSearchData:
final progress =
widget.task.progress as TaskUpdateMeiliSearchDataProgress;
return progress.updatedGallery / progress.totalGallery;
}
}

String get percentText {
return "${(percent * 100).toStringAsFixed(2)}%";
}

@override
void dispose() {
listener.removeEventListener("task_meta_updated", _onStateChanged);
listener.removeEventListener("task_progress_updated", _onProgressUpdated);
super.dispose();
}

Widget _buildText(BuildContext context) {
final i18n = AppLocalizations.of(context)!;
if (widget.task.base.type == TaskType.download) {
final gid = widget.task.base.gid;
return Row(children: [
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Text(i18n.downloadTask)),
Text(tasks.meta.containsKey(gid)
? tasks.meta[gid]!.preferredTitle
: gid.toString()),
]);
}
return Container();
}

@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(8.0),
child: Column(children: [
_buildText(context),
LinearPercentIndicator(
progressColor: Colors.green,
lineHeight: 20.0,
barRadius: const Radius.circular(10),
padding: EdgeInsets.zero,
center: Text(percentText),
percent: percent,
),
]),
);
}
}
3 changes: 2 additions & 1 deletion lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -155,5 +155,6 @@
"createDownloadTask": "Create Download Task",
"galleryURL": "Gallery URL",
"galleryToken": "Gallery Token",
"randomFileSecret": "The secret of token to access random file without login"
"randomFileSecret": "The secret of token to access random file without login",
"downloadTask": "Download Task"
}
3 changes: 2 additions & 1 deletion lib/l10n/app_zh.arb
Original file line number Diff line number Diff line change
Expand Up @@ -155,5 +155,6 @@
"createDownloadTask": "新建下载任务",
"galleryURL": "画廊地址",
"galleryToken": "画廊令牌",
"randomFileSecret": "生成无需登录即可访问随机文件的令牌的密钥"
"randomFileSecret": "生成无需登录即可访问随机文件的令牌的密钥",
"downloadTask": "下载任务"
}
39 changes: 39 additions & 0 deletions lib/task.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:convert';
import 'package:logging/logging.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
import 'api/eh.dart';
import 'api/task.dart';
import 'globals.dart';
import 'utils/websocket.dart';
Expand All @@ -15,14 +16,47 @@ class TaskManager {
bool _allowReconnect = true;
Timer? _reconnectTimer;
List<int> tasksList = [];
Map<int, GalleryMetadataSingle> meta = {};
bool _isFetching = false;
List<int> peddingGids = [];
List<String> peddingTokens = [];
void clear() {
tasks.clear();
_channel?.stream.drain();
_channel?.sink.close();
_closed = true;
}

void fetchMeta() async {
if (_isFetching) return;
try {
if (peddingGids.isEmpty) return;
_isFetching = true;
final re = (await api.getMetaInfo(peddingGids, peddingTokens)).unwrap();
for (final e in re.metas.entries) {
if (e.value.ok) {
meta[e.key] = e.value.unwrap();
final index = peddingGids.indexOf(e.key);
if (index > -1) {
peddingGids.removeAt(index);
peddingTokens.removeAt(index);
}
} else {
_log.warning("Gallery id ${e.key}:", e.value.unwrapErr());
}
}
listener.tryEmit("task_meta_updated", null);
} catch (e) {
_log.warning("Failed to fetch metadatas:", e);
}
_isFetching = false;
}

void addToTasksList(Task task, TaskStatus status) {
if (task.type == TaskType.download && !meta.containsKey(task.gid)) {
peddingGids.add(task.gid);
peddingTokens.add(task.token);
}
if (status == TaskStatus.finished) {
tasksList.add(task.id);
return;
Expand Down Expand Up @@ -66,6 +100,7 @@ class TaskManager {
addToTasksList(task, status);
}
listener.tryEmit("task_list_changed", null);
fetchMeta();
} else if (type == "new_task") {
final task = Task.fromJson(data["detail"] as Map<String, dynamic>);
tasks[task.id] = TaskDetail(
Expand All @@ -74,6 +109,7 @@ class TaskManager {
);
addToTasksList(task, TaskStatus.wait);
listener.tryEmit("task_list_changed", null);
fetchMeta();
} else if (type == "task_started") {
final task = Task.fromJson(data["detail"] as Map<String, dynamic>);
tasks.update(task.id, (value) {
Expand All @@ -83,6 +119,7 @@ class TaskManager {
return value;
}, ifAbsent: () {
addToTasksList(task, TaskStatus.running);
fetchMeta();
return TaskDetail(
base: task,
status: TaskStatus.running,
Expand All @@ -99,6 +136,7 @@ class TaskManager {
return value;
});
listener.tryEmit("task_list_changed", null);
fetchMeta();
}
} else if (type == "task_progress") {
final task =
Expand All @@ -108,6 +146,7 @@ class TaskManager {
value.progress = task.detail;
return value;
});
listener.tryEmit("task_progress_updated", task.taskId);
}
} else if (type == "task_updated") {
final task = Task.fromJson(data["detail"] as Map<String, dynamic>);
Expand Down
3 changes: 2 additions & 1 deletion lib/task_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:go_router/go_router.dart';
import 'api/task.dart';
import 'components/task.dart';
import 'globals.dart';

enum TaskStatusFilterFlag with EnumFlag {
Expand Down Expand Up @@ -98,7 +99,7 @@ class _TaskManagerPage extends State<TaskManagerPage>
return Padding(
padding: const EdgeInsets.all(8),
key: ValueKey("task_${task.base.id}"),
child: Text("TODO ${task.base.id}"));
child: TaskView(task));
}

Widget _proxyDecorator(Widget child, int index, Animation<double> animation) {
Expand Down
8 changes: 8 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.2.1"
percent_indicator:
dependency: "direct main"
description:
name: percent_indicator
sha256: c37099ad833a883c9d71782321cb65c3a848c21b6939b6185f0ff6640d05814c
url: "https://pub.dev"
source: hosted
version: "4.2.3"
petitparser:
dependency: transitive
description:
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ dependencies:
palette_generator: ^0.3.3+3
path: ^1.8.3
path_provider: ^2.1.0
percent_indicator: ^4.2.3
photo_view: ^0.15.0
retrofit: ^4.0.1
shared_preferences: ^2.2.0
Expand Down

0 comments on commit 4237de5

Please sign in to comment.