Added properties and functions to the event bloc for showing the upload status snackbar

This commit is contained in:
Mariano Uvalle 2019-04-11 01:05:36 -05:00
parent f503cce0e3
commit aa1d9b9edf
6 changed files with 52 additions and 14 deletions

View file

@ -28,6 +28,9 @@ class EventBloc {
/// An instace of the auth service.
final AuthService _auth = authService;
/// An instance of the upload status service.
final UploadStatusService _uploadStatus = uploadStatusService;
/// A subject of list of task model.
final _tasks = BehaviorSubject<List<TaskModel>>();
@ -46,6 +49,9 @@ class EventBloc {
/// A subject of a cache that contains the image files.
final _images = BehaviorSubject<Map<String, Future<File>>>();
/// A subject of a flag that indicates if there is a snack bar showing.
final _snackBarStatus = BehaviorSubject<bool>(seedValue: false);
/// The event being managed by this bloc.
EventModel _event;
@ -68,6 +74,13 @@ class EventBloc {
/// An observable of a cache of the images files.
Observable<Map<String, Future<File>>> get images => _images.stream;
/// An observable of a flag that indicates whether or not a snackBar is
/// currently showing.
ValueObservable<bool> get snackBarStatus => _snackBarStatus.stream;
/// An observable of the status of files being uploaded.
Observable<UploadStatus> get uploadStatus => _uploadStatus.status;
// Sinks getters.
/// Starts the fetching process for an image given its path.
Function(String) get fetchImage => _imagesFetcher.sink.add;
@ -75,6 +88,9 @@ class EventBloc {
/// Starts the fetching process for an image thumbail given its path.
Function(String) get fetchThumbnail => _imagesThumbnailsFetcher.sink.add;
/// Updates the snack bar status.
Function(bool) get updateSnackBarStatus => _snackBarStatus.sink.add;
EventBloc({
@required this.eventName,
}) {
@ -143,6 +159,8 @@ class EventBloc {
}
void dispose() async {
await _snackBarStatus.drain();
_snackBarStatus.close();
await _imagesThumbnailsFetcher.drain();
_imagesThumbnailsFetcher.close();
await _imagesFetcher.drain();

View file

@ -9,8 +9,6 @@ import '../services/auth_service.dart';
export '../services/auth_service.dart' show FirebaseUser;
// TODO: Add the text search functionality.
/// A business logic component that manages the state of the home screen.
class HomeBloc {
/// An instance of the auth service.

View file

@ -6,11 +6,16 @@ import 'package:firebase_storage/firebase_storage.dart';
import 'package:path_provider/path_provider.dart';
import 'package:uuid/uuid.dart';
import '../services/upload_status_service.dart';
export 'package:firebase_storage/firebase_storage.dart'
show StorageUploadTask, StorageTaskSnapshot;
/// A connection to the firebase sotrage bucket.
class FirebaseStorageProvider {
/// An instance of the upload status service.
final UploadStatusService _uploadStatus = uploadStatusService;
/// The reference to the root path of the storage bucket.
final StorageReference _storage;
@ -35,10 +40,12 @@ class FirebaseStorageProvider {
final String fileId = _uuid.v1();
final StorageReference fileReference =
_storage.child('$folder$fileId.$type');
return fileReference.putFile(
final uploadTask = fileReference.putFile(
file,
StorageMetadata(contentType: 'image/png'),
);
_uploadStatus.addNewUpload(uploadTask);
return uploadTask;
}
/// Deletes a file from the firebase storage bucket given its path.

View file

@ -41,9 +41,6 @@ class _EventScreenState extends State<EventScreen>
/// Needed for showing snackbars.
BuildContext _scaffoldContext;
/// Flag that indicates if there is a snackbar currently being shown.
bool _hasSnackBar = false;
initState() {
super.initState();
bloc = EventBloc(eventName: widget.eventName);

View file

@ -5,24 +5,32 @@ import 'package:rxdart/rxdart.dart';
/// A service that maintains a record of the upload operations made to
/// the firebase storage bucket.
class _UploadStatusService {
class UploadStatusService {
/// A subject of the current status of uploads.
final _status = BehaviorSubject<UploadStatus>();
/// A map that contains the information about all the current upload tasks.
Map<StorageUploadTask, List<int>> tasksData =
Map<StorageUploadTask, List<int>> _tasksData =
<StorageUploadTask, List<int>>{};
/// An observable of the status for all current upload tasks.
Observable<UploadStatus> get status => _status.stream;
/// Creates a new service that maintains a record of the upload operations
/// made to the firebase storage bucket.
///
/// Avoid multiple instantiaion of this service. Either use the
/// [uploadStatusService] singleton or instantiate once, the state will be
/// lost otherwise.
UploadStatusService();
/// Adds a new upload task to be tracked.
///
/// 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] = [
_tasksData[task] = [
initialSnap.bytesTransferred,
initialSnap.totalByteCount,
];
@ -30,7 +38,7 @@ class _UploadStatusService {
(StorageTaskEvent event) {
// Update the map with the current values.
final snap = event.snapshot;
tasksData[task] = [
_tasksData[task] = [
snap.bytesTransferred,
snap.totalByteCount,
];
@ -38,14 +46,14 @@ class _UploadStatusService {
},
);
await task.onComplete;
tasksData.remove(task);
_tasksData.remove(task);
}
/// Updates the _status subject with the most current data.
void _sendUpdate() {
int totalBytes = 0, bytestTransferred = 0;
double percentage = 0.0;
tasksData.forEach(
_tasksData.forEach(
(_, data) {
bytestTransferred += data[0];
totalBytes += data[1];
@ -56,7 +64,7 @@ class _UploadStatusService {
}
_status.sink.add(UploadStatus(
percentage: percentage,
numberOfFiles: tasksData.length,
numberOfFiles: _tasksData.length,
));
}
@ -83,4 +91,4 @@ class UploadStatus {
});
}
final uploadStatusService = _UploadStatusService();
final uploadStatusService = UploadStatusService();

View file

@ -1,7 +1,10 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';
import './models/task_model.dart';
import './services/upload_status_service.dart';
const kLowPriorityColor = Color(0xFF06AD12);
const kMediumPriorityColor = Color(0xFFF6A93B);
@ -67,3 +70,10 @@ String getImageThumbnailPath(String path) {
tokens.last = 'thumb@' + tokens.last;
return tokens.join('/');
}
///
void showUploadStatusSnackBar(
BuildContext context,
Observable<UploadStatus> uploadStatus,
ValueObservable<bool> snackBarStatus,
) {}