mirror of
https://codeberg.org/shroff/phylum.git
synced 2026-01-06 11:39:42 -06:00
[client] Show pending actions in info view
This commit is contained in:
@@ -12,27 +12,27 @@ import 'package:provider/provider.dart';
|
||||
|
||||
import '../../libphylum/explorer/explorer_controller.dart';
|
||||
|
||||
enum _SyncState {
|
||||
enum SyncState {
|
||||
none(Icons.block),
|
||||
waiting(Icons.cloud_queue),
|
||||
error(Icons.sync_problem),
|
||||
syncing(Icons.sync);
|
||||
|
||||
const _SyncState(this.icon);
|
||||
const SyncState(this.icon);
|
||||
|
||||
final IconData icon;
|
||||
|
||||
factory _SyncState.fromStatus(ActionStatus status) {
|
||||
factory SyncState.fromStatus(ActionStatus status) {
|
||||
if (status is ActionStatusReady || status is ActionStatusWaiting) {
|
||||
return _SyncState.waiting;
|
||||
return SyncState.waiting;
|
||||
}
|
||||
if (status is ActionStatusUploading) {
|
||||
return _SyncState.syncing;
|
||||
return SyncState.syncing;
|
||||
}
|
||||
if (status is ActionStatusError) {
|
||||
return _SyncState.error;
|
||||
return SyncState.error;
|
||||
}
|
||||
return _SyncState.none;
|
||||
return SyncState.none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,10 +47,10 @@ class ResourceDetailsRow extends StatelessWidget {
|
||||
final showBorder = context.select<ExplorerState, bool>((state) => state.focusId == resource.id && state.showFocus);
|
||||
final highlight = context.select<ExplorerState, bool>((state) => state.isSelected(resource.id));
|
||||
final dim = context.select<ExplorerState, bool>((state) => state.isSelected(resource.id) && state.dragging);
|
||||
final sync = context.select<PhylumActionQueueState, _SyncState>((state) {
|
||||
return state.actions.fold(_SyncState.none, (acc, action) {
|
||||
final sync = context.select<PhylumActionQueueState, SyncState>((state) {
|
||||
return state.actions.fold(SyncState.none, (acc, action) {
|
||||
if (action is ResourceAction && action.resourceId == resource.id) {
|
||||
final actionState = _SyncState.fromStatus(action.status);
|
||||
final actionState = SyncState.fromStatus(action.status);
|
||||
if (actionState.index > acc.index) return actionState;
|
||||
}
|
||||
return acc;
|
||||
@@ -117,7 +117,7 @@ class ResourceDetailsRow extends StatelessWidget {
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
if (sync != _SyncState.none)
|
||||
if (sync != SyncState.none)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 6.0),
|
||||
child: Icon(sync.icon, size: 14),
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:offtheline/offtheline.dart';
|
||||
import 'package:phylum/libphylum/actions/action_resource.dart';
|
||||
import 'package:phylum/libphylum/db/db.dart';
|
||||
import 'package:phylum/libphylum/db/resource_helpers.dart';
|
||||
import 'package:phylum/libphylum/phylum_account.dart';
|
||||
import 'package:phylum/libphylum/explorer/explorer_controller.dart';
|
||||
import 'package:phylum/libphylum/phylum_api_types.dart';
|
||||
import 'package:phylum/ui/explorer/resource_details_row.dart';
|
||||
import 'package:phylum/util/file_size.dart';
|
||||
import 'package:phylum/util/permissions.dart';
|
||||
import 'package:phylum/util/time.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:state_notifier/state_notifier.dart';
|
||||
|
||||
import 'resource_icon_extension.dart';
|
||||
|
||||
@@ -47,7 +52,7 @@ class ReactiveResourceInfoView extends StatelessWidget {
|
||||
class ResourceInfoView extends StatelessWidget {
|
||||
final Resource resource;
|
||||
|
||||
const ResourceInfoView({super.key, required this.resource});
|
||||
ResourceInfoView({required this.resource}) : super(key: ValueKey(resource.id));
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -59,6 +64,7 @@ class ResourceInfoView extends StatelessWidget {
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
PendingActionsTile(resourceId: resource.id),
|
||||
ListTile(
|
||||
title: const Text('Type'),
|
||||
subtitle: Text(resource.dir ? 'Folder' : resource.contentType),
|
||||
@@ -93,10 +99,75 @@ class ResourceInfoView extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class PendingActionsTile extends StatefulWidget {
|
||||
final String resourceId;
|
||||
|
||||
const PendingActionsTile({super.key, required this.resourceId});
|
||||
|
||||
@override
|
||||
State<PendingActionsTile> createState() => _PendingActionsTileState();
|
||||
}
|
||||
|
||||
class _PendingActionsTileState extends State<PendingActionsTile> {
|
||||
RemoveListener? _removeListener;
|
||||
final Map<PhylumAction, RemoveListener> _listeners = {};
|
||||
final Map<PhylumAction, ActionStatus> _statusMap = {};
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_removeListener = context.read<PhylumActionQueue>().addListener((state) {
|
||||
final actions =
|
||||
state.actions.where((action) => action is ResourceAction && action.resourceId == widget.resourceId);
|
||||
for (final action in actions) {
|
||||
if (!_listeners.containsKey(action)) {
|
||||
_listeners[action] = action.statusNotifier.addListener((status) {
|
||||
if (_statusMap[action].runtimeType != status.runtimeType) {
|
||||
if (status is ActionStatusDone) {
|
||||
final l = _listeners.remove(action);
|
||||
_statusMap.remove(action);
|
||||
if (l != null) {
|
||||
Future.microtask(() => l());
|
||||
}
|
||||
} else {
|
||||
_statusMap[action] = status;
|
||||
}
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
}, fireImmediately: true);
|
||||
}
|
||||
}
|
||||
}, fireImmediately: true);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_removeListener?.call();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
for (final e in _statusMap.entries)
|
||||
ListTile(
|
||||
visualDensity: VisualDensity.compact,
|
||||
dense: true,
|
||||
leading: Icon(SyncState.fromStatus(e.value).icon),
|
||||
title: Text(e.key.description, maxLines: 1),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PermissionsTile extends StatefulWidget {
|
||||
final String resourceId;
|
||||
|
||||
PermissionsTile({required this.resourceId}) : super(key: ValueKey(resourceId));
|
||||
const PermissionsTile({super.key, required this.resourceId});
|
||||
|
||||
@override
|
||||
State<PermissionsTile> createState() => _PermissionsTileState();
|
||||
@@ -105,8 +176,8 @@ class PermissionsTile extends StatefulWidget {
|
||||
class _PermissionsTileState extends State<PermissionsTile> {
|
||||
Permission? myPermission;
|
||||
Map<String, Permission>? otherPermissions;
|
||||
|
||||
StreamSubscription<List<ParentsResult>>? sub;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
Reference in New Issue
Block a user