diff --git a/Modules/RSParser/Sources/ObjC/RSAtomParser.m b/Modules/RSParser/Sources/ObjC/RSAtomParser.m index 307e15b25d..20ee137378 100755 --- a/Modules/RSParser/Sources/ObjC/RSAtomParser.m +++ b/Modules/RSParser/Sources/ObjC/RSAtomParser.m @@ -85,7 +85,7 @@ - (RSParsedFeed *)parseFeed { [self parse]; - RSParsedFeed *parsedFeed = [[RSParsedFeed alloc] initWithURLString:self.urlString title:self.title homepageURLString:self.homepageURLString language:self.language articles:self.articles]; + RSParsedFeed *parsedFeed = [[RSParsedFeed alloc] initWithURLString:self.urlString title:self.title homepageURLString:self.homepageURLString language:self.language iconURLString:nil articles:self.articles]; return parsedFeed; } diff --git a/Modules/RSParser/Sources/ObjC/RSParsedFeed.h b/Modules/RSParser/Sources/ObjC/RSParsedFeed.h index 61de4e853b..3039a8fcce 100755 --- a/Modules/RSParser/Sources/ObjC/RSParsedFeed.h +++ b/Modules/RSParser/Sources/ObjC/RSParsedFeed.h @@ -12,12 +12,13 @@ @interface RSParsedFeed : NSObject -- (nonnull instancetype)initWithURLString:(NSString * _Nonnull)urlString title:(NSString * _Nullable)title homepageURLString:(NSString * _Nullable)homepageURLString language:(NSString * _Nullable)language articles:(NSArray * _Nonnull)articles; +- (nonnull instancetype)initWithURLString:(NSString * _Nonnull)urlString title:(NSString * _Nullable)title homepageURLString:(NSString * _Nullable)homepageURLString language:(NSString * _Nullable)language iconURLString:(NSString * _Nullable)iconURLString articles:(NSArray * _Nonnull)articles; @property (nonatomic, readonly, nonnull) NSString *urlString; @property (nonatomic, readonly, nullable) NSString *title; @property (nonatomic, readonly, nullable) NSString *homepageURLString; @property (nonatomic, readonly, nullable) NSString *language; +@property (nonatomic, readonly, nullable) NSString *iconURLString; @property (nonatomic, readonly, nonnull) NSSet *articles; @end diff --git a/Modules/RSParser/Sources/ObjC/RSParsedFeed.m b/Modules/RSParser/Sources/ObjC/RSParsedFeed.m index 9035c1862b..a38bd5726b 100755 --- a/Modules/RSParser/Sources/ObjC/RSParsedFeed.m +++ b/Modules/RSParser/Sources/ObjC/RSParsedFeed.m @@ -12,7 +12,7 @@ @implementation RSParsedFeed -- (instancetype)initWithURLString:(NSString *)urlString title:(NSString *)title homepageURLString:(NSString *)homepageURLString language:(NSString *)language articles:(NSSet *)articles { +- (instancetype)initWithURLString:(NSString *)urlString title:(NSString *)title homepageURLString:(NSString *)homepageURLString language:(NSString *)language iconURLString:(NSString *)iconURLString articles:(NSSet *)articles { self = [super init]; if (!self) { @@ -23,6 +23,7 @@ - (instancetype)initWithURLString:(NSString *)urlString title:(NSString *)title _title = title; _homepageURLString = homepageURLString; _language = language; + _iconURLString = iconURLString; _articles = articles; return self; diff --git a/Modules/RSParser/Sources/ObjC/RSRSSParser.m b/Modules/RSParser/Sources/ObjC/RSRSSParser.m index e3e26cdd48..de3ea538d3 100755 --- a/Modules/RSParser/Sources/ObjC/RSRSSParser.m +++ b/Modules/RSParser/Sources/ObjC/RSRSSParser.m @@ -36,6 +36,7 @@ @interface RSRSSParser () @property (nonatomic, readonly) NSDate *currentDate; @property (nonatomic) BOOL endRSSFound; @property (nonatomic) NSString *homepageURLString; +@property (nonatomic) NSString *iconURLString; @property (nonatomic) NSString *title; @property (nonatomic) NSDate *dateParsed; @property (nonatomic) BOOL isRDF; @@ -77,7 +78,7 @@ - (RSParsedFeed *)parseFeed { [self parse]; - RSParsedFeed *parsedFeed = [[RSParsedFeed alloc] initWithURLString:self.urlString title:self.title homepageURLString:self.homepageURLString language:self.language articles:self.articles]; + RSParsedFeed *parsedFeed = [[RSParsedFeed alloc] initWithURLString:self.urlString title:self.title homepageURLString:self.homepageURLString language:self.language iconURLString:self.iconURLString articles:self.articles]; return parsedFeed; } @@ -452,6 +453,9 @@ - (void)saxParser:(RSSAXParser *)SAXParser XMLStartElement:(const xmlChar *)loca if (!self.parsingChannelImage) { [self.parser beginStoringCharacters]; } + else if (!prefix && RSSAXEqualTags(localName, kURL, kURLLength)) { + [self.parser beginStoringCharacters]; + } } @@ -472,6 +476,14 @@ - (void)saxParser:(RSSAXParser *)SAXParser XMLEndElement:(const xmlChar *)localN else if (RSSAXEqualTags(localName, kImage, kImageLength)) { self.parsingChannelImage = NO; } + else if (self.parsingChannelImage && !prefix && RSSAXEqualTags(localName, kURL, kURLLength)) { + if (RSParserStringIsEmpty(self.iconURLString)) { + NSString *urlString = [self currentString]; + if (!RSParserStringIsEmpty(urlString)) { + self.iconURLString = [self urlString:urlString]; + } + } + } else if (RSSAXEqualTags(localName, kItem, kItemLength)) { self.parsingArticle = NO; diff --git a/Modules/RSParser/Sources/Swift/Feeds/XML/RSParsedFeedTransformer.swift b/Modules/RSParser/Sources/Swift/Feeds/XML/RSParsedFeedTransformer.swift index e035374494..96f065c94b 100644 --- a/Modules/RSParser/Sources/Swift/Feeds/XML/RSParsedFeedTransformer.swift +++ b/Modules/RSParser/Sources/Swift/Feeds/XML/RSParsedFeedTransformer.swift @@ -21,7 +21,7 @@ struct RSParsedFeedTransformer { static func parsedFeed(_ rsParsedFeed: RSParsedFeed) -> ParsedFeed { let items = parsedItems(rsParsedFeed.articles) - return ParsedFeed(type: .rss, title: rsParsedFeed.title, homePageURL: rsParsedFeed.homepageURLString, feedURL: rsParsedFeed.urlString, language: rsParsedFeed.language, feedDescription: nil, nextURL: nil, iconURL: nil, faviconURL: nil, authors: nil, expired: false, hubs: nil, items: items) + return ParsedFeed(type: .rss, title: rsParsedFeed.title, homePageURL: rsParsedFeed.homepageURLString, feedURL: rsParsedFeed.urlString, language: rsParsedFeed.language, feedDescription: nil, nextURL: nil, iconURL: rsParsedFeed.iconURLString, faviconURL: nil, authors: nil, expired: false, hubs: nil, items: items) } } diff --git a/Shared/Images/FeedIconDownloader.swift b/Shared/Images/FeedIconDownloader.swift index a95517e702..9a482f5687 100644 --- a/Shared/Images/FeedIconDownloader.swift +++ b/Shared/Images/FeedIconDownloader.swift @@ -102,6 +102,11 @@ extension Notification.Name { } } + if feed.iconURL != nil { + checkFeedIconURL() + return nil + } + if let previouslyFoundIconURL = feedURLToIconURLCache[feed.url] { icon(forURL: previouslyFoundIconURL, feed: feed) { image in MainActor.assumeIsolated { diff --git a/iOS/MainFeed/MainFeedCollectionViewController.swift b/iOS/MainFeed/MainFeedCollectionViewController.swift index 30c7e1a303..9c49bc4762 100644 --- a/iOS/MainFeed/MainFeedCollectionViewController.swift +++ b/iOS/MainFeed/MainFeedCollectionViewController.swift @@ -551,7 +551,7 @@ final class MainFeedCollectionViewController: UICollectionViewController, Undoab } func configureCellsForRepresentedObject(_ representedObject: AnyObject) { -// applyToCellsForRepresentedObject(representedObject, configure) + applyToCellsForRepresentedObject(representedObject, configureIcon(_:_:)) } func applyToCellsForRepresentedObject(_ representedObject: AnyObject, _ completion: (MainFeedCollectionViewCell, IndexPath) -> Void) { @@ -694,7 +694,7 @@ final class MainFeedCollectionViewController: UICollectionViewController, Undoab guard let feed = note.object as? Feed, let key = note.userInfo?[Feed.SettingUserInfoKey] as? Feed.SettingKey else { return } - if key == .homePageURL || key == .faviconURL { + if key == .iconURL || key == .homePageURL || key == .faviconURL { configureCellsForRepresentedObject(feed) } } diff --git a/iOS/MainTimeline/MainTimelineModernViewController.swift b/iOS/MainTimeline/MainTimelineModernViewController.swift index a0ebbb3236..1bca8808e3 100644 --- a/iOS/MainTimeline/MainTimelineModernViewController.swift +++ b/iOS/MainTimeline/MainTimelineModernViewController.swift @@ -597,6 +597,7 @@ private extension MainTimelineModernViewController { NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidChange(_:)), name: .UnreadCountDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(statusesDidChange(_:)), name: .StatusesDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(feedIconDidBecomeAvailable(_:)), name: .feedIconDidBecomeAvailable, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(feedSettingDidChange(_:)), name: .feedSettingDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(avatarDidBecomeAvailable(_:)), name: .AvatarDidBecomeAvailable, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(faviconDidBecomeAvailable(_:)), name: .FaviconDidBecomeAvailable, object: nil) @@ -951,6 +952,27 @@ private extension MainTimelineModernViewController { queueReloadAvailableCells() } + @objc func feedSettingDidChange(_ note: Notification) { + Self.logger.debug("MainTimelineModernViewController: feedSettingDidChange") + + guard isViewLoaded, + let feed = note.object as? Feed, + let key = note.userInfo?[Feed.SettingUserInfoKey] as? Feed.SettingKey else { + return + } + guard key == .iconURL || key == .homePageURL || key == .faviconURL else { + return + } + guard let articles else { + return + } + + let shouldReloadVisibleCells = articles.contains { $0.feed == feed } + if shouldReloadVisibleCells { + queueReloadAvailableCells() + } + } + @objc func avatarDidBecomeAvailable(_ note: Notification) { Self.logger.debug("MainTimelineModernViewController: avatarDidBecomeAvailable")