From 34e7756e8027ac5ec972d56784eb987633374b0b Mon Sep 17 00:00:00 2001 From: AYM1607 Date: Thu, 11 Apr 2019 01:59:53 -0500 Subject: [PATCH] Added support for the upload status snackbar in the event screen --- lib/src/screens/event_screen.dart | 11 +++++- lib/src/screens/new_image_screen.dart | 2 +- lib/src/services/upload_status_service.dart | 15 +++---- lib/src/utils.dart | 43 +++++++++++++++++++-- 4 files changed, 56 insertions(+), 15 deletions(-) diff --git a/lib/src/screens/event_screen.dart b/lib/src/screens/event_screen.dart index 9cbe263..e210c05 100644 --- a/lib/src/screens/event_screen.dart +++ b/lib/src/screens/event_screen.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import '../utils.dart' show getImageThumbnailPath; +import '../utils.dart' show getImageThumbnailPath, showUploadStatusSnackBar; import '../blocs/event_bloc.dart'; import '../screens/gallery_screen.dart'; import '../models/task_model.dart'; @@ -189,9 +189,16 @@ class _EventScreenState extends State ); } + // TODO: use a block provider instead of passing callbacks Future onAddPicturePressed() async { await Navigator.of(context).pushNamed('newImage/${bloc.eventName}'); - print('popped the pictures'); + if (bloc.snackBarStatus.value == false) { + showUploadStatusSnackBar( + _scaffoldContext, + bloc.uploadStatus, + bloc.updateSnackBarStatus, + ); + } } void dispose() { diff --git a/lib/src/screens/new_image_screen.dart b/lib/src/screens/new_image_screen.dart index c8c3633..90b21c8 100644 --- a/lib/src/screens/new_image_screen.dart +++ b/lib/src/screens/new_image_screen.dart @@ -154,7 +154,7 @@ class _NewImageScreenState extends State { /// Saves the image to the storage bucket. void onSubmit() async { - await bloc.submit(); + bloc.submit(); Navigator.of(context).pop(); } diff --git a/lib/src/services/upload_status_service.dart b/lib/src/services/upload_status_service.dart index abfc542..f04ccdd 100644 --- a/lib/src/services/upload_status_service.dart +++ b/lib/src/services/upload_status_service.dart @@ -28,12 +28,8 @@ class UploadStatusService { /// /// The task gets automatically removed when done. void addNewUpload(StorageUploadTask task) async { - final initialSnap = task.lastSnapshot; - // Initialize the map entry with the initial values. - _tasksData[task] = [ - initialSnap.bytesTransferred, - initialSnap.totalByteCount, - ]; + // Initialize the map entry with initial values. + _tasksData[task] = [0, 0]; task.events.listen( (StorageTaskEvent event) { // Update the map with the current values. @@ -47,6 +43,7 @@ class UploadStatusService { ); await task.onComplete; _tasksData.remove(task); + _sendUpdate(); } /// Updates the _status subject with the most current data. @@ -60,10 +57,10 @@ class UploadStatusService { }, ); if (bytestTransferred != 0) { - percentage = totalBytes / bytestTransferred; + percentage = bytestTransferred / totalBytes; } _status.sink.add(UploadStatus( - percentage: percentage, + percentage: (percentage * 100).toStringAsFixed(2), numberOfFiles: _tasksData.length, )); } @@ -77,7 +74,7 @@ class UploadStatusService { /// The status of an upload. class UploadStatus { /// Percentage of the upload. - final double percentage; + final String percentage; /// Number of files being uploaded. /// diff --git a/lib/src/utils.dart b/lib/src/utils.dart index 6a9832f..9b6b5b7 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -71,9 +71,46 @@ String getImageThumbnailPath(String path) { return tokens.join('/'); } +/// Shows an upload status snack bar. /// +/// Takes the data from the [uploadStatus] stream and shows in the snack bar. +/// Calls [onSuccessfullyClosed] with [false] when all files are done being +/// uploaded. void showUploadStatusSnackBar( - BuildContext context, + BuildContext scaffoldContext, Observable uploadStatus, - ValueObservable snackBarStatus, -) {} + Function(bool) onSuccessfullyClosed, +) { + assert(scaffoldContext != null); + assert(uploadStatus != null); + assert(onSuccessfullyClosed != null); + final scaffoldState = Scaffold.of(scaffoldContext); + scaffoldState.showSnackBar(SnackBar( + /// The snack bar shouldn't close until the files are done uploading + /// hence the long duration. It gets closed programatically. + duration: Duration(hours: 1), + content: StreamBuilder( + stream: uploadStatus, + builder: (BuildContext context, AsyncSnapshot snap) { + if (!snap.hasData) { + return Text(''); + } + print('Number of files: ${snap.data.numberOfFiles}'); + if (snap.data.numberOfFiles == 0) { + onSuccessfullyClosed(false); + scaffoldState.hideCurrentSnackBar(); + return Text(''); + } + return Row( + children: [ + Spacer(), + Text('${snap.data.numberOfFiles} pending files'), + Spacer(flex: 5), + Text(snap.data.percentage + '%'), + Spacer(), + ], + ); + }, + ), + )); +}