gallery_app_bar_widget.dart 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. import 'package:flutter/cupertino.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:photos/core/event_bus.dart';
  4. import 'package:photos/db/db_helper.dart';
  5. import 'package:photos/events/remote_sync_event.dart';
  6. import 'package:photos/models/photo.dart';
  7. import 'package:photos/photo_repository.dart';
  8. import 'package:photos/ui/setup_page.dart';
  9. import 'package:photo_manager/photo_manager.dart';
  10. import 'package:photos/utils/share_util.dart';
  11. class GalleryAppBarWidget extends StatefulWidget
  12. implements PreferredSizeWidget {
  13. final String title;
  14. final Set<Photo> selectedPhotos;
  15. final Function() onSelectionClear;
  16. final Function(List<Photo>) onPhotosDeleted;
  17. GalleryAppBarWidget(this.title, this.selectedPhotos,
  18. {this.onSelectionClear, this.onPhotosDeleted});
  19. @override
  20. _GalleryAppBarWidgetState createState() => _GalleryAppBarWidgetState();
  21. @override
  22. Size get preferredSize => Size.fromHeight(60.0);
  23. }
  24. class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
  25. bool _hasSyncErrors = false;
  26. @override
  27. void initState() {
  28. Bus.instance.on<RemoteSyncEvent>().listen((event) {
  29. setState(() {
  30. _hasSyncErrors = !event.success;
  31. });
  32. });
  33. super.initState();
  34. }
  35. @override
  36. Widget build(BuildContext context) {
  37. if (widget.selectedPhotos.isEmpty) {
  38. return AppBar(
  39. title: Text(widget.title),
  40. actions: _getDefaultActions(context),
  41. );
  42. }
  43. return AppBar(
  44. leading: IconButton(
  45. icon: Icon(Icons.close),
  46. onPressed: () {
  47. _clearSelectedPhotos();
  48. },
  49. ),
  50. title: Text(widget.selectedPhotos.length.toString()),
  51. actions: _getPhotoActions(context),
  52. );
  53. }
  54. List<Widget> _getDefaultActions(BuildContext context) {
  55. List<Widget> actions = List<Widget>();
  56. if (_hasSyncErrors) {
  57. actions.add(IconButton(
  58. icon: Icon(Icons.sync_problem),
  59. onPressed: () {
  60. _openSyncConfiguration(context);
  61. },
  62. ));
  63. }
  64. return actions;
  65. }
  66. List<Widget> _getPhotoActions(BuildContext context) {
  67. List<Widget> actions = List<Widget>();
  68. if (widget.selectedPhotos.isNotEmpty) {
  69. actions.add(IconButton(
  70. icon: Icon(Icons.delete),
  71. onPressed: () {
  72. _showDeletePhotosSheet(context);
  73. },
  74. ));
  75. actions.add(IconButton(
  76. icon: Icon(Icons.share),
  77. onPressed: () {
  78. _shareSelectedPhotos(context);
  79. },
  80. ));
  81. }
  82. return actions;
  83. }
  84. void _shareSelectedPhotos(BuildContext context) {
  85. shareMultiple(widget.selectedPhotos.toList());
  86. }
  87. void _showDeletePhotosSheet(BuildContext context) {
  88. final action = CupertinoActionSheet(
  89. actions: <Widget>[
  90. CupertinoActionSheetAction(
  91. child: Text("Delete on device"),
  92. isDestructiveAction: true,
  93. onPressed: () async {
  94. await _deleteSelectedPhotos(context, false);
  95. },
  96. ),
  97. CupertinoActionSheetAction(
  98. child: Text("Delete everywhere [WiP]"),
  99. isDestructiveAction: true,
  100. onPressed: () async {
  101. await _deleteSelectedPhotos(context, true);
  102. },
  103. )
  104. ],
  105. cancelButton: CupertinoActionSheetAction(
  106. child: Text("Cancel"),
  107. onPressed: () {
  108. Navigator.of(context, rootNavigator: true).pop();
  109. },
  110. ),
  111. );
  112. showCupertinoModalPopup(context: context, builder: (_) => action);
  113. }
  114. Future _deleteSelectedPhotos(
  115. BuildContext context, bool deleteEverywhere) async {
  116. await PhotoManager.editor
  117. .deleteWithIds(widget.selectedPhotos.map((p) => p.localId).toList());
  118. for (Photo photo in widget.selectedPhotos) {
  119. deleteEverywhere
  120. ? await DatabaseHelper.instance.markPhotoForDeletion(photo)
  121. : await DatabaseHelper.instance.deletePhoto(photo);
  122. }
  123. Navigator.of(context, rootNavigator: true).pop();
  124. PhotoRepository.instance.reloadPhotos();
  125. if (widget.onPhotosDeleted != null) {
  126. widget.onPhotosDeleted(widget.selectedPhotos.toList());
  127. }
  128. _clearSelectedPhotos();
  129. }
  130. void _clearSelectedPhotos() {
  131. setState(() {
  132. widget.selectedPhotos.clear();
  133. });
  134. if (widget.onSelectionClear != null) {
  135. widget.onSelectionClear();
  136. }
  137. }
  138. void _openSyncConfiguration(BuildContext context) {
  139. final page = SetupPage();
  140. Navigator.of(context).push(
  141. MaterialPageRoute(
  142. settings: RouteSettings(name: "/setup"),
  143. builder: (BuildContext context) {
  144. return page;
  145. },
  146. ),
  147. );
  148. }
  149. }