From 7521821462013c7867d3a279819e9c89c456c7af Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Fri, 1 Sep 2023 15:25:22 +0200 Subject: [PATCH 01/18] docs(ui_storage): add Firebase UI Storage docs --- packages/firebase_ui_storage/README.md | 171 +----------------- .../doc/getting-started.md | 124 +++++++++++++ packages/firebase_ui_storage/doc/grid-view.md | 87 +++++++++ packages/firebase_ui_storage/doc/list-view.md | 68 +++++++ .../doc/paginated-loading-controller.md | 42 +++++ .../firebase_ui_storage/doc/storage-image.md | 169 +++++++++++++++++ .../doc/task-progress-indicator.md | 48 +++++ .../firebase_ui_storage/doc/upload-button.md | 70 +++++++ .../lib/firebase_ui_storage.dart | 20 +- .../lib/src/widgets/grid_view.dart | 36 ++++ .../lib/src/widgets/progress_indicator.dart | 2 +- 11 files changed, 666 insertions(+), 171 deletions(-) create mode 100644 packages/firebase_ui_storage/doc/getting-started.md create mode 100644 packages/firebase_ui_storage/doc/grid-view.md create mode 100644 packages/firebase_ui_storage/doc/list-view.md create mode 100644 packages/firebase_ui_storage/doc/paginated-loading-controller.md create mode 100644 packages/firebase_ui_storage/doc/storage-image.md create mode 100644 packages/firebase_ui_storage/doc/task-progress-indicator.md create mode 100644 packages/firebase_ui_storage/doc/upload-button.md diff --git a/packages/firebase_ui_storage/README.md b/packages/firebase_ui_storage/README.md index 0db2bf21..544c340a 100644 --- a/packages/firebase_ui_storage/README.md +++ b/packages/firebase_ui_storage/README.md @@ -4,171 +4,18 @@ Firebase UI Storage is a set of Flutter widgets and utilities designed to help you build and integrate your user interface with Firebase Storage. -## Installation +## Documentation -Install dependencies +- [Getting started](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/getting-started.md) -```sh -flutter pub add firebase_core firebase_storage firebase_ui_storage -``` +## Issues -Download Firebase project config +Please file Firebase UI Storage specific issues, bugs, or feature requests in our [issue tracker]. -```sh -flutterfire configure -``` +## Contributing -## Configuration +If you wish to contribute a change to any of the existing plugins in this repo, please review our [contribution guide] and open a [pull request]. -This section will walk you through the configuration process of the Firebase UI Storage - -### macOS - -If you're building for macOS, you will need to add an entitlement for either read-only access if you only upload files: - -```xml - com.apple.security.files.user-selected.read-only - -``` - -or read/write access if you want to be able to download files as well: - -```xml - com.apple.security.files.user-selected.read-write - -``` - -Make sure to add network client entitlement as well: - -```xml -com.apple.security.network.client - -``` - -### FirebaseUIStorage.configure() - -To reduce boilerplate for widgets, `FirebaseUIStroage` has a top-level configuration: - -```dart -import 'package:firebase_core/firebase_core.dart'; -import 'package:firebase_storage/firebase_storage.dart'; -import 'package:firebase_ui_storage/firebase_ui_storage.dart'; -import 'package:flutter/material.dart'; - -import 'firebase_options.dart'; - -Future main() async { - WidgetsFlutterBinding.ensureInitialized(); - - await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); - - final storage = FirebaseStorage.instance; - final config = FirebaseUIStorageConfiguration(storage: storage); - - await FirebaseUIStorage.configure(config); - - runApp(const MyApp()); -} -``` - -See [API docs](https://pub.dev/documentation/firebase_ui_storage/latest/firebase_ui_storage/FirebaseUIStorageConfiguration-class.html) for more configuration options. - -### Overriding configuration - -It is possible to override a top-level configuration for a widget subtree: - -```dart -class MyWidget extends StatelessWidget { - @override - Widget build(BuildContext context) { - return FirebaseUIStorageConfigOverride( - config: FirebaseUIStorageConfiguration( - uploadRoot: storage.ref('${FirebaseAuth.instance.currentUser.uid}/'), - namingPolicy: const UuidFileUploadNamingPolicy(), - child: const MyUserPage(), - ), - ); - } -} -``` - -## Widgets - -### UploadButton - -```dart -class MyUploadPage extends StatelessWidget { - const MyUploadPage({super.key}); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: UploadButton( - mimeTypes: const ['image/png', 'image/jpeg'], - onError: (err, stackTrace) { - print(err.toString()); - }, - onUploadComplete: (ref) { - print('File uploaded to ${ref.fullPath}'); - }, - ), - ), - ); - } -} - -``` - -### TaskProgressIndicator - -```dart -class MyUploadProgress extends StatelessWidget { - final UploadTask task; - - const MyUploadProgress({super.key, required this.task}); - - @override - Widget build(BuildContext context) { - return Card( - child: Column(children: [ - Text('Uploading ${task.snapshot.ref.name}...'), - TaskProgressIndicator(task: task), - ]), - ); - } -} -``` - -### StorageListView - -```dart -StorageListView( - ref: storage.ref('images'), - itemBuilder: (context, ref) { - return AspectRatio( - aspectRatio: 1, - child: StorageImage(ref: ref), - ); - }, - loadingBuilder: (context) { - return const Center( - child: CircularProgressIndicator(), - ); - }, - errorBuilder: (context, error, controller) { - return Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text('Error: $error'), - TextButton( - onPressed: () => controller.load(), - child: const Text('Retry'), - ), - ], - ), - ); - }, -); -``` +[issue tracker]: https://github.com/firebase/FirebaseUI-Flutter/issues/new/choose +[contribution guide]: https://github.com/firebase/FirebaseUI-Flutter/blob/main/docs/contributing.md +[pull request]: https://github.com/firebase/FirebaseUI-Flutter/pulls diff --git a/packages/firebase_ui_storage/doc/getting-started.md b/packages/firebase_ui_storage/doc/getting-started.md new file mode 100644 index 00000000..630e644a --- /dev/null +++ b/packages/firebase_ui_storage/doc/getting-started.md @@ -0,0 +1,124 @@ +# Getting started with Firebase UI Storage + +Firebase UI Storage is a set of Flutter widgets and utilities designed to help you build and integrate your user interface with Firebase Storage. + +## Installation + +Install dependencies + +```sh +flutter pub add firebase_core firebase_storage firebase_ui_storage +``` + +Download Firebase project config + +```sh +flutterfire configure +``` + +## Configuration + +This section will walk you through the configuration process of the Firebase UI Storage + +### macOS + +If you're building for macOS, you will need to add an entitlement for either read-only access if you only upload files: + +```xml + com.apple.security.files.user-selected.read-only + +``` + +or read/write access if you want to be able to download files as well: + +```xml + com.apple.security.files.user-selected.read-write + +``` + +Make sure to add network client entitlement as well: + +```xml +com.apple.security.network.client + +``` + +### Initialize Firebase + +```dart +import 'package:firebase_core/firebase_core.dart'; +import 'firebase_options.dart'; + +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + + await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); +} +``` + +### Configure Firebase UI Storage + +`FirebaseUIStorage` has a top-level configuration, that reduces amount of widget properties needed +to be passed to the widget constructors. + +```dart +import 'package:firebase_storage/firebase_storage.dart'; + +Future main() async { + // configuration steps from above + + final storage = FirebaseStorage.instance; + + final config = FirebaseUIStorageConfiguration( + storage: storage, + uploadRoot: storage.ref('flutter-tests'), + namingPolicy: UuidFileUploadNamingPolicy(), // optional, will generate a UUID for each uploaded file + ); + + await FirebaseUIStorage.configure(config); +} +``` + +Available file naming policies: + +- [`KeepOriginalNameUploadPolicy`] – keeps the original file name +- [`KeepPathUploadPolicy`] - keeps the original file path +- [`UuidFileUploadNamingPolicy`] – generates a UUID for each uploaded file + +[`KeepOriginalNameUploadPolicy`]: https://pub.dev/documentation/firebase_ui_storage/latest/firebase_ui_storage/KeepOriginalNameUploadPolicy-class.html +[`KeepPathUploadPolicy`]: https://pub.dev/documentation/firebase_ui_storage/latest/firebase_ui_storage/KeepPathUploadPolicy-class.html +[`UuidFileUploadNamingPolicy`]: https://pub.dev/documentation/firebase_ui_storage/latest/firebase_ui_storage/UuidFileUploadNamingPolicy-class.html + +If you ever need to override this top-level configuration, you can do so by using `FirebaseUIStorageConfigOverride`: + +```dart +import 'package:firebase_storage/firebase_storage.dart'; +import 'package:firebase_ui_storage/firebase_ui_storage.dart'; + +class MyWidget extends StatelessWidget { + const MyWidget({super.key}); + + @override + Widget build(BuildContext context) { + return FirebaseUIStorageConfigOverride( + config: FirebaseUIStorageConfiguration( + uploadRoot: FirebaseStorage.instance.ref('other-location'), + ), + child: const OtherWidget(), + ); + } +} +``` + +### Firebase UI Storage widgets + +- [`UploadButton`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/upload-button.md) +- [`TaskProgressIndicator`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/task-progress-indicator.md) +- [`StorageImage`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/storage-image.md) +- [`ListView`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/list-view.md) +- [`GridView`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/grid-view.md) +- [`PaginatedLoadingController`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/paginated-loading-controller.md) + +--- + +> See [API reference](https://pub.dev/documentation/firebase_ui_storage/latest/firebase_ui_storage/firebase_ui_storage-library.html) for more details. diff --git a/packages/firebase_ui_storage/doc/grid-view.md b/packages/firebase_ui_storage/doc/grid-view.md new file mode 100644 index 00000000..1e56505c --- /dev/null +++ b/packages/firebase_ui_storage/doc/grid-view.md @@ -0,0 +1,87 @@ +# StorageGridView + +When loading large amounts of objects from the Firebase Storage, it makes sense to load them in batches, but requires handling of the pagination logic. + +`StorageGridView` implements pagination logic for you, and allows to load objects from the Firebase Storage in batches while scrolling. + +## Usage + +```dart +StorageGridView( + ref: FirebaseStorage.instance.ref('images'), + itemBuilder: (context, ref) { + return AspectRatio( + aspectRatio: 1, + child: StorageImage(ref: ref), + ); + }, +); +``` + +By default, `StorageGridView` uses `const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3)` grid delegate, but you can pass your own `gridDelegate`: + +```dart +StorageGridView( + ref: FirebaseStorage.instance.ref('images'), + gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent( + maxCrossAxisExtent: 200, + mainAxisSpacing: 10, + crossAxisSpacing: 10, + ), + itemBuilder: (context, ref) { + return AspectRatio( + aspectRatio: 1, + child: StorageImage(ref: ref), + ); + }, +); +``` + +### Custom inital page loading state + +When the first page of objects is loading, `StorageGridView` will show a `CircularProgressIndicator` under `MaterialApp` and `CupertinoActivityIndicator` under `CupertinoApp`. + +You can pass `loadingBuilder` to customize the loading state: + +```dart +StorageGridView( + ref: FirebaseStorage.instance.ref('images'), + loadingBuilder: (context) { + return Center( + child: Text('Loading...'), + ); + }, + itemBuilder: (context, ref) { + return AspectRatio( + aspectRatio: 1, + child: StorageImage(ref: ref), + ); + }, +); +``` + +### Controlling page size + +By default, `StorageGridView` will load 50 objects per page. You can customize the page size by passing `pageSize`: + +```dart +StorageGridView( + ref: FirebaseStorage.instance.ref('images'), + pageSize: 100, + itemBuilder: (context, ref) { + return AspectRatio( + aspectRatio: 1, + child: StorageImage(ref: ref), + ); + }, +); +``` + +### Custom scroll views with pagination logic + +If you need something more customizable, but stil have pagination logic handled for you, you can use +[`PaginatedLoadingController`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/paginated-loading-controller.md) + +--- + +See [API reference](https://pub.dev/documentation/firebase_ui_storage/latest/firebase_ui_storage/GridView-class.html) for more details. diff --git a/packages/firebase_ui_storage/doc/list-view.md b/packages/firebase_ui_storage/doc/list-view.md new file mode 100644 index 00000000..6fac110b --- /dev/null +++ b/packages/firebase_ui_storage/doc/list-view.md @@ -0,0 +1,68 @@ +# StorageListView + +When loading large amounts of objects from the Firebase Storage, it makes sense to load them in batches, but requires handling of the pagination logic. + +`StorageListView` implements pagination logic for you, and allows to load objects from the Firebase Storage in batches while scrolling. + +## Usage + +```dart +StorageListView( + ref: FirebaseStorage.instance.ref('images'), + itemBuilder: (context, ref) { + return AspectRatio( + aspectRatio: 1, + child: StorageImage(ref: ref), + ); + }, +); +``` + +### Custom inital page loading state + +When the first page of objects is loading, `StorageListView` will show a `CircularProgressIndicator` under `MaterialApp` and `CupertinoActivityIndicator` under `CupertinoApp`. + +You can pass `loadingBuilder` to customize the loading state: + +```dart +StorageListView( + ref: FirebaseStorage.instance.ref('images'), + loadingBuilder: (context) { + return Center( + child: Text('Loading...'), + ); + }, + itemBuilder: (context, ref) { + return AspectRatio( + aspectRatio: 1, + child: StorageImage(ref: ref), + ); + }, +); +``` + +### Controlling page size + +By default, `StorageListView` will load 50 objects per page. You can customize the page size by passing `pageSize`: + +```dart +StorageListView( + ref: FirebaseStorage.instance.ref('images'), + pageSize: 100, + itemBuilder: (context, ref) { + return AspectRatio( + aspectRatio: 1, + child: StorageImage(ref: ref), + ); + }, +); +``` + +### Custom scroll views with pagination logic + +If you need something more customizable, but stil have pagination logic handled for you, you can use +[`PaginatedLoadingController`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/paginated-loading-controller.md) + +--- + +See [API reference](https://pub.dev/documentation/firebase_ui_storage/latest/firebase_ui_storage/ListView-class.html) for more details. diff --git a/packages/firebase_ui_storage/doc/paginated-loading-controller.md b/packages/firebase_ui_storage/doc/paginated-loading-controller.md new file mode 100644 index 00000000..05455f12 --- /dev/null +++ b/packages/firebase_ui_storage/doc/paginated-loading-controller.md @@ -0,0 +1,42 @@ +# PaginatedLoadingController + +When loading large amounts of objects from the Firebase Storage, it makes sense to load them in batches, but requires handling of the pagination logic. + +Firebase UI Storage provides [`StorageListView`] and [`StorageGridView`] widgets that implement pagination logic for you, and allow to load objects from the Firebase Storage in batches while scrolling. + +In cases where you want to build a completely custom scroll view, but still have pagination logic handled – you can use [`PaginatedLoadingController`]. + +```dart +class MyWidget extends StatefulWidget { + const MyWidget({super.key}); + + @override + State createState() => _MyWidgetState(); +} + +class _MyWidgetState extends State { + final ctrl = PaginatedLoadingController( + ref: FirebaseStorage.instance.ref('images'), + pageSize: 100, + ); + + @override + Widget build(BuildContext context) { + return AnimatedBuilder( + animation: ctrl, + builder: (context, _) { + return switch (ctrl.state) { + InitialPageLoading() => const Text('Loading...'), + PageLoadError(error: final error) => Text('Error: $error'), + PageLoading() => const Text('Loading...'), + PageLoadComplete(items: final items) => MyCustomScrollView(items: items), + }; + }, + ); + } +} +``` + +--- + +See [API reference](https://pub.dev/documentation/firebase_ui_storage/latest/firebase_ui_storage/PaginatedLoadingController-class.html) for more details. diff --git a/packages/firebase_ui_storage/doc/storage-image.md b/packages/firebase_ui_storage/doc/storage-image.md new file mode 100644 index 00000000..8a49dab6 --- /dev/null +++ b/packages/firebase_ui_storage/doc/storage-image.md @@ -0,0 +1,169 @@ +# StorageImage + +A widget that loads and displays an image from the Firebase Storage. + +## Usage + +```dart +StorageImage( + ref: FirebaseStorage.instance.ref('images/dash_and_sparky.png'), + fit: BoxFit.cover, +); +``` + +## Customizing loading state + +`StorageImage` supports multiple variants of loading states: + +- [`LoadingStateVariant.solidColor`](#solid-color-placeholder) (default) +- [`LoadingStateVariant.loadingIndicator`](#loading-indicator) +- [`LoadingStateVariant.shimmer`](#shimmer-placeholder) +- [`LoadingStateVariant.blurHash`](#blur-hash-placeholder) + +### Solid color placeholder + +By default, `solidColor` placeholder uses `surfaceTint.withOpacity(0.12)` color from the app color scheme. + +The color could be customized: + +```dart +StorageImage( + ref: FirebaseStorage.instance.ref('images/dash_and_sparky.png'), + fit: BoxFit.cover, + loadingState: LoadingStateVariant.solidColor( + color: Colors.white.withOpacity(0.5) + ), +); +``` + +### Loading indicator + +Loading indicator placeholder will show a `CircularProgressIndicator` under `MaterialApp` and `CupertinoActivityIndicator` under `CupertinoApp`. + +You can customize `size`, `color` and `strokeWidth` of the loading indicator: + +```dart +StorageImage( + ref: FirebaseStorage.instance.ref('images/dash_and_sparky.png'), + fit: BoxFit.cover, + loadingState: LoadingStateVariant.loadingIndicator( + size: 48.0, + color: Colors.pink, + strokeWidth: 1.0, + ), +); +``` + +> `color` and `strokeWidth` are only applicable to `CircularProgressIndicator`. + +### Shimmer placeholder + +Shimmer placeholder is a combination of the `solidColor` placeholder with a +[shimmer](<(https://docs.flutter.dev/cookbook/effects/shimmer-loading)>) animation. + +```dart +StorageImage( + ref: FirebaseStorage.instance.ref('images/dash_and_sparky.png'), + fit: BoxFit.cover, + loadingState: LoadingStateVariant.shimmer(), +); +``` + +### Blur hash placeholder + +[BlurHash](https://blurha.sh/) is a compact blurred version of the image that could be used as a placeholder while the full image is loading. + +```dart +StorageImage( + ref: FirebaseStorage.instance.ref('images/dash_and_sparky.png'), + fit: BoxFit.cover, + loadingState: LoadingStateVariant.blurHash(), +); +``` + +`blurHash` string should be set on the object's `customMetadata`. + +Here's an example Cloud Function for Firebase, that could be used to generated and write BlurHash string to the object's metadata: + +```ts +import * as functions from "firebase-functions/v2"; +import { getStorage } from "firebase-admin/storage"; +import { encode } from "blurhash"; +import * as sharp from "sharp"; +import { initializeApp } from "firebase-admin/app"; + +initializeApp(); + +type ResizeResult = { + buffer: Buffer; + width: number; + height: number; +}; + +exports.genBlurHash = functions.storage.onObjectFinalized(async (event) => { + const { bucket: fileBucket, name, contentType } = event.data; + + if (!contentType?.startsWith("image/")) { + return; + } + + const bucket = getStorage().bucket(fileBucket); + const file = bucket.file(name); + const res = await file.download(); + const [buffer] = res; + + const { + buffer: sharpBuffer, + width, + height, + } = await new Promise((resolve, reject) => { + sharp(buffer) + .raw() + .ensureAlpha() + .resize(64, 64, { + fit: "inside", + }) + .toBuffer((err, buffer, { width, height }) => { + if (err) { + reject(err); + return; + } + resolve({ buffer, width, height }); + }); + }); + + const blurHashString = encode( + new Uint8ClampedArray(sharpBuffer), + width, + height, + 8, + 8 + ); + + await file.setMetadata({ + metadata: { + blurHash: blurHashString, + }, + }); +}); +``` + +> Learn more about Cloud Functions for Firebase [here](https://firebase.google.com/docs/functions). + +Alternatively, you could set a genereic, pre-generated blur-hash string directly on the object's metadata: + +```dart +StorageImage( + ref: FirebaseStorage.instance.ref('images/dash_and_sparky.png'), + fit: BoxFit.cover, + loadingState: LoadingStateVariant.blurHash( + blurHash: ':eDJq[9wo~xUbKNexqWG-@M|xuRlt7ayWVoMIwskxVIvs+slNHt' + '2j]j?RiocR%fRo0oJtRW=V@t2R*bHoMfSbca#oJaybHj@flbIsoWCbHaya}bHoeazbIayofWC' + 'n~j[R*oJ'; + ), +); +``` + +--- + +See [API reference](https://pub.dev/documentation/firebase_ui_storage/latest/firebase_ui_storage/StorageImage-class.html) for more details. diff --git a/packages/firebase_ui_storage/doc/task-progress-indicator.md b/packages/firebase_ui_storage/doc/task-progress-indicator.md new file mode 100644 index 00000000..3541d6c3 --- /dev/null +++ b/packages/firebase_ui_storage/doc/task-progress-indicator.md @@ -0,0 +1,48 @@ +# TaskProgressIndicator + +`TaskProgressIndicator` shows `LinearProgressIndicator` under `MaterialApp` and a custom iOS-styled alternative under `CupertinoApp` while the file is being uploaded/downloaded, reflecting the amount of bytes trasnferred. + +## Usage + +```dart +FirebaseStorage storage = FirebaseStorage.instance; +Reference ref = storage.ref('my_file'); + +UploadTask task = ref.putFile(myFile); + +TaskProgressIndicator(task: task); +``` + +> You can see how to use `TaskProgressIndicator` together with `UploadButton` [here](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/upload-button.md#showing-upload-progress). + +`TaskProgressIndicator` also works for download tasks: + +```dart +FirebaseStorage storage = FirebaseStorage.instance; +Reference ref = storage.ref('my_file'); + +DownloadTask task = ref.writeToFile(myFile); + +TaskProgressIndicator(task: task); +``` + +## Building custom progress indicators + +Firebase UI storage provides and abstract class, that simplifies building custom progress indicators. You can extend `TaskProgressWidget` and override `buildProgressIndicator` to build your own progress indicator: + +```dart +class MyProgressIndicator extends TaskProgressWidget { + final Task task; + + const MyProgressIndicator({super.key, required this.task}); + + @override + Widget buildProgressIndicator(BuildContext context, double progress) { + return Text('Progress: ${progress.toStringAsFixed(2)}'); + } +} +``` + +--- + +See [API reference](https://pub.dev/documentation/firebase_ui_storage/latest/firebase_ui_storage/TaskProgressIndicator-class.html) for more details. diff --git a/packages/firebase_ui_storage/doc/upload-button.md b/packages/firebase_ui_storage/doc/upload-button.md new file mode 100644 index 00000000..cab21a35 --- /dev/null +++ b/packages/firebase_ui_storage/doc/upload-button.md @@ -0,0 +1,70 @@ +# UploadButton + +UploadButton is a widget that will trigger a file picker and upload the selected file to Firebase Storage. + +Example usage: + +```dart +class MyUploadButton extends StatelessWidget { + const MyUploadButton({super.key}); + + @override + Widget build(BuildContext context) { + return UploadButton( + onError: (e, s) => ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(e.toString()), + ), + ), + onUploadComplete: (ref) => ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Upload complete: ${ref.fullPath}'), + ), + ), + variant: ButtonVariant.filled, + ); + } +} +``` + +Upload buttons uses `uploadRoot` and `namingPolicy` from [`FirebaseUIStorageConfiguration`](https://pub.dev/documentation/firebase_ui_storage/latest/firebase_ui_storage/FirebaseUIStorageConfiguration-class.html) to determine the location and file name of the uploaded file. + +## Showing upload progress + +`UploadButton` shows `CircularProgressIndicator` under `MaterialApp` and `CupertinoActivityIndicator` under `CupertinoApp` while the upload is in progress. For large uploads, you might want to show upload progress, so you could replace the button with a [`TaskProgressIndicator`](<(https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/task-progress-indicator.md)>) in a stateful widget, using `onUploadStarted`: + +```dart +class MyUploadWidget extends StatelessWidget { + const MyUploadWidget({super.key}); + + @override + Widget build(BuildContext context) { + UploadTask? task; + + return StatefulBuilder(builder: (context, setState) { + if (task != null) return TaskProgressIndicator(task: task!); + + return UploadButton( + onUploadStarted: (t) => setState(() => task = t), + onUploadComplete: (ref) {/* handle succesful upload */}, + onError: (e, stackTrace) {/* handle error */}, + ); + }); + } +} +``` + +## Filtering file types + +By default, `UploadButton` will show all files in the file picker. You can filter the file types by setting `extensions` or `mimeTypes`: + +```dart +UploadButton( + extensions: ['jpg', 'png'], + mimeTypes: ['image/jpeg', 'image/png'], +); +``` + +--- + +See [API reference](https://pub.dev/documentation/firebase_ui_storage/latest/firebase_ui_storage/UploadButton-class.html) for more details. diff --git a/packages/firebase_ui_storage/lib/firebase_ui_storage.dart b/packages/firebase_ui_storage/lib/firebase_ui_storage.dart index d604d5f1..c86ed949 100644 --- a/packages/firebase_ui_storage/lib/firebase_ui_storage.dart +++ b/packages/firebase_ui_storage/lib/firebase_ui_storage.dart @@ -12,14 +12,18 @@ export 'src/config.dart' KeepOriginalNameUploadPolicy, KeepPathUploadPolicy, UuidFileUploadNamingPolicy; - export 'src/lib.dart' show FirebaseUIStorage; - -export 'src/widgets/upload_button.dart' show UploadButton; +export 'src/paginated_loading_controller.dart' + show + PaginatedLoadingController, + PaginatedLoadingState, + InitialPageLoading, + PageLoadComplete, + PageLoadError, + PageLoading; +export 'src/widgets/grid_view.dart' show StorageGridView; +export 'src/widgets/image.dart' show StorageImage, LoadingStateVariant; +export 'src/widgets/list_view.dart' show StorageListView; export 'src/widgets/progress_indicator.dart' show TaskProgressIndicator, TaskProgressWidget, ErrorBuilder; - -export 'src/widgets/image.dart' show StorageImage, LoadingStateVariant; -export 'src/paginated_loading_controller.dart'; -export 'src/widgets/list_view.dart'; -export 'src/widgets/grid_view.dart'; +export 'src/widgets/upload_button.dart' show UploadButton; diff --git a/packages/firebase_ui_storage/lib/src/widgets/grid_view.dart b/packages/firebase_ui_storage/lib/src/widgets/grid_view.dart index ba8f6780..bc3496f4 100644 --- a/packages/firebase_ui_storage/lib/src/widgets/grid_view.dart +++ b/packages/firebase_ui_storage/lib/src/widgets/grid_view.dart @@ -12,6 +12,42 @@ Widget _defaultLoadingBuilder(BuildContext context) { return const DefaultLoadingIndicator(); } +/// /// A [GridView.builder] that automatically handles paginated loading from +/// [FirebaseStorage]. +/// +/// Example usage: +/// +/// ```dart +/// class MyGridView extends StatelessWidget { +/// const MyGridView({super.key}); +/// +/// @override +/// Widget build(BuildContext context) { +/// return StorageGridView( +/// ref: FirebaseStorage.instance.ref('list'), +/// itemBuilder: (context, ref) { +/// return Card( +/// child: Center( +/// child: FutureBuilder( +/// future: ref.getData(), +/// builder: (context, snapshot) { +/// if (snapshot.hasError) { +/// return Text(snapshot.error.toString()); +/// } +/// if (snapshot.hasData) { +/// return Text(utf8.decode(snapshot.data!)); +/// } +/// +/// return const CircularProgressIndicator(); +/// }, +/// ), +/// ), +/// ); +/// }, +/// ); +/// } +///} +/// ``` class StorageGridView extends StatefulWidget { /// The [Reference] to list items from. /// If not provided, a [loadingController] must be created and passed. diff --git a/packages/firebase_ui_storage/lib/src/widgets/progress_indicator.dart b/packages/firebase_ui_storage/lib/src/widgets/progress_indicator.dart index 835f2f41..3c721816 100644 --- a/packages/firebase_ui_storage/lib/src/widgets/progress_indicator.dart +++ b/packages/firebase_ui_storage/lib/src/widgets/progress_indicator.dart @@ -90,7 +90,7 @@ abstract class TaskProgressWidget extends StatelessWidget { task: task, errorBuilder: errorBuilder, builder: (context, progress) { - return CircularProgressIndicator(value: progress); + return buildProgressIndicator(context, progress); }, ); } From bf1544eaebd5e81ad0267150cf4b3a58018131db Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Fri, 1 Sep 2023 15:29:30 +0200 Subject: [PATCH 02/18] docs(ui_storage): update root readme --- packages/firebase_ui_storage/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/firebase_ui_storage/README.md b/packages/firebase_ui_storage/README.md index 544c340a..99328399 100644 --- a/packages/firebase_ui_storage/README.md +++ b/packages/firebase_ui_storage/README.md @@ -7,6 +7,15 @@ Firebase UI Storage is a set of Flutter widgets and utilities designed to help y ## Documentation - [Getting started](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/getting-started.md) +- Widgets + + - [`UploadButton`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/upload-button.md) + - [`TaskProgressIndicator`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/task-progress-indicator.md) + - [`StorageImage`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/storage-image.md) + - [`ListView`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/list-view.md) + - [`GridView`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/grid-view.md) + +- [`PaginatedLoadingController`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/paginated-loading-controller.md) ## Issues From b9fac09b8c5577e661bdeb58ae7eb508d1dd007b Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Fri, 1 Sep 2023 15:31:52 +0200 Subject: [PATCH 03/18] docs(ui_storage): fix widget names --- packages/firebase_ui_storage/README.md | 4 ++-- packages/firebase_ui_storage/doc/getting-started.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/firebase_ui_storage/README.md b/packages/firebase_ui_storage/README.md index 99328399..0b826f68 100644 --- a/packages/firebase_ui_storage/README.md +++ b/packages/firebase_ui_storage/README.md @@ -12,8 +12,8 @@ Firebase UI Storage is a set of Flutter widgets and utilities designed to help y - [`UploadButton`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/upload-button.md) - [`TaskProgressIndicator`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/task-progress-indicator.md) - [`StorageImage`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/storage-image.md) - - [`ListView`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/list-view.md) - - [`GridView`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/grid-view.md) + - [`StorageListView`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/list-view.md) + - [`StorageGridView`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/grid-view.md) - [`PaginatedLoadingController`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/paginated-loading-controller.md) diff --git a/packages/firebase_ui_storage/doc/getting-started.md b/packages/firebase_ui_storage/doc/getting-started.md index 630e644a..34541dae 100644 --- a/packages/firebase_ui_storage/doc/getting-started.md +++ b/packages/firebase_ui_storage/doc/getting-started.md @@ -115,8 +115,8 @@ class MyWidget extends StatelessWidget { - [`UploadButton`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/upload-button.md) - [`TaskProgressIndicator`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/task-progress-indicator.md) - [`StorageImage`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/storage-image.md) -- [`ListView`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/list-view.md) -- [`GridView`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/grid-view.md) +- [`StorageListView`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/list-view.md) +- [`StorageGridView`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/grid-view.md) - [`PaginatedLoadingController`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/paginated-loading-controller.md) --- From 07938f668f70d3343b3ee9de20c6cae8ddf70414 Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Fri, 1 Sep 2023 15:48:15 +0200 Subject: [PATCH 04/18] docs(ui_storage): fix links --- .../firebase_ui_storage/doc/paginated-loading-controller.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/firebase_ui_storage/doc/paginated-loading-controller.md b/packages/firebase_ui_storage/doc/paginated-loading-controller.md index 05455f12..5cc756f4 100644 --- a/packages/firebase_ui_storage/doc/paginated-loading-controller.md +++ b/packages/firebase_ui_storage/doc/paginated-loading-controller.md @@ -4,7 +4,10 @@ When loading large amounts of objects from the Firebase Storage, it makes sense Firebase UI Storage provides [`StorageListView`] and [`StorageGridView`] widgets that implement pagination logic for you, and allow to load objects from the Firebase Storage in batches while scrolling. -In cases where you want to build a completely custom scroll view, but still have pagination logic handled – you can use [`PaginatedLoadingController`]. +In cases where you want to build a completely custom scroll view, but still have pagination logic handled – you can use `PaginatedLoadingController`. + +[`StorageListView`]: https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/list-view.md +[`StorageGridView`]: https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/grid-view.md ```dart class MyWidget extends StatefulWidget { From aa8ee60bf6fecc14d7b0606527f01c138433074b Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Fri, 1 Sep 2023 16:01:15 +0200 Subject: [PATCH 05/18] docs(ui_storage): mark KeepOriginalNameUploadPolicy as a default --- packages/firebase_ui_storage/doc/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_ui_storage/doc/getting-started.md b/packages/firebase_ui_storage/doc/getting-started.md index 34541dae..8e99601d 100644 --- a/packages/firebase_ui_storage/doc/getting-started.md +++ b/packages/firebase_ui_storage/doc/getting-started.md @@ -81,7 +81,7 @@ Future main() async { Available file naming policies: -- [`KeepOriginalNameUploadPolicy`] – keeps the original file name +- [`KeepOriginalNameUploadPolicy`] – keeps the original file name (default) - [`KeepPathUploadPolicy`] - keeps the original file path - [`UuidFileUploadNamingPolicy`] – generates a UUID for each uploaded file From 88b5cd26f4965ba9dce6900c5598ebfb20d610ca Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Fri, 1 Sep 2023 16:04:05 +0200 Subject: [PATCH 06/18] docs(ui_storage): demonstrate how to use shouldLoadNextPage and load --- .../doc/paginated-loading-controller.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/firebase_ui_storage/doc/paginated-loading-controller.md b/packages/firebase_ui_storage/doc/paginated-loading-controller.md index 5cc756f4..b6d8e977 100644 --- a/packages/firebase_ui_storage/doc/paginated-loading-controller.md +++ b/packages/firebase_ui_storage/doc/paginated-loading-controller.md @@ -32,7 +32,16 @@ class _MyWidgetState extends State { InitialPageLoading() => const Text('Loading...'), PageLoadError(error: final error) => Text('Error: $error'), PageLoading() => const Text('Loading...'), - PageLoadComplete(items: final items) => MyCustomScrollView(items: items), + PageLoadComplete(items: final items) => ListView.builder( + itemCount: items.length, + itemBuilder: (context, index) { + if (ctrl.shouldLoadNextPage(index)) { + ctrl.load(); + } + + return StorageImage(ref: items[index]); + }, + ), }; }, ); From c23f8b245924639af0d52c2ef315beaf6e099418 Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Fri, 1 Sep 2023 16:09:25 +0200 Subject: [PATCH 07/18] Update packages/firebase_ui_storage/doc/getting-started.md Co-authored-by: Russell Wheatley --- packages/firebase_ui_storage/doc/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_ui_storage/doc/getting-started.md b/packages/firebase_ui_storage/doc/getting-started.md index 8e99601d..2e8086b1 100644 --- a/packages/firebase_ui_storage/doc/getting-started.md +++ b/packages/firebase_ui_storage/doc/getting-started.md @@ -18,7 +18,7 @@ flutterfire configure ## Configuration -This section will walk you through the configuration process of the Firebase UI Storage +This section will walk you through the configuration process for Firebase UI Storage ### macOS From 5d808ff6821f64c78036a3c0ea15bf1ef149b1c4 Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Fri, 1 Sep 2023 16:10:45 +0200 Subject: [PATCH 08/18] docs(ui_storage): explain flutterfire_cli in more details --- packages/firebase_ui_storage/doc/getting-started.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/firebase_ui_storage/doc/getting-started.md b/packages/firebase_ui_storage/doc/getting-started.md index 2e8086b1..706cbd49 100644 --- a/packages/firebase_ui_storage/doc/getting-started.md +++ b/packages/firebase_ui_storage/doc/getting-started.md @@ -10,7 +10,15 @@ Install dependencies flutter pub add firebase_core firebase_storage firebase_ui_storage ``` -Download Firebase project config +Install the FlutterFire CLI by running the following command from any directory: + +```sh +flutter pub global activate flutterfire_cli +``` + +Use the FlutterFire CLI to configure your Flutter apps to connect to Firebase. + +From your Flutter project directory, run the following command to start the app configuration workflow: ```sh flutterfire configure From 964cc310857e314ea2200d946e0304798ef3c169 Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Fri, 1 Sep 2023 16:11:37 +0200 Subject: [PATCH 09/18] Update packages/firebase_ui_storage/doc/getting-started.md Co-authored-by: Russell Wheatley --- packages/firebase_ui_storage/doc/getting-started.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/firebase_ui_storage/doc/getting-started.md b/packages/firebase_ui_storage/doc/getting-started.md index 706cbd49..cffef857 100644 --- a/packages/firebase_ui_storage/doc/getting-started.md +++ b/packages/firebase_ui_storage/doc/getting-started.md @@ -30,7 +30,9 @@ This section will walk you through the configuration process for Firebase UI Sto ### macOS -If you're building for macOS, you will need to add an entitlement for either read-only access if you only upload files: +If you're building for macOS, you will need to add an entitlement. + +For read-only access if you only upload files: ```xml com.apple.security.files.user-selected.read-only From 71db6fd88b8452ff6a13083cd052ff2134622868 Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Fri, 1 Sep 2023 16:12:10 +0200 Subject: [PATCH 10/18] Update packages/firebase_ui_storage/doc/storage-image.md Co-authored-by: Russell Wheatley --- packages/firebase_ui_storage/doc/storage-image.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_ui_storage/doc/storage-image.md b/packages/firebase_ui_storage/doc/storage-image.md index 8a49dab6..65ff17c2 100644 --- a/packages/firebase_ui_storage/doc/storage-image.md +++ b/packages/firebase_ui_storage/doc/storage-image.md @@ -59,7 +59,7 @@ StorageImage( ### Shimmer placeholder Shimmer placeholder is a combination of the `solidColor` placeholder with a -[shimmer](<(https://docs.flutter.dev/cookbook/effects/shimmer-loading)>) animation. +[shimmer](https://docs.flutter.dev/cookbook/effects/shimmer-loading) animation. ```dart StorageImage( From 6313ea723fd178904e6d01319b0269ceab04c61e Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Fri, 1 Sep 2023 16:12:30 +0200 Subject: [PATCH 11/18] Update packages/firebase_ui_storage/doc/getting-started.md Co-authored-by: Russell Wheatley --- packages/firebase_ui_storage/doc/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_ui_storage/doc/getting-started.md b/packages/firebase_ui_storage/doc/getting-started.md index cffef857..43ba4ba2 100644 --- a/packages/firebase_ui_storage/doc/getting-started.md +++ b/packages/firebase_ui_storage/doc/getting-started.md @@ -39,7 +39,7 @@ For read-only access if you only upload files: ``` -or read/write access if you want to be able to download files as well: +For read/write access if you want to be able to download files as well: ```xml com.apple.security.files.user-selected.read-write From 197f87e62c55df311b5dea78e2b87379c7cdb36b Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Fri, 1 Sep 2023 16:13:19 +0200 Subject: [PATCH 12/18] Update packages/firebase_ui_storage/doc/grid-view.md Co-authored-by: Russell Wheatley --- packages/firebase_ui_storage/doc/grid-view.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_ui_storage/doc/grid-view.md b/packages/firebase_ui_storage/doc/grid-view.md index 1e56505c..63e79c3e 100644 --- a/packages/firebase_ui_storage/doc/grid-view.md +++ b/packages/firebase_ui_storage/doc/grid-view.md @@ -1,6 +1,6 @@ # StorageGridView -When loading large amounts of objects from the Firebase Storage, it makes sense to load them in batches, but requires handling of the pagination logic. +When loading large amounts of objects from Firebase Storage, it makes sense to load them in batches, but requires handling of the pagination logic. `StorageGridView` implements pagination logic for you, and allows to load objects from the Firebase Storage in batches while scrolling. From 08665d94c6e769e8d16a09c51ba410870cc9df0e Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Fri, 1 Sep 2023 16:13:34 +0200 Subject: [PATCH 13/18] Update packages/firebase_ui_storage/doc/task-progress-indicator.md Co-authored-by: Russell Wheatley --- packages/firebase_ui_storage/doc/task-progress-indicator.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_ui_storage/doc/task-progress-indicator.md b/packages/firebase_ui_storage/doc/task-progress-indicator.md index 3541d6c3..2b2b3fa8 100644 --- a/packages/firebase_ui_storage/doc/task-progress-indicator.md +++ b/packages/firebase_ui_storage/doc/task-progress-indicator.md @@ -1,6 +1,6 @@ # TaskProgressIndicator -`TaskProgressIndicator` shows `LinearProgressIndicator` under `MaterialApp` and a custom iOS-styled alternative under `CupertinoApp` while the file is being uploaded/downloaded, reflecting the amount of bytes trasnferred. +`TaskProgressIndicator` shows `LinearProgressIndicator` under `MaterialApp`, and a custom iOS-styled alternative under `CupertinoApp` while the file is being uploaded/downloaded, reflecting the amount of bytes transferred. ## Usage From 747b56abc296f9b1dd8b6758ffb4895ea2758d78 Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Fri, 1 Sep 2023 16:13:48 +0200 Subject: [PATCH 14/18] Update packages/firebase_ui_storage/doc/task-progress-indicator.md Co-authored-by: Russell Wheatley --- packages/firebase_ui_storage/doc/task-progress-indicator.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_ui_storage/doc/task-progress-indicator.md b/packages/firebase_ui_storage/doc/task-progress-indicator.md index 2b2b3fa8..992e06f7 100644 --- a/packages/firebase_ui_storage/doc/task-progress-indicator.md +++ b/packages/firebase_ui_storage/doc/task-progress-indicator.md @@ -28,7 +28,7 @@ TaskProgressIndicator(task: task); ## Building custom progress indicators -Firebase UI storage provides and abstract class, that simplifies building custom progress indicators. You can extend `TaskProgressWidget` and override `buildProgressIndicator` to build your own progress indicator: +Firebase UI storage provides an abstract class that simplifies building custom progress indicators. You can extend `TaskProgressWidget` and override `buildProgressIndicator` to build your own progress indicator: ```dart class MyProgressIndicator extends TaskProgressWidget { From a8c16998966f1c27dc316be1d9acfec4e6d58bec Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Fri, 1 Sep 2023 16:14:45 +0200 Subject: [PATCH 15/18] Update packages/firebase_ui_storage/doc/upload-button.md --- packages/firebase_ui_storage/doc/upload-button.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_ui_storage/doc/upload-button.md b/packages/firebase_ui_storage/doc/upload-button.md index cab21a35..c3b37f6a 100644 --- a/packages/firebase_ui_storage/doc/upload-button.md +++ b/packages/firebase_ui_storage/doc/upload-button.md @@ -27,7 +27,7 @@ class MyUploadButton extends StatelessWidget { } ``` -Upload buttons uses `uploadRoot` and `namingPolicy` from [`FirebaseUIStorageConfiguration`](https://pub.dev/documentation/firebase_ui_storage/latest/firebase_ui_storage/FirebaseUIStorageConfiguration-class.html) to determine the location and file name of the uploaded file. +`UploadButton` uses `uploadRoot` and `namingPolicy` from [`FirebaseUIStorageConfiguration`](https://pub.dev/documentation/firebase_ui_storage/latest/firebase_ui_storage/FirebaseUIStorageConfiguration-class.html) to determine the location and file name of the uploaded file. ## Showing upload progress From 2a9b4bb061c2964061947e4abbdfc2e807e7efe7 Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Fri, 1 Sep 2023 16:14:57 +0200 Subject: [PATCH 16/18] Update packages/firebase_ui_storage/doc/upload-button.md Co-authored-by: Russell Wheatley --- packages/firebase_ui_storage/doc/upload-button.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_ui_storage/doc/upload-button.md b/packages/firebase_ui_storage/doc/upload-button.md index c3b37f6a..918ad4b4 100644 --- a/packages/firebase_ui_storage/doc/upload-button.md +++ b/packages/firebase_ui_storage/doc/upload-button.md @@ -31,7 +31,7 @@ class MyUploadButton extends StatelessWidget { ## Showing upload progress -`UploadButton` shows `CircularProgressIndicator` under `MaterialApp` and `CupertinoActivityIndicator` under `CupertinoApp` while the upload is in progress. For large uploads, you might want to show upload progress, so you could replace the button with a [`TaskProgressIndicator`](<(https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/task-progress-indicator.md)>) in a stateful widget, using `onUploadStarted`: +`UploadButton` shows `CircularProgressIndicator` under `MaterialApp`, and `CupertinoActivityIndicator` under `CupertinoApp` while the upload is in progress. For large uploads, you might want to show upload progress, so you could replace the button with a [`TaskProgressIndicator`](<(https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/task-progress-indicator.md)>) in a stateful widget using `onUploadStarted`: ```dart class MyUploadWidget extends StatelessWidget { From 7c231c536f561232a3bcc74b91640b64a8966bed Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Fri, 1 Sep 2023 16:16:44 +0200 Subject: [PATCH 17/18] Apply suggestions from code review Co-authored-by: Russell Wheatley --- packages/firebase_ui_storage/doc/grid-view.md | 6 +++--- packages/firebase_ui_storage/doc/list-view.md | 6 +++--- .../firebase_ui_storage/doc/paginated-loading-controller.md | 4 ++-- packages/firebase_ui_storage/doc/storage-image.md | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/firebase_ui_storage/doc/grid-view.md b/packages/firebase_ui_storage/doc/grid-view.md index 63e79c3e..1ee64e5d 100644 --- a/packages/firebase_ui_storage/doc/grid-view.md +++ b/packages/firebase_ui_storage/doc/grid-view.md @@ -2,7 +2,7 @@ When loading large amounts of objects from Firebase Storage, it makes sense to load them in batches, but requires handling of the pagination logic. -`StorageGridView` implements pagination logic for you, and allows to load objects from the Firebase Storage in batches while scrolling. +`StorageGridView` implements pagination logic for you, and allows to load objects from Firebase Storage in batches while scrolling. ## Usage @@ -39,7 +39,7 @@ StorageGridView( ### Custom inital page loading state -When the first page of objects is loading, `StorageGridView` will show a `CircularProgressIndicator` under `MaterialApp` and `CupertinoActivityIndicator` under `CupertinoApp`. +When the first page of objects is loading, `StorageGridView` will show a `CircularProgressIndicator` under `MaterialApp`, and `CupertinoActivityIndicator` under `CupertinoApp`. You can pass `loadingBuilder` to customize the loading state: @@ -79,7 +79,7 @@ StorageGridView( ### Custom scroll views with pagination logic -If you need something more customizable, but stil have pagination logic handled for you, you can use +If you need something more customizable, but still want pagination logic handled for you, you can use [`PaginatedLoadingController`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/paginated-loading-controller.md) --- diff --git a/packages/firebase_ui_storage/doc/list-view.md b/packages/firebase_ui_storage/doc/list-view.md index 6fac110b..1e46c770 100644 --- a/packages/firebase_ui_storage/doc/list-view.md +++ b/packages/firebase_ui_storage/doc/list-view.md @@ -2,7 +2,7 @@ When loading large amounts of objects from the Firebase Storage, it makes sense to load them in batches, but requires handling of the pagination logic. -`StorageListView` implements pagination logic for you, and allows to load objects from the Firebase Storage in batches while scrolling. +`StorageListView` implements pagination logic for you, and allows to load objects from Firebase Storage in batches while scrolling. ## Usage @@ -20,7 +20,7 @@ StorageListView( ### Custom inital page loading state -When the first page of objects is loading, `StorageListView` will show a `CircularProgressIndicator` under `MaterialApp` and `CupertinoActivityIndicator` under `CupertinoApp`. +When the first page of objects is loading, `StorageListView` will show a `CircularProgressIndicator` under `MaterialApp`, and `CupertinoActivityIndicator` under `CupertinoApp`. You can pass `loadingBuilder` to customize the loading state: @@ -60,7 +60,7 @@ StorageListView( ### Custom scroll views with pagination logic -If you need something more customizable, but stil have pagination logic handled for you, you can use +If you need something more customizable, but still want pagination logic handled for you, you can use [`PaginatedLoadingController`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/paginated-loading-controller.md) --- diff --git a/packages/firebase_ui_storage/doc/paginated-loading-controller.md b/packages/firebase_ui_storage/doc/paginated-loading-controller.md index b6d8e977..139d8aea 100644 --- a/packages/firebase_ui_storage/doc/paginated-loading-controller.md +++ b/packages/firebase_ui_storage/doc/paginated-loading-controller.md @@ -1,8 +1,8 @@ # PaginatedLoadingController -When loading large amounts of objects from the Firebase Storage, it makes sense to load them in batches, but requires handling of the pagination logic. +When loading large amounts of objects from Firebase Storage, it makes sense to load them in batches, but requires handling of the pagination logic. -Firebase UI Storage provides [`StorageListView`] and [`StorageGridView`] widgets that implement pagination logic for you, and allow to load objects from the Firebase Storage in batches while scrolling. +Firebase UI Storage provides [`StorageListView`] and [`StorageGridView`] widgets that implement pagination logic for you, and allows objects to be loaded from Firebase Storage in batches while scrolling. In cases where you want to build a completely custom scroll view, but still have pagination logic handled – you can use `PaginatedLoadingController`. diff --git a/packages/firebase_ui_storage/doc/storage-image.md b/packages/firebase_ui_storage/doc/storage-image.md index 65ff17c2..77e54084 100644 --- a/packages/firebase_ui_storage/doc/storage-image.md +++ b/packages/firebase_ui_storage/doc/storage-image.md @@ -1,6 +1,6 @@ # StorageImage -A widget that loads and displays an image from the Firebase Storage. +A widget that loads and displays an image from Firebase Storage. ## Usage @@ -38,7 +38,7 @@ StorageImage( ### Loading indicator -Loading indicator placeholder will show a `CircularProgressIndicator` under `MaterialApp` and `CupertinoActivityIndicator` under `CupertinoApp`. +Loading indicator placeholder will show a `CircularProgressIndicator` under `MaterialApp`, and `CupertinoActivityIndicator` under `CupertinoApp`. You can customize `size`, `color` and `strokeWidth` of the loading indicator: From 8f09319e7991aa2be2d1766168e3b29f7a4fd528 Mon Sep 17 00:00:00 2001 From: Andrei Lesnitsky Date: Fri, 1 Sep 2023 16:19:15 +0200 Subject: [PATCH 18/18] Update packages/firebase_ui_storage/doc/upload-button.md --- packages/firebase_ui_storage/doc/upload-button.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_ui_storage/doc/upload-button.md b/packages/firebase_ui_storage/doc/upload-button.md index 918ad4b4..dc863e55 100644 --- a/packages/firebase_ui_storage/doc/upload-button.md +++ b/packages/firebase_ui_storage/doc/upload-button.md @@ -31,7 +31,7 @@ class MyUploadButton extends StatelessWidget { ## Showing upload progress -`UploadButton` shows `CircularProgressIndicator` under `MaterialApp`, and `CupertinoActivityIndicator` under `CupertinoApp` while the upload is in progress. For large uploads, you might want to show upload progress, so you could replace the button with a [`TaskProgressIndicator`](<(https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/task-progress-indicator.md)>) in a stateful widget using `onUploadStarted`: +`UploadButton` shows `CircularProgressIndicator` under `MaterialApp`, and `CupertinoActivityIndicator` under `CupertinoApp` while the upload is in progress. For large uploads, you might want to show upload progress, so you could replace the button with a [`TaskProgressIndicator`](https://github.com/firebase/FirebaseUI-Flutter/tree/main/packages/firebase_ui_storage/doc/task-progress-indicator.md) in a stateful widget using `onUploadStarted`: ```dart class MyUploadWidget extends StatelessWidget {