From 1b118959fdafedbcffbb2e19d9d1174c7432e104 Mon Sep 17 00:00:00 2001 From: relikd Date: Sun, 19 Aug 2018 14:40:45 +0200 Subject: [PATCH] Bugfix: unread count needs sorted children! + ManagedContext fix --- baRSS/Preferences/FeedConfig+Ext.m | 2 +- baRSS/Preferences/Feeds Tab/ModalFeedEdit.m | 18 ++++++++++----- baRSS/Preferences/Feeds Tab/SettingsFeeds.m | 15 +++++++------ baRSS/Status Bar Menu/BarMenu.m | 25 ++++++++++----------- baRSS/StoreCoordinator.m | 9 ++++---- 5 files changed, 37 insertions(+), 32 deletions(-) diff --git a/baRSS/Preferences/FeedConfig+Ext.m b/baRSS/Preferences/FeedConfig+Ext.m index 69f93da..4cdaca6 100644 --- a/baRSS/Preferences/FeedConfig+Ext.m +++ b/baRSS/Preferences/FeedConfig+Ext.m @@ -48,7 +48,7 @@ */ - (BOOL)descendantFeedItems:(FeedConfigRecursiveItemsBlock)block { if (self.children.count > 0) { - for (FeedConfig *config in self.children) { + for (FeedConfig *config in self.sortedChildren) { if ([config descendantFeedItems:block] == NO) return NO; } diff --git a/baRSS/Preferences/Feeds Tab/ModalFeedEdit.m b/baRSS/Preferences/Feeds Tab/ModalFeedEdit.m index 99add36..19b5f7d 100644 --- a/baRSS/Preferences/Feeds Tab/ModalFeedEdit.m +++ b/baRSS/Preferences/Feeds Tab/ModalFeedEdit.m @@ -105,14 +105,18 @@ item.refreshUnit = (int16_t)self.refreshUnit.indexOfSelectedItem; if (self.feedResult) { - Feed *rss = [StoreCoordinator createFeedFromDictionary:self.feedResult inContext:item.managedObjectContext]; - if (item.feed) - [item.managedObjectContext deleteObject:(NSManagedObject*)item.feed]; - item.feed = rss; + [item.managedObjectContext performBlockAndWait:^{ + Feed *rss = [StoreCoordinator createFeedFromDictionary:self.feedResult inContext:item.managedObjectContext]; + if (item.feed) + [item.managedObjectContext deleteObject:(NSManagedObject*)item.feed]; + item.feed = rss; + }]; } if ([item.managedObjectContext hasChanges]) { self.objectIsModified = YES; - [item.managedObjectContext refreshObject:item mergeChanges:YES]; + [item.managedObjectContext performBlockAndWait:^{ + [item.managedObjectContext refreshObject:item mergeChanges:YES]; + }]; } } @@ -202,7 +206,9 @@ NSString *name = ((NSTextField*)self.view).stringValue; if (![item.name isEqualToString: name]) { item.name = name; - [item.managedObjectContext refreshObject:item mergeChanges:YES]; + [item.managedObjectContext performBlockAndWait:^{ + [item.managedObjectContext refreshObject:item mergeChanges:YES]; + }]; [self.delegate modalDidUpdateFeedConfig:item]; } } diff --git a/baRSS/Preferences/Feeds Tab/SettingsFeeds.m b/baRSS/Preferences/Feeds Tab/SettingsFeeds.m index 34138c4..6d2aded 100644 --- a/baRSS/Preferences/Feeds Tab/SettingsFeeds.m +++ b/baRSS/Preferences/Feeds Tab/SettingsFeeds.m @@ -59,14 +59,15 @@ static NSString *dragNodeType = @"baRSS-feed-drag"; self.undoManager = self.dataStore.managedObjectContext.undoManager; } -- (void)dealloc { - [self saveAndRebuildMenu]; -} - - (void)saveAndRebuildMenu { - [StoreCoordinator saveContext:self.dataStore.managedObjectContext]; - [StoreCoordinator saveContext:self.dataStore.managedObjectContext.parentContext]; - [[(AppHook*)NSApp barMenu] rebuildMenu]; // updating individual items was way to complicated ... + [self.dataStore.managedObjectContext performBlock:^{ + [StoreCoordinator saveContext:self.dataStore.managedObjectContext]; + [[(AppHook*)NSApp barMenu] rebuildMenu]; // updating individual items was way to complicated ... + [self.dataStore.managedObjectContext.parentContext performBlock:^{ + [StoreCoordinator saveContext:self.dataStore.managedObjectContext.parentContext]; + }]; + + }]; } - (IBAction)addFeed:(id)sender { diff --git a/baRSS/Status Bar Menu/BarMenu.m b/baRSS/Status Bar Menu/BarMenu.m index 3c3ed7f..93ca250 100644 --- a/baRSS/Status Bar Menu/BarMenu.m +++ b/baRSS/Status Bar Menu/BarMenu.m @@ -31,13 +31,11 @@ /// @c NSMenuItem options that are assigned to the @c tag attribute. typedef NS_OPTIONS(NSInteger, MenuItemTag) { /// Item visible at the very first menu level - ScopeGlobal = 1, + ScopeGlobal = 2, /// Item visible at each grouping, e.g., multiple feeds in one group - ScopeGroup = 2, + ScopeGroup = 4, /// Item visible at the deepest menu level (@c FeedItem elements and header) - ScopeLocal = 4, - /// @c NSMenuItem is an alternative - ScopeAlternative = 8, + ScopeLocal = 8, /// TagPreferences = (1 << 4), TagPauseUpdates = (2 << 4), @@ -79,12 +77,12 @@ typedef NS_OPTIONS(NSInteger, MenuItemTag) { - (void)printUnreadRecurisve:(NSMenu*)menu str:(NSString*)prefix { for (NSMenuItem *item in menu.itemArray) { - if (!item.hasUnread) continue; MenuItemInfo *info = item.representedObject; + if (!info) continue; id obj = [StoreCoordinator objectWithID:info.objID]; - if ([obj isKindOfClass:[FeedItem class]]) + if ([obj isKindOfClass:[FeedItem class]] && ([obj unread] > 0 || item.unreadCount > 0)) NSLog(@"%@ %@ (%d == %d)", prefix, item.title, item.unreadCount, [obj unread]); - else + else if (item.hasUnread) NSLog(@"%@ %@ (%d)", prefix, item.title, item.unreadCount); if (item.hasSubmenu) { [self printUnreadRecurisve:item.submenu str:[NSString stringWithFormat:@" %@", prefix]]; @@ -242,10 +240,11 @@ typedef NS_OPTIONS(NSInteger, MenuItemTag) { [self addTitle:NSLocalizedString(@"Mark all unread", nil) selector:@selector(markAllUnread:) toMenu:menu tag:TagMarkAllUnread | scope]; [self addTitle:NSLocalizedString(@"Open all unread", nil) selector:@selector(openAllUnread:) toMenu:menu tag:TagOpenAllUnread | scope]; - NSString *alternateTitle = [NSString stringWithFormat:NSLocalizedString(@"Open a few unread (%d)", nil), 3]; - [self addTitle:alternateTitle selector:@selector(openAllUnread:) toMenu:menu tag:TagOpenAllUnread | scope | ScopeAlternative]; - menu.itemArray.lastObject.alternate = YES; - menu.itemArray.lastObject.keyEquivalentModifierMask = NSEventModifierFlagOption; + NSMenuItem *openSomeUrls = [menu.itemArray.lastObject copy]; + openSomeUrls.title = [NSString stringWithFormat:NSLocalizedString(@"Open a few unread (%d)", nil), 3]; + openSomeUrls.alternate = YES; + openSomeUrls.keyEquivalentModifierMask = NSEventModifierFlagOption; + [menu addItem:openSomeUrls]; [menu addItem:[NSMenuItem separatorItem]]; return menu; @@ -281,7 +280,7 @@ typedef NS_OPTIONS(NSInteger, MenuItemTag) { NSLocalizedString(@"Preferences", nil)]; // one time token to set reference to nil, which will release window NSNotificationCenter * __weak center = [NSNotificationCenter defaultCenter]; - id __block token = [center addObserverForName:NSWindowWillCloseNotification object:self.prefWindow.window queue:nil usingBlock:^(NSNotification *note) { + __block id token = [center addObserverForName:NSWindowWillCloseNotification object:self.prefWindow.window queue:nil usingBlock:^(NSNotification *note) { self.prefWindow = nil; [center removeObserver:token]; }]; diff --git a/baRSS/StoreCoordinator.m b/baRSS/StoreCoordinator.m index 21a8f7e..c5b3b4f 100644 --- a/baRSS/StoreCoordinator.m +++ b/baRSS/StoreCoordinator.m @@ -66,9 +66,8 @@ return [[self getContext] objectWithID:objID]; } -+ (Feed*)createFeedFromDictionary:(NSDictionary*)obj inContext:(NSManagedObjectContext*)moc { -// NSManagedObjectContext *moc = [self getContext]; - Feed *a = [[Feed alloc] initWithEntity:Feed.entity insertIntoManagedObjectContext:moc]; ++ (Feed*)createFeedFromDictionary:(NSDictionary*)obj inContext:(NSManagedObjectContext*)context { + Feed *a = [[Feed alloc] initWithEntity:Feed.entity insertIntoManagedObjectContext:context]; a.title = obj[@"feed"][@"title"]; a.subtitle = obj[@"feed"][@"subtitle"]; a.author = obj[@"feed"][@"author"]; @@ -79,7 +78,7 @@ a.date = obj[@"header"][@"date"]; a.modified = obj[@"header"][@"modified"]; for (NSDictionary *entry in obj[@"entries"]) { - FeedItem *b = [[FeedItem alloc] initWithEntity:FeedItem.entity insertIntoManagedObjectContext:moc]; + FeedItem *b = [[FeedItem alloc] initWithEntity:FeedItem.entity insertIntoManagedObjectContext:context]; b.title = entry[@"title"]; b.subtitle = entry[@"subtitle"]; b.author = entry[@"author"]; @@ -87,7 +86,7 @@ b.published = entry[@"published"]; b.summary = entry[@"summary"]; for (NSString *tag in entry[@"tags"]) { - FeedTag *c = [[FeedTag alloc] initWithEntity:FeedTag.entity insertIntoManagedObjectContext:moc]; + FeedTag *c = [[FeedTag alloc] initWithEntity:FeedTag.entity insertIntoManagedObjectContext:context]; c.name = tag; [b addTagsObject:c]; }