diff --git a/Vienna Tests/ArticleTests.m b/Vienna Tests/ArticleTests.m new file mode 100644 index 0000000000..b16224966d --- /dev/null +++ b/Vienna Tests/ArticleTests.m @@ -0,0 +1,51 @@ +// +// VNAArticleTests.m +// Vienna +// +// Copyright © 2016 uk.co.opencommunity. All rights reserved. +// + +@import XCTest; + +#import "Article.h" +#import "Vienna_Tests-Swift.h" + +static NSString * const guid = @"07f446d2-8d6b-4d99-b488-cebc9eac7c33"; + +@interface VNAArticleTests : XCTestCase + +@property (nonatomic) Article *article; + +@end + +@implementation VNAArticleTests + +- (void)setUp +{ + self.article = [[Article alloc] initWithGUID:guid]; +} + +- (void)tearDown +{ + self.article = nil; +} + +- (void)testRandomCompatibilityKeyPath +{ + NSString *randomArticleDataKeyPath = [@"articleData." stringByAppendingString:@"dummyProperty"]; + + XCTAssertThrowsSpecificNamed([self.article valueForKeyPath:randomArticleDataKeyPath], + NSException, + NSUndefinedKeyException); +} + +- (void)testRandomKeyPath +{ + NSString *randomKeyPath = @"dummyProperty"; + + XCTAssertThrowsSpecificNamed([self.article valueForKeyPath:randomKeyPath], + NSException, + NSUndefinedKeyException); +} + +@end diff --git a/Vienna Tests/ArticleTests.swift b/Vienna Tests/ArticleTests.swift index a2d3ca6bcf..2c3568bd7d 100644 --- a/Vienna Tests/ArticleTests.swift +++ b/Vienna Tests/ArticleTests.swift @@ -42,20 +42,16 @@ class ArticleTests: XCTestCase { var article: Article! var articleConverter: WebKitArticleConverter! - override func setUpWithError() throws { - try super.setUpWithError() - // Put setup code here. This method is called before the invocation of each test method in the class. + override func setUp() { self.article = Article(guid: guid) self.articleConverter = WebKitArticleConverter() } - override func tearDownWithError() throws { - // Put teardown code here. This method is called after the invocation of each test method in the class. + override func tearDown() { self.article = nil - try super.tearDownWithError() } - // MARK: Article Tests + // MARK: - Article Tests func testAccessInstanceVariablesDirectly() { XCTAssertFalse(Article.accessInstanceVariablesDirectly) @@ -64,24 +60,32 @@ class ArticleTests: XCTestCase { // MARK: - Test custom setters func testTitle() { + XCTAssertNil(self.article.title) + self.article.title = title XCTAssertEqual(self.article.title, title) } func testAuthor() { + XCTAssertNil(self.article.author) + self.article.author = author XCTAssertEqual(self.article.author, author) } func testLink() { + XCTAssertNil(self.article.link) + self.article.link = link XCTAssertEqual(self.article.link, link) } func testLastUpdate() { + XCTAssertNil(self.article.lastUpdate) + let date = Date() self.article.lastUpdate = date @@ -90,6 +94,8 @@ class ArticleTests: XCTestCase { } func testPublicationDate() { + XCTAssertNil(self.article.publicationDate) + let date = Date() self.article.publicationDate = date @@ -98,30 +104,35 @@ class ArticleTests: XCTestCase { } func testBody() { + XCTAssertNil(self.article.body) + self.article.body = body XCTAssertEqual(self.article.body, body) } func testEnclosure() { + XCTAssertNil(self.article.enclosure) + self.article.enclosure = enclosure XCTAssertEqual(self.article.enclosure, enclosure) - } - func testEnclosureRemoval() { self.article.enclosure = nil - XCTAssertNil(self.article.enclosure) } func testHasEnclosure() { + XCTAssertFalse(self.article.hasEnclosure) + self.article.hasEnclosure = true XCTAssert(self.article.hasEnclosure) } func testFolderId() { + XCTAssertEqual(self.article.folderId, -1) + let folderId = 111 self.article.folderId = folderId @@ -130,12 +141,13 @@ class ArticleTests: XCTestCase { } func testGuid() { - self.article.guid = guid - + // The GUID is set by the initializer. XCTAssertEqual(self.article.guid, guid) } func testParentId() { + XCTAssertEqual(self.article.parentId, 0) + let parentId = 222 self.article.parentId = parentId @@ -144,7 +156,9 @@ class ArticleTests: XCTestCase { } func testStatus() { - let status = ArticleStatus.new.rawValue + XCTAssertEqual(self.article.status, .empty) + + let status = Article.Status.new self.article.status = status @@ -154,7 +168,7 @@ class ArticleTests: XCTestCase { func testMarkRead() { XCTAssertFalse(self.article.isRead) - self.article.markRead(true) + self.article.isRead = true XCTAssert(self.article.isRead) } @@ -162,7 +176,7 @@ class ArticleTests: XCTestCase { func testMarkRevised() { XCTAssertFalse(self.article.isRevised) - self.article.markRevised(true) + self.article.isRevised = true XCTAssert(self.article.isRevised) } @@ -170,7 +184,7 @@ class ArticleTests: XCTestCase { func testMarkDeleted() { XCTAssertFalse(self.article.isDeleted) - self.article.markDeleted(true) + self.article.isDeleted = true XCTAssert(self.article.isDeleted) } @@ -178,7 +192,7 @@ class ArticleTests: XCTestCase { func testMarkFlagged() { XCTAssertFalse(self.article.isFlagged) - self.article.markFlagged(true) + self.article.isFlagged = true XCTAssert(self.article.isFlagged) } @@ -186,7 +200,7 @@ class ArticleTests: XCTestCase { func testMarkEnclosureDowloaded() { XCTAssertFalse(self.article.enclosureDownloaded) - self.article.markEnclosureDownloaded(true) + self.article.enclosureDownloaded = true XCTAssert(self.article.enclosureDownloaded) } @@ -235,18 +249,6 @@ class ArticleTests: XCTestCase { XCTAssertEqual(self.article.value(forKeyPath: summaryKeyPath) as? String, summary) } -// func testRandomCompatibilityKeyPath() { -// let randomArticleDataKeyPath = "articleData.dummyProperty" -// -// XCTAssertThrowsSpecificNamed(self.article.value(forKeyPath: randomArticleDataKeyPath), NSException, NSUndefinedKeyException); -// } - -// func testRandomKeyPath() { -// let randomKeyPath = "dummyProperty" -// -// XCTAssertThrowsSpecificNamed(self.article.value(forKeyPath: randomKeyPath), NSException, NSUndefinedKeyException); -// } - func testDescription() { let title = "Lorem ipsum dolor sit amet" diff --git a/Vienna Tests/VNAArticleTests.m b/Vienna Tests/VNAArticleTests.m deleted file mode 100644 index bc2784b480..0000000000 --- a/Vienna Tests/VNAArticleTests.m +++ /dev/null @@ -1,366 +0,0 @@ -// -// VNAArticleTests.m -// Vienna -// -// Copyright © 2016 uk.co.opencommunity. All rights reserved. -// - -@import XCTest; - -#import "Article.h" -#import "ArticleConverter.h" -#import "Vienna_Tests-Swift.h" - -static NSString * const GUID = @"07f446d2-8d6b-4d99-b488-cebc9eac7c33"; -static NSString * const Author = @"Author McAuthorface"; -static NSString * const Title = @"Lorem ipsum dolor sit amet"; -static NSString * const Link = @"http://www.vienna-rss.com"; -static NSString * const Enclosure = @"http://vienna-rss.sourceforge.net/img/vienna_logo.png"; -static NSString * const EnclosureFilename = @"vienna_logo.png"; // last path component of Enclosure -static NSString * const Body = - @"

