diff --git a/Blog/BlogController.h b/Blog/BlogController.h index 95cea60..ed634cf 100644 --- a/Blog/BlogController.h +++ b/Blog/BlogController.h @@ -29,8 +29,8 @@ - (PMKPromise *)requestCreateDraft:(Post *)draft publishImmediatelyToEnvironment:(NSString *)env waitForCompilation:(BOOL)waitForCompilation; - (PMKPromise *)requestUpdatePost:(Post *)post waitForCompilation:(BOOL)waitForCompilation; -- (PMKPromise *)requestPublishDraft:(Post *)post; -- (PMKPromise *)requestUnpublishPost:(Post *)post; +- (PMKPromise *)requestPublishDraft:(Post *)draft; +- (PMKPromise *)requestUnpublishPost:(Post *)publishedPost; - (PMKPromise *)requestDeletePost:(Post *)post; - (PMKPromise *)requestSync; diff --git a/Blog/BlogController.m b/Blog/BlogController.m index bd28bfd..1c416cf 100644 --- a/Blog/BlogController.m +++ b/Blog/BlogController.m @@ -95,26 +95,26 @@ } - (PMKPromise *)requestUpdatePost:(Post *)post waitForCompilation:(BOOL)waitForCompilation { - return [_service requestUpdatePostWithPath:post.path title:post.title body:post.body link:post.url.absoluteString waitForCompilation:NO] + return [_service requestUpdatePostWithPath:post.path title:post.title body:post.body link:post.url.absoluteString waitForCompilation:waitForCompilation] .then(^{ [_store savePost:post]; return post; }); } -- (PMKPromise *)requestPublishDraft:(Post *)post { - return [_service requestPublishDraftWithPath:post.path].then(^(Post *post) { - [_store removeDraft:post]; - [_store addPublishedPost:post]; - return post; +- (PMKPromise *)requestPublishDraft:(Post *)draft { + return [_service requestPublishDraftWithPath:draft.path].then(^(Post *publishedPost) { + [_store removeDraft:draft]; + [_store addPublishedPost:publishedPost]; + return publishedPost; }); } -- (PMKPromise *)requestUnpublishPost:(Post *)post { - return [_service requestUnpublishPostWithPath:post.path].then(^(Post *post) { - [_store removePost:post]; - [_store addDraft:post]; - return post; +- (PMKPromise *)requestUnpublishPost:(Post *)publishedPost { + return [_service requestUnpublishPostWithPath:publishedPost.path].then(^(Post *draft) { + [_store removePost:publishedPost]; + [_store addDraft:draft]; + return draft; }); } diff --git a/Blog/EditorViewController.m b/Blog/EditorViewController.m index 20a11a7..61487a2 100644 --- a/Blog/EditorViewController.m +++ b/Blog/EditorViewController.m @@ -217,14 +217,12 @@ static NSString *const StateRestorationPostKey = @"post"; static NSString *const StateRestorationModifiedPostKey = @"modifiedPost"; - (void)encodeRestorableStateWithCoder:(NSCoder *)coder { - NSLog(@"%@ encode restorable state with coder %@", self, coder); [coder encodeObject:self.post forKey:StateRestorationPostKey]; [coder encodeObject:self.modifiedPost forKey:StateRestorationModifiedPostKey]; [super encodeRestorableStateWithCoder:coder]; } - (void)decodeRestorableStateWithCoder:(NSCoder *)coder { - NSLog(@"%@ decode restorable state with coder %@", self, coder); self.post = [coder decodeObjectForKey:StateRestorationPostKey]; self.modifiedPost = [coder decodeObjectForKey:StateRestorationModifiedPostKey]; [super decodeRestorableStateWithCoder:coder]; diff --git a/Blog/PostsViewController.m b/Blog/PostsViewController.m index 77c0076..515f5b6 100644 --- a/Blog/PostsViewController.m +++ b/Blog/PostsViewController.m @@ -64,6 +64,11 @@ static const NSUInteger SectionPublished = 1; [self setupTitleView]; [self setupFontAwesomeIcons]; self.refreshControl.tintColor = [UIColor whiteColor]; + [self setupNotifications]; +} + +- (void)dealloc { + [self teardownNotifications]; } - (void)setupTitleView { @@ -184,7 +189,6 @@ static const NSUInteger SectionPublished = 1; - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(postUpdated:) name:PostUpdatedNotification object:nil]; [self setupBlogStatusTimer]; [self requestStatusWithCaching:YES]; if (!self.postCollections) { @@ -197,7 +201,6 @@ static const NSUInteger SectionPublished = 1; - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:PostUpdatedNotification object:nil]; [self teardownBlogStatusTimer]; } @@ -324,10 +327,50 @@ static const NSUInteger SectionPublished = 1; [self presentViewController:alertController animated:YES completion:nil]; } +- (void)setupNotifications { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(postUpdated:) name:PostUpdatedNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(draftAdded:) name:DraftAddedNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(draftRemoved:) name:DraftRemovedNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(publishedPostAdded:) name:PublishedPostAddedNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(publishedPostRemoved:) name:PublishedPostRemovedNotification object:nil]; +} + +- (void)teardownNotifications { + [[NSNotificationCenter defaultCenter] removeObserver:self name:PostUpdatedNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:DraftAddedNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:DraftRemovedNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:PublishedPostAddedNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:PublishedPostRemovedNotification object:nil]; +} + +- (void)addPost:(Post *)post toSection:(NSUInteger)section { + PostCollection *collection = [self postCollectionForSection:section]; + NSInteger row = 0; + [collection.posts insertObject:post atIndex:row]; + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section]; + [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; +} + +- (void)removePost:(Post *)post fromSection:(NSUInteger)section { + BOOL (^isThisPost)(Post *, NSUInteger, BOOL *) = ^BOOL(Post *p, NSUInteger idx, BOOL *stop) { + return [p.path isEqualToString:post.path]; + }; + PostCollection *collection = [self postCollectionForSection:section]; + NSUInteger row = [collection.posts indexOfObjectPassingTest:isThisPost]; + if (row != NSNotFound) { + [collection.posts removeObjectAtIndex:row]; + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section]; + [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; + } + else { + NSLog(@"cannot find removed post %@", post); + } +} + - (void)postUpdated:(NSNotification *)note { Post *post = note.userInfo[PostUserInfoKey]; BOOL (^isThisPost)(Post *, NSUInteger, BOOL *) = ^BOOL(Post *p, NSUInteger idx, BOOL *stop) { - return [p.objectID isEqualToString:post.objectID]; + return [p.path isEqualToString:post.path]; }; NSUInteger section = SectionDrafts; NSUInteger row = [self.drafts indexOfObjectPassingTest:isThisPost]; @@ -341,6 +384,43 @@ static const NSUInteger SectionPublished = 1; NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section]; [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; } + else { + NSLog(@"cannot find updated post %@", post); + } +} + +- (void)draftAdded:(NSNotification *)note { + // New drafts may already be here, because we insert newly created drafts that are unsaved. + // Once saved this triggers, and we have to make sure we replace the existing one instead of + // adding a duplicate. + Post *post = note.userInfo[PostUserInfoKey]; + NSInteger row = [self.drafts indexOfObjectPassingTest:^BOOL(Post *p, NSUInteger idx, BOOL *stop) { + return [post.path isEqualToString:p.path]; + }]; + if (row == NSNotFound) + { + [self addPost:post toSection:SectionDrafts]; + } + else + { + self.drafts[row] = post; + [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:row inSection:SectionDrafts]] withRowAnimation:UITableViewRowAnimationNone]; + } +} + +- (void)draftRemoved:(NSNotification *)note { + Post *post = note.userInfo[PostUserInfoKey]; + [self removePost:post fromSection:SectionDrafts]; +} + +- (void)publishedPostAdded:(NSNotification *)note { + Post *post = note.userInfo[PostUserInfoKey]; + [self addPost:post toSection:SectionPublished]; +} + +- (void)publishedPostRemoved:(NSNotification *)note { + Post *post = note.userInfo[PostUserInfoKey]; + [self removePost:post fromSection:SectionPublished]; } #pragma mark - Segues @@ -364,14 +444,12 @@ static NSString *const StateRestorationBlogStatusDateKey = @"blogStatusDate"; static NSString *const StateRestorationBlogStatusTextKey = @"blogStatusText"; - (void)encodeRestorableStateWithCoder:(NSCoder *)coder { - NSLog(@"%@ encode restorable state with coder %@", self, coder); [coder encodeObject:self.blogStatusDate forKey:StateRestorationBlogStatusDateKey]; [coder encodeObject:self.blogStatusText forKey:StateRestorationBlogStatusTextKey]; [super encodeRestorableStateWithCoder:coder]; } - (void)decodeRestorableStateWithCoder:(NSCoder *)coder { - NSLog(@"%@ decode restorable state with coder %@", self, coder); self.blogStatusDate = [coder decodeObjectForKey:StateRestorationBlogStatusDateKey]; self.blogStatusText = [coder decodeObjectForKey:StateRestorationBlogStatusTextKey]; [super decodeRestorableStateWithCoder:coder];