Added properties and functions to the event bloc for showing the upload status snackbar
This commit is contained in:
parent
f503cce0e3
commit
aa1d9b9edf
6 changed files with 52 additions and 14 deletions
|
|
@ -28,6 +28,9 @@ class EventBloc {
|
||||||
/// An instace of the auth service.
|
/// An instace of the auth service.
|
||||||
final AuthService _auth = authService;
|
final AuthService _auth = authService;
|
||||||
|
|
||||||
|
/// An instance of the upload status service.
|
||||||
|
final UploadStatusService _uploadStatus = uploadStatusService;
|
||||||
|
|
||||||
/// A subject of list of task model.
|
/// A subject of list of task model.
|
||||||
final _tasks = BehaviorSubject<List<TaskModel>>();
|
final _tasks = BehaviorSubject<List<TaskModel>>();
|
||||||
|
|
||||||
|
|
@ -46,6 +49,9 @@ class EventBloc {
|
||||||
/// A subject of a cache that contains the image files.
|
/// A subject of a cache that contains the image files.
|
||||||
final _images = BehaviorSubject<Map<String, Future<File>>>();
|
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.
|
/// The event being managed by this bloc.
|
||||||
EventModel _event;
|
EventModel _event;
|
||||||
|
|
||||||
|
|
@ -68,6 +74,13 @@ class EventBloc {
|
||||||
/// An observable of a cache of the images files.
|
/// An observable of a cache of the images files.
|
||||||
Observable<Map<String, Future<File>>> get images => _images.stream;
|
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.
|
// Sinks getters.
|
||||||
/// Starts the fetching process for an image given its path.
|
/// Starts the fetching process for an image given its path.
|
||||||
Function(String) get fetchImage => _imagesFetcher.sink.add;
|
Function(String) get fetchImage => _imagesFetcher.sink.add;
|
||||||
|
|
@ -75,6 +88,9 @@ class EventBloc {
|
||||||
/// Starts the fetching process for an image thumbail given its path.
|
/// Starts the fetching process for an image thumbail given its path.
|
||||||
Function(String) get fetchThumbnail => _imagesThumbnailsFetcher.sink.add;
|
Function(String) get fetchThumbnail => _imagesThumbnailsFetcher.sink.add;
|
||||||
|
|
||||||
|
/// Updates the snack bar status.
|
||||||
|
Function(bool) get updateSnackBarStatus => _snackBarStatus.sink.add;
|
||||||
|
|
||||||
EventBloc({
|
EventBloc({
|
||||||
@required this.eventName,
|
@required this.eventName,
|
||||||
}) {
|
}) {
|
||||||
|
|
@ -143,6 +159,8 @@ class EventBloc {
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispose() async {
|
void dispose() async {
|
||||||
|
await _snackBarStatus.drain();
|
||||||
|
_snackBarStatus.close();
|
||||||
await _imagesThumbnailsFetcher.drain();
|
await _imagesThumbnailsFetcher.drain();
|
||||||
_imagesThumbnailsFetcher.close();
|
_imagesThumbnailsFetcher.close();
|
||||||
await _imagesFetcher.drain();
|
await _imagesFetcher.drain();
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,6 @@ import '../services/auth_service.dart';
|
||||||
|
|
||||||
export '../services/auth_service.dart' show FirebaseUser;
|
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.
|
/// A business logic component that manages the state of the home screen.
|
||||||
class HomeBloc {
|
class HomeBloc {
|
||||||
/// An instance of the auth service.
|
/// An instance of the auth service.
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,16 @@ import 'package:firebase_storage/firebase_storage.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
|
import '../services/upload_status_service.dart';
|
||||||
|
|
||||||
export 'package:firebase_storage/firebase_storage.dart'
|
export 'package:firebase_storage/firebase_storage.dart'
|
||||||
show StorageUploadTask, StorageTaskSnapshot;
|
show StorageUploadTask, StorageTaskSnapshot;
|
||||||
|
|
||||||
/// A connection to the firebase sotrage bucket.
|
/// A connection to the firebase sotrage bucket.
|
||||||
class FirebaseStorageProvider {
|
class FirebaseStorageProvider {
|
||||||
|
/// An instance of the upload status service.
|
||||||
|
final UploadStatusService _uploadStatus = uploadStatusService;
|
||||||
|
|
||||||
/// The reference to the root path of the storage bucket.
|
/// The reference to the root path of the storage bucket.
|
||||||
final StorageReference _storage;
|
final StorageReference _storage;
|
||||||
|
|
||||||
|
|
@ -35,10 +40,12 @@ class FirebaseStorageProvider {
|
||||||
final String fileId = _uuid.v1();
|
final String fileId = _uuid.v1();
|
||||||
final StorageReference fileReference =
|
final StorageReference fileReference =
|
||||||
_storage.child('$folder$fileId.$type');
|
_storage.child('$folder$fileId.$type');
|
||||||
return fileReference.putFile(
|
final uploadTask = fileReference.putFile(
|
||||||
file,
|
file,
|
||||||
StorageMetadata(contentType: 'image/png'),
|
StorageMetadata(contentType: 'image/png'),
|
||||||
);
|
);
|
||||||
|
_uploadStatus.addNewUpload(uploadTask);
|
||||||
|
return uploadTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deletes a file from the firebase storage bucket given its path.
|
/// Deletes a file from the firebase storage bucket given its path.
|
||||||
|
|
|
||||||
|
|
@ -41,9 +41,6 @@ class _EventScreenState extends State<EventScreen>
|
||||||
/// Needed for showing snackbars.
|
/// Needed for showing snackbars.
|
||||||
BuildContext _scaffoldContext;
|
BuildContext _scaffoldContext;
|
||||||
|
|
||||||
/// Flag that indicates if there is a snackbar currently being shown.
|
|
||||||
bool _hasSnackBar = false;
|
|
||||||
|
|
||||||
initState() {
|
initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
bloc = EventBloc(eventName: widget.eventName);
|
bloc = EventBloc(eventName: widget.eventName);
|
||||||
|
|
|
||||||
|
|
@ -5,24 +5,32 @@ import 'package:rxdart/rxdart.dart';
|
||||||
|
|
||||||
/// A service that maintains a record of the upload operations made to
|
/// A service that maintains a record of the upload operations made to
|
||||||
/// the firebase storage bucket.
|
/// the firebase storage bucket.
|
||||||
class _UploadStatusService {
|
class UploadStatusService {
|
||||||
/// A subject of the current status of uploads.
|
/// A subject of the current status of uploads.
|
||||||
final _status = BehaviorSubject<UploadStatus>();
|
final _status = BehaviorSubject<UploadStatus>();
|
||||||
|
|
||||||
/// A map that contains the information about all the current upload tasks.
|
/// 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>>{};
|
<StorageUploadTask, List<int>>{};
|
||||||
|
|
||||||
/// An observable of the status for all current upload tasks.
|
/// An observable of the status for all current upload tasks.
|
||||||
Observable<UploadStatus> get status => _status.stream;
|
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.
|
/// Adds a new upload task to be tracked.
|
||||||
///
|
///
|
||||||
/// 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;
|
final initialSnap = task.lastSnapshot;
|
||||||
// Initialize the map entry with the initial values.
|
// Initialize the map entry with the initial values.
|
||||||
tasksData[task] = [
|
_tasksData[task] = [
|
||||||
initialSnap.bytesTransferred,
|
initialSnap.bytesTransferred,
|
||||||
initialSnap.totalByteCount,
|
initialSnap.totalByteCount,
|
||||||
];
|
];
|
||||||
|
|
@ -30,7 +38,7 @@ class _UploadStatusService {
|
||||||
(StorageTaskEvent event) {
|
(StorageTaskEvent event) {
|
||||||
// Update the map with the current values.
|
// Update the map with the current values.
|
||||||
final snap = event.snapshot;
|
final snap = event.snapshot;
|
||||||
tasksData[task] = [
|
_tasksData[task] = [
|
||||||
snap.bytesTransferred,
|
snap.bytesTransferred,
|
||||||
snap.totalByteCount,
|
snap.totalByteCount,
|
||||||
];
|
];
|
||||||
|
|
@ -38,14 +46,14 @@ class _UploadStatusService {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
await task.onComplete;
|
await task.onComplete;
|
||||||
tasksData.remove(task);
|
_tasksData.remove(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates the _status subject with the most current data.
|
/// Updates the _status subject with the most current data.
|
||||||
void _sendUpdate() {
|
void _sendUpdate() {
|
||||||
int totalBytes = 0, bytestTransferred = 0;
|
int totalBytes = 0, bytestTransferred = 0;
|
||||||
double percentage = 0.0;
|
double percentage = 0.0;
|
||||||
tasksData.forEach(
|
_tasksData.forEach(
|
||||||
(_, data) {
|
(_, data) {
|
||||||
bytestTransferred += data[0];
|
bytestTransferred += data[0];
|
||||||
totalBytes += data[1];
|
totalBytes += data[1];
|
||||||
|
|
@ -56,7 +64,7 @@ class _UploadStatusService {
|
||||||
}
|
}
|
||||||
_status.sink.add(UploadStatus(
|
_status.sink.add(UploadStatus(
|
||||||
percentage: percentage,
|
percentage: percentage,
|
||||||
numberOfFiles: tasksData.length,
|
numberOfFiles: _tasksData.length,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,4 +91,4 @@ class UploadStatus {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
final uploadStatusService = _UploadStatusService();
|
final uploadStatusService = UploadStatusService();
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:rxdart/rxdart.dart';
|
||||||
|
|
||||||
import './models/task_model.dart';
|
import './models/task_model.dart';
|
||||||
|
import './services/upload_status_service.dart';
|
||||||
|
|
||||||
const kLowPriorityColor = Color(0xFF06AD12);
|
const kLowPriorityColor = Color(0xFF06AD12);
|
||||||
const kMediumPriorityColor = Color(0xFFF6A93B);
|
const kMediumPriorityColor = Color(0xFFF6A93B);
|
||||||
|
|
@ -67,3 +70,10 @@ String getImageThumbnailPath(String path) {
|
||||||
tokens.last = 'thumb@' + tokens.last;
|
tokens.last = 'thumb@' + tokens.last;
|
||||||
return tokens.join('/');
|
return tokens.join('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
void showUploadStatusSnackBar(
|
||||||
|
BuildContext context,
|
||||||
|
Observable<UploadStatus> uploadStatus,
|
||||||
|
ValueObservable<bool> snackBarStatus,
|
||||||
|
) {}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue