magic_util.dart 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // @dart=2.9
  2. import 'package:flutter/material.dart';
  3. import 'package:logging/logging.dart';
  4. import 'package:path/path.dart';
  5. import 'package:photos/core/event_bus.dart';
  6. import 'package:photos/events/force_reload_home_gallery_event.dart';
  7. import 'package:photos/models/collection.dart';
  8. import 'package:photos/models/file.dart';
  9. import 'package:photos/models/magic_metadata.dart';
  10. import 'package:photos/services/collections_service.dart';
  11. import 'package:photos/services/file_magic_service.dart';
  12. import 'package:photos/ui/common/progress_dialog.dart';
  13. import 'package:photos/ui/common/rename_dialog.dart';
  14. import 'package:photos/utils/dialog_util.dart';
  15. import 'package:photos/utils/toast_util.dart';
  16. final _logger = Logger('MagicUtil');
  17. Future<void> changeVisibility(
  18. BuildContext context,
  19. List<File> files,
  20. int newVisibility,
  21. ) async {
  22. final dialog = createProgressDialog(
  23. context,
  24. newVisibility == visibilityArchive
  25. ? "Archiving..."
  26. : "Unarchiving..."
  27. "...",
  28. );
  29. await dialog.show();
  30. try {
  31. await FileMagicService.instance.changeVisibility(files, newVisibility);
  32. showShortToast(
  33. context,
  34. newVisibility == visibilityArchive
  35. ? "Successfully archived"
  36. : "Successfully unarchived",
  37. );
  38. await dialog.hide();
  39. } catch (e, s) {
  40. _logger.severe("failed to update file visibility", e, s);
  41. await dialog.hide();
  42. rethrow;
  43. }
  44. }
  45. Future<void> changeCollectionVisibility(
  46. BuildContext context,
  47. Collection collection,
  48. int newVisibility,
  49. ) async {
  50. final dialog = createProgressDialog(
  51. context,
  52. newVisibility == visibilityArchive ? "Archiving..." : "Unarchiving...",
  53. );
  54. await dialog.show();
  55. try {
  56. final Map<String, dynamic> update = {magicKeyVisibility: newVisibility};
  57. await CollectionsService.instance.updateMagicMetadata(collection, update);
  58. // Force reload home gallery to pull in the now unarchived files
  59. Bus.instance.fire(ForceReloadHomeGalleryEvent());
  60. showShortToast(
  61. context,
  62. newVisibility == visibilityArchive
  63. ? "Successfully archived"
  64. : "Successfully unarchived",
  65. );
  66. await dialog.hide();
  67. } catch (e, s) {
  68. _logger.severe("failed to update collection visibility", e, s);
  69. await dialog.hide();
  70. rethrow;
  71. }
  72. }
  73. Future<bool> editTime(
  74. BuildContext context,
  75. List<File> files,
  76. int editedTime,
  77. ) async {
  78. try {
  79. await _updatePublicMetadata(
  80. context,
  81. files,
  82. pubMagicKeyEditedTime,
  83. editedTime,
  84. );
  85. return true;
  86. } catch (e) {
  87. showToast(context, 'something went wrong');
  88. return false;
  89. }
  90. }
  91. Future<bool> editFilename(
  92. BuildContext context,
  93. File file,
  94. ) async {
  95. try {
  96. final fileName = file.displayName;
  97. final nameWithoutExt = basenameWithoutExtension(fileName);
  98. final extName = extension(fileName);
  99. var result = await showDialog<String>(
  100. context: context,
  101. builder: (BuildContext context) {
  102. return RenameDialog(nameWithoutExt, 'file', maxLength: 50);
  103. },
  104. barrierColor: Colors.black.withOpacity(0.85),
  105. );
  106. if (result == null || result.trim() == nameWithoutExt.trim()) {
  107. return true;
  108. }
  109. result = result + extName;
  110. await _updatePublicMetadata(
  111. context,
  112. List.of([file]),
  113. pubMagicKeyEditedName,
  114. result,
  115. );
  116. return true;
  117. } catch (e) {
  118. showToast(context, 'Something went wrong');
  119. return false;
  120. }
  121. }
  122. Future<bool> editFileCaption(
  123. BuildContext context,
  124. File file,
  125. String caption,
  126. ) async {
  127. try {
  128. await _updatePublicMetadata(context, [file], pubMagicKeyCaption, caption);
  129. return true;
  130. } catch (e) {
  131. if (context != null) {
  132. showToast(context, "Something went wrong");
  133. }
  134. return false;
  135. }
  136. }
  137. Future<void> _updatePublicMetadata(
  138. BuildContext context,
  139. List<File> files,
  140. String key,
  141. dynamic value,
  142. ) async {
  143. if (files.isEmpty) {
  144. return;
  145. }
  146. ProgressDialog dialog;
  147. if (context != null) {
  148. dialog = createProgressDialog(context, 'Please wait...');
  149. await dialog.show();
  150. }
  151. try {
  152. final Map<String, dynamic> update = {key: value};
  153. await FileMagicService.instance.updatePublicMagicMetadata(files, update);
  154. if (context != null) {
  155. showShortToast(context, 'Done');
  156. await dialog.hide();
  157. }
  158. if (_shouldReloadGallery(key)) {
  159. Bus.instance.fire(ForceReloadHomeGalleryEvent());
  160. }
  161. } catch (e, s) {
  162. _logger.severe("failed to update $key = $value", e, s);
  163. if (context != null) {
  164. await dialog.hide();
  165. }
  166. rethrow;
  167. }
  168. }
  169. bool _shouldReloadGallery(String key) {
  170. return key == pubMagicKeyEditedTime;
  171. }