diff --git a/server/activity.go b/server/activity.go index d272328..a75ea92 100644 --- a/server/activity.go +++ b/server/activity.go @@ -12,6 +12,7 @@ import ( type Activity struct { *ent.History InBackgroud bool `json:"in_backgroud"` + Progress int `json:"progress"` } func (s *Server) GetAllActivities(c *gin.Context) (interface{}, error) { @@ -22,9 +23,15 @@ func (s *Server) GetAllActivities(c *gin.Context) (interface{}, error) { History: h, } for id, task := range s.tasks { + if h.ID == id { + a.Progress = task.Progress() + } if h.ID == id && task.Processing { a.InBackgroud = true - } + } + } + if a.Completed { + a.Progress = 100 } activities = append(activities, a) } @@ -50,7 +57,7 @@ func (s *Server) RemoveActivity(c *gin.Context) (interface{}, error) { } delete(s.tasks, his.ID) } - + err = s.db.DeleteHistory(id) if err != nil { return nil, errors.Wrap(err, "db") diff --git a/ui/lib/activity.dart b/ui/lib/activity.dart index 7388779..51d32bf 100644 --- a/ui/lib/activity.dart +++ b/ui/lib/activity.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:ui/providers/activity.dart'; +import 'package:ui/widgets/progress_indicator.dart'; class ActivityPage extends ConsumerWidget { static const route = "/activities"; @@ -18,8 +19,7 @@ class ActivityPage extends ConsumerWidget { DataColumn(label: Text("id"), numeric: true), DataColumn(label: Text("名称")), DataColumn(label: Text("开始时间")), - DataColumn(label: Text("是否完成")), - DataColumn(label: Text("后台操作")), + DataColumn(label: Text("状态")), DataColumn(label: Text("操作")) ], rows: List.generate(activities.length, (i) { @@ -29,8 +29,24 @@ class ActivityPage extends ConsumerWidget { DataCell(Text("${activity.id}")), DataCell(Text("${activity.sourceTitle}")), DataCell(Text("${activity.date!.toLocal()}")), - DataCell(Text("${activity.completed}")), - DataCell(Text("${activity.inBackgroud}")), + DataCell(() { + if (activity.inBackgroud == true) { + return MyProgressIndicator(size: 20,); + } + + if (activity.completed != true && activity.progress == 0) { + return MyProgressIndicator( + value: 1, + color: Colors.red, + size: 20, + ); + } + + return MyProgressIndicator( + value: activity.progress!.toDouble() / 100, + size: 20, + ); + }()), DataCell(IconButton( onPressed: () { ref @@ -44,8 +60,6 @@ class ActivityPage extends ConsumerWidget { ); }, error: (err, trace) => Text("$err"), - loading: () => const Center( - child: SizedBox( - width: 30, height: 30, child: CircularProgressIndicator()))); + loading: () => MyProgressIndicator()); } } diff --git a/ui/lib/providers/activity.dart b/ui/lib/providers/activity.dart index 319f04d..c5aafce 100644 --- a/ui/lib/providers/activity.dart +++ b/ui/lib/providers/activity.dart @@ -4,7 +4,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:ui/providers/APIs.dart'; import 'package:ui/providers/server_response.dart'; -var activitiesDataProvider = AsyncNotifierProvider.autoDispose>( +var activitiesDataProvider = + AsyncNotifierProvider.autoDispose>( ActivityData.new); class ActivityData extends AutoDisposeAsyncNotifier> { @@ -35,40 +36,42 @@ class ActivityData extends AutoDisposeAsyncNotifier> { } class Activity { - Activity({ - required this.id, - required this.seriesId, - required this.episodeId, - required this.sourceTitle, - required this.date, - required this.targetDir, - required this.completed, - required this.saved, - required this.inBackgroud, - }); + Activity({ + required this.id, + required this.seriesId, + required this.episodeId, + required this.sourceTitle, + required this.date, + required this.targetDir, + required this.completed, + required this.saved, + required this.inBackgroud, + required this.progress + }); - final int? id; - final int? seriesId; - final int? episodeId; - final String? sourceTitle; - final DateTime? date; - final String? targetDir; - final bool? completed; - final String? saved; - final bool? inBackgroud; - - factory Activity.fromJson(Map json){ - return Activity( - id: json["id"], - seriesId: json["series_id"], - episodeId: json["episode_id"], - sourceTitle: json["source_title"], - date: DateTime.tryParse(json["date"] ?? ""), - targetDir: json["target_dir"], - completed: json["completed"], - saved: json["saved"], - inBackgroud: json["in_backgroud"], - ); - } + final int? id; + final int? seriesId; + final int? episodeId; + final String? sourceTitle; + final DateTime? date; + final String? targetDir; + final bool? completed; + final String? saved; + final bool? inBackgroud; + final int? progress; + factory Activity.fromJson(Map json) { + return Activity( + id: json["id"], + seriesId: json["series_id"], + episodeId: json["episode_id"], + sourceTitle: json["source_title"], + date: DateTime.tryParse(json["date"] ?? ""), + targetDir: json["target_dir"], + completed: json["completed"], + saved: json["saved"], + inBackgroud: json["in_backgroud"], + progress: json["progress"] + ); + } } diff --git a/ui/lib/search.dart b/ui/lib/search.dart index 16748ae..3d53fda 100644 --- a/ui/lib/search.dart +++ b/ui/lib/search.dart @@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:ui/providers/APIs.dart'; import 'package:ui/providers/settings.dart'; import 'package:ui/providers/welcome_data.dart'; +import 'package:ui/widgets/progress_indicator.dart'; class SearchPage extends ConsumerStatefulWidget { const SearchPage({super.key}); @@ -69,7 +70,7 @@ class _SearchPageState extends ConsumerState { return cards; }, error: (err, trace) => [Text("$err")], - loading: () => [const CircularProgressIndicator()]); + loading: () => [MyProgressIndicator()]); var f = FutureBuilder( // We listen to the pending operation, to update the UI accordingly. @@ -77,9 +78,7 @@ class _SearchPageState extends ConsumerState { builder: (context, snapshot) { if (snapshot.connectionState != ConnectionState.done && snapshot.connectionState != ConnectionState.none) { - return const Center( - child: SizedBox( - width: 30, height: 30, child: CircularProgressIndicator())); + return MyProgressIndicator(); } return ListView( children: res, @@ -149,7 +148,7 @@ class _SearchPageState extends ConsumerState { ); }, error: (err, trace) => Text("$err"), - loading: () => const CircularProgressIndicator()), + loading: () => MyProgressIndicator()), ], ), actions: [ diff --git a/ui/lib/system_settings.dart b/ui/lib/system_settings.dart index 243f45f..cdc6a21 100644 --- a/ui/lib/system_settings.dart +++ b/ui/lib/system_settings.dart @@ -4,6 +4,7 @@ import 'package:quiver/strings.dart'; import 'package:ui/providers/login.dart'; import 'package:ui/providers/settings.dart'; import 'package:ui/utils.dart'; +import 'package:ui/widgets/progress_indicator.dart'; import 'providers/APIs.dart'; @@ -61,7 +62,7 @@ class _SystemSettingsPageState extends ConsumerState { ); }, error: (err, trace) => Text("$err"), - loading: () => const CircularProgressIndicator()), + loading: () => MyProgressIndicator()), dirKey.when( data: (data) { _downloadDirController.text = data; @@ -80,7 +81,7 @@ class _SystemSettingsPageState extends ConsumerState { ); }, error: (err, trace) => Text("$err"), - loading: () => const CircularProgressIndicator()), + loading: () => MyProgressIndicator()), Center( child: Padding( padding: const EdgeInsets.only(top: 28.0), @@ -154,7 +155,7 @@ class _SystemSettingsPageState extends ConsumerState { ))); }), error: (err, trace) => Text("$err"), - loading: () => const CircularProgressIndicator()); + loading: () => MyProgressIndicator()); }); var downloadClients = ref.watch(dwonloadClientsProvider); @@ -197,7 +198,7 @@ class _SystemSettingsPageState extends ConsumerState { ))); }), error: (err, trace) => Text("$err"), - loading: () => const CircularProgressIndicator()); + loading: () => MyProgressIndicator()); }); var storageSettingData = ref.watch(storageSettingProvider); @@ -238,7 +239,7 @@ class _SystemSettingsPageState extends ConsumerState { ))); }), error: (err, trace) => Text("$err"), - loading: () => const CircularProgressIndicator()); + loading: () => MyProgressIndicator()); }); var authData = ref.watch(authSettingProvider); @@ -293,7 +294,7 @@ class _SystemSettingsPageState extends ConsumerState { ); }, error: (err, trace) => Text("$err"), - loading: () => const CircularProgressIndicator()); + loading: () => MyProgressIndicator()); return ListView( children: [ diff --git a/ui/lib/tv_details.dart b/ui/lib/tv_details.dart index a8b93c9..a82a798 100644 --- a/ui/lib/tv_details.dart +++ b/ui/lib/tv_details.dart @@ -5,6 +5,7 @@ import 'package:ui/providers/APIs.dart'; import 'package:ui/providers/series_details.dart'; import 'package:ui/utils.dart'; import 'package:ui/weclome.dart'; +import 'package:ui/widgets/progress_indicator.dart'; class TvDetailsPage extends ConsumerStatefulWidget { static const route = "/series/:id"; @@ -160,11 +161,7 @@ class _TvDetailsPageState extends ConsumerState { error: (err, trace) { return Text("$err"); }, - loading: () => const Center( - child: SizedBox( - width: 30, - height: 30, - child: CircularProgressIndicator()))); + loading: () => MyProgressIndicator()); }); } } diff --git a/ui/lib/weclome.dart b/ui/lib/weclome.dart index 5e9ef5f..ed9ce2c 100644 --- a/ui/lib/weclome.dart +++ b/ui/lib/weclome.dart @@ -4,6 +4,7 @@ import 'package:go_router/go_router.dart'; import 'package:ui/providers/APIs.dart'; import 'package:ui/providers/welcome_data.dart'; import 'package:ui/tv_details.dart'; +import 'package:ui/widgets/progress_indicator.dart'; class WelcomePage extends ConsumerWidget { static const route = "/series"; @@ -48,9 +49,7 @@ class WelcomePage extends ConsumerWidget { ), )); }), - _ => const Center( - child: SizedBox( - width: 30, height: 30, child: CircularProgressIndicator())), + _ => MyProgressIndicator(), }; } } diff --git a/ui/lib/widgets/progress_indicator.dart b/ui/lib/widgets/progress_indicator.dart new file mode 100644 index 0000000..e93ca26 --- /dev/null +++ b/ui/lib/widgets/progress_indicator.dart @@ -0,0 +1,20 @@ +import 'package:flutter/material.dart'; + +class MyProgressIndicator extends StatelessWidget { + double size; + Color? color; + double? value; + + MyProgressIndicator({super.key, this.size = 30, this.color, this.value}); + @override + Widget build(BuildContext context) { + return Center( + child: SizedBox( + width: size, + height: size, + child: CircularProgressIndicator( + color: color, + value: value, + ))); + } +}