Added support for the upload status snackbar in the event screen

This commit is contained in:
Mariano Uvalle 2019-04-11 01:59:53 -05:00
parent aa1d9b9edf
commit 34e7756e80
4 changed files with 56 additions and 15 deletions

View file

@ -2,7 +2,7 @@ import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../utils.dart' show getImageThumbnailPath; import '../utils.dart' show getImageThumbnailPath, showUploadStatusSnackBar;
import '../blocs/event_bloc.dart'; import '../blocs/event_bloc.dart';
import '../screens/gallery_screen.dart'; import '../screens/gallery_screen.dart';
import '../models/task_model.dart'; import '../models/task_model.dart';
@ -189,9 +189,16 @@ class _EventScreenState extends State<EventScreen>
); );
} }
// TODO: use a block provider instead of passing callbacks
Future<void> onAddPicturePressed() async { Future<void> onAddPicturePressed() async {
await Navigator.of(context).pushNamed('newImage/${bloc.eventName}'); 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() { void dispose() {

View file

@ -154,7 +154,7 @@ class _NewImageScreenState extends State<NewImageScreen> {
/// Saves the image to the storage bucket. /// Saves the image to the storage bucket.
void onSubmit() async { void onSubmit() async {
await bloc.submit(); bloc.submit();
Navigator.of(context).pop(); Navigator.of(context).pop();
} }

View file

@ -28,12 +28,8 @@ class UploadStatusService {
/// ///
/// The task gets automatically removed when done. /// The task gets automatically removed when done.
void addNewUpload(StorageUploadTask task) async { void addNewUpload(StorageUploadTask task) async {
final initialSnap = task.lastSnapshot; // Initialize the map entry with initial values.
// Initialize the map entry with the initial values. _tasksData[task] = [0, 0];
_tasksData[task] = [
initialSnap.bytesTransferred,
initialSnap.totalByteCount,
];
task.events.listen( task.events.listen(
(StorageTaskEvent event) { (StorageTaskEvent event) {
// Update the map with the current values. // Update the map with the current values.
@ -47,6 +43,7 @@ class UploadStatusService {
); );
await task.onComplete; await task.onComplete;
_tasksData.remove(task); _tasksData.remove(task);
_sendUpdate();
} }
/// Updates the _status subject with the most current data. /// Updates the _status subject with the most current data.
@ -60,10 +57,10 @@ class UploadStatusService {
}, },
); );
if (bytestTransferred != 0) { if (bytestTransferred != 0) {
percentage = totalBytes / bytestTransferred; percentage = bytestTransferred / totalBytes;
} }
_status.sink.add(UploadStatus( _status.sink.add(UploadStatus(
percentage: percentage, percentage: (percentage * 100).toStringAsFixed(2),
numberOfFiles: _tasksData.length, numberOfFiles: _tasksData.length,
)); ));
} }
@ -77,7 +74,7 @@ class UploadStatusService {
/// The status of an upload. /// The status of an upload.
class UploadStatus { class UploadStatus {
/// Percentage of the upload. /// Percentage of the upload.
final double percentage; final String percentage;
/// Number of files being uploaded. /// Number of files being uploaded.
/// ///

View file

@ -71,9 +71,46 @@ String getImageThumbnailPath(String path) {
return tokens.join('/'); 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( void showUploadStatusSnackBar(
BuildContext context, BuildContext scaffoldContext,
Observable<UploadStatus> uploadStatus, Observable<UploadStatus> uploadStatus,
ValueObservable<bool> 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<UploadStatus> 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: <Widget>[
Spacer(),
Text('${snap.data.numberOfFiles} pending files'),
Spacer(flex: 5),
Text(snap.data.percentage + '%'),
Spacer(),
],
);
},
),
));
}