diff --git a/packages/neon/neon_files/lib/dialogs/choose_folder.dart b/packages/neon/neon_files/lib/dialogs/choose_folder.dart index 551f461b..16b37295 100644 --- a/packages/neon/neon_files/lib/dialogs/choose_folder.dart +++ b/packages/neon/neon_files/lib/dialogs/choose_folder.dart @@ -25,8 +25,7 @@ class FilesChooseFolderDialog extends StatelessWidget { child: FilesBrowserView( bloc: bloc, filesBloc: filesBloc, - enableFileActions: false, - onlyShowDirectories: true, + mode: FilesBrowserMode.selectDirectory, ), ), StreamBuilder>( diff --git a/packages/neon/neon_files/lib/pages/main.dart b/packages/neon/neon_files/lib/pages/main.dart index 5254b7ba..ecd5f2da 100644 --- a/packages/neon/neon_files/lib/pages/main.dart +++ b/packages/neon/neon_files/lib/pages/main.dart @@ -27,21 +27,6 @@ class _FilesMainPageState extends State { body: FilesBrowserView( bloc: bloc.browser, filesBloc: bloc, - onPickFile: (final details) async { - final sizeWarning = bloc.options.downloadSizeWarning.value; - if (sizeWarning != null && details.size != null && details.size! > sizeWarning) { - if (!(await showConfirmationDialog( - context, - AppLocalizations.of(context).downloadConfirmSizeWarning( - filesize(sizeWarning), - filesize(details.size), - ), - ))) { - return; - } - } - bloc.openFile(details.path, details.etag!, details.mimeType); - }, ), floatingActionButton: FloatingActionButton( onPressed: () async { diff --git a/packages/neon/neon_files/lib/widgets/browser_view.dart b/packages/neon/neon_files/lib/widgets/browser_view.dart index 2d06b8aa..7f066028 100644 --- a/packages/neon/neon_files/lib/widgets/browser_view.dart +++ b/packages/neon/neon_files/lib/widgets/browser_view.dart @@ -1,21 +1,30 @@ part of '../neon_files.dart'; +/// Mode to operate the [FilesBrowserView] in. +enum FilesBrowserMode { + /// Default file browser mode. + /// + /// When a file is selecteed it will be opened or downloaded. + browser, + + /// Select directory. + selectDirectory, + + /// Don't show file actions. + noActions, +} + class FilesBrowserView extends StatefulWidget { const FilesBrowserView({ required this.bloc, required this.filesBloc, - this.onPickFile, - this.enableFileActions = true, - this.onlyShowDirectories = false, + this.mode = FilesBrowserMode.browser, super.key, - // ignore: prefer_asserts_with_message - }) : assert((onPickFile == null) == onlyShowDirectories); + }); final FilesBrowserBloc bloc; final FilesBloc filesBloc; - final Function(FileDetails)? onPickFile; - final bool enableFileActions; - final bool onlyShowDirectories; + final FilesBrowserMode mode; @override State createState() => _FilesBrowserViewState(); @@ -24,11 +33,11 @@ class FilesBrowserView extends StatefulWidget { class _FilesBrowserViewState extends State { @override void initState() { - super.initState(); - widget.bloc.errors.listen((final error) { NeonException.showSnackbar(context, error); }); + + super.initState(); } @override @@ -68,12 +77,11 @@ class _FilesBrowserViewState extends State { details: FileDetails.fromUploadTask( task: uploadTask, ), - enableFileActions: widget.enableFileActions, - onPickFile: widget.onPickFile, + mode: widget.mode, ), ], for (final file in sorted) ...[ - if (!widget.onlyShowDirectories || file.isDirectory) ...[ + if (widget.mode != FilesBrowserMode.selectDirectory || file.isDirectory) ...[ Builder( builder: (final context) { final matchingTask = tasksSnapshot.requireData @@ -93,8 +101,7 @@ class _FilesBrowserViewState extends State { bloc: widget.filesBloc, browserBloc: widget.bloc, details: details, - enableFileActions: widget.enableFileActions, - onPickFile: widget.onPickFile, + mode: widget.mode, ); }, ), diff --git a/packages/neon/neon_files/lib/widgets/file_list_tile.dart b/packages/neon/neon_files/lib/widgets/file_list_tile.dart index 3db2d1f8..fb5aaf85 100644 --- a/packages/neon/neon_files/lib/widgets/file_list_tile.dart +++ b/packages/neon/neon_files/lib/widgets/file_list_tile.dart @@ -1,7 +1,9 @@ import 'package:filesize/filesize.dart'; import 'package:flutter/material.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; +import 'package:neon/utils.dart'; import 'package:neon/widgets.dart'; +import 'package:neon_files/l10n/localizations.dart'; import 'package:neon_files/neon_files.dart'; import 'package:neon_files/widgets/actions.dart'; @@ -10,66 +12,72 @@ class FileListTile extends StatelessWidget { required this.bloc, required this.browserBloc, required this.details, - this.enableFileActions = true, - this.onPickFile, + this.mode = FilesBrowserMode.browser, super.key, }); final FilesBloc bloc; final FilesBrowserBloc browserBloc; final FileDetails details; - final bool enableFileActions; - final Function(FileDetails)? onPickFile; + final FilesBrowserMode mode; - @override - Widget build(final BuildContext context) { - // When the ETag is null it means we are uploading this file right now - final onTap = details.isDirectory || details.etag != null - ? () { - if (details.isDirectory) { - browserBloc.setPath(details.path); - } else { - onPickFile?.call(details); - } - } - : null; + Future _onTap(final BuildContext context, final FileDetails details) async { + if (details.isDirectory) { + browserBloc.setPath(details.path); + } else if (mode == FilesBrowserMode.browser) { + final sizeWarning = bloc.options.downloadSizeWarning.value; + if (sizeWarning != null && details.size != null && details.size! > sizeWarning) { + if (!(await showConfirmationDialog( + context, + AppLocalizations.of(context).downloadConfirmSizeWarning( + filesize(sizeWarning), + filesize(details.size), + ), + ))) { + return; + } + } + bloc.openFile(details.path, details.etag!, details.mimeType); + } + } - return ListTile( - onTap: onTap, - title: Text( - details.name, - overflow: TextOverflow.ellipsis, - ), - subtitle: Row( - children: [ - if (details.lastModified != null) - RelativeTime( - date: details.lastModified!, - ), - if (details.size != null && details.size! > 0) ...[ - const SizedBox( - width: 10, - ), - Text( - filesize(details.size, 1), - style: DefaultTextStyle.of(context).style.copyWith( - color: Colors.grey, - ), - ), + @override + Widget build(final BuildContext context) => ListTile( + // When the ETag is null it means we are uploading this file right now + onTap: details.isDirectory || details.etag != null ? () async => _onTap(context, details) : null, + title: Text( + details.name, + overflow: TextOverflow.ellipsis, + ), + subtitle: Row( + children: [ + if (details.lastModified != null) + RelativeTime( + date: details.lastModified!, + ), + if (details.size != null && details.size! > 0) ...[ + const SizedBox( + width: 10, + ), + Text( + filesize(details.size, 1), + style: DefaultTextStyle.of(context).style.copyWith( + color: Colors.grey, + ), + ), + ], ], - ], - ), - leading: _FileIcon( - details: details, - bloc: bloc, - ), - trailing: !details.hasTask && enableFileActions - ? FileActions(details: details) - : const SizedBox.square( - dimension: 48, - ), - ); - } + ), + leading: _FileIcon( + details: details, + bloc: bloc, + ), + trailing: !details.hasTask && mode != FilesBrowserMode.noActions + ? FileActions(details: details) + : const SizedBox.square( + dimension: 48, + ), + ); } class _FileIcon extends StatelessWidget {