Rework progress mode of export backup UI.
This commit is contained in:
parent
980b3d25a7
commit
857ca56ab6
@ -4,6 +4,7 @@
|
||||
|
||||
#import "OWSBackupViewController.h"
|
||||
#import "OWSBackup.h"
|
||||
#import "OWSProgressView.h"
|
||||
#import "Signal-Swift.h"
|
||||
#import "ThreadUtil.h"
|
||||
#import <SignalMessaging/AttachmentSharing.h>
|
||||
@ -20,6 +21,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@property (nonatomic) OWSBackup *backup;
|
||||
|
||||
@property (nonatomic, nullable) OWSProgressView *progressView;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
@ -58,6 +61,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
for (UIView *subview in self.view.subviews) {
|
||||
[subview removeFromSuperview];
|
||||
}
|
||||
self.progressView = nil;
|
||||
|
||||
switch (self.backup.backupState) {
|
||||
case OWSBackupState_InProgress:
|
||||
@ -69,32 +73,37 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
case OWSBackupState_Complete:
|
||||
[self showCompleteUI];
|
||||
break;
|
||||
case OWSBackupState_Failed:
|
||||
[self showFailedUI];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)showInProgressUI
|
||||
{
|
||||
|
||||
UIView *container = [UIView new];
|
||||
[self.view addSubview:container];
|
||||
[container autoCenterInSuperview];
|
||||
|
||||
UIActivityIndicatorView *activityIndicatorView =
|
||||
[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
||||
[container addSubview:activityIndicatorView];
|
||||
[activityIndicatorView autoPinEdgeToSuperviewEdge:ALEdgeTop];
|
||||
[activityIndicatorView autoHCenterInSuperview];
|
||||
[activityIndicatorView startAnimating];
|
||||
self.progressView = [OWSProgressView new];
|
||||
self.progressView.color = [UIColor ows_materialBlueColor];
|
||||
self.progressView.progress = self.backup.backupProgress;
|
||||
[self.progressView autoSetDimension:ALDimensionWidth toSize:300];
|
||||
[self.progressView autoSetDimension:ALDimensionHeight toSize:20];
|
||||
|
||||
UILabel *label = [UILabel new];
|
||||
label.text = NSLocalizedString(
|
||||
@"BACKUP_EXPORT_IN_PROGRESS_MESSAGE", @"Message indicating that backup export is in progress.");
|
||||
label.textColor = [UIColor blackColor];
|
||||
label.font = [UIFont ows_regularFontWithSize:18.f];
|
||||
[container addSubview:label];
|
||||
[label autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:activityIndicatorView withOffset:20.f];
|
||||
[label autoPinEdgeToSuperviewEdge:ALEdgeBottom];
|
||||
[label autoPinWidthToSuperview];
|
||||
label.textAlignment = NSTextAlignmentCenter;
|
||||
label.numberOfLines = 0;
|
||||
label.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
|
||||
UIView *container = [UIView verticalStackWithSubviews:@[
|
||||
label,
|
||||
self.progressView,
|
||||
]
|
||||
spacing:10];
|
||||
[self.view addSubview:container];
|
||||
[container autoVCenterInSuperview];
|
||||
[container autoPinWidthToSuperviewWithMargin:25.f];
|
||||
}
|
||||
|
||||
- (void)showCancelledUI
|
||||
@ -108,7 +117,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
{
|
||||
NSString *message = NSLocalizedString(
|
||||
@"BACKUP_EXPORT_COMPLETE_MESSAGE", @"Message indicating that backup export without password is complete.");
|
||||
@"BACKUP_EXPORT_COMPLETE_MESSAGE", @"Message indicating that backup export is complete.");
|
||||
|
||||
UILabel *label = [UILabel new];
|
||||
label.text = message;
|
||||
@ -122,8 +131,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
if (self.backup.backupPassword) {
|
||||
NSString *message = [NSString stringWithFormat:NSLocalizedString(@"BACKUP_EXPORT_PASSWORD_MESSAGE_FORMAT",
|
||||
@"Format for message indicating that backup export with "
|
||||
@"password is complete. Embeds: {{the backup password}}."),
|
||||
@"Format for message indicating that backup export "
|
||||
@"is complete. Embeds: {{the backup password}}."),
|
||||
self.backup.backupPassword];
|
||||
|
||||
UILabel *label = [UILabel new];
|
||||
@ -164,6 +173,32 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
[container autoPinWidthToSuperviewWithMargin:25.f];
|
||||
}
|
||||
|
||||
- (void)showFailedUI
|
||||
{
|
||||
NSMutableArray<UIView *> *subviews = [NSMutableArray new];
|
||||
|
||||
{
|
||||
NSString *message
|
||||
= NSLocalizedString(@"BACKUP_EXPORT_FAILED_MESSAGE", @"Message indicating that backup export failed.");
|
||||
|
||||
UILabel *label = [UILabel new];
|
||||
label.text = message;
|
||||
label.textColor = [UIColor blackColor];
|
||||
label.font = [UIFont ows_regularFontWithSize:18.f];
|
||||
label.textAlignment = NSTextAlignmentCenter;
|
||||
label.numberOfLines = 0;
|
||||
label.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
[subviews addObject:label];
|
||||
}
|
||||
|
||||
// TODO: We should offer the option to save the backup to "Files", iCloud, Dropbox, etc.
|
||||
|
||||
UIView *container = [UIView verticalStackWithSubviews:subviews spacing:10];
|
||||
[self.view addSubview:container];
|
||||
[container autoVCenterInSuperview];
|
||||
[container autoPinWidthToSuperviewWithMargin:25.f];
|
||||
}
|
||||
|
||||
- (UIView *)makeButtonWithTitle:(NSString *)title selector:(SEL)selector
|
||||
{
|
||||
const CGFloat kButtonHeight = 40;
|
||||
@ -264,6 +299,14 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
[self updateUI];
|
||||
}
|
||||
|
||||
|
||||
- (void)backupProgressDidChange
|
||||
{
|
||||
DDLogInfo(@"%@ %s.", self.logTag, __PRETTY_FUNCTION__);
|
||||
|
||||
self.progressView.progress = self.backup.backupProgress;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@ -8,6 +8,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
- (void)backupStateDidChange;
|
||||
|
||||
- (void)backupProgressDidChange;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
@ -16,6 +18,7 @@ typedef NS_ENUM(NSUInteger, OWSBackupState) {
|
||||
OWSBackupState_InProgress,
|
||||
OWSBackupState_Cancelled,
|
||||
OWSBackupState_Complete,
|
||||
OWSBackupState_Failed,
|
||||
};
|
||||
|
||||
@class TSThread;
|
||||
@ -24,7 +27,9 @@ typedef NS_ENUM(NSUInteger, OWSBackupState) {
|
||||
|
||||
@property (nonatomic, weak) id<OWSBackupDelegate> delegate;
|
||||
|
||||
@property (nonatomic) OWSBackupState backupState;
|
||||
@property (nonatomic, readonly) OWSBackupState backupState;
|
||||
|
||||
@property (nonatomic, readonly) CGFloat backupProgress;
|
||||
|
||||
// If non-nil, backup is encrypted.
|
||||
@property (nonatomic, nullable, readonly) NSString *backupPassword;
|
||||
|
||||
@ -23,6 +23,10 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OWSBackup ()
|
||||
|
||||
@property (nonatomic) OWSBackupState backupState;
|
||||
|
||||
@property (nonatomic) CGFloat backupProgress;
|
||||
|
||||
@property (nonatomic, nullable) TSThread *currentThread;
|
||||
|
||||
@property (nonatomic, nullable) NSString *backupPassword;
|
||||
@ -51,14 +55,21 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
[self.delegate backupStateDidChange];
|
||||
}
|
||||
|
||||
- (void)fail
|
||||
{
|
||||
if (!self.isCancelledOrFailed) {
|
||||
self.backupState = OWSBackupState_Failed;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)cancel
|
||||
{
|
||||
self.backupState = OWSBackupState_Cancelled;
|
||||
}
|
||||
|
||||
- (BOOL)isCancelled
|
||||
- (BOOL)isCancelledOrFailed
|
||||
{
|
||||
return self.backupState == OWSBackupState_Cancelled;
|
||||
return (self.backupState == OWSBackupState_Cancelled || self.backupState == OWSBackupState_Failed);
|
||||
}
|
||||
|
||||
- (void)exportBackup:(nullable TSThread *)currentThread skipPassword:(BOOL)skipPassword
|
||||
@ -90,7 +101,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
[self exportToFilesAndZip];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (!self.isCancelled) {
|
||||
if (!self.isCancelledOrFailed) {
|
||||
self.backupState = OWSBackupState_Complete;
|
||||
}
|
||||
[self.delegate backupStateDidChange];
|
||||
@ -125,32 +136,35 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
[OWSFileSystem protectFolderAtPath:rootDirPath];
|
||||
[OWSFileSystem ensureDirectoryExists:backupDirPath];
|
||||
|
||||
if (self.isCancelled) {
|
||||
if (self.isCancelledOrFailed) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSData *databasePassword = [TSStorageManager sharedManager].databasePassword;
|
||||
|
||||
if (![self writeData:databasePassword fileName:@"databasePassword" backupDirPath:backupDirPath]) {
|
||||
[self fail];
|
||||
return;
|
||||
}
|
||||
if (self.isCancelled) {
|
||||
if (self.isCancelledOrFailed) {
|
||||
return;
|
||||
}
|
||||
if (![self writeUserDefaults:NSUserDefaults.standardUserDefaults
|
||||
fileName:@"standardUserDefaults"
|
||||
backupDirPath:backupDirPath]) {
|
||||
[self fail];
|
||||
return;
|
||||
}
|
||||
if (self.isCancelled) {
|
||||
if (self.isCancelledOrFailed) {
|
||||
return;
|
||||
}
|
||||
if (![self writeUserDefaults:NSUserDefaults.appUserDefaults
|
||||
fileName:@"appUserDefaults"
|
||||
backupDirPath:backupDirPath]) {
|
||||
[self fail];
|
||||
return;
|
||||
}
|
||||
if (self.isCancelled) {
|
||||
if (self.isCancelledOrFailed) {
|
||||
return;
|
||||
}
|
||||
// Use a read/write transaction to acquire a file lock on the database files.
|
||||
@ -161,21 +175,24 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
if (![self copyDirectory:OWSFileSystem.appDocumentDirectoryPath
|
||||
dstDirName:@"appDocumentDirectoryPath"
|
||||
backupDirPath:backupDirPath]) {
|
||||
[self fail];
|
||||
return;
|
||||
}
|
||||
if (self.isCancelled) {
|
||||
if (self.isCancelledOrFailed) {
|
||||
return;
|
||||
}
|
||||
if (![self copyDirectory:OWSFileSystem.appSharedDataDirectoryPath
|
||||
dstDirName:@"appSharedDataDirectoryPath"
|
||||
backupDirPath:backupDirPath]) {
|
||||
[self fail];
|
||||
return;
|
||||
}
|
||||
}];
|
||||
if (self.isCancelled) {
|
||||
if (self.isCancelledOrFailed) {
|
||||
return;
|
||||
}
|
||||
if (![self zipDirectory:backupDirPath dstFilePath:backupZipPath]) {
|
||||
[self fail];
|
||||
return;
|
||||
}
|
||||
|
||||
@ -281,7 +298,10 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
entryNumber,
|
||||
total,
|
||||
entryNumber / (CGFloat)total);
|
||||
// TODO:
|
||||
|
||||
CGFloat progress = entryNumber / (CGFloat)total;
|
||||
self.backupProgress = progress;
|
||||
[self.delegate backupProgressDidChange];
|
||||
}];
|
||||
|
||||
if (!success) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user