Pellentesque habitant morbi tristique senectus et netus " - "et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, " - "ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper." - "Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet " - "est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo " - "vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, " - "eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. " - "Donec non enim in turpis pulvinar facilisis. Ut felis.

"; - - -@interface VNAArticleTests : XCTestCase - -@property (nonatomic, strong) Article *article; -@property (nonatomic, strong) WebKitArticleConverter *articleConverter; - -@end - -@implementation VNAArticleTests - -- (void)setUp -{ - [super setUp]; - - self.article = [[Article alloc] initWithGuid:GUID]; - self.articleConverter = [[WebKitArticleConverter alloc] init]; -} - -- (void)testAccessInstanceVariablesDirectly -{ - XCTAssertFalse([Article accessInstanceVariablesDirectly]); -} - -#pragma mark - Test custom setters - -- (void)testTitle -{ - self.article.title = Title; - - XCTAssertEqualObjects(self.article.title, Title); -} - -- (void)testAuthor -{ - self.article.author = Author; - - XCTAssertEqualObjects(self.article.author, Author); -} - -- (void)testLink -{ - self.article.link = Link; - - XCTAssertEqualObjects(self.article.link, Link); -} - -- (void)testLastUpdate -{ - NSDate *date = [NSDate date]; - - self.article.lastUpdate = date; - - XCTAssertEqualObjects(self.article.lastUpdate, date); -} - -- (void)testPublicationDate -{ - NSDate *date = [NSDate date]; - - self.article.publicationDate = date; - - XCTAssertEqualObjects(self.article.publicationDate, date); -} - -- (void)testBody -{ - self.article.body = Body; - - XCTAssertEqualObjects(self.article.body, Body); -} - -- (void)testEnclosure -{ - self.article.enclosure = Enclosure; - - XCTAssertEqualObjects(self.article.enclosure, Enclosure); -} - -- (void)testEnclosureRemoval -{ - self.article.enclosure = nil; - - XCTAssertNil(self.article.enclosure); -} - -- (void)testHasEnclosure -{ - self.article.hasEnclosure = YES; - - XCTAssert(self.article.hasEnclosure); -} - -- (void)testFolderId -{ - NSInteger folderId = 111; - - self.article.folderId = folderId; - - XCTAssertEqual(self.article.folderId, folderId); -} - -- (void)testGuid -{ - self.article.guid = GUID; - - XCTAssertEqualObjects(self.article.guid, GUID); -} - -- (void)testParentId -{ - NSInteger parentId = 222; - - self.article.parentId = parentId; - - XCTAssertEqual(self.article.parentId, parentId); -} - -- (void)testStatus -{ - NSInteger status = ArticleStatusNew; - - self.article.status = status; - - XCTAssertEqual(self.article.status, status); -} - -- (void)testMarkRead -{ - XCTAssertFalse(self.article.isRead); - - [self.article markRead:YES]; - - XCTAssert(self.article.isRead); -} - -- (void)testMarkRevised -{ - XCTAssertFalse(self.article.isRevised); - - [self.article markRevised:YES]; - - XCTAssert(self.article.isRevised); -} - -- (void)testMarkDeleted -{ - XCTAssertFalse(self.article.isDeleted); - - [self.article markDeleted:YES]; - - XCTAssert(self.article.isDeleted); -} - -- (void)testMarkFlagged -{ - XCTAssertFalse(self.article.isFlagged); - - [self.article markFlagged:YES]; - - XCTAssert(self.article.isFlagged); -} - -- (void)testMarkEnclosureDowloaded -{ - XCTAssertFalse(self.article.enclosureDownloaded); - - [self.article markEnclosureDownloaded:YES]; - - XCTAssert(self.article.enclosureDownloaded); -} - -- (void)testCompatibilityDate -{ - NSDate *date = [NSDate date]; - NSString *dateKeyPath = [@"articleData." stringByAppendingString:MA_Field_LastUpdate]; - - self.article.lastUpdate = date; - - XCTAssertEqualObjects([self.article valueForKeyPath:dateKeyPath], date); -} - -- (void)testCompatibilityAuthor -{ - NSString *authorKeyPath = [@"articleData." stringByAppendingString:MA_Field_Author]; - - self.article.author = Author; - - XCTAssertEqualObjects([self.article valueForKeyPath:authorKeyPath], Author); -} - -- (void)testCompatibilitySubject -{ - NSString *subject = @"Lorem ipsum dolor sit amet"; - NSString *subjectKeyPath = [@"articleData." stringByAppendingString:MA_Field_Subject]; - - self.article.title = subject; - - XCTAssertEqualObjects([self.article valueForKeyPath:subjectKeyPath], subject); -} - -- (void)testCompatibilityLink -{ - NSString *link = @"http://www.vienna-rss.com"; - NSString *linkKeyPath = [@"articleData." stringByAppendingString:MA_Field_Link]; - - self.article.link = link; - - XCTAssertEqualObjects([self.article valueForKeyPath:linkKeyPath], link); -} - -- (void)testCompatibilitySummary -{ - NSString *summary = @"Lorem ipsum dolor sit amet"; - NSString *summaryKeyPath = [@"articleData." stringByAppendingString:MA_Field_Summary]; - - self.article.body = summary; - - XCTAssertEqualObjects([self.article valueForKeyPath:summaryKeyPath], summary); -} - -- (void)testRandomCompatibilityKeyPath -{ - NSString *randomArticleDataKeyPath = [@"articleData." stringByAppendingString:@"dummyProperty"]; - - XCTAssertThrowsSpecificNamed([self.article valueForKeyPath:randomArticleDataKeyPath], - NSException, - NSUndefinedKeyException); -} - -- (void)testRandomKeyPath -{ - NSString *randomKeyPath = @"dummyProperty"; - - XCTAssertThrowsSpecificNamed([self.article valueForKeyPath:randomKeyPath], - NSException, - NSUndefinedKeyException); -} - -- (void)testDescription -{ - NSString *title = @"Lorem ipsum dolor sit amet"; - - self.article.guid = GUID; - self.article.title = title; - - NSString *expectedDescription = - [NSString stringWithFormat:@"{GUID=%@ title=\"%@\"", GUID, title]; - - XCTAssertEqualObjects(self.article.description, expectedDescription); -} - -#pragma mark - Expand tags - -- (void)testExpandLinkTag -{ - NSString *string = @"$ArticleLink$/development"; - - NSString *expectedString = [NSString stringWithFormat:@"%@/development", Link]; - - self.article.link = Link; - - NSString *expandedString = [self.articleConverter expandTagsOfArticle:self.article intoTemplate:string withConditional:YES]; - - XCTAssertEqualObjects(expandedString, expectedString); -} - -- (void)testExpandTitleTag -{ - NSString *string = @"$ArticleTitle$"; - NSString *expectedString = Title; - - self.article.title = Title; - - NSString *expandedString = [self.articleConverter expandTagsOfArticle:self.article intoTemplate:string withConditional:YES]; - - XCTAssertEqualObjects(expandedString, expectedString); -} - -- (void)testExpandArticleBodyTag -{ - NSString *string = @"$ArticleBody$"; - NSString *expectedString = Body; - - self.article.body = Body; - - NSString *expandedString = [self.articleConverter expandTagsOfArticle:self.article intoTemplate:string withConditional:YES]; - - XCTAssertEqualObjects(expandedString, expectedString); -} - -- (void)testExpandArticleAuthorTag -{ - NSString *string = @"$ArticleAuthor$"; - NSString *expectedString = Author; - - self.article.author = Author; - - NSString *expandedString = [self.articleConverter expandTagsOfArticle:self.article intoTemplate:string withConditional:YES]; - - XCTAssertEqualObjects(expandedString, expectedString); -} - -- (void)testExpandArticleEnclosureLinkTag -{ - NSString *string = @"$ArticleEnclosureLink$"; - NSString *expectedString = Enclosure; - - self.article.enclosure = Enclosure; - - NSString *expandedString = [self.articleConverter expandTagsOfArticle:self.article intoTemplate:string withConditional:YES]; - - XCTAssertEqualObjects(expandedString, expectedString); -} - -- (void)testExpandArticleEnclosureFileName -{ - NSString *string = @"$ArticleEnclosureFilename$"; - NSString *expectedString = EnclosureFilename; - - self.article.enclosure = Enclosure; - NSString *expandedString = [self.articleConverter expandTagsOfArticle:self.article intoTemplate:string withConditional:YES]; - - XCTAssertEqualObjects(expandedString, expectedString); -} - -- (void)testURLIDNinArticleView -{ - self.article.link = @"http://ουτοπία.δπθ.gr/نجيب_محفوظ/"; - NSString * htmlTextFromIDNALink = [self.articleConverter articleTextFromArray:@[self.article]]; - - self.article.link = @"http://xn--kxae4bafwg.xn--pxaix.gr/%D9%86%D8%AC%D9%8A%D8%A8_%D9%85%D8%AD%D9%81%D9%88%D8%B8/"; - NSString * htmlTextFromResolvedIDNALink = [self.articleConverter articleTextFromArray:@[self.article]]; - - XCTAssertEqualObjects(htmlTextFromIDNALink, htmlTextFromResolvedIDNALink); -} - -@end diff --git a/Vienna.xcodeproj/project.pbxproj b/Vienna.xcodeproj/project.pbxproj index 6efffd98c8..4da0780719 100644 --- a/Vienna.xcodeproj/project.pbxproj +++ b/Vienna.xcodeproj/project.pbxproj @@ -132,7 +132,7 @@ 435028B8165DE9E00018EDB7 /* URLHandlerCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 43502890165DE9DF0018EDB7 /* URLHandlerCommand.m */; }; 435028B9165DE9E00018EDB7 /* ViennaApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 43502892165DE9DF0018EDB7 /* ViennaApp.m */; }; 43BA97FE1664804E00B95F35 /* DSClickableURLTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = B2E09F2C111192B7003B530A /* DSClickableURLTextField.m */; settings = {COMPILER_FLAGS = "-Xclang -analyzer-tidy-checker=-readability-braces-around-statements"; }; }; - 4D36B44B1D37F91E009736C1 /* VNAArticleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D36B44A1D37F91E009736C1 /* VNAArticleTests.m */; }; + 4D36B44B1D37F91E009736C1 /* ArticleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D36B44A1D37F91E009736C1 /* ArticleTests.m */; }; 664F87C713C62DFE00E266DE /* OpenReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 664F87C613C62DFE00E266DE /* OpenReader.m */; }; 793C95331C42A0DD00984D4E /* FoldersFilterable.m in Sources */ = {isa = PBXBuildFile; fileRef = 793C95321C42A0DD00984D4E /* FoldersFilterable.m */; }; 8D15AC320486D014006FF6A4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A37F4B0FDCFA73011CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; @@ -428,7 +428,7 @@ 439824221666B3DB00FFE219 /* notes.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = notes.html; sourceTree = SOURCE_ROOT; }; 439824231666B3DB00FFE219 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = SOURCE_ROOT; }; 439824241666B3DB00FFE219 /* Release Instructions.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = "Release Instructions.md"; sourceTree = SOURCE_ROOT; }; - 4D36B44A1D37F91E009736C1 /* VNAArticleTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VNAArticleTests.m; sourceTree = ""; }; + 4D36B44A1D37F91E009736C1 /* ArticleTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ArticleTests.m; sourceTree = ""; }; 664F87C513C62DFE00E266DE /* OpenReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenReader.h; sourceTree = ""; }; 664F87C613C62DFE00E266DE /* OpenReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OpenReader.m; sourceTree = ""; }; 793C95311C42A0DD00984D4E /* FoldersFilterable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FoldersFilterable.h; sourceTree = ""; }; @@ -679,7 +679,7 @@ 035B703619E0E4AE00197334 /* Vienna Tests */ = { isa = PBXGroup; children = ( - 4D36B44A1D37F91E009736C1 /* VNAArticleTests.m */, + 4D36B44A1D37F91E009736C1 /* ArticleTests.m */, 3A8D9AE225A9DA4B0016F30F /* ArticleTests.swift */, 2F437B3A25CF336400AD1B57 /* SubscriptionModelTests.swift */, 2FE328F025CF436C005B9C18 /* CriteriaTests.swift */, @@ -1725,7 +1725,7 @@ 2F437B3C25CF336400AD1B57 /* SubscriptionModelTests.swift in Sources */, F6A179D326B82BE3008DDA42 /* NSFileManagerExtensionTests.swift in Sources */, F6AC41AC25A4FAF6007DED7B /* FeedDiscovererTests.swift in Sources */, - 4D36B44B1D37F91E009736C1 /* VNAArticleTests.m in Sources */, + 4D36B44B1D37F91E009736C1 /* ArticleTests.m in Sources */, F6E01A072C652DEE0082E07B /* RSSFeedTests.swift in Sources */, F648C2B81E7F3BEA00CE4043 /* DirectoryMonitorTests.swift in Sources */, 3A50014E259AA2BE00AA6AAD /* WebKitArticleConverter.swift in Sources */, diff --git a/Vienna/Sources/Application/AppController.m b/Vienna/Sources/Application/AppController.m index 6800b4c2a8..3ccb2ef3d3 100644 --- a/Vienna/Sources/Application/AppController.m +++ b/Vienna/Sources/Application/AppController.m @@ -2344,7 +2344,7 @@ -(IBAction)markReadToggle:(id)sender Article * theArticle = self.selectedArticle; if (theArticle != nil && !db.readOnly) { NSArray * articleArray = self.articleController.markedArticleRange; - [self.articleController markReadByArray:articleArray readFlag:!theArticle.read]; + [self.articleController markReadByArray:articleArray readFlag:!theArticle.isRead]; } } @@ -2380,7 +2380,7 @@ -(IBAction)markFlagged:(id)sender Article * theArticle = self.selectedArticle; if (theArticle != nil && !db.readOnly) { NSArray * articleArray = self.articleController.markedArticleRange; - [self.articleController markFlaggedByArray:articleArray flagged:!theArticle.flagged]; + [self.articleController markFlaggedByArray:articleArray flagged:!theArticle.isFlagged]; } } @@ -3333,7 +3333,7 @@ -(BOOL)validateMenuItem:(NSMenuItem *)menuItem } else if (theAction == @selector(markFlagged:)) { Article * thisArticle = self.selectedArticle; if (thisArticle != nil) { - if (thisArticle.flagged) { + if (thisArticle.isFlagged) { [menuItem setTitle:NSLocalizedString(@"Mark Unflagged", nil)]; } else { [menuItem setTitle:NSLocalizedString(@"Mark Flagged", nil)]; diff --git a/Vienna/Sources/Database/Database.m b/Vienna/Sources/Database/Database.m index 1330510f6b..c9f32d47e3 100644 --- a/Vienna/Sources/Database/Database.m +++ b/Vienna/Sources/Database/Database.m @@ -1506,10 +1506,10 @@ -(BOOL)addArticle:(Article *)article toFolder:(NSInteger)folderID NSString * articleEnclosure = article.enclosure.vna_trimmed; NSString * articleGuid = article.guid; NSInteger parentId = article.parentId; - BOOL marked_flag = article.flagged; - BOOL read_flag = article.read; - BOOL revised_flag = article.revised; - BOOL deleted_flag = article.deleted; + BOOL marked_flag = article.isFlagged; + BOOL read_flag = article.isRead; + BOOL revised_flag = article.isRevised; + BOOL deleted_flag = article.isDeleted; BOOL hasenclosure_flag = article.hasEnclosure; NSDate *currentDate = [NSDate date]; @@ -1601,7 +1601,7 @@ -(BOOL)updateArticle:(Article *)existingArticle ofFolder:(NSInteger)folderID wit NSString * userName = articleUpdate.author.vna_trimmed; NSString * articleGuid = articleUpdate.guid; NSInteger parentId = articleUpdate.parentId; - BOOL revised_flag = articleUpdate.revised; + BOOL revised_flag = articleUpdate.isRevised; // keep last update date the same if not set in the current version of the article NSDate * lastUpdate = existingArticle.lastUpdate; @@ -1657,7 +1657,7 @@ -(BOOL)updateArticle:(Article *)existingArticle ofFolder:(NSInteger)folderID wit // Articles preexisting in database should be marked as revised. // New articles created during the current refresh should not be marked as revised, // even if there are multiple versions of the new article in the feed. - if (existingArticle.revised || (existingArticle.status == ArticleStatusEmpty)) { + if (existingArticle.isRevised || (existingArticle.status == ArticleStatusEmpty)) { revised_flag = YES; } @@ -1684,7 +1684,7 @@ -(BOOL)updateArticle:(Article *)existingArticle ofFolder:(NSInteger)folderID wit // update the existing article in memory existingArticle.title = articleTitle; existingArticle.body = articleBody; - [existingArticle markRevised:revised_flag]; + existingArticle.revised = revised_flag; existingArticle.parentId = parentId; existingArticle.author = userName; existingArticle.link = articleLink; @@ -1760,13 +1760,13 @@ -(BOOL)deleteArticle:(Article *)article }]; if (success) { - if (!article.read) { + if (!article.isRead) { [self setFolderUnreadCount:folder adjustment:-1]; } if (folder.countOfCachedArticles > 0) { // If we're in a smart folder, the cached article may be different. Article * cachedArticle = [folder articleFromGuid:guid]; - [cachedArticle markDeleted:YES]; + cachedArticle.deleted = YES; [folder removeArticleFromCache:guid]; } return YES; @@ -2043,11 +2043,11 @@ -(NSArray *)minimalCacheForFolder:(NSInteger)folderId ++unread_count; } - Article * article = [[Article alloc] initWithGuid:guid]; - [article markRead:read_flag]; - [article markFlagged:marked_flag]; - [article markRevised:revised_flag]; - [article markDeleted:deleted_flag]; + Article * article = [[Article alloc] initWithGUID:guid]; + article.read = read_flag; + article.flagged = marked_flag; + article.revised = revised_flag; + article.deleted = deleted_flag; article.folderId = folderId; article.title = title; article.link = link; @@ -2238,12 +2238,12 @@ -(NSArray *)arrayOfArticles:(NSInteger)folderId filterString:(NSString *)filterS } while ([results next]) { NSString * guid = [results stringForColumnIndex:0]; - Article * article = [[Article alloc] initWithGuid:guid]; + Article * article = [[Article alloc] initWithGUID:guid]; article.folderId = [results intForColumnIndex:1]; article.parentId = [results intForColumnIndex:2]; - [article markRead:[results intForColumnIndex:3]]; - [article markFlagged:[results intForColumnIndex:4]]; - [article markDeleted:[results intForColumnIndex:5]]; + article.read = [results intForColumnIndex:3]; + article.flagged = [results intForColumnIndex:4]; + article.deleted = [results intForColumnIndex:5]; article.title = [results stringForColumnIndex:6]; article.author = [results stringForColumnIndex:7]; article.link = [results stringForColumnIndex:8]; @@ -2251,18 +2251,18 @@ -(NSArray *)arrayOfArticles:(NSInteger)folderId filterString:(NSString *)filterS article.lastUpdate = [NSDate dateWithTimeIntervalSince1970:[results stringForColumnIndex:10].doubleValue]; NSString * text = [results stringForColumnIndex:11]; article.body = text; - [article markRevised:[results intForColumnIndex:12]]; + article.revised = [results intForColumnIndex:12]; article.hasEnclosure = [results intForColumnIndex:13]; article.enclosure = [results stringForColumnIndex:14]; Folder * articleFolder = [self folderFromID:article.folderId]; article.status = [articleFolder retrieveKnownStatusForGuid:guid]; - if (folder == nil || !article.deleted || folder.type == VNAFolderTypeTrash) { + if (folder == nil || !article.isDeleted || folder.type == VNAFolderTypeTrash) { [newArray addObject:article]; } // Keep our own track of unread articles - if (!article.read) { + if (!article.isRead) { ++unread_count; } @@ -2331,7 +2331,7 @@ -(void)markArticleRead:(NSInteger)folderId guid:(NSString *)guid isRead:(BOOL)is Folder * folder = [self folderFromID:folderId]; if (folder != nil) { Article * article = [folder articleFromGuid:guid]; - if (article != nil && isRead != article.read) { + if (article != nil && isRead != article.isRead) { // Mark an individual article read FMDatabaseQueue *queue = self.databaseQueue; __block BOOL success; @@ -2342,7 +2342,7 @@ -(void)markArticleRead:(NSInteger)folderId guid:(NSString *)guid isRead:(BOOL)is if (success) { NSInteger adjustment = (isRead ? -1 : 1); - [article markRead:isRead]; + article.read = isRead; [self setFolderUnreadCount:folder adjustment:adjustment]; } } @@ -2426,7 +2426,7 @@ -(void)markArticleFlagged:(NSInteger)folderId guid:(NSString *)guid isFlagged:(B Folder * folder = [self folderFromID:folderId]; if (folder != nil) { Article * article = [folder articleFromGuid:guid]; - if (article != nil && isFlagged != article.flagged) { + if (article != nil && isFlagged != article.isFlagged) { FMDatabaseQueue *queue = self.databaseQueue; __block BOOL success; [queue inDatabase:^(FMDatabase *db) { @@ -2438,7 +2438,7 @@ -(void)markArticleFlagged:(NSInteger)folderId guid:(NSString *)guid isFlagged:(B if (success) { // Mark an individual article flagged - [article markFlagged:isFlagged]; + article.flagged = isFlagged; } } } @@ -2453,7 +2453,7 @@ -(void)markArticleDeleted:(Article *)article isDeleted:(BOOL)isDeleted NSString * guid = article.guid; Folder * folder = [self folderFromID:folderId]; if (folder !=nil) { - if (isDeleted && !article.read) { + if (isDeleted && !article.isRead) { [self markArticleRead:folderId guid:guid isRead:YES]; } FMDatabaseQueue *queue = self.databaseQueue; @@ -2463,14 +2463,14 @@ -(void)markArticleDeleted:(Article *)article isDeleted:(BOOL)isDeleted @(folderId), guid]; }]; - [article markDeleted:isDeleted]; + article.deleted = isDeleted; //TODO this should all move to the folder implementation, to make this less of a god object. // Or even better: when marking an article as deleted it triggers the deletion from its folder itself, and that in turn triggers the db update. // The same also applies to deleteArticle and probably many other parts of this class. if (folder.countOfCachedArticles > 0) { // If we're in a smart folder, the cached article may be different. Article * cachedArticle = [folder articleFromGuid:guid]; - [cachedArticle markDeleted:isDeleted]; + cachedArticle.deleted = isDeleted; } } } diff --git a/Vienna/Sources/Fetching/OpenReader.m b/Vienna/Sources/Fetching/OpenReader.m index 0f5d808138..8a9c96e2ff 100644 --- a/Vienna/Sources/Fetching/OpenReader.m +++ b/Vienna/Sources/Fetching/OpenReader.m @@ -570,7 +570,7 @@ -(void)feedRequestDone:(NSMutableURLRequest *)request response:(NSURLResponse *) for (NSDictionary *newsItem in (NSArray *)subscriptionsDict[@"items"]) { NSString *articleGuid = newsItem[@"id"]; - Article *article = [[Article alloc] initWithGuid:articleGuid]; + Article *article = [[Article alloc] initWithGUID:articleGuid]; article.folderId = refreshedFolder.itemId; if (newsItem[@"author"] != nil) { @@ -589,13 +589,13 @@ -(void)feedRequestDone:(NSMutableURLRequest *)request response:(NSURLResponse *) for (NSString *category in (NSArray *)newsItem[@"categories"]) { if ([category hasSuffix:@"/read"]) { - [article markRead:YES]; + article.read = YES; } if ([category hasSuffix:@"/starred"]) { - [article markFlagged:YES]; + article.flagged = YES; } if ([category hasSuffix:@"/kept-unread"]) { - [article markRead:NO]; + article.read = NO; } } @@ -737,13 +737,13 @@ -(void)readRequestDone:(NSMutableURLRequest *)request response:(NSURLResponse *) [guidArray addObject:guid]; // now, mark relevant articles unread - [[refreshedFolder articleFromGuid:guid] markRead:NO]; + [refreshedFolder articleFromGuid:guid].read = NO; } [[Database sharedManager] markUnreadArticlesFromFolder:refreshedFolder guidArray:guidArray]; // reset starred statuses in cache : we will receive in -StarredRequestDone: the updated list for (Article *article in refreshedFolder.articles) { - [article markFlagged:NO]; + article.flagged = NO; } } @catch (NSException *exception) { [aItem appendDetail:[NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"Error", nil), exception]]; @@ -801,7 +801,7 @@ -(void)starredRequestDone:(NSMutableURLRequest *)request response:(NSURLResponse guid = [NSString stringWithFormat:@"tag:google.com,2005:reader/item/%016qx", (long long)shortId]; } [guidArray addObject:guid]; - [[refreshedFolder articleFromGuid:guid] markFlagged:YES]; + [refreshedFolder articleFromGuid:guid].flagged = YES; } [[Database sharedManager] markStarredArticlesFromFolder:refreshedFolder guidArray:guidArray]; @@ -1152,7 +1152,7 @@ -(void)markReadDone:(NSMutableURLRequest *)request response:(NSURLResponse *)res Article *article = ((NSDictionary *)[request vna_userInfo])[@"article"]; BOOL readFlag = [[((NSDictionary *)[request vna_userInfo]) valueForKey:@"readFlag"] boolValue]; [[Database sharedManager] markArticleRead:article.folderId guid:article.guid isRead:readFlag]; - [article markRead:readFlag]; + article.read = readFlag; NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc vna_postNotificationOnMainThreadWithName:MA_Notify_ArticleListStateChange object:@(article.folderId)]; } diff --git a/Vienna/Sources/Fetching/RefreshManager.m b/Vienna/Sources/Fetching/RefreshManager.m index c66866922a..4eddddfe7c 100644 --- a/Vienna/Sources/Fetching/RefreshManager.m +++ b/Vienna/Sources/Fetching/RefreshManager.m @@ -839,7 +839,7 @@ -(void)finalizeFolderRefresh:(NSDictionary *)parameters NSString * articleGuid = [self getOrCalculateArticleGuid:newsItem folderId:folderId articles:articleArray articleGuidArray:articleGuidArray]; [articleGuidArray addObject:articleGuid]; - Article * article = [[Article alloc] initWithGuid:articleGuid]; + Article * article = [[Article alloc] initWithGUID:articleGuid]; article.folderId = folderId; article.author = newsItem.authors; article.body = newsItem.content; diff --git a/Vienna/Sources/Main window/ArticleController.m b/Vienna/Sources/Main window/ArticleController.m index cb307865b8..e001011ab0 100644 --- a/Vienna/Sources/Main window/ArticleController.m +++ b/Vienna/Sources/Main window/ArticleController.m @@ -364,7 +364,7 @@ -(void)displayFirstUnread { // mark current article read Article * currentArticle = self.selectedArticle; - if (currentArticle != nil && !currentArticle.read) { + if (currentArticle != nil && !currentArticle.isRead) { [self markReadByArray:@[currentArticle] readFlag:YES]; } @@ -392,7 +392,7 @@ -(void)displayNextUnread { // mark current article read Article * currentArticle = self.selectedArticle; - if (currentArticle != nil && !currentArticle.read) { + if (currentArticle != nil && !currentArticle.isRead) { [self markReadByArray:@[currentArticle] readFlag:YES]; } @@ -480,7 +480,7 @@ -(void)reloadArrayOfArticles // Make sure selectedArticle hasn't changed since reload started. if (articleToPreserve != nil && articleToPreserve != article) { - if (article != nil && !article.deleted) { + if (article != nil && !article.isDeleted) { articleToPreserve = article; } else { articleToPreserve = nil; @@ -503,7 +503,7 @@ -(void)reloadArrayOfArticles Article *currentArticle = self.selectedArticle; if (currentArticle == article && [[Preferences standardPreferences] boolForKey:MAPref_CheckForUpdatedArticles] - && currentArticle.revised) + && currentArticle.isRevised) { [[NSNotificationCenter defaultCenter] postNotificationName:MA_Notify_ArticleViewChange object:nil]; } @@ -757,7 +757,7 @@ -(void)innerMarkFlaggedByArray:(NSArray *)articleArray flagged:(BOOL)flagged [[Database sharedManager] markArticleFlagged:theArticle.folderId guid:theArticle.guid isFlagged:flagged]; - [theArticle markFlagged:flagged]; + theArticle.flagged = flagged; } } @@ -804,12 +804,12 @@ -(void)innerMarkReadByArray:(NSArray *)articleArray readFlag:(BOOL)readFlag { for (Article * theArticle in articleArray) { NSInteger folderId = theArticle.folderId; - if (theArticle.read != readFlag) { + if (theArticle.isRead != readFlag) { if ([[Database sharedManager] folderFromID:folderId].type == VNAFolderTypeOpenReader) { [[OpenReader sharedManager] markRead:theArticle readFlag:readFlag]; } else { [[Database sharedManager] markArticleRead:folderId guid:theArticle.guid isRead:readFlag]; - [theArticle markRead:readFlag]; + theArticle.read = readFlag; } } } @@ -872,7 +872,7 @@ -(void)markAllFoldersReadByArray:(NSArray *)folderArray ![folderArray containsObject:currentFolder])) { for (Article *theArticle in folderArrayOfArticles) { - [theArticle markRead:YES]; + theArticle.read = YES; } } @@ -1028,7 +1028,7 @@ -(void)handleArticleListContentChange:(NSNotification *)note - (BOOL)filterArticle:(Article *)article usingMode:(NSInteger)filterMode { switch (filterMode) { case VNAFilterUnread: - return !article.read; + return !article.isRead; case VNAFilterLastRefresh: { return article.status == ArticleStatusNew || article.status == ArticleStatusUpdated; } @@ -1042,9 +1042,9 @@ - (BOOL)filterArticle:(Article *)article usingMode:(NSInteger)filterMode { return [article.lastUpdate compare:twoDaysAgo] != NSOrderedAscending; } case VNAFilterFlagged: - return article.flagged; + return article.isFlagged; case VNAFilterUnreadOrFlagged: - return (!article.read || article.flagged); + return (!article.isRead || article.isFlagged); default: return true; } diff --git a/Vienna/Sources/Main window/ArticleListView.m b/Vienna/Sources/Main window/ArticleListView.m index ad72864c34..73953de2bc 100644 --- a/Vienna/Sources/Main window/ArticleListView.m +++ b/Vienna/Sources/Main window/ArticleListView.m @@ -321,11 +321,11 @@ -(IBAction)singleClickRow:(id)sender Article * theArticle = allArticles[row]; NSString * columnName = ((NSTableColumn *)columns[column]).identifier; if ([columnName isEqualToString:MA_Field_Read]) { - [self.controller.articleController markReadByArray:@[theArticle] readFlag:!theArticle.read]; + [self.controller.articleController markReadByArray:@[theArticle] readFlag:!theArticle.isRead]; return; } if ([columnName isEqualToString:MA_Field_Flagged]) { - [self.controller.articleController markFlaggedByArray:@[theArticle] flagged:!theArticle.flagged]; + [self.controller.articleController markFlaggedByArray:@[theArticle] flagged:!theArticle.isFlagged]; return; } if ([columnName isEqualToString:MA_Field_HasEnclosure]) { @@ -889,7 +889,7 @@ -(BOOL)viewNextUnreadInCurrentFolder:(NSInteger)currentRow Article * theArticle; while (currentRow < totalRows) { theArticle = allArticles[currentRow]; - if (!theArticle.read) { + if (!theArticle.isRead) { [self makeRowSelectedAndVisible:currentRow]; return YES; } @@ -968,7 +968,7 @@ -(void)performFindPanelAction:(NSInteger)actionTag BOOL shouldSelectArticle = YES; if ([Preferences standardPreferences].markReadInterval > 0.0f) { Article * article = self.controller.articleController.allArticles[0u]; - if (!article.read) { + if (!article.isRead) { shouldSelectArticle = NO; } } @@ -1016,7 +1016,7 @@ -(void)refreshImmediatelyArticleAtCurrentRow [self refreshArticlePane]; Article * theArticle = self.selectedArticle; - if (theArticle != nil && !theArticle.read) { + if (theArticle != nil && !theArticle.isRead) { CGFloat interval = [Preferences standardPreferences].markReadInterval; if (interval > 0 && !isAppInitialising) { markReadTimer = [NSTimer scheduledTimerWithTimeInterval:(double)interval @@ -1157,7 +1157,7 @@ -(void)refreshArticlePane -(void)markCurrentRead:(NSTimer *)aTimer { Article * theArticle = self.selectedArticle; - if (theArticle != nil && !theArticle.read && ![Database sharedManager].readOnly) { + if (theArticle != nil && !theArticle.isRead && ![Database sharedManager].readOnly) { [self.controller.articleController markReadByArray:@[theArticle] readFlag:YES]; } } @@ -1187,10 +1187,10 @@ -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColum theArticle = allArticles[rowIndex]; NSString * identifier = aTableColumn.identifier; if ([identifier isEqualToString:MA_Field_Read]) { - if (!theArticle.read) { + if (!theArticle.isRead) { if (@available(macOS 11, *)) { NSImage *image = nil; - if (theArticle.revised) { + if (theArticle.isRevised) { image = [NSImage imageWithSystemSymbolName:@"sparkles" accessibilityDescription:nil]; // Setting the template property to NO enables the tint color. @@ -1203,7 +1203,7 @@ -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColum } return image; } else { - if (theArticle.revised) { + if (theArticle.isRevised) { return [NSImage imageNamed:ACImageNameRevised]; } else { return [NSImage imageNamed:ACImageNameUnread]; @@ -1213,7 +1213,7 @@ -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColum return nil; } if ([identifier isEqualToString:MA_Field_Flagged]) { - if (theArticle.flagged) { + if (theArticle.isFlagged) { if (@available(macOS 11, *)) { NSImage *image = [NSImage imageWithSystemSymbolName:@"flag.fill" accessibilityDescription:nil]; @@ -1247,7 +1247,7 @@ -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColum if ([db fieldByName:MA_Field_Subject].visible) { NSDictionary * topLineDictPtr; - if (theArticle.read) { + if (theArticle.isRead) { topLineDictPtr = (isSelectedRow ? selectionDict : topLineDict); } else { topLineDictPtr = (isSelectedRow ? unreadTopLineSelectionDict : unreadTopLineDict); @@ -1338,7 +1338,7 @@ -(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColum [NSException raise:@"ArticleListView unknown table column identifier exception" format:@"Unknown table column identifier: %@", identifier]; } - theAttributedString = [[NSMutableAttributedString alloc] initWithString:SafeString(cellString) attributes:(theArticle.read ? reportCellDict : unreadReportCellDict)]; + theAttributedString = [[NSMutableAttributedString alloc] initWithString:SafeString(cellString) attributes:(theArticle.isRead ? reportCellDict : unreadReportCellDict)]; [theAttributedString fixFontAttributeInRange:NSMakeRange(0u, theAttributedString.length)]; return theAttributedString; } diff --git a/Vienna/Sources/Main window/UnifiedDisplayView.m b/Vienna/Sources/Main window/UnifiedDisplayView.m index 2ba5fb4897..bfe52b904e 100644 --- a/Vienna/Sources/Main window/UnifiedDisplayView.m +++ b/Vienna/Sources/Main window/UnifiedDisplayView.m @@ -247,7 +247,7 @@ -(void)performFindPanelAction:(NSInteger)actionTag BOOL shouldSelectArticle = YES; if ([Preferences standardPreferences].markReadInterval > 0.0f) { Article * article = self.controller.articleController.allArticles[0u]; - if (!article.read) { + if (!article.isRead) { shouldSelectArticle = NO; } } @@ -393,7 +393,7 @@ -(BOOL)viewNextUnreadInCurrentFolder:(NSInteger)currentRow Article * theArticle; while (currentRow < totalRows) { theArticle = allArticles[currentRow]; - if (!theArticle.read) { + if (!theArticle.isRead) { [self makeRowSelectedAndVisible:currentRow]; return YES; } @@ -483,7 +483,7 @@ -(void)refreshFolder:(NSInteger)refreshFlag -(void)markCurrentRead:(NSTimer *)aTimer { Article * theArticle = self.selectedArticle; - if (theArticle != nil && !theArticle.read && ![Database sharedManager].readOnly) { + if (theArticle != nil && !theArticle.isRead && ![Database sharedManager].readOnly) { [self.controller.articleController markReadByArray:@[theArticle] readFlag:YES]; } } diff --git a/Vienna/Sources/Models/Article.h b/Vienna/Sources/Models/Article.h index a5aef227fe..0181aa0b39 100644 --- a/Vienna/Sources/Models/Article.h +++ b/Vienna/Sources/Models/Article.h @@ -43,8 +43,6 @@ extern NSString * const MA_Field_Enclosure; extern NSString * const MA_Field_EnclosureDownloaded; extern NSString * const MA_Field_HasEnclosure; -NS_ASSUME_NONNULL_END - typedef NS_ENUM(NSInteger, VNAArticleFieldTag) { VNAArticleFieldTagGUID = 400, VNAArticleFieldTagSubject, @@ -70,14 +68,17 @@ typedef NS_ENUM(NSInteger, ArticleStatus) { ArticleStatusEmpty = 0, ArticleStatusNew, ArticleStatusUpdated -}; +} NS_SWIFT_NAME(Article.Status); @interface Article : NSObject -// Accessor functions --(instancetype _Nonnull)initWithGuid:(NSString * _Nonnull)theGuid /*NS_DESIGNATED_INITIALIZER*/; +- (instancetype)initWithGUID:(NSString *)guid NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + @property (nonatomic) NSInteger parentId; -@property (nonnull, nonatomic, copy) NSString *guid; +@property (nonatomic, copy) NSString *guid; @property (nullable, nonatomic, copy) NSString *author; @property (nullable, nonatomic, copy) NSString *body; @property (nullable, nonatomic, copy) NSString *title; @@ -88,17 +89,14 @@ typedef NS_ENUM(NSInteger, ArticleStatus) { @property (nullable, nonatomic) NSDate *publicationDate; @property (nullable, nonatomic, readonly) Folder *containingFolder; @property (nonatomic) NSInteger folderId; -@property (nonatomic, getter=isRead, readonly) BOOL read; -@property (nonatomic, getter=isRevised, readonly) BOOL revised; -@property (nonatomic, getter=isFlagged, readonly) BOOL flagged; -@property (nonatomic, getter=isDeleted, readonly) BOOL deleted; +@property (nonatomic, getter=isRead) BOOL read; +@property (nonatomic, getter=isRevised) BOOL revised; +@property (nonatomic, getter=isFlagged) BOOL flagged; +@property (nonatomic, getter=isDeleted) BOOL deleted; @property (nonatomic) BOOL hasEnclosure; -@property (nonatomic, readonly) BOOL enclosureDownloaded; -@property (nonatomic) NSInteger status; --(void)markRead:(BOOL)flag; --(void)markRevised:(BOOL)flag; --(void)markFlagged:(BOOL)flag; --(void)markDeleted:(BOOL)flag; --(void)markEnclosureDownloaded:(BOOL)flag; +@property (nonatomic) BOOL enclosureDownloaded; +@property (nonatomic) ArticleStatus status; @end + +NS_ASSUME_NONNULL_END diff --git a/Vienna/Sources/Models/Article.m b/Vienna/Sources/Models/Article.m index a48f0dc314..6215e34b1d 100644 --- a/Vienna/Sources/Models/Article.m +++ b/Vienna/Sources/Models/Article.m @@ -45,39 +45,15 @@ @implementation Article { NSMutableDictionary *articleData; - BOOL readFlag; - BOOL revisedFlag; - BOOL markedFlag; - BOOL deletedFlag; - BOOL enclosureDownloadedFlag; - BOOL hasEnclosureFlag; - NSInteger status; } -- (instancetype)init +- (instancetype)initWithGUID:(NSString *)guid { self = [super init]; if (self) { + _guid = [guid copy]; + _folderId = -1; articleData = [[NSMutableDictionary alloc] init]; - readFlag = NO; - revisedFlag = NO; - markedFlag = NO; - deletedFlag = NO; - hasEnclosureFlag = NO; - enclosureDownloadedFlag = NO; - status = ArticleStatusEmpty; - self.folderId = -1; - self.parentId = 0; - } - return self; -} - -/* initWithGuid - */ --(instancetype)initWithGuid:(NSString *)theGuid -{ - if ((self = [self init]) != nil) { - self.guid = theGuid; } return self; } @@ -139,48 +115,6 @@ -(void)setEnclosure:(NSString *)enclosure } } -/* markEnclosureDownloaded - */ --(void)markEnclosureDownloaded:(BOOL)flag -{ - enclosureDownloadedFlag = flag; -} - -/* setHasEnclosure - */ --(void)setHasEnclosure:(BOOL)flag -{ - hasEnclosureFlag = flag; -} - -/* markRead - */ --(void)markRead:(BOOL)flag -{ - readFlag = flag; -} - -/* markRevised - */ --(void)markRevised:(BOOL)flag -{ - revisedFlag = flag; -} - -/* markFlagged - */ --(void)markFlagged:(BOOL)flag -{ - markedFlag = flag; -} - -/* markDeleted - */ --(void)markDeleted:(BOOL)flag -{ - deletedFlag = flag; -} - /* accessInstanceVariablesDirectly * Override this so that KVC doesn't get the articleData ivar */ @@ -218,18 +152,8 @@ -(id)valueForKeyPath:(NSString *)keyPath /* Accessor functions */ --(BOOL)isRead { return readFlag; } --(BOOL)isRevised { return revisedFlag; } --(BOOL)isFlagged { return markedFlag; } --(BOOL)isDeleted { return deletedFlag; } --(BOOL)hasEnclosure { return hasEnclosureFlag; } --(BOOL)enclosureDownloaded { return enclosureDownloadedFlag; } --(NSInteger)status { return status; } --(NSInteger)folderId { return [articleData[MA_Field_Folder] integerValue]; } -(NSString *)author { return articleData[MA_Field_Author]; } -(NSString *)link { return articleData[MA_Field_Link]; } --(NSString *)guid { return articleData[MA_Field_GUID]; } --(NSInteger)parentId { return [articleData[MA_Field_Parent] integerValue]; } -(NSString *)title { return articleData[MA_Field_Subject]; } -(NSString *)summary { @@ -255,34 +179,6 @@ -(Folder *)containingFolder return [[Database sharedManager] folderFromID:self.folderId]; } -/* setFolderId - */ --(void)setFolderId:(NSInteger)newFolderId -{ - articleData[MA_Field_Folder] = @(newFolderId); -} - -/* setGuid - */ --(void)setGuid:(NSString *)newGuid -{ - articleData[MA_Field_GUID] = [newGuid copy]; -} - -/* setParentId - */ --(void)setParentId:(NSInteger)newParentId -{ - articleData[MA_Field_Parent] = @(newParentId); -} - -/* setStatus - */ --(void)setStatus:(NSInteger)newStatus -{ - status = newStatus; -} - /* description * Return a human readable description of this article for debugging. */ diff --git a/Vienna/Sources/Models/Folder.m b/Vienna/Sources/Models/Folder.m index 7c4d7262d2..420be404a0 100644 --- a/Vienna/Sources/Models/Folder.m +++ b/Vienna/Sources/Models/Folder.m @@ -504,14 +504,14 @@ -(BOOL)createArticle:(Article *)article guidHistory:(NSArray *)guidHistory NSString * guid = article.guid; [self.cachedArticles setObject:article forKey:guid]; [self.cachedGuids addObject:guid]; - if(!article.read) { + if(!article.isRead) { adjustment = 1; } } else { return NO; } } - } else if (existingArticle.deleted) { + } else if (existingArticle.isDeleted) { return NO; } else if (![[Preferences standardPreferences] boolForKey:MAPref_CheckForUpdatedArticles]) { return NO; @@ -519,10 +519,10 @@ -(BOOL)createArticle:(Article *)article guidHistory:(NSArray *)guidHistory BOOL success = [[Database sharedManager] updateArticle:existingArticle ofFolder:self.itemId withArticle:article]; if (success) { // Update folder unread count if necessary - if (existingArticle.read) { + if (existingArticle.isRead) { adjustment = 1; article.status = ArticleStatusNew; - [existingArticle markRead:NO]; + existingArticle.read = NO; } else { article.status = ArticleStatusUpdated; } @@ -638,8 +638,8 @@ -(void)markArticlesInCacheRead // so it makes the code slightly faster. for (id obj in self.cachedGuids.reverseObjectEnumerator.allObjects) { Article * article = [self.cachedArticles objectForKey:(NSString *)obj]; - if (!article.read) { - [article markRead:YES]; + if (!article.isRead) { + article.read = YES; count--; if (count == 0) { break; @@ -682,7 +682,7 @@ -(void)resetArticleStatuses NSMutableArray * result = [NSMutableArray arrayWithCapacity:unreadCount]; for (id obj in self.cachedGuids.reverseObjectEnumerator.allObjects) { Article * article = [self.cachedArticles objectForKey:(NSString *)obj]; - if (!article.read) { + if (!article.isRead) { [result addObject:[ArticleReference makeReference:article]]; count--; if (count == 0) {