mirror of
https://github.com/samsonjs/samhuri.net-ios.git
synced 2026-04-27 15:07:44 +00:00
implement creating new drafts
This commit is contained in:
parent
c702143073
commit
ea426550f3
9 changed files with 115 additions and 74 deletions
|
|
@ -103,9 +103,14 @@
|
||||||
|
|
||||||
#pragma mark - UISplitViewDelegate methods
|
#pragma mark - UISplitViewDelegate methods
|
||||||
|
|
||||||
- (BOOL)splitViewController:(UISplitViewController *)splitViewController collapseSecondaryViewController:(UIViewController *)secondaryViewController ontoPrimaryViewController:(UIViewController *)primaryViewController {
|
- (BOOL) splitViewController:(UISplitViewController *)splitViewController
|
||||||
UINavigationController *navigationController = [secondaryViewController isKindOfClass:[UINavigationController class]] ? (UINavigationController *)secondaryViewController : nil;
|
collapseSecondaryViewController:(UIViewController *)secondaryViewController
|
||||||
if ([navigationController.topViewController isKindOfClass:[EditorViewController class]] && ([(EditorViewController *)navigationController.topViewController post] == nil)) {
|
ontoPrimaryViewController:(UIViewController *)primaryViewController {
|
||||||
|
UINavigationController *navigationController = [secondaryViewController isKindOfClass:[UINavigationController class]]
|
||||||
|
? (UINavigationController *)secondaryViewController : nil;
|
||||||
|
if ([navigationController
|
||||||
|
.topViewController isKindOfClass:[EditorViewController class]] && ([(EditorViewController *)navigationController
|
||||||
|
.topViewController post] == nil)) {
|
||||||
// Return YES to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded.
|
// Return YES to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded.
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ extern NSString *BlogPostDeletedNotification;
|
||||||
@class PMKPromise;
|
@class PMKPromise;
|
||||||
@class ModelStore;
|
@class ModelStore;
|
||||||
@class BlogService;
|
@class BlogService;
|
||||||
|
@class Post;
|
||||||
|
|
||||||
@interface BlogController : NSObject
|
@interface BlogController : NSObject
|
||||||
|
|
||||||
|
|
@ -36,8 +37,8 @@ extern NSString *BlogPostDeletedNotification;
|
||||||
- (PMKPromise *)requestAllPostsWithCaching:(BOOL)useCache;
|
- (PMKPromise *)requestAllPostsWithCaching:(BOOL)useCache;
|
||||||
- (PMKPromise *)requestPostWithPath:(NSString *)path;
|
- (PMKPromise *)requestPostWithPath:(NSString *)path;
|
||||||
|
|
||||||
- (PMKPromise *)requestCreateDraftWithID:(NSString *)draftID title:(NSString *)title body:(NSString *)body link:(NSString *)link;
|
- (PMKPromise *)requestCreateDraft:(Post *)draft;
|
||||||
- (PMKPromise *)requestUpdatePostWithPath:(NSString *)path title:(NSString *)title body:(NSString *)body link:(NSString *)link;
|
- (PMKPromise *)requestUpdatePost:(Post *)post;
|
||||||
- (PMKPromise *)requestPublishDraftWithPath:(NSString *)path;
|
- (PMKPromise *)requestPublishDraftWithPath:(NSString *)path;
|
||||||
- (PMKPromise *)requestUnpublishPostWithPath:(NSString *)path;
|
- (PMKPromise *)requestUnpublishPostWithPath:(NSString *)path;
|
||||||
- (PMKPromise *)requestDeletePostWithPath:(NSString *)path;
|
- (PMKPromise *)requestDeletePostWithPath:(NSString *)path;
|
||||||
|
|
|
||||||
|
|
@ -100,24 +100,20 @@ NSString *BlogPostDeletedNotification = @"BlogPostDeletedNotification";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (PMKPromise *)requestCreateDraftWithID:(NSString *)draftID title:(NSString *)title body:(NSString *)body link:(NSString *)link {
|
- (PMKPromise *)requestCreateDraft:(Post *)draft {
|
||||||
Post *post = [[Post alloc] initWithDictionary:@{@"objectID": draftID ?: [NSNull null],
|
return [_service requestCreateDraftWithID:draft.objectID title:draft.title body:draft.body
|
||||||
@"title": title ?: [NSNull null],
|
link:draft.url.absoluteString].then(^(Post *post) {
|
||||||
@"body": body ?: [NSNull null],
|
|
||||||
@"link": link ?: [NSNull null],
|
|
||||||
@"draft": @YES,
|
|
||||||
} error:nil];
|
|
||||||
return [_service requestCreateDraftWithID:draftID title:title body:body link:link].then(^(Post *post) {
|
|
||||||
[_store addDraft:post];
|
[_store addDraft:post];
|
||||||
return post;
|
return post;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (PMKPromise *)requestUpdatePostWithPath:(NSString *)path title:(NSString *)title body:(NSString *)body link:(NSString *)link {
|
- (PMKPromise *)requestUpdatePost:(Post *)post {
|
||||||
return [_service requestUpdatePostWithPath:path title:title body:body link:link].then(^(Post *post) {
|
return [_service requestUpdatePostWithPath:post.path title:post.title body:post.body link:post.url.absoluteString]
|
||||||
[_store savePost:post];
|
.then(^(Post *post) {
|
||||||
return post;
|
[_store savePost:post];
|
||||||
});
|
return post;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (PMKPromise *)requestPublishDraftWithPath:(NSString *)path {
|
- (PMKPromise *)requestPublishDraftWithPath:(NSString *)path {
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ NSString *const BlogServiceErrorDomain = @"BlogServiceErrorDomain";
|
||||||
- (PMKPromise *)requestCreateDraftWithID:(NSString *)draftID title:(NSString *)title body:(NSString *)body link:(NSString *)link {
|
- (PMKPromise *)requestCreateDraftWithID:(NSString *)draftID title:(NSString *)title body:(NSString *)body link:(NSString *)link {
|
||||||
NSDictionary *fields = @{
|
NSDictionary *fields = @{
|
||||||
@"id" : draftID,
|
@"id" : draftID,
|
||||||
@"title" : title,
|
@"title" : title ?: [NSNull null],
|
||||||
@"body" : body,
|
@"body" : body,
|
||||||
@"link" : link ?: [NSNull null],
|
@"link" : link ?: [NSNull null],
|
||||||
};
|
};
|
||||||
|
|
@ -109,7 +109,7 @@ NSString *const BlogServiceErrorDomain = @"BlogServiceErrorDomain";
|
||||||
|
|
||||||
- (PMKPromise *)requestUpdatePostWithPath:(NSString *)path title:(NSString *)title body:(NSString *)body link:(NSString *)link {
|
- (PMKPromise *)requestUpdatePostWithPath:(NSString *)path title:(NSString *)title body:(NSString *)body link:(NSString *)link {
|
||||||
NSDictionary *fields = @{
|
NSDictionary *fields = @{
|
||||||
@"title" : title,
|
@"title" : title ?: [NSNull null],
|
||||||
@"body" : body,
|
@"body" : body,
|
||||||
@"link" : link ?: [NSNull null],
|
@"link" : link ?: [NSNull null],
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -15,5 +15,6 @@
|
||||||
|
|
||||||
@property (strong, nonatomic) BlogController *blogController;
|
@property (strong, nonatomic) BlogController *blogController;
|
||||||
@property (strong, nonatomic) Post *post;
|
@property (strong, nonatomic) Post *post;
|
||||||
|
@property (copy, nonatomic) void (^postUpdatedBlock)(Post *post);
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
CGPoint scrollOffset = CGPointZero;
|
CGPoint scrollOffset = CGPointZero;
|
||||||
if (self.post) {
|
if (self.post) {
|
||||||
// FIXME: date, status (draft, published)
|
// FIXME: date, status (draft, published)
|
||||||
title = self.post.title ?: @"Untitled";
|
title = self.post.title.length ? self.post.title : @"Untitled";
|
||||||
text = self.post.body;
|
text = self.post.body;
|
||||||
// TODO: restore scroll offset for this post ... user defaults?
|
// TODO: restore scroll offset for this post ... user defaults?
|
||||||
}
|
}
|
||||||
|
|
@ -67,20 +67,44 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (PMKPromise *)savePostBody {
|
- (PMKPromise *)savePostBody {
|
||||||
if (!self.post || !self.textView) { return [PMKPromise promiseWithValue:nil]; }
|
NSString *body = self.textView.text;
|
||||||
|
if (!self.post || !body.length) {
|
||||||
Post *newPost = [self.post copyWithBody:self.textView.text];
|
return [PMKPromise promiseWithValue:nil];
|
||||||
if (![self.post isEqual:newPost])
|
|
||||||
{
|
|
||||||
self.post = newPost;
|
|
||||||
return [self.blogController requestUpdatePostWithPath:self.post.path title:self.post.title body:self.post.body link:self.post.url.absoluteString]
|
|
||||||
.then(^(Post *post) {
|
|
||||||
NSLog(@"saved post at path %@", self.post.path);
|
|
||||||
}).catch(^(NSError *error) {
|
|
||||||
NSLog(@"Error saving post at path %@: %@ %@", self.post.path, error.localizedDescription, error.userInfo);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return [PMKPromise promiseWithValue:self.post];
|
|
||||||
|
Post *newPost = [self.post copyWithBody:body];
|
||||||
|
if ([newPost isEqual:self.post]) {
|
||||||
|
return [PMKPromise promiseWithValue:self.post];
|
||||||
|
}
|
||||||
|
|
||||||
|
self.post = newPost;
|
||||||
|
NSString *path = self.post.path;
|
||||||
|
PMKPromise *savePromise;
|
||||||
|
NSString *verb;
|
||||||
|
if (self.post.new) {
|
||||||
|
verb = @"create";
|
||||||
|
savePromise = [self.blogController requestCreateDraft:self.post];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
verb = @"update";
|
||||||
|
savePromise = [self.blogController requestUpdatePost:self.post];
|
||||||
|
}
|
||||||
|
return savePromise.then(^(Post *post) {
|
||||||
|
NSLog(@"%@ post at path %@", verb, path);
|
||||||
|
|
||||||
|
// TODO: something better than this
|
||||||
|
// update our post because "new" may have changed, which is essential to correct operation
|
||||||
|
self.post = post;
|
||||||
|
[self configureView];
|
||||||
|
if (self.postUpdatedBlock) {
|
||||||
|
self.postUpdatedBlock(self.post);
|
||||||
|
}
|
||||||
|
|
||||||
|
return post;
|
||||||
|
}).catch(^(NSError *error) {
|
||||||
|
NSLog(@"Falied to %@ post at path %@: %@ %@", verb, path, error.localizedDescription, error.userInfo);
|
||||||
|
return error;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,10 @@
|
||||||
@property (nonatomic, readonly, strong) NSURL *url;
|
@property (nonatomic, readonly, strong) NSURL *url;
|
||||||
@property (nonatomic, readonly, getter=isDraft) BOOL draft;
|
@property (nonatomic, readonly, getter=isDraft) BOOL draft;
|
||||||
@property (nonatomic, readonly, getter=isLink) BOOL link;
|
@property (nonatomic, readonly, getter=isLink) BOOL link;
|
||||||
|
@property (nonatomic, readonly, getter=isNew) BOOL new;
|
||||||
@property (nonatomic, readonly) NSString *formattedDate;
|
@property (nonatomic, readonly) NSString *formattedDate;
|
||||||
|
|
||||||
|
+ (instancetype)newDraftWithTitle:(NSString *)title body:(NSString *)body url:(NSURL *)url;
|
||||||
- (instancetype)copyWithBody:(NSString *)body;
|
- (instancetype)copyWithBody:(NSString *)body;
|
||||||
- (instancetype)copyWithTitle:(NSString *)title;
|
- (instancetype)copyWithTitle:(NSString *)title;
|
||||||
- (instancetype)copyWithURL:(NSURL *)url;
|
- (instancetype)copyWithURL:(NSURL *)url;
|
||||||
|
|
|
||||||
66
Blog/Post.m
66
Blog/Post.m
|
|
@ -41,56 +41,56 @@
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (instancetype)newDraftWithTitle:(NSString *)title body:(NSString *)body url:(NSURL *)url {
|
||||||
|
NSDictionary *fields = @{
|
||||||
|
@"new" : @(YES),
|
||||||
|
@"draft" : @(YES),
|
||||||
|
@"title" : title ?: @"",
|
||||||
|
@"body" : body ?: @"",
|
||||||
|
@"url" : url ?: [NSNull null],
|
||||||
|
};
|
||||||
|
return [[self alloc] initWithDictionary:fields error:nil];
|
||||||
|
}
|
||||||
|
|
||||||
- (id)copyWithZone:(NSZone *)zone {
|
- (id)copyWithZone:(NSZone *)zone {
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)copyWithBody:(NSString *)body {
|
- (instancetype)copyWithBody:(NSString *)body {
|
||||||
return [[Post alloc] initWithDictionary:@{@"objectID": self.objectID ?: [NSNull null],
|
return [self copyWithTitle:self.title body:body url:self.url];
|
||||||
@"slug": self.slug ?: [NSNull null],
|
|
||||||
@"author": self.author ?: [NSNull null],
|
|
||||||
@"title": self.title ?: [NSNull null],
|
|
||||||
@"date": self.date ?: [NSNull null],
|
|
||||||
@"body": body ?: [NSNull null],
|
|
||||||
@"path": self.path ?: [NSNull null],
|
|
||||||
@"url": self.url ?: [NSNull null],
|
|
||||||
@"draft": @(self.draft),
|
|
||||||
} error:nil];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)copyWithTitle:(NSString *)title {
|
- (instancetype)copyWithTitle:(NSString *)title {
|
||||||
return [[Post alloc] initWithDictionary:@{@"objectID": self.objectID ?: [NSNull null],
|
return [self copyWithTitle:title body:self.body url:self.url];
|
||||||
@"slug": self.slug ?: [NSNull null],
|
|
||||||
@"author": self.author ?: [NSNull null],
|
|
||||||
@"title": title ?: [NSNull null],
|
|
||||||
@"date": self.date ?: [NSNull null],
|
|
||||||
@"body": self.body ?: [NSNull null],
|
|
||||||
@"path": self.path ?: [NSNull null],
|
|
||||||
@"url": self.url ?: [NSNull null],
|
|
||||||
@"draft": @(self.draft),
|
|
||||||
} error:nil];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)copyWithURL:(NSURL *)url {
|
- (instancetype)copyWithURL:(NSURL *)url {
|
||||||
return [[Post alloc] initWithDictionary:@{@"objectID": self.objectID ?: [NSNull null],
|
return [self copyWithTitle:self.title body:self.body url:url];
|
||||||
@"slug": self.slug ?: [NSNull null],
|
}
|
||||||
@"author": self.author ?: [NSNull null],
|
|
||||||
@"title": self.title ?: [NSNull null],
|
- (instancetype)copyWithTitle:(NSString *)title body:(NSString *)body url:(NSURL *)url {
|
||||||
@"date": self.date ?: [NSNull null],
|
return [[Post alloc] initWithDictionary:@{
|
||||||
@"body": self.body ?: [NSNull null],
|
@"objectID" : self.objectID ?: [NSNull null],
|
||||||
@"path": self.path ?: [NSNull null],
|
@"slug" : self.slug ?: [NSNull null],
|
||||||
@"url": url ?: [NSNull null],
|
@"author" : self.author ?: [NSNull null],
|
||||||
@"draft": @(self.draft),
|
@"title" : title ?: [NSNull null],
|
||||||
} error:nil];
|
@"date" : self.date ?: [NSNull null],
|
||||||
|
@"body" : body ?: [NSNull null],
|
||||||
|
@"path" : self.path ?: [NSNull null],
|
||||||
|
@"url" : url ?: [NSNull null],
|
||||||
|
@"draft" : @(self.draft),
|
||||||
|
@"new" : @(self.new),
|
||||||
|
} error:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)isEqualToPost:(Post *)other {
|
- (BOOL)isEqualToPost:(Post *)other {
|
||||||
return [self.objectID isEqualToString:other.objectID]
|
return [self.objectID isEqualToString:other.objectID]
|
||||||
&& [self.path isEqualToString:other.path]
|
&& [self.path isEqualToString:other.path]
|
||||||
&& [self.title isEqualToString:other.title]
|
&& ((!self.title && !other.title) || [self.title isEqual:other.title])
|
||||||
&& [self.body isEqualToString:other.body]
|
&& ((!self.body && !other.body) || [self.body isEqual:other.body])
|
||||||
&& self.draft == other.draft
|
&& self.draft == other.draft
|
||||||
&& ((!self.url && !other.url) || [self.url isEqual:other.url]);
|
&& ((!self.url && !other.url) || [self.url isEqual:other.url]);
|
||||||
|
// include "new" here too?
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)isEqual:(id)object {
|
- (BOOL)isEqual:(id)object {
|
||||||
|
|
@ -154,7 +154,7 @@
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
NSAssert(self.slug && self.date, @"slug and date are required");
|
NSAssert(self.slug && self.date, @"slug and date are required");
|
||||||
NSString *paddedMonth = [self paddedMonthForDate:self.date];
|
NSString *paddedMonth = [self paddedMonthForDate:self.time];
|
||||||
_path = [NSString stringWithFormat:@"/posts/%ld/%@/%@", (long)self.time.mm_year, paddedMonth, self.slug];
|
_path = [NSString stringWithFormat:@"/posts/%ld/%@/%@", (long)self.time.mm_year, paddedMonth, self.slug];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@
|
||||||
@interface PostsViewController ()
|
@interface PostsViewController ()
|
||||||
|
|
||||||
@property (strong, nonatomic) NSMutableArray *posts;
|
@property (strong, nonatomic) NSMutableArray *posts;
|
||||||
@property (strong, nonatomic) EditorViewController *editorViewController;
|
|
||||||
@property (strong, nonatomic) IBOutlet UIBarButtonItem *publishButton;
|
@property (strong, nonatomic) IBOutlet UIBarButtonItem *publishButton;
|
||||||
@property (strong, nonatomic) IBOutlet UIBarButtonItem *addButton;
|
@property (strong, nonatomic) IBOutlet UIBarButtonItem *addButton;
|
||||||
@property (weak, nonatomic) UILabel *titleLabel;
|
@property (weak, nonatomic) UILabel *titleLabel;
|
||||||
|
|
@ -72,8 +71,8 @@
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
self.blogStatusTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(updateBlogStatus) userInfo:nil repeats:YES];
|
|
||||||
- (void)setupBlogStatusTimer {
|
- (void)setupBlogStatusTimer {
|
||||||
|
self.blogStatusTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(updateBlogStatus) userInfo:nil repeats:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)teardownBlogStatusTimer {
|
- (void)teardownBlogStatusTimer {
|
||||||
|
|
@ -84,7 +83,6 @@
|
||||||
- (void)viewDidLoad {
|
- (void)viewDidLoad {
|
||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
UINavigationController *detailNavController = self.splitViewController.viewControllers.lastObject;
|
UINavigationController *detailNavController = self.splitViewController.viewControllers.lastObject;
|
||||||
self.editorViewController = (EditorViewController *)detailNavController.topViewController;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateStatusLabel:(NSString *)blogStatus {
|
- (void)updateStatusLabel:(NSString *)blogStatus {
|
||||||
|
|
@ -98,8 +96,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateBlogStatus {
|
- (void)updateBlogStatus {
|
||||||
[self updateStatusLabel:[NSString stringWithFormat:@"%@ as of %@", self.blogStatusText,
|
[self updateStatusLabel:[NSString stringWithFormat:@"%@ as of %@", self.blogStatusText, [self.blogStatusDate mm_relativeToNow]]];
|
||||||
[self.blogStatusDate mm_relativeToNow]]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewWillAppear:(BOOL)animated {
|
- (void)viewWillAppear:(BOOL)animated {
|
||||||
|
|
@ -161,10 +158,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)insertNewObject:(id)sender {
|
- (IBAction)insertNewObject:(id)sender {
|
||||||
Post *post = [[Post alloc] initWithDictionary:@{@"draft": @(YES)} error:nil];
|
NSString *title = [UIPasteboard generalPasteboard].string;
|
||||||
|
NSURL *url = [UIPasteboard generalPasteboard].URL;
|
||||||
|
// TODO: image, anything else interesting
|
||||||
|
Post *post = [Post newDraftWithTitle:title body:nil url:url];
|
||||||
[self.posts insertObject:post atIndex:0];
|
[self.posts insertObject:post atIndex:0];
|
||||||
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
|
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
|
||||||
[self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
|
[self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||||
|
[self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionTop];
|
||||||
|
[self performSegueWithIdentifier:@"showDetail" sender:sender];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)publish:(id)sender {
|
- (IBAction)publish:(id)sender {
|
||||||
|
|
@ -182,6 +184,16 @@
|
||||||
[controller setPost:post];
|
[controller setPost:post];
|
||||||
controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
|
controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
|
||||||
controller.navigationItem.leftItemsSupplementBackButton = YES;
|
controller.navigationItem.leftItemsSupplementBackButton = YES;
|
||||||
|
controller.postUpdatedBlock = ^(Post *post) {
|
||||||
|
NSUInteger row = [self.posts indexOfObjectPassingTest:^BOOL(Post *p, NSUInteger idx, BOOL *stop) {
|
||||||
|
return [p.objectID isEqualToString:post.objectID];
|
||||||
|
}];
|
||||||
|
if (row != NSNotFound) {
|
||||||
|
[self.posts replaceObjectAtIndex:row withObject:post];
|
||||||
|
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
|
||||||
|
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -200,7 +212,7 @@
|
||||||
|
|
||||||
Post *post = self.posts[indexPath.row];
|
Post *post = self.posts[indexPath.row];
|
||||||
// FIXME: unique title
|
// FIXME: unique title
|
||||||
NSString *title = post.title ?: @"Untitled";
|
NSString *title = post.title.length ? post.title : @"Untitled";
|
||||||
NSString *date = post.draft ? @"Draft" : post.formattedDate;
|
NSString *date = post.draft ? @"Draft" : post.formattedDate;
|
||||||
[cell configureWithTitle:title date:date];
|
[cell configureWithTitle:title date:date];
|
||||||
return cell;
|
return cell;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue