Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ios] Implement the Recently Deleted screen to restore deleted categories #7978

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
184 changes: 184 additions & 0 deletions data/strings/strings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30167,3 +30167,187 @@
vi = Thu nhỏ
zh-Hans = 放大
zh-Hant = 縮小

[delete_all]
comment = Text for the "Delete All" button on the Recently Deleted screen
tags = ios
en = Delete All
af = Vee alles uit
ar = حذف الكل
az = Hamısını Sil
be = Выдаліць усе
bg = Изтриване на всички
ca = Eliminar tots
cs = Smazat vše
da = Slet alle
de = Alle löschen
el = Διαγραφή όλων
es = Borrar todo
et = Kustuta kõik
eu = Ezabatu guztiak
fa = حذف همه
fi = Poista kaikki
fr = Supprimer tout
he = מחק הכל
hi = सभी हटा दो
hu = Mindent törölni
id = Hapus Semua
it = Cancella tutto
ja = すべて削除する
ko = 모두 삭제
lt = Ištrinti viską
mr = सर्व हटवा
nb = Slett alle
nl = Alles verwijderen
pl = Usuń wszystko
pt = Eliminar tudo
pt-BR = Excluir tudo
ro = Ștergeți toate
ru = Удалить все
sk = Odstrániť všetko
sv = Radera alla
sw = Futa Zote
th = ลบทั้งหมด
tr = Tümünü Sil
uk = Видалити все
vi = Xóa hết
zh-Hans = 全部删除
zh-Hant = 刪除所有

[recover]
comment = Text for the "Recover" button on the Recently Deleted screen
tags = ios
en = Recover
af = Herstel
ar = استعادة
az = Bərpa edin
be = Аднавіць
bg = Възстановяване
ca = Recuperar
cs = Obnovit
da = Gendan
de = Wiederherstellen
el = Ανάκτηση
es = Recuperar
et = Taasta
eu = Berreskuratu
fa = بازیابی کنید
fi = Palauta
fr = Récupérer
he = לשחזר
hi = पुनः प्राप्त करें
hu = Visszaállítás
id = Memulihkan
it = Recupera
ja = 回復する
ko = 복구
lt = Atkurti
mr = पुनर्प्राप्त करा
nb = Gjenopprette
nl = Herstellen
pl = Odzyskaj
pt = Recuperar
pt-BR = Recuperar
ro = Recuperare
ru = Восстановить
sk = Obnoviť
sv = Återställa
sw = Rudisha
th = กู้คืน
tr = Kurtarmak
uk = Відновити
vi = Khôi phục
zh-Hans = 恢复
zh-Hant = 恢復

[recover_all]
comment = Text for the "Recover All" button on the Recently Deleted screen
tags = ios
en = Recover All
af = Herwin alles
ar = استرداد الكل
az = Hamısını bərpa edin
be = Аднавіць усё
bg = Възстановяване на всички
ca = Recuperar-ho tot
cs = Obnovit vše
da = Gendan alt
de = Alles wiederherstellen
el = Ανάκτηση όλων
es = Recuperar todo
et = Taasta kõik
eu = Berreskuratu guztiak
fa = بازیابی همه
fi = Palauta kaikki
fr = Récupère tout
he = שחזר הכל
hi = सभी को पुनर्प्राप्त करें
hu = Mindent visszaállítani
id = Pulihkan Semua
it = Recupera tutto
ja = すべてを回復する
ko = 모두 복구
lt = Atkurti viską
mr = सर्व पुनर्प्राप्त करा
nb = Gjenopprett alt
nl = Alles herstellen
pl = Odzyskaj wszystko
pt = Recupera tudo
pt-BR = Recuperar tudo
ro = Recuperează totul
ru = Восстановить все
sk = Obnoviť všetko
sv = Återställ alla
sw = Rejesha Wote
th = กู้คืนทั้งหมด
tr = Tümünü Kurtar
uk = Відновити все
vi = Khôi phục tất cả
zh-Hans = 全部恢复
zh-Hant = 全部恢復

[bookmarks_recently_deleted]
comment = Title for the Recently Deleted screen
tags = ios
en = Recently Deleted
af = Onlangs verwyder
ar = المحذوفة مؤخراً
az = Bu yaxınlarda silindi
be = Нядаўна выдаленае
bg = Наскоро изтрити
ca = Eliminat recentment
cs = Nedávno odstraněné
da = Nyligt slettet
de = Kürzlich gestrichen
el = Πρόσφατα διαγραμμένο
es = Eliminado recientemente
et = Hiljuti kustutatud
eu = Duela gutxi ezabatu da
fa = اخیراً حذف شده است
fi = Äskettäin poistettu
fr = Récemment supprimé
he = נמחק לאחרונה
hi = हाल ही में हटाया गया
hu = Nemrégiben törölve
id = Baru-baru ini Dihapus
it = Eliminato di recente
ja = 最近削除された
ko = 최근 삭제됨
lt = Neseniai pašalintas
mr = अलीकडे हटवले
nb = Nylig slettet
nl = Onlangs verwijderd
pl = Ostatnio usunięte
pt = Eliminado recentemente
pt-BR = Excluídos recentemente
ro = Șterse recent
ru = Недавно удалённое
sk = Nedávno odstránené
sv = Nyligen borttagen
sw = Iliyofutwa Hivi Karibuni
th = เพิ่งถูกลบ
tr = Yakın Zamanda Silindi
uk = Нещодавно видалено
vi = Đã xóa gần đây
zh-Hans = 最近删除
zh-Hant = 最近刪除
14 changes: 13 additions & 1 deletion iphone/CoreApi/CoreApi/Bookmarks/MWMBookmarksManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,15 @@ typedef void (^SearchBookmarksCompletionBlock)(NSArray<MWMBookmark *> *bookmarks
typedef void (^SortBookmarksCompletionBlock)(NSArray<MWMBookmarksSection *> * _Nullable sortedSections);
typedef void (^SharingResultCompletionHandler)(MWMBookmarksShareStatus status, NSURL * _Nullable urlToALocalFile);

@protocol RecentlyDeletedCategoriesManager <NSObject>
- (BOOL)areRecentlyDeletedCategoriesEmpty;
- (NSArray<NSURL *> *)getRecentlyDeletedCategories;
- (void)deleteRecentlyDeletedCategoryAtURLs:(NSArray<NSURL *> *)urls;
- (void)recoverRecentlyDeletedCategoriesAtURLs:(NSArray<NSURL *> *)urls;
@end

NS_SWIFT_NAME(BookmarksManager)
@interface MWMBookmarksManager : NSObject
@interface MWMBookmarksManager : NSObject <RecentlyDeletedCategoriesManager>

+ (MWMBookmarksManager *)sharedManager;

Expand Down Expand Up @@ -149,5 +156,10 @@ NS_SWIFT_NAME(BookmarksManager)
- (void)setElevationMyPositionChanged:(uint64_t)trackId callback:(ElevationPointChangedBlock)callback;
- (void)resetElevationMyPositionChanged;

- (BOOL)areRecentlyDeletedCategoriesEmpty;
- (NSArray<NSURL *> *)getRecentlyDeletedCategories;
- (void)deleteRecentlyDeletedCategoryAtURLs:(NSArray<NSURL *> *)urls;
- (void)recoverRecentlyDeletedCategoriesAtURLs:(NSArray<NSURL *> *)urls;

@end
NS_ASSUME_NONNULL_END
101 changes: 99 additions & 2 deletions iphone/CoreApi/CoreApi/Bookmarks/MWMBookmarksManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -321,8 +321,12 @@ - (void)setCatalogCategoriesVisible:(BOOL)isVisible {
self.bm.SetAllCategoriesVisibility(isVisible);
}

- (void)deleteCategory:(MWMMarkGroupID)groupId
{

- (void)deleteCategory:(MWMMarkGroupID)groupId {
/* FIXME: - Temporary solution. Should be implemented in cpp's DeleteBmCategory */
if (!self.bm.IsCategoryEmpty(groupId))
[self moveCategoryToTrash:groupId];

self.bm.GetEditSession().DeleteBmCategory(groupId);
[self loopObservers:^(id<MWMBookmarksObserver> observer) {
if ([observer respondsToSelector:@selector(onBookmarksCategoryDeleted:)])
Expand Down Expand Up @@ -773,6 +777,99 @@ - (void)resetElevationMyPositionChanged {
self.bm.SetElevationMyPositionChangedCallback(nullptr);
}

// MARK: - RecentlyDeletedCategoriesManager
- (BOOL)areRecentlyDeletedCategoriesEmpty {
return [self getRecentlyDeletedCategories].count == 0;
}

- (NSArray<NSURL *> *)getRecentlyDeletedCategories {
NSError * error;
NSArray<NSURL *> * contents = [NSFileManager.defaultManager contentsOfDirectoryAtURL:[self bookmarksDirectoryURLBasedOn:self.trashDirectoryURL]
includingPropertiesForKeys:@[NSURLNameKey, NSURLCreationDateKey, NSURLPathKey]
options:NSDirectoryEnumerationSkipsHiddenFiles
error:&error];
return contents;
}

- (void)deleteRecentlyDeletedCategoryAtURLs:(NSArray<NSURL *> *)urls; {
NSError * error;
for (NSURL * url in urls) {
[NSFileManager.defaultManager removeItemAtURL:url error:&error];
ASSERT(!error, ([NSString stringWithFormat:@"Failed to delete file at %@", url.path]));
}
}

- (void)recoverRecentlyDeletedCategoriesAtURLs:(NSArray<NSURL *> *)urls {
NSError * error;
for (NSURL * url in urls) {
NSString * filePath = [[url URLByResolvingSymlinksInPath] path];
NSRange range = [filePath rangeOfString:[[self.trashDirectoryURL URLByResolvingSymlinksInPath] path]];
NSString * relativeFilePath = [filePath substringFromIndex:range.location + range.length];
NSURL * newFileURL = [self.documentsDirectoryURL URLByAppendingPathComponent:relativeFilePath];
[NSFileManager.defaultManager moveItemAtURL:url toURL:newFileURL error:&error];
ASSERT(!error, ([NSString stringWithFormat:@"Failed to move file from %@ to %@", filePath, newFileURL.path]));
}

// TODO: Recover for the particular files should be implemented. It's not very efficient to reload all categories.
[self loadBookmarks];
}

// MARK: - Helpers
- (NSURL *)documentsDirectoryURL {
return [NSFileManager.defaultManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].firstObject;
}

- (NSURL *)trashDirectoryURL {
NSString * trashPathComponent = @".Trash";
NSURL * trashURL = [[self documentsDirectoryURL] URLByAppendingPathComponent:trashPathComponent isDirectory:YES];
if (![NSFileManager.defaultManager fileExistsAtPath:trashURL.path]) {
NSError * error;
[NSFileManager.defaultManager createDirectoryAtURL:trashURL withIntermediateDirectories:YES attributes:nil error:&error];
ASSERT(!error, ("Failed to create './Trash' directory", error));
}
return trashURL;
}

- (NSURL *)bookmarksDirectoryURLBasedOn:(NSURL *)url {
NSString * trashPathComponent = @"bookmarks";
NSURL * bookmarksURL = [url URLByAppendingPathComponent:trashPathComponent isDirectory:YES];
if (![NSFileManager.defaultManager fileExistsAtPath:bookmarksURL.path]) {
NSError * error;
[NSFileManager.defaultManager createDirectoryAtURL:bookmarksURL withIntermediateDirectories:YES attributes:nil error:&error];
ASSERT(!error, ("Failed to create 'bookmarks' directory", error));
}
return bookmarksURL;
}

- (void)moveCategoryToTrash:(MWMMarkGroupID)groupId {
NSURL * fileURL = [NSURL fileURLWithPath: @(self.bm.GetCategoryFileName(groupId).c_str())];
NSString * filePath = [fileURL absoluteString];
NSRange range = [filePath rangeOfString:[self.documentsDirectoryURL absoluteString]];
NSString * relativeFilePath = [filePath substringFromIndex:range.location + range.length];
NSURL * trashedFileURL = [NSURL URLWithString:relativeFilePath relativeToURL:self.trashDirectoryURL];

// Resolve name conflicts
if ([NSFileManager.defaultManager fileExistsAtPath:trashedFileURL.path]) {
// TODO: NSDateFormatter shouldn't be created on every call. This only for testing purposes.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyyMMdd-HHmmss"];
NSString * dateString = [dateFormatter stringFromDate:[NSDate date]];

NSString * newTrashedFilePath = [[trashedFileURL.path stringByDeletingPathExtension] stringByAppendingFormat:@"-%@.%@", dateString, trashedFileURL.pathExtension];
trashedFileURL = [NSURL fileURLWithPath:newTrashedFilePath];
}

NSError * error;
NSString * parentDirectoryPath = [trashedFileURL.path stringByDeletingLastPathComponent];
if (![NSFileManager.defaultManager fileExistsAtPath:parentDirectoryPath]) {
[NSFileManager.defaultManager createDirectoryAtPath:parentDirectoryPath withIntermediateDirectories:YES attributes:nil error:&error];
ASSERT(!error, ("Failed to create directory at path:", parentDirectoryPath));
}

[NSFileManager.defaultManager moveItemAtPath:fileURL.path toPath:trashedFileURL.path error:&error];
ASSERT(!error, ([NSString stringWithFormat:@"Failed to move file from %@ to %@", fileURL, trashedFileURL]));
}

+ (dp::Color)getColorFromUIColor:(UIColor *)color {
CGFloat fRed, fGreen, fBlue, fAlpha;
[color getRed:&fRed green:&fGreen blue:&fBlue alpha:&fAlpha];
Expand Down
5 changes: 5 additions & 0 deletions iphone/Maps/Bookmarks/Categories/BMCModels.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ protocol BMCModel {}
enum BMCAction: BMCModel {
case create
case exportAll
case recentlyDeleted
}

extension BMCAction {
Expand All @@ -18,6 +19,8 @@ extension BMCAction {
return L("bookmarks_create_new_group")
case .exportAll:
return L("bookmarks_export")
case .recentlyDeleted:
return L("bookmarks_recently_deleted")
}
}

Expand All @@ -27,6 +30,8 @@ extension BMCAction {
return UIImage(named: "ic24PxAddCopy")!
case .exportAll:
return UIImage(named: "ic24PxShare")!
case .recentlyDeleted:
return UIImage(named: "ic_route_manager_trash")!
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,12 @@ final class BMCViewController: MWMViewController {

present(actionSheet, animated: true, completion: nil)
}

private func openRecentlyDeleted() {
let recentlyDeletedController = RecentlyDeletedCategoriesViewController()
MapViewController.topViewController().navigationController?.pushViewController(recentlyDeletedController,
animated: true)
}
}

extension BMCViewController: BMCView {
Expand Down Expand Up @@ -272,6 +278,7 @@ extension BMCViewController: UITableViewDelegate {
switch viewModel.action(at: indexPath.row) {
case .create: createNewCategory()
case .exportAll: shareAllCategories(anchor: tableView.cellForRow(at: indexPath))
case .recentlyDeleted: openRecentlyDeleted()
}
default:
assertionFailure()
Expand Down