gallery_app_bar_widget.dart 5.6 KB

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