[client] Separate lists for action statuses

This commit is contained in:
Abhishek Shroff
2024-12-11 22:26:54 +05:30
parent 4e70839679
commit 7a64d70c86
6 changed files with 116 additions and 38 deletions

View File

@@ -15,10 +15,29 @@ class ActionQueueStatusNotifier extends ChangeNotifier {
int get submittingCount => _count<ActionStatusUploading>();
int get errorCount => _count<ActionStatusError>();
int _count<T extends ActionStatus>() => _statusMap.values.fold(0, (acc, status) => status is T ? acc + 1 : acc);
List<QueuedAction<PhylumAccount>>? _failedActions;
final _statusActionsMap = <Type, List<QueuedAction<PhylumAccount>>>{};
List<QueuedAction<PhylumAccount>> _actionsByStatus(Type t) {
return _statusActionsMap.putIfAbsent(
t,
() => List.of(_statusMap.entries.where((e) => e.value.runtimeType == t).map((e) => e.key), growable: false),
);
}
List<QueuedAction<PhylumAccount>> get failedActions {
_failedActions ??= List.of(_statusMap.entries.where((e) => e.value is ActionStatusError).map((e) => e.key), growable: false);
return _failedActions!;
return _actionsByStatus(ActionStatusError);
}
List<QueuedAction<PhylumAccount>> get submittingActions {
return _actionsByStatus(ActionStatusUploading);
}
List<QueuedAction<PhylumAccount>> get readyActions {
return _actionsByStatus(ActionStatusReady);
}
List<QueuedAction<PhylumAccount>> get waitingActions {
return _actionsByStatus(ActionStatusWaiting);
}
ActionQueueStatusNotifier(PhylumActionQueue queue) {
@@ -29,9 +48,8 @@ class ActionQueueStatusNotifier extends ChangeNotifier {
_listeners[action] = action.statusNotifier.addListener((status) {
// Ignore progress updates
if (_statusMap[action].runtimeType != status.runtimeType) {
if (status is ActionStatusError || _statusMap[action] is ActionStatusError) {
_failedActions = null;
}
_statusActionsMap.remove(status.runtimeType);
_statusActionsMap.remove(_statusMap[action].runtimeType);
_statusMap[action] = status;
if (status is ActionStatusDone) {
Future.microtask(() {

View File

@@ -0,0 +1,30 @@
import 'package:flutter/material.dart';
import 'package:offtheline/offtheline.dart';
import 'package:phylum/libphylum/phylum_account.dart';
import 'package:phylum/ui/app/action_queue_status_notifier.dart';
import 'package:provider/provider.dart';
import 'action_view.dart';
class SubmittingSliver extends StatelessWidget {
const SubmittingSliver({super.key});
@override
Widget build(BuildContext context) {
final actions = context.select<ActionQueueStatusNotifier, List<QueuedAction<PhylumAccount>>>((state) {
return state.readyActions;
});
return SliverList(
delegate: SliverChildBuilderDelegate(
(context, i) {
if (i == 0) {
return const ListTile(dense: true, title: Text('Ready'));
}
return ActionView(action: actions[i - 1]);
},
childCount: actions.isEmpty ? 0 : actions.length + 1,
),
);
}
}

View File

@@ -0,0 +1,30 @@
import 'package:flutter/material.dart';
import 'package:offtheline/offtheline.dart';
import 'package:phylum/libphylum/phylum_account.dart';
import 'package:phylum/ui/app/action_queue_status_notifier.dart';
import 'package:provider/provider.dart';
import 'action_view.dart';
class SubmittingSliver extends StatelessWidget {
const SubmittingSliver({super.key});
@override
Widget build(BuildContext context) {
final actions = context.select<ActionQueueStatusNotifier, List<QueuedAction<PhylumAccount>>>((state) {
return state.submittingActions;
});
return SliverList(
delegate: SliverChildBuilderDelegate(
(context, i) {
if (i == 0) {
return const ListTile(dense: true, title: Text('Submitting'));
}
return ActionView(action: actions[i - 1]);
},
childCount: actions.isEmpty ? 0 : actions.length + 1,
),
);
}
}

View File

@@ -1,30 +0,0 @@
import 'package:flutter/material.dart';
import 'package:offtheline/offtheline.dart';
import 'package:phylum/libphylum/actions/action_resource_upload.dart';
import 'package:phylum/libphylum/phylum_account.dart';
import 'package:phylum/libphylum/phylum_api_types.dart';
import 'package:provider/provider.dart';
import 'action_view.dart';
class UpdatesSliver extends StatelessWidget {
const UpdatesSliver({super.key});
@override
Widget build(BuildContext context) {
final actions = context.select<PhylumActionQueueState, List<QueuedAction<PhylumAccount>>>((state) => state.actions);
final updates = actions.where((action) => action.action is! ResourceUploadAction && action.status is! ActionStatusError).toList(growable: false);
return SliverList(
delegate: SliverChildBuilderDelegate(
(context, i) {
if (i == 0) {
return const ListTile(dense: true, title: Text('Updates'));
}
return ActionView(action: updates[i - 1]);
},
childCount: updates.isEmpty ? 0 : updates.length + 1,
),
);
}
}

View File

@@ -0,0 +1,30 @@
import 'package:flutter/material.dart';
import 'package:offtheline/offtheline.dart';
import 'package:phylum/libphylum/phylum_account.dart';
import 'package:phylum/ui/app/action_queue_status_notifier.dart';
import 'package:provider/provider.dart';
import 'action_view.dart';
class SubmittingSliver extends StatelessWidget {
const SubmittingSliver({super.key});
@override
Widget build(BuildContext context) {
final actions = context.select<ActionQueueStatusNotifier, List<QueuedAction<PhylumAccount>>>((state) {
return state.waitingActions;
});
return SliverList(
delegate: SliverChildBuilderDelegate(
(context, i) {
if (i == 0) {
return const ListTile(dense: true, title: Text('Waiting'));
}
return ActionView(action: actions[i - 1]);
},
childCount: actions.isEmpty ? 0 : actions.length + 1,
),
);
}
}

View File

@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:phylum/ui/sync/sliver_updates.dart';
import 'package:phylum/ui/sync/sliver_submitting.dart';
import 'package:phylum/ui/sync/sliver_offline.dart';
import 'package:phylum/ui/sync/sliver_uploads.dart';
import 'package:phylum/ui/sync/sliver_downloads.dart';
@@ -42,6 +42,6 @@ class SyncDialog extends StatelessWidget {
}
Widget buildContents(BuildContext context) => const CustomScrollView(
slivers: [OfflineSliver(), DownloadsSliver(), ErrorsSliver(), UploadsSliver(), UpdatesSliver()],
slivers: [OfflineSliver(), DownloadsSliver(), ErrorsSliver(), UploadsSliver(), SubmittingSliver()],
);
}