123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- import 'dart:async';
- import 'dart:io';
- import 'package:flutter/cupertino.dart';
- import 'package:flutter/material.dart';
- import 'package:logging/logging.dart';
- import 'package:page_transition/page_transition.dart';
- import 'package:photos/core/configuration.dart';
- import 'package:photos/core/event_bus.dart';
- import 'package:photos/events/subscription_purchased_event.dart';
- import 'package:photos/models/collection.dart';
- import 'package:photos/models/selected_files.dart';
- import 'package:photos/services/collections_service.dart';
- import 'package:photos/ui/create_collection_page.dart';
- import 'package:photos/ui/share_collection_widget.dart';
- import 'package:photos/utils/delete_file_util.dart';
- import 'package:photos/utils/dialog_util.dart';
- import 'package:photos/utils/share_util.dart';
- import 'package:photos/utils/toast_util.dart';
- enum GalleryAppBarType {
- homepage,
- local_folder,
- // indicator for gallery view of collections shared with the user
- shared_collection,
- owned_collection,
- search_results
- }
- class GalleryAppBarWidget extends StatefulWidget {
- final GalleryAppBarType type;
- final String title;
- final SelectedFiles selectedFiles;
- final String path;
- final Collection collection;
- GalleryAppBarWidget(
- this.type,
- this.title,
- this.selectedFiles, {
- this.path,
- this.collection,
- });
- @override
- _GalleryAppBarWidgetState createState() => _GalleryAppBarWidgetState();
- }
- class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
- final _logger = Logger("GalleryAppBar");
- StreamSubscription _userAuthEventSubscription;
- Function() _selectedFilesListener;
- @override
- void initState() {
- _selectedFilesListener = () {
- setState(() {});
- };
- widget.selectedFiles.addListener(_selectedFilesListener);
- _userAuthEventSubscription =
- Bus.instance.on<SubscriptionPurchasedEvent>().listen((event) {
- setState(() {});
- });
- super.initState();
- }
- @override
- void dispose() {
- _userAuthEventSubscription.cancel();
- widget.selectedFiles.removeListener(_selectedFilesListener);
- super.dispose();
- }
- @override
- Widget build(BuildContext context) {
- if (widget.selectedFiles.files.isEmpty) {
- return AppBar(
- backgroundColor: widget.type == GalleryAppBarType.homepage
- ? Color(0x00000000)
- : null,
- elevation: 0,
- title: widget.type == GalleryAppBarType.homepage
- ? Container()
- : Text(
- widget.title,
- style: TextStyle(
- color: Colors.white.withOpacity(0.80),
- ),
- ),
- actions: _getDefaultActions(context),
- );
- }
- return AppBar(
- leading: IconButton(
- icon: Icon(Platform.isAndroid ? Icons.clear : CupertinoIcons.clear),
- onPressed: () {
- _clearSelectedFiles();
- },
- ),
- title: Text(widget.selectedFiles.files.length.toString()),
- actions: _getActions(context),
- );
- }
- List<Widget> _getDefaultActions(BuildContext context) {
- List<Widget> actions = <Widget>[];
- if (Configuration.instance.hasConfiguredAccount() &&
- (widget.type == GalleryAppBarType.local_folder ||
- widget.type == GalleryAppBarType.owned_collection)) {
- actions.add(IconButton(
- icon: Icon(Icons.person_add),
- onPressed: () {
- _showShareCollectionDialog();
- },
- ));
- }
- return actions;
- }
- Future<void> _showShareCollectionDialog() async {
- var collection = widget.collection;
- final dialog = createProgressDialog(context, "please wait...");
- await dialog.show();
- if (collection == null) {
- if (widget.type == GalleryAppBarType.local_folder) {
- collection =
- CollectionsService.instance.getCollectionForPath(widget.path);
- if (collection == null) {
- try {
- collection = await CollectionsService.instance
- .getOrCreateForPath(widget.path);
- } catch (e, s) {
- _logger.severe(e, s);
- await dialog.hide();
- showGenericErrorDialog(context);
- }
- }
- } else {
- throw Exception(
- "Cannot create a collection of type" + widget.type.toString());
- }
- } else {
- final sharees =
- await CollectionsService.instance.getSharees(collection.id);
- collection = collection.copyWith(sharees: sharees);
- }
- await dialog.hide();
- return showDialog<void>(
- context: context,
- builder: (BuildContext context) {
- return SharingDialog(collection);
- },
- );
- }
- Future<void> _createAlbum() async {
- Navigator.push(
- context,
- PageTransition(
- type: PageTransitionType.bottomToTop,
- child: CreateCollectionPage(
- widget.selectedFiles,
- null,
- )));
- }
- Future<void> _moveFiles() async {
- Navigator.push(
- context,
- PageTransition(
- type: PageTransitionType.bottomToTop,
- child: CreateCollectionPage(
- widget.selectedFiles,
- null,
- actionType: CollectionActionType.moveFiles,
- )));
- }
- List<Widget> _getActions(BuildContext context) {
- List<Widget> actions = <Widget>[];
- // skip add button for incoming collection till this feature is implemented
- if (Configuration.instance.hasConfiguredAccount() &&
- widget.type != GalleryAppBarType.shared_collection) {
- actions.add(IconButton(
- icon:
- Icon(Platform.isAndroid ? Icons.add_outlined : CupertinoIcons.add),
- onPressed: () {
- _createAlbum();
- },
- ));
- }
- if (Configuration.instance.hasConfiguredAccount() &&
- widget.type == GalleryAppBarType.owned_collection) {
- actions.add(IconButton(
- icon: Icon(Platform.isAndroid
- ? Icons.arrow_right_alt_rounded
- : CupertinoIcons.arrow_right),
- onPressed: () {
- _moveFiles();
- },
- ));
- }
- actions.add(IconButton(
- icon: Icon(
- Platform.isAndroid ? Icons.share_outlined : CupertinoIcons.share),
- onPressed: () {
- _shareSelected(context);
- },
- ));
- if (widget.type == GalleryAppBarType.homepage ||
- widget.type == GalleryAppBarType.local_folder) {
- actions.add(IconButton(
- icon: Icon(
- Platform.isAndroid ? Icons.delete_outline : CupertinoIcons.delete),
- onPressed: () {
- _showDeleteSheet(context);
- },
- ));
- } else if (widget.type == GalleryAppBarType.owned_collection) {
- if (widget.collection.type == CollectionType.folder) {
- actions.add(IconButton(
- icon: Icon(Platform.isAndroid
- ? Icons.delete_outline
- : CupertinoIcons.delete),
- onPressed: () {
- _showDeleteSheet(context);
- },
- ));
- } else {
- actions.add(IconButton(
- icon: Icon(Icons.remove_circle_outline_rounded),
- onPressed: () {
- _showRemoveFromCollectionSheet(context);
- },
- ));
- }
- }
- if (widget.type == GalleryAppBarType.homepage) {
- actions.add(PopupMenuButton(
- itemBuilder: (context) {
- final List<PopupMenuItem> items = [];
- items.add(
- PopupMenuItem(
- value: 1,
- child: Row(
- children: [
- Icon(Platform.isAndroid
- ? Icons.archive_outlined
- : CupertinoIcons.archivebox),
- Padding(
- padding: EdgeInsets.all(8),
- ),
- Text("archive"),
- ],
- ),
- ),
- );
- return items;
- },
- onSelected: (value) {
- if (value == 1) {
- showToast("coming soon");
- }
- },
- ));
- }
- return actions;
- }
- void _shareSelected(BuildContext context) {
- share(context, widget.selectedFiles.files.toList());
- }
- void _showRemoveFromCollectionSheet(BuildContext context) {
- final count = widget.selectedFiles.files.length;
- final action = CupertinoActionSheet(
- title: Text("remove " +
- count.toString() +
- " file" +
- (count == 1 ? "" : "s") +
- " from " +
- widget.collection.name +
- "?"),
- actions: <Widget>[
- CupertinoActionSheetAction(
- child: Text("remove"),
- isDestructiveAction: true,
- onPressed: () async {
- Navigator.of(context, rootNavigator: true).pop();
- final dialog = createProgressDialog(context, "removing files...");
- await dialog.show();
- try {
- await CollectionsService.instance.removeFromCollection(
- widget.collection.id, widget.selectedFiles.files.toList());
- await dialog.hide();
- widget.selectedFiles.clearAll();
- } catch (e, s) {
- _logger.severe(e, s);
- await dialog.hide();
- showGenericErrorDialog(context);
- }
- },
- ),
- ],
- cancelButton: CupertinoActionSheetAction(
- child: Text("cancel"),
- onPressed: () {
- Navigator.of(context, rootNavigator: true).pop();
- },
- ),
- );
- showCupertinoModalPopup(context: context, builder: (_) => action);
- }
- void _showDeleteSheet(BuildContext context) {
- final count = widget.selectedFiles.files.length;
- bool containsUploadedFile = false, containsLocalFile = false;
- for (final file in widget.selectedFiles.files) {
- if (file.uploadedFileID != null) {
- containsUploadedFile = true;
- }
- if (file.localID != null) {
- containsLocalFile = true;
- }
- }
- final actions = <Widget>[];
- if (containsUploadedFile && containsLocalFile) {
- actions.add(CupertinoActionSheetAction(
- child: Text("this device"),
- isDestructiveAction: true,
- onPressed: () async {
- Navigator.of(context, rootNavigator: true).pop();
- await deleteFilesOnDeviceOnly(
- context, widget.selectedFiles.files.toList());
- _clearSelectedFiles();
- showToast("files deleted from device");
- },
- ));
- actions.add(CupertinoActionSheetAction(
- child: Text("everywhere"),
- isDestructiveAction: true,
- onPressed: () async {
- Navigator.of(context, rootNavigator: true).pop();
- await deleteFilesFromEverywhere(
- context, widget.selectedFiles.files.toList());
- _clearSelectedFiles();
- },
- ));
- } else {
- actions.add(CupertinoActionSheetAction(
- child: Text("delete forever"),
- isDestructiveAction: true,
- onPressed: () async {
- Navigator.of(context, rootNavigator: true).pop();
- await deleteFilesFromEverywhere(
- context, widget.selectedFiles.files.toList());
- _clearSelectedFiles();
- },
- ));
- }
- final action = CupertinoActionSheet(
- title: Text("delete " +
- count.toString() +
- " file" +
- (count == 1 ? "" : "s") +
- (containsUploadedFile && containsLocalFile ? " from" : "?")),
- actions: actions,
- cancelButton: CupertinoActionSheetAction(
- child: Text("cancel"),
- onPressed: () {
- Navigator.of(context, rootNavigator: true).pop();
- },
- ),
- );
- showCupertinoModalPopup(context: context, builder: (_) => action);
- }
- void _clearSelectedFiles() {
- widget.selectedFiles.clearAll();
- }
- }
|