gallery_app_bar_widget.dart 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. import 'dart:async';
  2. import 'package:flutter/cupertino.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:photos/core/configuration.dart';
  5. import 'package:photos/file_repository.dart';
  6. import 'package:photos/models/selected_files.dart';
  7. import 'package:photos/ui/email_entry_page.dart';
  8. import 'package:photos/ui/ott_verification_page.dart';
  9. import 'package:photos/ui/share_folder_widget.dart';
  10. import 'package:photos/utils/dialog_util.dart';
  11. import 'package:photos/utils/file_util.dart';
  12. import 'package:photos/utils/share_util.dart';
  13. enum GalleryAppBarType {
  14. homepage,
  15. local_folder,
  16. remote_folder,
  17. search_results,
  18. }
  19. class GalleryAppBarWidget extends StatefulWidget
  20. implements PreferredSizeWidget {
  21. final GalleryAppBarType type;
  22. final String title;
  23. final SelectedFiles selectedFiles;
  24. final String path;
  25. GalleryAppBarWidget(
  26. this.type,
  27. this.title,
  28. this.selectedFiles, [
  29. this.path,
  30. ]);
  31. @override
  32. _GalleryAppBarWidgetState createState() => _GalleryAppBarWidgetState();
  33. @override
  34. Size get preferredSize => Size.fromHeight(60.0);
  35. }
  36. class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
  37. @override
  38. void initState() {
  39. widget.selectedFiles.addListener(() {
  40. setState(() {});
  41. });
  42. super.initState();
  43. }
  44. @override
  45. Widget build(BuildContext context) {
  46. if (widget.selectedFiles.files.isEmpty) {
  47. return AppBar(
  48. title: Text(widget.title),
  49. actions: _getDefaultActions(context),
  50. );
  51. }
  52. return AppBar(
  53. leading: IconButton(
  54. icon: Icon(Icons.close),
  55. onPressed: () {
  56. _clearSelectedFiles();
  57. },
  58. ),
  59. title: Text(widget.selectedFiles.files.length.toString()),
  60. actions: _getActions(context),
  61. );
  62. }
  63. List<Widget> _getDefaultActions(BuildContext context) {
  64. List<Widget> actions = List<Widget>();
  65. if (!Configuration.instance.hasConfiguredAccount()) {
  66. actions.add(IconButton(
  67. icon: Icon(Configuration.instance.hasConfiguredAccount()
  68. ? Icons.sync_problem
  69. : Icons.sync_disabled),
  70. onPressed: () {
  71. _navigateToSignInPage(context);
  72. },
  73. ));
  74. } else if (widget.type == GalleryAppBarType.local_folder &&
  75. widget.title != "Favorites") {
  76. actions.add(IconButton(
  77. icon: Icon(Icons.person_add),
  78. onPressed: () {
  79. _showShareCollectionDialog();
  80. },
  81. ));
  82. }
  83. return actions;
  84. }
  85. Future<void> _showShareCollectionDialog() async {
  86. return showDialog<void>(
  87. context: context,
  88. builder: (BuildContext context) {
  89. return ShareFolderWidget(widget.title, widget.path);
  90. },
  91. );
  92. }
  93. List<Widget> _getActions(BuildContext context) {
  94. List<Widget> actions = List<Widget>();
  95. if (widget.selectedFiles.files.isNotEmpty) {
  96. if (widget.type != GalleryAppBarType.remote_folder &&
  97. widget.type != GalleryAppBarType.search_results) {
  98. actions.add(IconButton(
  99. icon: Icon(Icons.delete),
  100. onPressed: () {
  101. _showDeleteSheet(context);
  102. },
  103. ));
  104. }
  105. actions.add(IconButton(
  106. icon: Icon(Icons.share),
  107. onPressed: () {
  108. _shareSelected(context);
  109. },
  110. ));
  111. }
  112. return actions;
  113. }
  114. void _shareSelected(BuildContext context) {
  115. shareMultiple(context, widget.selectedFiles.files.toList());
  116. }
  117. void _showDeleteSheet(BuildContext context) {
  118. final action = CupertinoActionSheet(
  119. actions: <Widget>[
  120. CupertinoActionSheetAction(
  121. child: Text("Delete on device"),
  122. isDestructiveAction: true,
  123. onPressed: () {
  124. _deleteSelected(context, false);
  125. },
  126. ),
  127. CupertinoActionSheetAction(
  128. child: Text("Delete everywhere [WiP]"),
  129. isDestructiveAction: true,
  130. onPressed: () {
  131. _deleteSelected(context, true);
  132. },
  133. )
  134. ],
  135. cancelButton: CupertinoActionSheetAction(
  136. child: Text("Cancel"),
  137. onPressed: () {
  138. Navigator.of(context, rootNavigator: true).pop();
  139. },
  140. ),
  141. );
  142. showCupertinoModalPopup(context: context, builder: (_) => action);
  143. }
  144. _deleteSelected(BuildContext context, bool deleteEveryWhere) async {
  145. Navigator.of(context, rootNavigator: true).pop();
  146. final dialog = createProgressDialog(context, "Deleting...");
  147. await dialog.show();
  148. await deleteFiles(widget.selectedFiles.files.toList(),
  149. deleteEveryWhere: deleteEveryWhere);
  150. await FileRepository.instance.reloadFiles();
  151. _clearSelectedFiles();
  152. await dialog.hide();
  153. }
  154. void _clearSelectedFiles() {
  155. widget.selectedFiles.clearAll();
  156. }
  157. void _navigateToSignInPage(BuildContext context) {
  158. Navigator.of(context).push(
  159. MaterialPageRoute(
  160. builder: (BuildContext context) {
  161. return EmailEntryPage();
  162. },
  163. ),
  164. );
  165. }
  166. }