[client] WIP: start to unify NavHistoryManager and ExplorerController

This commit is contained in:
Abhishek Shroff
2024-11-26 13:18:18 +05:30
parent f5865bf342
commit 6c8343191e
17 changed files with 130 additions and 123 deletions
+2 -1
View File
@@ -9,7 +9,8 @@ import 'package:phylum/libphylum/phylum_api_types.dart';
import 'package:phylum/ui/app/action_queue_status_notifier.dart';
import 'package:phylum/ui/app/app_layout.dart';
import 'package:phylum/ui/app/app_logout.dart';
import 'package:phylum/ui/app/nav_history.dart';
import 'package:phylum/ui/navigation/destination.dart';
import 'package:phylum/ui/navigation/history_manager.dart';
import 'package:provider/provider.dart';
final _appRouter = GoRouter(
+7 -6
View File
@@ -1,7 +1,8 @@
import 'package:flutter/material.dart';
import 'package:phylum/app_shortcuts.dart';
import 'package:phylum/ui/app/nav_history.dart';
import 'package:phylum/ui/explorer/explorer_view_controller.dart';
import 'package:phylum/ui/navigation/destination.dart';
import 'package:phylum/ui/navigation/history_manager.dart';
import 'package:phylum/ui/navigation/explorer_controller.dart';
import 'package:phylum/util/upload_utils.dart';
import 'package:provider/provider.dart';
@@ -14,16 +15,16 @@ class AppActions extends StatelessWidget {
return Actions(
actions: {
NewFolderIntent: CallbackAction<NewFolderIntent>(
onInvoke: (intent) => createDirectory(context, context.read<ExplorerViewState>().folderId),
onInvoke: (intent) => createDirectory(context, context.read<ExplorerState>().folderId),
),
UploadFilesIntent: CallbackAction<UploadFilesIntent>(
onInvoke: (intent) => pickAndUploadFiles(context, context.read<ExplorerViewState>().folderId),
onInvoke: (intent) => pickAndUploadFiles(context, context.read<ExplorerState>().folderId),
),
UploadFolderIntent: CallbackAction<UploadFolderIntent>(
onInvoke: (intent) => pickAndUploadDirectory(context, context.read<ExplorerViewState>().folderId),
onInvoke: (intent) => pickAndUploadDirectory(context, context.read<ExplorerState>().folderId),
),
NavUpIntent: CallbackAction<NavUpIntent>(onInvoke: (i) async {
final parent = context.read<ExplorerViewState>().folder?.parent;
final parent = context.read<ExplorerState>().folder?.parent;
if (parent != null) {
context.read<NavHistoryManager>().go(context, NavDestinationFolder(folderId: parent));
}
+7 -6
View File
@@ -4,10 +4,11 @@ import 'package:phylum/app_shortcuts.dart';
import 'package:phylum/libphylum/phylum_account.dart';
import 'package:phylum/ui/app/app_actions.dart';
import 'package:phylum/ui/app/fab_action.dart';
import 'package:phylum/ui/app/nav_history.dart';
import 'package:phylum/ui/navigation/destination.dart';
import 'package:phylum/ui/navigation/history_manager.dart';
import 'package:phylum/ui/app/nav_list.dart';
import 'package:phylum/ui/explorer/explorer_view.dart';
import 'package:phylum/ui/explorer/explorer_view_controller.dart';
import 'package:phylum/ui/navigation/explorer_controller.dart';
import 'package:phylum/ui/explorer/path_view.dart';
import 'package:phylum/ui/explorer/resource_drop_and_drop.dart';
import 'package:phylum/ui/explorer/resource_info_view.dart';
@@ -19,8 +20,8 @@ class AppLayout {
static Widget create(NavDestination destination) {
return MultiProvider(
providers: [
StateNotifierProvider<ExplorerViewController, ExplorerViewState>(
create: (context) => ExplorerViewController(
StateNotifierProvider<ExplorerController, ExplorerState>(
create: (context) => ExplorerController(
navHistoryManager: context.read<NavHistoryManager>(),
account: context.read<PhylumAccount>(),
),
@@ -64,14 +65,14 @@ class CollapsedAppLayout extends StatelessWidget {
@override
Widget build(BuildContext context) {
final selected = context.select<ExplorerViewState, int>((state) => state.selectedIds.length);
final selected = context.select<ExplorerState, int>((state) => state.selectedIds.length);
return Scaffold(
appBar: selected == 0
? AppBar(title: const Text('Phylum'))
: AppBar(
leading: CloseButton(
onPressed: () {
context.read<ExplorerViewController>().updateSelection((i) => i, SelectionMode.none, false);
context.read<ExplorerController>().updateSelection((i) => i, SelectionMode.none, false);
},
),
backgroundColor: Colors.grey,
@@ -3,8 +3,8 @@ import 'package:flutter_state_notifier/flutter_state_notifier.dart';
import 'package:phylum/app_shortcuts.dart';
import 'package:phylum/libphylum/db/db.dart';
import 'package:phylum/libphylum/phylum_account.dart';
import 'package:phylum/ui/app/nav_history.dart';
import 'package:phylum/ui/explorer/explorer_view_controller.dart';
import 'package:phylum/ui/navigation/destination.dart';
import 'package:phylum/ui/navigation/explorer_controller.dart';
import 'package:phylum/ui/explorer/resource_icon_extension.dart';
import 'package:phylum/util/upload_utils.dart';
import 'package:provider/provider.dart';
@@ -20,8 +20,8 @@ class DestinationPicker extends StatefulWidget {
static Future<String?> show(BuildContext context, Resource initialFolder) {
return showDialog(
context: context,
builder: (context) => StateNotifierProvider<ExplorerViewController, ExplorerViewState>(
create: (context) => ExplorerViewController(
builder: (context) => StateNotifierProvider<ExplorerController, ExplorerState>(
create: (context) => ExplorerController(
account: context.read<PhylumAccount>(),
destination: NavDestinationFolder(folderId: initialFolder.id),
),
@@ -53,7 +53,7 @@ class _DestinationPickerState extends State<DestinationPicker> {
actions: [
IconButton(
onPressed: () {
createDirectory(context, context.read<ExplorerViewState>().folderId);
createDirectory(context, context.read<ExplorerState>().folderId);
},
icon: Icon(Icons.create_new_folder_outlined))
],
@@ -62,23 +62,23 @@ class _DestinationPickerState extends State<DestinationPicker> {
child: Actions(
actions: {
NavUpIntent: CallbackAction<NavUpIntent>(onInvoke: (i) async {
final parentId = context.read<ExplorerViewState>().folder?.parent;
final parentId = context.read<ExplorerState>().folder?.parent;
if (parentId != null) {
context.read<ExplorerViewController>().updateDestination(NavDestinationFolder(folderId: parentId));
context.read<ExplorerController>().updateDestination(NavDestinationFolder(folderId: parentId));
}
node.requestFocus();
return null;
}),
FocusDownIntent: CallbackAction<FocusDownIntent>(
onInvoke: (i) async => context.read<ExplorerViewController>().updateSelection((i) => i + 1, SelectionMode.single, false),
onInvoke: (i) async => context.read<ExplorerController>().updateSelection((i) => i + 1, SelectionMode.single, false),
),
FocusUpIntent: CallbackAction<FocusUpIntent>(
onInvoke: (i) async => context.read<ExplorerViewController>().updateSelection((i) => i - 1, SelectionMode.single, false),
onInvoke: (i) async => context.read<ExplorerController>().updateSelection((i) => i - 1, SelectionMode.single, false),
),
ActivateIntent: CallbackAction<ActivateIntent>(onInvoke: (i) async {
final selected = context.read<ExplorerViewState>().selectedSingle;
final selected = context.read<ExplorerState>().selectedSingle;
if (selected != null && selected.dir) {
context.read<ExplorerViewController>().updateDestination(NavDestinationFolder(folderId: selected.id));
context.read<ExplorerController>().updateDestination(NavDestinationFolder(folderId: selected.id));
}
return null;
}),
@@ -101,9 +101,9 @@ class _DestinationPickerState extends State<DestinationPicker> {
children: [
TextButton(onPressed: Navigator.of(context).pop, child: Text('Cancel')),
ElevatedButton(
onPressed: context.select<ExplorerViewState, bool>((state) => state.folderId == widget.initialFolderId)
onPressed: context.select<ExplorerState, bool>((state) => state.folderId == widget.initialFolderId)
? null
: () => Navigator.of(context).pop(context.read<ExplorerViewState>().folderId),
: () => Navigator.of(context).pop(context.read<ExplorerState>().folderId),
child: Text('OK'),
),
],
@@ -122,12 +122,12 @@ class DestinationFolderView extends StatelessWidget {
@override
Widget build(BuildContext context) {
final items = context.select<ExplorerViewState, List<Resource>>((state) => state.resources);
final items = context.select<ExplorerState, List<Resource>>((state) => state.resources);
return ListView.builder(
itemBuilder: (BuildContext context, int index) {
final r = items[index];
return Builder(builder: (context) {
final selected = context.select<ExplorerViewState, bool>((state) => state.selectedIds.contains(r.id));
final selected = context.select<ExplorerState, bool>((state) => state.selectedIds.contains(r.id));
return ListTile(
key: ValueKey(r.id),
visualDensity: VisualDensity.compact,
@@ -135,7 +135,7 @@ class DestinationFolderView extends StatelessWidget {
leading: r.getIcon(),
title: Text(r.name),
enabled: r.dir,
onTap: () => context.read<ExplorerViewController>().updateDestination(NavDestinationFolder(folderId: r.id)),
onTap: () => context.read<ExplorerController>().updateDestination(NavDestinationFolder(folderId: r.id)),
);
});
},
+8 -8
View File
@@ -10,7 +10,7 @@ import 'package:phylum/util/dialogs.dart';
import 'package:provider/provider.dart';
import 'package:super_clipboard/super_clipboard.dart';
import 'explorer_view_controller.dart';
import '../navigation/explorer_controller.dart';
class ExplorerActions extends StatelessWidget {
final Widget child;
@@ -25,31 +25,31 @@ class ExplorerActions extends StatelessWidget {
PreviousFocusIntent: CallbackAction<PreviousFocusIntent>(onInvoke: (i) => null),
PasteFromClipboardIntent: CallbackAction<PasteFromClipboardIntent>(onInvoke: (PasteFromClipboardIntent i) => handlePasteAction(i, context)),
SelectAllIntent: CallbackAction<SelectAllIntent>(onInvoke: (i) {
context.read<ExplorerViewController>().selectAll(showFocus: true);
context.read<ExplorerController>().selectAll(showFocus: true);
return null;
}),
DismissIntent: CallbackAction<DismissIntent>(onInvoke: (i) {
context.read<ExplorerViewController>().updateSelection((i) => i, SelectionMode.none, true);
context.read<ExplorerController>().updateSelection((i) => i, SelectionMode.none, true);
return null;
}),
ToggleSelectionIntent: CallbackAction<ToggleSelectionIntent>(onInvoke: (i) {
context.read<ExplorerViewController>().updateSelection((i) => i, SelectionMode.toggle, true);
context.read<ExplorerController>().updateSelection((i) => i, SelectionMode.toggle, true);
return null;
}),
ActivateIntent: CallbackAction<ActivateIntent>(onInvoke: (i) {
final r = context.read<ExplorerViewState>().selectedSingle;
final r = context.read<ExplorerState>().selectedSingle;
if (r == null) return;
_openResource(context, r);
return null;
}),
DeleteIntent: CallbackAction<DeleteIntent>(onInvoke: (i) {
final selected = context.read<ExplorerViewState>().selected;
final selected = context.read<ExplorerState>().selected;
_deleteResources(context, selected);
return null;
}),
RenameIntent: CallbackAction<RenameIntent>(onInvoke: (i) async {
final account = context.read<PhylumAccount>();
final r = context.read<ExplorerViewState>().selectedSingle;
final r = context.read<ExplorerState>().selectedSingle;
if (r == null) return;
final name = await showInputDialog(context, title: 'Rename', preset: r.name);
if (name != null) {
@@ -59,7 +59,7 @@ class ExplorerActions extends StatelessWidget {
}),
CopyToClipboardIntent: CallbackAction<CopyToClipboardIntent>(onInvoke: (i) async {
final account = context.read<PhylumAccount>();
final selected = context.read<ExplorerViewState>().selected;
final selected = context.read<ExplorerState>().selected;
final items = selected.map((r) {
final uri = account.apiClient.createUriBuilder('/open');
uri.queryParameters['id'] = r.id;
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:phylum/app_shortcuts.dart';
import 'package:phylum/libphylum/phylum_account.dart';
import 'package:phylum/ui/explorer/explorer_view_controller.dart';
import 'package:phylum/ui/navigation/explorer_controller.dart';
import 'package:phylum/ui/menu/menu_option.dart';
import 'package:phylum/ui/menu/option_groups.dart';
import 'package:provider/provider.dart';
@@ -15,11 +15,11 @@ class ExplorerGestureHandler extends StatelessWidget {
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
context.read<ExplorerViewController>().updateSelection((i) => i, SelectionMode.none, false);
context.read<ExplorerController>().updateSelection((i) => i, SelectionMode.none, false);
},
onSecondaryTapUp: (details) async {
context.read<ExplorerViewController>().updateSelection((i) => i, SelectionMode.none, false);
final resource = context.read<ExplorerViewState>().folder;
context.read<ExplorerController>().updateSelection((i) => i, SelectionMode.none, false);
final resource = context.read<ExplorerState>().folder;
if (resource == null) return;
final position = RelativeRect.fromLTRB(
details.globalPosition.dx,
+4 -4
View File
@@ -3,7 +3,7 @@ import 'package:phylum/ui/explorer/explorer_actions.dart';
import 'package:phylum/ui/explorer/explorer_gesture_handler.dart';
import 'package:provider/provider.dart';
import 'explorer_view_controller.dart';
import '../navigation/explorer_controller.dart';
import 'folder_empty_view.dart';
import 'folder_list_view.dart';
@@ -20,7 +20,7 @@ class ExplorerView extends StatelessWidget {
}
Widget buildPage(BuildContext context) {
final type = context.select<ExplorerViewState, FolderEmptyViewType?>((state) {
final type = context.select<ExplorerState, FolderEmptyViewType?>((state) {
if (state.resources.isEmpty) {
if (state.refreshing) {
return FolderEmptyViewType.loading;
@@ -35,11 +35,11 @@ class ExplorerView extends StatelessWidget {
if (type != null) {
return FolderEmptyView(
type: type,
onRefresh: context.read<ExplorerViewController>().refresh,
onRefresh: context.read<ExplorerController>().refresh,
);
}
return RefreshIndicator(
onRefresh: context.read<ExplorerViewController>().refresh,
onRefresh: context.read<ExplorerController>().refresh,
child: const FolderListView(),
);
}
+4 -4
View File
@@ -5,7 +5,7 @@ import 'package:phylum/ui/explorer/resource_drop_and_drop.dart';
import 'package:phylum/ui/explorer/resource_item_gesture_handler.dart';
import 'package:provider/provider.dart';
import 'explorer_view_controller.dart';
import '../navigation/explorer_controller.dart';
class FolderListView extends StatefulWidget {
const FolderListView({super.key});
@@ -17,15 +17,15 @@ class FolderListView extends StatefulWidget {
class _FolderListViewState extends State<FolderListView> {
@override
Widget build(BuildContext context) {
final resources = context.select<ExplorerViewState, List<Resource>>((state) => state.resources);
final resources = context.select<ExplorerState, List<Resource>>((state) => state.resources);
return Actions(
actions: {
FocusUpIntent: CallbackAction<FocusUpIntent>(onInvoke: (i) {
context.read<ExplorerViewController>().updateSelection((i) => i - 1, i.mode, true);
context.read<ExplorerController>().updateSelection((i) => i - 1, i.mode, true);
return null;
}),
FocusDownIntent: CallbackAction<FocusDownIntent>(onInvoke: (i) {
context.read<ExplorerViewController>().updateSelection((i) => i + 1, i.mode, true);
context.read<ExplorerController>().updateSelection((i) => i + 1, i.mode, true);
return null;
}),
},
@@ -7,7 +7,7 @@ import 'package:phylum/libphylum/actions/action_resource_copy.dart';
import 'package:phylum/libphylum/actions/action_resource_move.dart';
import 'package:phylum/libphylum/db/db.dart';
import 'package:phylum/libphylum/phylum_account.dart';
import 'package:phylum/ui/explorer/explorer_view_controller.dart';
import 'package:phylum/ui/navigation/explorer_controller.dart';
import 'package:phylum/util/upload_utils.dart';
import 'package:phylum/libphylum/util/uuid.dart';
import 'package:provider/provider.dart';
@@ -15,7 +15,7 @@ import 'package:super_clipboard/super_clipboard.dart';
void handlePasteAction(PasteFromClipboardIntent i, BuildContext context) async {
final account = context.read<PhylumAccount>();
final controller = context.read<ExplorerViewState>();
final controller = context.read<ExplorerState>();
final target = controller.folder;
if (target == null) {
return;
+2 -2
View File
@@ -5,7 +5,7 @@ import 'package:flutter/services.dart';
import 'package:phylum/app_shortcuts.dart';
import 'package:phylum/libphylum/db/db.dart';
import 'package:phylum/libphylum/phylum_account.dart';
import 'package:phylum/ui/explorer/explorer_view_controller.dart';
import 'package:phylum/ui/navigation/explorer_controller.dart';
import 'package:phylum/ui/explorer/resource_drop_and_drop.dart';
import 'package:provider/provider.dart';
@@ -38,7 +38,7 @@ class _PathViewState extends State<PathView> {
@override
void initState() {
super.initState();
removeListener = context.read<ExplorerViewController>().addListener((state) {
removeListener = context.read<ExplorerController>().addListener((state) {
id = state.folderId;
sub = context.read<PhylumAccount>().db.parents(id).watch().listen((data) {
SystemChrome.setApplicationSwitcherDescription(ApplicationSwitcherDescription(
@@ -4,7 +4,7 @@ import 'package:phylum/ui/explorer/resource_icon_extension.dart';
import 'package:phylum/ui/menu/option_groups.dart';
import 'package:provider/provider.dart';
import 'explorer_view_controller.dart';
import '../navigation/explorer_controller.dart';
import '../menu/bottom_sheet.dart';
class ResourceDetailsRow extends StatelessWidget {
@@ -15,9 +15,9 @@ class ResourceDetailsRow extends StatelessWidget {
@override
Widget build(BuildContext context) {
final showBorder = context.select<ExplorerViewState, bool>((state) => state.focusId == r.id && state.showFocus);
final highlight = context.select<ExplorerViewState, bool>((state) => state.isSelected(r.id));
final dim = context.select<ExplorerViewState, bool>((state) => state.isSelected(r.id) && state.dragging);
final showBorder = context.select<ExplorerState, bool>((state) => state.focusId == r.id && state.showFocus);
final highlight = context.select<ExplorerState, bool>((state) => state.isSelected(r.id));
final dim = context.select<ExplorerState, bool>((state) => state.isSelected(r.id) && state.dragging);
final theme = Theme.of(context);
final border = dropTargetActive
? BorderSide(color: theme.colorScheme.secondary, width: 2.0)
@@ -7,7 +7,7 @@ import 'package:phylum/app_shortcuts.dart';
import 'package:phylum/libphylum/actions/action_resource_move.dart';
import 'package:phylum/libphylum/db/db.dart';
import 'package:phylum/libphylum/phylum_account.dart';
import 'package:phylum/ui/explorer/explorer_view_controller.dart';
import 'package:phylum/ui/navigation/explorer_controller.dart';
import 'package:phylum/ui/explorer/resource_details_row.dart';
import 'package:phylum/ui/explorer/resource_icon_extension.dart';
import 'package:phylum/util/upload_utils.dart';
@@ -38,7 +38,7 @@ class _ResourceDragTargetState extends State<ResourceDragTarget> {
return DragTarget(
builder: (context, candidate, rejected) => widget.buildItem(context, dropTargetActive),
onWillAcceptWithDetails: (details) {
final state = context.read<ExplorerViewState>();
final state = context.read<ExplorerState>();
if (state.selectedIds.contains(widget.resourceId) || state.folder?.id == widget.resourceId) {
// Don't accept drops into selected resources or the parent
return false;
@@ -51,7 +51,7 @@ class _ResourceDragTargetState extends State<ResourceDragTarget> {
},
onAcceptWithDetails: (details) async {
final account = context.read<PhylumAccount>();
final selected = context.read<ExplorerViewState>().selected;
final selected = context.read<ExplorerState>().selected;
for (final res in selected) {
account.addAction(ResourceMoveAction(r: res, parent: widget.resourceId));
}
@@ -128,7 +128,7 @@ class _ExternalDropRegionState extends State<ExternalDropRegion> {
}
}
if (context.mounted) {
final folderId = context.read<ExplorerViewState>().folderId;
final folderId = context.read<ExplorerState>().folderId;
uploadRecursive(context, folderId, paths);
}
}
@@ -151,18 +151,18 @@ class ResourceDraggable extends StatelessWidget {
data: '__selected',
dragAnchorStrategy: pointerDragAnchorStrategy,
onDragStarted: () {
final controller = context.read<ExplorerViewController>();
if (!context.read<ExplorerViewState>().isSelected(resource.id)) {
final controller = context.read<ExplorerController>();
if (!context.read<ExplorerState>().isSelected(resource.id)) {
controller.updateSelection((_) => index, SelectionMode.single, false);
}
controller.setDragging(true);
},
onDragEnd: (details) {
context.read<ExplorerViewController>().setDragging(false);
context.read<ExplorerController>().setDragging(false);
},
feedback: Builder(builder: (ctx) {
final theme = Theme.of(context);
final count = context.read<ExplorerViewState>().selectedIds.length;
final count = context.read<ExplorerState>().selectedIds.length;
return Card(
shape: RoundedRectangleBorder(side: BorderSide(color: theme.colorScheme.primary), borderRadius: BorderRadius.circular(4.0)),
elevation: 16.0,
@@ -3,7 +3,7 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:phylum/libphylum/db/db.dart';
import 'package:phylum/libphylum/phylum_account.dart';
import 'package:phylum/ui/explorer/explorer_view_controller.dart';
import 'package:phylum/ui/navigation/explorer_controller.dart';
import 'package:phylum/util/file_size.dart';
import 'package:phylum/util/permissions.dart';
import 'package:phylum/util/time.dart';
@@ -16,7 +16,7 @@ class ReactiveResourceInfoView extends StatelessWidget {
@override
Widget build(BuildContext context) {
final resource = context.select<ExplorerViewState, Resource?>((state) {
final resource = context.select<ExplorerState, Resource?>((state) {
return state.focussedIfSelected ?? state.folder;
});
@@ -3,7 +3,7 @@ import 'package:flutter/services.dart';
import 'package:phylum/app_shortcuts.dart';
import 'package:phylum/libphylum/db/db.dart';
import 'package:phylum/libphylum/phylum_account.dart';
import 'package:phylum/ui/explorer/explorer_view_controller.dart';
import 'package:phylum/ui/navigation/explorer_controller.dart';
import 'package:phylum/ui/explorer/resource_drop_and_drop.dart';
import 'package:phylum/ui/menu/menu_option.dart';
import 'package:phylum/ui/menu/option_groups.dart';
@@ -49,29 +49,29 @@ class _ResourceItemGestureHandlerState extends State<ResourceItemGestureHandler>
: HardwareKeyboard.instance.isShiftPressed
? SelectionMode.range
: SelectionMode.single;
if (context.read<ExplorerViewState>().isSelected(widget.resource.id) && mode == SelectionMode.single) {
if (context.read<ExplorerState>().isSelected(widget.resource.id) && mode == SelectionMode.single) {
deferHandling = true;
context.read<ExplorerViewController>().updateSelection((_) => widget.index, SelectionMode.noChange, false);
context.read<ExplorerController>().updateSelection((_) => widget.index, SelectionMode.noChange, false);
} else {
deferHandling = false;
context.read<ExplorerViewController>().updateSelection((_) => widget.index, mode, false);
context.read<ExplorerController>().updateSelection((_) => widget.index, mode, false);
}
},
onTap: () {
if (deferHandling) {
deferHandling = false;
context.read<ExplorerViewController>().updateSelection((_) => widget.index, SelectionMode.single, false);
context.read<ExplorerController>().updateSelection((_) => widget.index, SelectionMode.single, false);
}
},
onSecondaryTapUp: (details) async {
ExplorerViewState state = context.read<ExplorerViewState>();
ExplorerState state = context.read<ExplorerState>();
if (!state.isSelected(widget.resource.id)) {
final mode =
HardwareKeyboard.instance.isShiftPressed || HardwareKeyboard.instance.isControlPressed ? SelectionMode.add : SelectionMode.single;
context.read<ExplorerViewController>().updateSelection((i) => widget.index, mode, false);
state = context.read<ExplorerViewState>();
context.read<ExplorerController>().updateSelection((i) => widget.index, mode, false);
state = context.read<ExplorerState>();
} else {
context.read<ExplorerViewController>().updateSelection(null, SelectionMode.noChange, false);
context.read<ExplorerController>().updateSelection(null, SelectionMode.noChange, false);
}
final position = RelativeRect.fromLTRB(
details.globalPosition.dx,
@@ -92,7 +92,7 @@ class _ResourceItemGestureHandlerState extends State<ResourceItemGestureHandler>
}
},
onDoubleTap: () {
context.read<ExplorerViewController>().updateSelection((_) => widget.index, SelectionMode.single, false);
context.read<ExplorerController>().updateSelection((_) => widget.index, SelectionMode.single, false);
Actions.maybeInvoke(context, const ActivateIntent());
},
child: ResourceDraggable(
+38
View File
@@ -0,0 +1,38 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
sealed class NavDestination {
const NavDestination();
void go(BuildContext context);
}
class NavDestinationHome extends NavDestination {
const NavDestinationHome();
@override
void go(BuildContext context) {
context.goNamed('home');
}
@override
String toString() {
return 'NavDestinationHome';
}
}
class NavDestinationFolder extends NavDestination {
final String folderId;
NavDestinationFolder({required this.folderId});
@override
void go(BuildContext context) {
context.goNamed('folder', pathParameters: {'id': folderId});
}
@override
String toString() {
return 'NavDestinationFolder($folderId)';
}
}
@@ -5,10 +5,12 @@ import 'package:phylum/app_shortcuts.dart';
import 'package:phylum/libphylum/db/db.dart';
import 'package:phylum/libphylum/phylum_account.dart';
import 'package:phylum/libphylum/repositories/resource_repository.dart';
import 'package:phylum/ui/app/nav_history.dart';
import 'package:state_notifier/state_notifier.dart';
class ExplorerViewState {
import 'destination.dart';
import 'history_manager.dart';
class ExplorerState {
final String folderId;
final Resource? folder;
final List<Resource> resources;
@@ -26,7 +28,7 @@ class ExplorerViewState {
Resource? get selectedSingle => selectedIds.length != 1 ? null : resources.where((r) => selectedIds.contains(r.id)).firstOrNull;
Resource? get focussedIfSelected => selectedIds.isEmpty ? null : focussed;
const ExplorerViewState({
const ExplorerState({
required this.folderId,
this.folder,
this.resources = const [],
@@ -39,7 +41,7 @@ class ExplorerViewState {
this.refreshError = false,
});
ExplorerViewState copyWith({
ExplorerState copyWith({
String? folderId,
Resource? folder,
List<Resource>? resources,
@@ -51,7 +53,7 @@ class ExplorerViewState {
bool? refreshing,
bool? refreshError,
}) =>
ExplorerViewState(
ExplorerState(
folderId: folderId ?? this.folderId,
folder: folder ?? this.folder,
resources: resources ?? this.resources,
@@ -69,20 +71,20 @@ class ExplorerViewState {
}
}
class ExplorerViewController extends StateNotifier<ExplorerViewState> {
class ExplorerController extends StateNotifier<ExplorerState> {
final ResourceRepository _repository;
final String _homeId;
void Function()? removeHistoryManagerListener;
StreamSubscription<Resource?>? _folderSubscription;
StreamSubscription<List<Resource>>? _childrenSubscription;
ExplorerViewController({
ExplorerController({
required PhylumAccount account,
NavHistoryManager? navHistoryManager,
NavDestination? destination,
}) : _repository = account.resourceRepository,
_homeId = account.userHome,
super(ExplorerViewState(folderId: '')) {
super(ExplorerState(folderId: '')) {
removeHistoryManagerListener = navHistoryManager?.addListener((state) {
updateDestination(state.current);
}, fireImmediately: true);
@@ -99,7 +101,7 @@ class ExplorerViewController extends StateNotifier<ExplorerViewState> {
folderId = _homeId;
}
if (folderId == state.folderId) return;
state = ExplorerViewState(folderId: folderId);
state = ExplorerState(folderId: folderId);
refresh();
_folderSubscription?.cancel();
_childrenSubscription?.cancel();
@@ -1,44 +1,8 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:phylum/ui/navigation/destination.dart';
import 'package:state_notifier/state_notifier.dart';
sealed class NavDestination {
const NavDestination();
void go(BuildContext context);
}
class NavDestinationHome extends NavDestination {
const NavDestinationHome();
@override
void go(BuildContext context) {
context.goNamed('home');
}
@override
String toString() {
return 'NavDestinationHome';
}
}
class NavDestinationFolder extends NavDestination {
final String folderId;
NavDestinationFolder({required this.folderId});
@override
void go(BuildContext context) {
context.goNamed('folder', pathParameters: {'id': folderId});
}
@override
String toString() {
return 'NavDestinationFolder($folderId)';
}
}
class NavHistoryState {
final NavDestination current;
final List<NavDestination> _back;