Skip to content

Commit

Permalink
add task manager
Browse files Browse the repository at this point in the history
  • Loading branch information
lifegpc committed Feb 17, 2024
1 parent 02b211a commit 7cec3fd
Show file tree
Hide file tree
Showing 17 changed files with 430 additions and 21 deletions.
13 changes: 13 additions & 0 deletions lib/api/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,19 @@ class EHApi extends __EHApi {
return newUri.toString();
}

Uri getTaskUrl() {
final uri = Uri.parse(_combineBaseUrls(_dio.options.baseUrl, baseUrl));
final nuri = uri.resolve("task");
return Uri(
scheme: uri.scheme == "https" ? "wss" : "ws",
userInfo: nuri.userInfo,
host: nuri.host,
port: nuri.port,
path: nuri.path,
query: nuri.query,
);
}

String getThumbnailUrl(int id,
{int? max,
int? width,
Expand Down
50 changes: 39 additions & 11 deletions lib/api/task.dart
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,11 @@ class TaskProgress {
const TaskProgress({
required this.type,
required this.taskId,
required this.progress,
required this.detail,
});
final TaskType type;
final int taskId;
final TaskProgressBasicType progress;
final TaskProgressBasicType detail;
factory TaskProgress.fromJson(Map<String, dynamic> json) {
final type = json['type'] as int;
final taskId = json['task_id'] as int;
Expand All @@ -151,29 +151,29 @@ class TaskProgress {
return TaskProgress(
type: TaskType.download,
taskId: taskId,
progress: TaskDownloadProgess.fromJson(
json['progress'] as Map<String, dynamic>),
detail: TaskDownloadProgess.fromJson(
json['detail'] as Map<String, dynamic>),
);
case 1:
return TaskProgress(
type: TaskType.exportZip,
taskId: taskId,
progress: TaskExportZipProgress.fromJson(
json['progress'] as Map<String, dynamic>),
detail: TaskExportZipProgress.fromJson(
json['detail'] as Map<String, dynamic>),
);
case 2:
return TaskProgress(
type: TaskType.updateMeiliSearchData,
taskId: taskId,
progress: TaskUpdateMeiliSearchDataProgress.fromJson(
json['progress'] as Map<String, dynamic>),
detail: TaskUpdateMeiliSearchDataProgress.fromJson(
json['detail'] as Map<String, dynamic>),
);
case 3:
return TaskProgress(
type: TaskType.fixGalleryPage,
taskId: taskId,
progress: TaskFixGalleryPageProgress.fromJson(
json['progress'] as Map<String, dynamic>),
detail: TaskFixGalleryPageProgress.fromJson(
json['detail'] as Map<String, dynamic>),
);
default:
throw ArgumentError.value(type, 'type', 'Invalid task type');
Expand All @@ -200,9 +200,37 @@ class TaskDetail {
this.error,
this.fataled,
});
final Task base;
Task base;
TaskProgressBasicType? progress;
TaskStatus status;
String? error;
bool? fataled;
}

@JsonSerializable()
class TaskList {
const TaskList({
required this.tasks,
required this.running,
});
final List<Task> tasks;
final List<int> running;
factory TaskList.fromJson(Map<String, dynamic> json) =>
_$TaskListFromJson(json);
Map<String, dynamic> toJson() => _$TaskListToJson(this);
}

@JsonSerializable()
class TaskError {
const TaskError({
required this.task,
required this.error,
required this.fatal,
});
final Task task;
final String error;
final bool fatal;
factory TaskError.fromJson(Map<String, dynamic> json) =>
_$TaskErrorFromJson(json);
Map<String, dynamic> toJson() => _$TaskErrorToJson(this);
}
24 changes: 24 additions & 0 deletions lib/api/task.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions lib/auth.dart
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ class AuthInfo {
_log.info(
"Logged in as ${u.username} (${u.id}). isAdmin: ${u.isAdmin}. permissions: ${u.permissions}");
await checkSessionInfo();
if (canManageTasks == true) {
await tasks.connect();
}
} else if (re.status == 401 || re.status == 1 || re.status == 404) {
_user = null;
} else {
Expand Down
15 changes: 15 additions & 0 deletions lib/globals.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ final dio = Dio()
..options.extra['withCredentials'] = true;
Config? _prefs;
EHApi? _api;
PersistCookieJar? _jar;

Future<void> prepareJar() async {
final jar = PersistCookieJar(storage: FileStorage(await getJarPath()));
_jar = jar;
dio.interceptors.add(CookieManager(jar));
}

Expand Down Expand Up @@ -104,6 +106,10 @@ EHApi get api {
return _api!;
}

PersistCookieJar? get cookieJar {
return _jar;
}

final AuthInfo auth = AuthInfo();
final Clipboard platformClipboard = Clipboard();
final Display platformDisplay = Display();
Expand All @@ -121,6 +127,7 @@ enum MoreVertSettings {
markAsNsfw,
markAsSfw,
serverSettings,
taskManager,
}

void onMoreVertSettingsSelected(BuildContext context, MoreVertSettings value) {
Expand All @@ -143,6 +150,9 @@ void onMoreVertSettingsSelected(BuildContext context, MoreVertSettings value) {
case MoreVertSettings.serverSettings:
context.push("/server_settings");
break;
case MoreVertSettings.taskManager:
context.push("/task_manager");
break;
default:
break;
}
Expand Down Expand Up @@ -176,6 +186,11 @@ List<PopupMenuEntry<MoreVertSettings>> buildMoreVertSettings(
value: MoreVertSettings.serverSettings,
child: Text(AppLocalizations.of(context)!.serverSettings)));
}
if (path != "/task_manager" && auth.canManageTasks == true) {
list.add(PopupMenuItem(
value: MoreVertSettings.taskManager,
child: Text(AppLocalizations.of(context)!.taskManager)));
}
var showNsfw = prefs.getBool("showNsfw") ?? false;
list.add(PopupMenuItem(
child: StatefulBuilder(
Expand Down
10 changes: 10 additions & 0 deletions lib/home.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ class HomeDrawer extends StatelessWidget {
},
)
: Container(),
auth.canManageTasks == true
? ListTile(
leading: const Icon(Icons.task),
title: Text(AppLocalizations.of(context)!.taskManager),
onTap: () {
Scaffold.of(context).closeDrawer();
context.push("/task_manager");
},
)
: Container(),
ListTile(
leading: const Icon(Icons.settings),
title: Text(AppLocalizations.of(context)!.settings),
Expand Down
8 changes: 7 additions & 1 deletion lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -143,5 +143,11 @@
"redirectToFlutter": "Redirect to Flutter frontend when accessing the root URL.",
"downloadTimeoutCheckInterval": "The interval of checking download timeout",
"downloadTimeoutCheckIntervalHelp": "The smaller the value, the more accurate the timeout detection, but the higher CPU usage.",
"dockerHelper": "The server is running in a Docker container. Unless you know what you are doing, do not change this setting."
"dockerHelper": "The server is running in a Docker container. Unless you know what you are doing, do not change this setting.",
"taskManager": "Task Manager",
"waiting": "Waiting",
"running": "Running",
"finished": "Finished",
"failed": "Failed",
"allTasks": "All Tasks"
}
8 changes: 7 additions & 1 deletion lib/l10n/app_zh.arb
Original file line number Diff line number Diff line change
Expand Up @@ -143,5 +143,11 @@
"redirectToFlutter": "访问根 URL 时重定向到 flutter 前端。",
"downloadTimeoutCheckInterval": "下载超时检测间隔",
"downloadTimeoutCheckIntervalHelp": "值越小,检测准确性越高,但是消耗更多的 CPU。",
"dockerHelper": "服务器运行在 Docker 容器中。除非你知道你在做什么,否则不要修改这个设置。"
"dockerHelper": "服务器运行在 Docker 容器中。除非你知道你在做什么,否则不要修改这个设置。",
"taskManager": "任务管理器",
"waiting": "等待中",
"running": "运行中",
"finished": "已完成",
"failed": "已失败",
"allTasks": "所有任务"
}
30 changes: 27 additions & 3 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import 'logs/file.dart';
import 'server_settings.dart';
import 'set_server.dart';
import 'settings.dart';
import 'task_manager.dart';
import 'utils.dart';
import 'viewer/single.dart';

Expand Down Expand Up @@ -159,8 +160,12 @@ final _router = GoRouter(
}),
GoRoute(
path: ServerSettingsPage.routeName,
builder: (context, state) => const ServerSettingsPage(),
)
builder: (context, state) => ServerSettingsPage(key: state.pageKey),
),
GoRoute(
path: TaskManagerPage.routeName,
builder: (context, state) => TaskManagerPage(key: state.pageKey),
),
],
);

