Browse Source

refactor(neon_files): move task progress into FileDetails

Signed-off-by: Nikolas Rimikis <rimikis.nikolas@gmail.com>
pull/556/head
Nikolas Rimikis 1 year ago
parent
commit
4bd5a029be
No known key found for this signature in database
GPG Key ID: 85ED1DE9786A4FF2
  1. 33
      packages/neon/neon_files/lib/models/file_details.dart
  2. 75
      packages/neon/neon_files/lib/widgets/browser_view.dart
  3. 52
      packages/neon/neon_files/lib/widgets/file_list_tile.dart

33
packages/neon/neon_files/lib/models/file_details.dart

@ -11,7 +11,9 @@ class FileDetails {
required this.lastModified, required this.lastModified,
required this.hasPreview, required this.hasPreview,
required this.isFavorite, required this.isFavorite,
}); }) : progress = null,
isUploading = false,
isDownloading = false;
FileDetails.fromWebDav({ FileDetails.fromWebDav({
required final WebDavFile file, required final WebDavFile file,
@ -23,19 +25,40 @@ class FileDetails {
mimeType = file.mimeType, mimeType = file.mimeType,
lastModified = file.lastModified, lastModified = file.lastModified,
hasPreview = file.hasPreview, hasPreview = file.hasPreview,
isFavorite = file.favorite; isFavorite = file.favorite,
progress = null,
isUploading = false,
isDownloading = false;
FileDetails.fromUploadTask({ FileDetails.fromUploadTask({
required final UploadTask task, required final UploadTask task,
}) : path = task.path, }) : path = task.path,
size = task.size, size = task.size,
lastModified = task.lastModified, lastModified = task.lastModified,
progress = task.progress,
isUploading = true,
isDownloading = false,
isDirectory = false, isDirectory = false,
etag = null, etag = null,
mimeType = null, mimeType = null,
hasPreview = null, hasPreview = null,
isFavorite = null; isFavorite = null;
FileDetails.fromDownloadTask({
required final DownloadTask task,
required final WebDavFile file,
}) : path = task.path,
isDirectory = file.isDirectory,
size = file.size,
etag = file.etag,
mimeType = file.mimeType,
lastModified = file.lastModified,
hasPreview = file.hasPreview,
isFavorite = file.favorite,
progress = task.progress,
isUploading = false,
isDownloading = true;
String get name => path.last; String get name => path.last;
final List<String> path; final List<String> path;
@ -53,4 +76,10 @@ class FileDetails {
final bool? hasPreview; final bool? hasPreview;
final bool? isFavorite; final bool? isFavorite;
final Stream<double>? progress;
final bool isUploading;
final bool isDownloading;
bool get isLoading => isUploading || isDownloading;
} }

75
packages/neon/neon_files/lib/widgets/browser_view.dart

@ -68,21 +68,13 @@ class _FilesBrowserViewState extends State<FilesBrowserView> {
(final task) => (final task) =>
sorted.where((final file) => _pathMatchesFile(task.path, file.name)).isEmpty, sorted.where((final file) => _pathMatchesFile(task.path, file.name)).isEmpty,
)) ...[ )) ...[
StreamBuilder<double>( FileListTile(
stream: uploadTask.progress, context: context,
builder: (final context, final uploadTaskProgressSnapshot) => details: FileDetails.fromUploadTask(
!uploadTaskProgressSnapshot.hasData task: uploadTask,
? const SizedBox() ),
: FileListTile( enableFileActions: widget.enableFileActions,
context: context, onPickFile: widget.onPickFile,
details: FileDetails.fromUploadTask(
task: uploadTask,
),
uploadProgress: uploadTaskProgressSnapshot.data,
downloadProgress: null,
enableFileActions: widget.enableFileActions,
onPickFile: widget.onPickFile,
),
), ),
], ],
if (sorted != null) ...[ if (sorted != null) ...[
@ -91,39 +83,32 @@ class _FilesBrowserViewState extends State<FilesBrowserView> {
Builder( Builder(
builder: (final context) { builder: (final context) {
final matchingUploadTasks = uploadTasksSnapshot.requireData final matchingUploadTasks = uploadTasksSnapshot.requireData
.where((final task) => _pathMatchesFile(task.path, file.name)); .firstWhereOrNull((final task) => _pathMatchesFile(task.path, file.name));
final matchingDownloadTasks = downloadTasksSnapshot.requireData final matchingDownloadTasks = downloadTasksSnapshot.requireData
.where((final task) => _pathMatchesFile(task.path, file.name)); .firstWhereOrNull((final task) => _pathMatchesFile(task.path, file.name));
return StreamBuilder<double?>( final FileDetails details;
stream: if (matchingDownloadTasks != null) {
matchingUploadTasks.isNotEmpty ? matchingUploadTasks.first.progress : null, details = FileDetails.fromDownloadTask(
builder: (final context, final uploadTaskProgressSnapshot) => task: matchingDownloadTasks,
StreamBuilder<double?>( file: file,
stream: matchingDownloadTasks.isNotEmpty );
? matchingDownloadTasks.first.progress } else if (matchingUploadTasks != null) {
: null, details = FileDetails.fromUploadTask(
builder: (final context, final downloadTaskProgressSnapshot) { task: matchingUploadTasks,
final path = widget.bloc.path.value; );
final details = matchingUploadTasks.isEmpty } else {
? FileDetails.fromWebDav( details = FileDetails.fromWebDav(
file: file, file: file,
path: path, path: widget.bloc.path.value,
) );
: FileDetails.fromUploadTask( }
task: matchingUploadTasks.first,
);
return FileListTile( return FileListTile(
context: context, context: context,
details: details, details: details,
uploadProgress: uploadTaskProgressSnapshot.data, enableFileActions: widget.enableFileActions,
downloadProgress: downloadTaskProgressSnapshot.data, onPickFile: widget.onPickFile,
enableFileActions: widget.enableFileActions,
onPickFile: widget.onPickFile,
);
},
),
); );
}, },
), ),

52
packages/neon/neon_files/lib/widgets/file_list_tile.dart

@ -10,8 +10,6 @@ class FileListTile extends StatelessWidget {
const FileListTile({ const FileListTile({
required this.context, required this.context,
required this.details, required this.details,
required this.uploadProgress,
required this.downloadProgress,
this.enableFileActions = true, this.enableFileActions = true,
this.onPickFile, this.onPickFile,
super.key, super.key,
@ -19,23 +17,9 @@ class FileListTile extends StatelessWidget {
final BuildContext context; final BuildContext context;
final FileDetails details; final FileDetails details;
final double? uploadProgress;
final double? downloadProgress;
final bool enableFileActions; final bool enableFileActions;
final Function(FileDetails)? onPickFile; final Function(FileDetails)? onPickFile;
bool get _isUploading => uploadProgress != null;
bool get _hasProgress => uploadProgress != null || downloadProgress != null;
double? get _progress {
if (!_hasProgress) {
return null;
}
return (uploadProgress ?? downloadProgress)!;
}
@override @override
Widget build(final BuildContext context) { Widget build(final BuildContext context) {
final bloc = Provider.of<FilesBloc>(context); final bloc = Provider.of<FilesBloc>(context);
@ -79,12 +63,9 @@ class FileListTile extends StatelessWidget {
], ],
), ),
leading: _FileIcon( leading: _FileIcon(
hasProgress: _hasProgress,
isUploading: _isUploading,
progress: _progress,
details: details, details: details,
), ),
trailing: !_hasProgress && enableFileActions trailing: !details.isLoading && enableFileActions
? FileActions(details: details) ? FileActions(details: details)
: const SizedBox.square( : const SizedBox.square(
dimension: 48, dimension: 48,
@ -96,14 +77,8 @@ class FileListTile extends StatelessWidget {
class _FileIcon extends StatelessWidget { class _FileIcon extends StatelessWidget {
const _FileIcon({ const _FileIcon({
required this.details, required this.details,
required this.hasProgress,
required this.isUploading,
this.progress,
}); });
final bool hasProgress;
final bool isUploading;
final double? progress;
final FileDetails details; final FileDetails details;
@override @override
@ -111,17 +86,20 @@ class _FileIcon extends StatelessWidget {
final bloc = Provider.of<FilesBloc>(context); final bloc = Provider.of<FilesBloc>(context);
Widget icon = Center( Widget icon = Center(
child: hasProgress child: details.isLoading
? Column( ? StreamBuilder<double>(
children: [ stream: details.progress,
Icon( builder: (final context, final progress) => Column(
isUploading ? MdiIcons.upload : MdiIcons.download, children: [
color: Theme.of(context).colorScheme.primary, Icon(
), details.isUploading ? MdiIcons.upload : MdiIcons.download,
LinearProgressIndicator( color: Theme.of(context).colorScheme.primary,
value: progress, ),
), LinearProgressIndicator(
], value: progress.data,
),
],
),
) )
: FilePreview( : FilePreview(
bloc: bloc, bloc: bloc,

Loading…
Cancel
Save