123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- import "dart:async";
- import 'package:flutter/material.dart';
- import 'package:logging/logging.dart';
- import 'package:path/path.dart';
- import 'package:photos/core/event_bus.dart';
- import "package:photos/events/collection_meta_event.dart";
- import "package:photos/events/collection_updated_event.dart";
- import "package:photos/events/files_updated_event.dart";
- import 'package:photos/events/force_reload_home_gallery_event.dart';
- import "package:photos/generated/l10n.dart";
- import 'package:photos/models/collection/collection.dart';
- import 'package:photos/models/file/file.dart';
- import "package:photos/models/metadata/collection_magic.dart";
- import "package:photos/models/metadata/common_keys.dart";
- import "package:photos/models/metadata/file_magic.dart";
- import 'package:photos/services/collections_service.dart';
- import 'package:photos/services/file_magic_service.dart';
- import 'package:photos/ui/common/progress_dialog.dart';
- import 'package:photos/utils/dialog_util.dart';
- import 'package:photos/utils/toast_util.dart';
- final _logger = Logger('MagicUtil');
- enum _VisibilityAction { hide, unHide, archive, unarchive }
- Future<void> changeVisibility(
- BuildContext context,
- List<EnteFile> files,
- int newVisibility,
- ) async {
- final dialog = createProgressDialog(
- context,
- newVisibility == archiveVisibility
- ? S.of(context).archiving
- : S.of(context).unarchiving,
- );
- await dialog.show();
- try {
- await FileMagicService.instance.changeVisibility(files, newVisibility);
- showShortToast(
- context,
- newVisibility == archiveVisibility
- ? S.of(context).successfullyArchived
- : S.of(context).successfullyUnarchived,
- );
- await dialog.hide();
- } catch (e, s) {
- _logger.severe("failed to update file visibility", e, s);
- await dialog.hide();
- rethrow;
- }
- }
- Future<void> changeCollectionVisibility(
- BuildContext context, {
- required Collection collection,
- required int newVisibility,
- required int prevVisibility,
- bool isOwner = true,
- }) async {
- final visibilityAction =
- _getVisibilityAction(context, newVisibility, prevVisibility);
- final dialog = createProgressDialog(
- context,
- _visActionProgressDialogText(
- context,
- visibilityAction,
- ),
- );
- await dialog.show();
- try {
- final Map<String, dynamic> update = {magicKeyVisibility: newVisibility};
- if (isOwner) {
- await CollectionsService.instance.updateMagicMetadata(collection, update);
- } else {
- await CollectionsService.instance
- .updateShareeMagicMetadata(collection, update);
- }
- // Force reload home gallery to pull in/remove the now visibility changed
- // files
- Bus.instance.fire(
- ForceReloadHomeGalleryEvent(
- "CollectionVisibilityChange: $visibilityAction",
- ),
- );
- showShortToast(
- context,
- _visActionSuccessfulText(
- context,
- visibilityAction,
- ),
- );
- await dialog.hide();
- } catch (e, s) {
- _logger.severe("failed to update collection visibility", e, s);
- await dialog.hide();
- rethrow;
- }
- }
- Future<void> changeSortOrder(
- BuildContext context,
- Collection collection,
- bool sortedInAscOrder,
- ) async {
- try {
- final Map<String, dynamic> update = {"asc": sortedInAscOrder};
- await CollectionsService.instance
- .updatePublicMagicMetadata(collection, update);
- Bus.instance.fire(
- CollectionMetaEvent(collection.id, CollectionMetaEventType.sortChanged),
- );
- } catch (e, s) {
- _logger.severe("failed to update collection visibility", e, s);
- showShortToast(context, S.of(context).somethingWentWrong);
- rethrow;
- }
- }
- Future<void> updateOrder(
- BuildContext context,
- Collection collection,
- int order,
- ) async {
- try {
- final Map<String, dynamic> update = {
- orderKey: order,
- };
- await CollectionsService.instance.updateMagicMetadata(collection, update);
- Bus.instance.fire(
- CollectionMetaEvent(collection.id, CollectionMetaEventType.orderChanged),
- );
- } catch (e, s) {
- _logger.severe("failed to update order", e, s);
- showShortToast(context, S.of(context).somethingWentWrong);
- rethrow;
- }
- }
- // changeCoverPhoto is used to change cover photo for a collection. To reset to
- // default cover photo, pass uploadedFileID as 0
- Future<void> changeCoverPhoto(
- BuildContext context,
- Collection collection,
- int uploadedFileID,
- ) async {
- try {
- final Map<String, dynamic> update = {"coverID": uploadedFileID};
- await CollectionsService.instance
- .updatePublicMagicMetadata(collection, update);
- Bus.instance.fire(
- CollectionUpdatedEvent(
- collection.id,
- <EnteFile>[],
- "cover_change",
- type: EventType.coverChanged,
- ),
- );
- } catch (e, s) {
- _logger.severe("failed to update cover", e, s);
- showShortToast(context, S.of(context).somethingWentWrong);
- rethrow;
- }
- }
- Future<bool> editTime(
- BuildContext context,
- List<EnteFile> files,
- int editedTime,
- ) async {
- try {
- await _updatePublicMetadata(
- context,
- files,
- editTimeKey,
- editedTime,
- );
- return true;
- } catch (e) {
- showShortToast(context, S.of(context).somethingWentWrong);
- return false;
- }
- }
- Future<void> editFilename(
- BuildContext context,
- EnteFile file,
- ) async {
- final fileName = file.displayName;
- final nameWithoutExt = basenameWithoutExtension(fileName);
- final extName = extension(fileName);
- final result = await showTextInputDialog(
- context,
- title: S.of(context).renameFile,
- submitButtonLabel: S.of(context).rename,
- initialValue: nameWithoutExt,
- message: extName.toUpperCase(),
- alignMessage: Alignment.centerRight,
- hintText: S.of(context).enterFileName,
- maxLength: 50,
- alwaysShowSuccessState: true,
- onSubmit: (String text) async {
- if (text.isEmpty || text.trim() == nameWithoutExt.trim()) {
- return;
- }
- final newName = text + extName;
- await _updatePublicMetadata(
- context,
- List.of([file]),
- editNameKey,
- newName,
- showProgressDialogs: false,
- showDoneToast: false,
- );
- },
- );
- if (result is Exception) {
- _logger.severe("Failed to rename file");
- await showGenericErrorDialog(context: context, error: result);
- }
- }
- Future<bool> editFileCaption(
- BuildContext? context,
- EnteFile file,
- String caption,
- ) async {
- try {
- await _updatePublicMetadata(
- context,
- [file],
- captionKey,
- caption,
- showDoneToast: false,
- );
- return true;
- } catch (e) {
- if (context != null) {
- showShortToast(context, S.of(context).somethingWentWrong);
- }
- return false;
- }
- }
- Future<void> _updatePublicMetadata(
- BuildContext? context,
- List<EnteFile> files,
- String key,
- dynamic value, {
- bool showDoneToast = true,
- bool showProgressDialogs = true,
- }) async {
- if (files.isEmpty) {
- return;
- }
- ProgressDialog? dialog;
- if (context != null && showProgressDialogs) {
- dialog = createProgressDialog(context, S.of(context).pleaseWait);
- await dialog.show();
- }
- try {
- final Map<String, dynamic> update = {key: value};
- await FileMagicService.instance.updatePublicMagicMetadata(files, update);
- if (context != null) {
- if (showDoneToast) {
- showShortToast(context, S.of(context).done);
- }
- await dialog?.hide();
- }
- if (_shouldReloadGallery(key)) {
- Bus.instance.fire(ForceReloadHomeGalleryEvent("FileMetadataChange-$key"));
- }
- } catch (e, s) {
- _logger.severe("failed to update $key = $value", e, s);
- if (context != null) {
- await dialog?.hide();
- }
- rethrow;
- }
- }
- bool _shouldReloadGallery(String key) {
- return key == editTimeKey;
- }
- _visActionProgressDialogText(BuildContext context, _VisibilityAction action) {
- switch (action) {
- case _VisibilityAction.archive:
- return S.of(context).archiving;
- case _VisibilityAction.hide:
- return S.of(context).hiding;
- case _VisibilityAction.unarchive:
- return S.of(context).unarchiving;
- case _VisibilityAction.unHide:
- return S.of(context).unhiding;
- }
- }
- _visActionSuccessfulText(BuildContext context, _VisibilityAction action) {
- switch (action) {
- case _VisibilityAction.archive:
- return S.of(context).successfullyArchived;
- case _VisibilityAction.hide:
- return S.of(context).successfullyHid;
- case _VisibilityAction.unarchive:
- return S.of(context).successfullyUnarchived;
- case _VisibilityAction.unHide:
- return S.of(context).successfullyUnhid;
- }
- }
- _VisibilityAction _getVisibilityAction(
- context,
- int newVisibility,
- int prevVisibility,
- ) {
- if (newVisibility == archiveVisibility) {
- return _VisibilityAction.archive;
- } else if (newVisibility == hiddenVisibility) {
- return _VisibilityAction.hide;
- } else if (newVisibility == visibleVisibility &&
- prevVisibility == archiveVisibility) {
- return _VisibilityAction.unarchive;
- } else {
- return _VisibilityAction.unHide;
- }
- }
|