Expand Down Expand Up @@ -225,13 +230,15 @@ class MainApp extends StatefulWidget {
context.findAncestorStateOfType<_MainApp>()!;
}

class _MainApp extends State<MainApp> {
class _MainApp extends State<MainApp> with WidgetsBindingObserver {
ThemeMode _themeMode = ThemeMode.system;
ThemeData _themeData = ThemeData(useMaterial3: true);
ThemeData _darkThemeData = ThemeData.dark(useMaterial3: true);
ThemeMode get themeMode => _themeMode;
Lang _lang = Lang.system;
Lang get lang => _lang;
AppLifecycleState? _lifecycleState;
AppLifecycleState? get lifecycleState => _lifecycleState;

@override
void initState() {
Expand All @@ -250,6 +257,23 @@ class _MainApp extends State<MainApp> {
_themeData = _themeData.useSystemChineseFont(Brightness.light);
_darkThemeData = _darkThemeData.useSystemChineseFont(Brightness.dark);
}
WidgetsBinding.instance.addObserver(this);
if (WidgetsBinding.instance.lifecycleState != null) {
_lifecycleState = WidgetsBinding.instance.lifecycleState;
listener.tryEmit("lifecycle", _lifecycleState);
}
}

@override
void didChangeAppLifecycleState(AppLifecycleState state) {
_lifecycleState = state;
listener.tryEmit("lifecycle", _lifecycleState);
}

@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}

@override
Expand Down
Loading

0 comments on commit 7cec3fd

Please sign in to comment.