mirror of
https://codeberg.org/shroff/phylum.git
synced 2026-05-05 11:50:04 -05:00
[client] WIP: start to unify NavHistoryManager and ExplorerController
This commit is contained in:
+2
-1
@@ -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(
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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)),
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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)';
|
||||
}
|
||||
}
|
||||
+11
-9
@@ -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;
|
||||
Reference in New Issue
Block a user