gallery_app_bar_widget.dart 4.5 KB

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