From 6a989ff18becfd1cf4d294e11b341a545d3c20f7 Mon Sep 17 00:00:00 2001 From: Abhishek Shroff Date: Wed, 11 Dec 2024 22:46:58 +0530 Subject: [PATCH] [client] Unified list of all actions --- .../ui/app/action_queue_status_notifier.dart | 53 ++++++++----------- ...{sliver_ready.dart => sliver_actions.dart} | 8 +-- client/lib/ui/sync/sliver_errors.dart | 31 ----------- client/lib/ui/sync/sliver_submitting.dart | 30 ----------- client/lib/ui/sync/sliver_waiting.dart | 30 ----------- client/lib/ui/sync/sync_dialog.dart | 10 ++-- 6 files changed, 33 insertions(+), 129 deletions(-) rename client/lib/ui/sync/{sliver_ready.dart => sliver_actions.dart} (78%) delete mode 100644 client/lib/ui/sync/sliver_errors.dart delete mode 100644 client/lib/ui/sync/sliver_submitting.dart delete mode 100644 client/lib/ui/sync/sliver_waiting.dart diff --git a/client/lib/ui/app/action_queue_status_notifier.dart b/client/lib/ui/app/action_queue_status_notifier.dart index b89d7993..a6c24008 100644 --- a/client/lib/ui/app/action_queue_status_notifier.dart +++ b/client/lib/ui/app/action_queue_status_notifier.dart @@ -4,6 +4,14 @@ import 'package:phylum/libphylum/phylum_account.dart'; import 'package:phylum/libphylum/phylum_api_types.dart'; import 'package:state_notifier/state_notifier.dart'; +const _order = { + ActionStatusDone: 0, + ActionStatusError: 1, + ActionStatusUploading: 2, + ActionStatusReady: 3, + ActionStatusWaiting: 4, +}; + class ActionQueueStatusNotifier extends ChangeNotifier { final Map, RemoveListener> _listeners = {}; final Map, ActionStatus> _statusMap = {}; @@ -16,28 +24,16 @@ class ActionQueueStatusNotifier extends ChangeNotifier { int get errorCount => _count(); int _count() => _statusMap.values.fold(0, (acc, status) => status is T ? acc + 1 : acc); - final _statusActionsMap = >>{}; - List> _actionsByStatus(Type t) { - return _statusActionsMap.putIfAbsent( - t, - () => List.of(_statusMap.entries.where((e) => e.value.runtimeType == t).map((e) => e.key), growable: false), - ); - } - - List> get failedActions { - return _actionsByStatus(ActionStatusError); - } - - List> get submittingActions { - return _actionsByStatus(ActionStatusUploading); - } - - List> get readyActions { - return _actionsByStatus(ActionStatusReady); - } - - List> get waitingActions { - return _actionsByStatus(ActionStatusWaiting); + List>? _orderedActions; + List> get orderedActions { + _orderedActions ??= List.of(_statusMap.keys, growable: false) + ..sort((a, b) { + if (_statusMap[a] == _statusMap[b]) { + return a.id.compareTo(b.id); + } + return _order[_statusMap[a].runtimeType]! - _order[_statusMap[b].runtimeType]!; + }); + return _orderedActions!; } ActionQueueStatusNotifier(PhylumActionQueue queue) { @@ -48,15 +44,12 @@ class ActionQueueStatusNotifier extends ChangeNotifier { _listeners[action] = action.statusNotifier.addListener((status) { // Ignore progress updates if (_statusMap[action].runtimeType != status.runtimeType) { - _statusActionsMap.remove(status.runtimeType); - _statusActionsMap.remove(_statusMap[action].runtimeType); - _statusMap[action] = status; + _orderedActions = null; if (status is ActionStatusDone) { - Future.microtask(() { - _listeners[action]?.call(); - _listeners.remove(action); - _statusMap.remove(action); - }); + _listeners.remove(action)?.call(); + _statusMap.remove(action); + } else { + _statusMap[action] = status; } notifyListeners(); } diff --git a/client/lib/ui/sync/sliver_ready.dart b/client/lib/ui/sync/sliver_actions.dart similarity index 78% rename from client/lib/ui/sync/sliver_ready.dart rename to client/lib/ui/sync/sliver_actions.dart index 694f3f12..32c5220c 100644 --- a/client/lib/ui/sync/sliver_ready.dart +++ b/client/lib/ui/sync/sliver_actions.dart @@ -6,20 +6,20 @@ import 'package:provider/provider.dart'; import 'action_view.dart'; -class SubmittingSliver extends StatelessWidget { - const SubmittingSliver({super.key}); +class ActionsSliver extends StatelessWidget { + const ActionsSliver({super.key}); @override Widget build(BuildContext context) { final actions = context.select>>((state) { - return state.readyActions; + return state.orderedActions; }); return SliverList( delegate: SliverChildBuilderDelegate( (context, i) { if (i == 0) { - return const ListTile(dense: true, title: Text('Ready')); + return const ListTile(dense: true, title: Text('Pending Updates')); } return ActionView(action: actions[i - 1]); }, diff --git a/client/lib/ui/sync/sliver_errors.dart b/client/lib/ui/sync/sliver_errors.dart deleted file mode 100644 index a1083eda..00000000 --- a/client/lib/ui/sync/sliver_errors.dart +++ /dev/null @@ -1,31 +0,0 @@ -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 ErrorsSliver extends StatelessWidget { - const ErrorsSliver({super.key}); - - @override - Widget build(BuildContext context) { - final actions = context.select>>((state) { - final failedActions = state.failedActions; - return failedActions; - }); - - return SliverList( - delegate: SliverChildBuilderDelegate( - (context, i) { - if (i == 0) { - return const ListTile(dense: true, title: Text('Errors')); - } - return ActionView(action: actions[i - 1]); - }, - childCount: actions.isEmpty ? 0 : actions.length + 1, - ), - ); - } -} diff --git a/client/lib/ui/sync/sliver_submitting.dart b/client/lib/ui/sync/sliver_submitting.dart deleted file mode 100644 index b849a653..00000000 --- a/client/lib/ui/sync/sliver_submitting.dart +++ /dev/null @@ -1,30 +0,0 @@ -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>>((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, - ), - ); - } -} diff --git a/client/lib/ui/sync/sliver_waiting.dart b/client/lib/ui/sync/sliver_waiting.dart deleted file mode 100644 index 4a9f6487..00000000 --- a/client/lib/ui/sync/sliver_waiting.dart +++ /dev/null @@ -1,30 +0,0 @@ -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>>((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, - ), - ); - } -} diff --git a/client/lib/ui/sync/sync_dialog.dart b/client/lib/ui/sync/sync_dialog.dart index 3858911f..107e5248 100644 --- a/client/lib/ui/sync/sync_dialog.dart +++ b/client/lib/ui/sync/sync_dialog.dart @@ -1,10 +1,8 @@ import 'package:flutter/material.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'; -import 'sliver_errors.dart'; +import 'sliver_actions.dart'; class SyncDialog extends StatelessWidget { const SyncDialog({super.key}); @@ -42,6 +40,10 @@ class SyncDialog extends StatelessWidget { } Widget buildContents(BuildContext context) => const CustomScrollView( - slivers: [OfflineSliver(), DownloadsSliver(), ErrorsSliver(), UploadsSliver(), SubmittingSliver()], + slivers: [ + OfflineSliver(), + DownloadsSliver(), + ActionsSliver(), + ], ); }