diff --git a/Multiplatform/Shared/Timeline/TimelineModel.swift b/Multiplatform/Shared/Timeline/TimelineModel.swift index 6870984c7..5fd90bccc 100644 --- a/Multiplatform/Shared/Timeline/TimelineModel.swift +++ b/Multiplatform/Shared/Timeline/TimelineModel.swift @@ -214,13 +214,13 @@ private extension TimelineModel { let groupByPublisher = groupByFeedSubject.removeDuplicates() timelineItemsPublisher = readFilterAndFeedsPublisher - .map { [weak self] (feeds, readFilter) -> Set
in - return self?.fetchArticles(feeds: feeds, isReadFiltered: readFilter) ?? Set
() + .flatMap { (feeds, readFilter) in + Self.fetchArticles(feeds: feeds, isReadFiltered: readFilter) } .combineLatest(sortDirectionPublisher, groupByPublisher) - .compactMap { [weak self] articles, sortDirection, groupBy in + .compactMap { articles, sortDirection, groupBy in let sortedArticles = Array(articles).sortedByDate(sortDirection ? .orderedDescending : .orderedAscending, groupByFeed: groupBy) - return self?.buildTimelineItems(articles: sortedArticles) ?? TimelineItems() + return Self.buildTimelineItems(articles: sortedArticles) } .share(replay: 1) .eraseToAnyPublisher() @@ -360,28 +360,44 @@ private extension TimelineModel { // MARK: Article Fetching - func fetchArticles(feeds: [Feed], isReadFiltered: Bool?) -> Set
{ - if feeds.isEmpty { - return Set
() - } + static func fetchArticles(feeds: [Feed], isReadFiltered: Bool?) -> Future, Never> { + return Future, Never> { promise in + + if feeds.isEmpty { + promise(.success(Set
())) + } - var fetchedArticles = Set
() - for feed in feeds { - if isReadFiltered ?? true { - if let articles = try? feed.fetchUnreadArticles() { - fetchedArticles.formUnion(articles) + let group = DispatchGroup() + var result = Set
() + + for feed in feeds { + if isReadFiltered ?? true { + group.enter() + feed.fetchUnreadArticlesAsync { articleSetResult in + let articles = (try? articleSetResult.get()) ?? Set
() + result.formUnion(articles) + group.leave() + } } - } else { - if let articles = try? feed.fetchArticles() { - fetchedArticles.formUnion(articles) + else { + group.enter() + feed.fetchArticlesAsync { articleSetResult in + let articles = (try? articleSetResult.get()) ?? Set
() + result.formUnion(articles) + group.leave() + } } } + + group.notify(queue: DispatchQueue.main) { + promise(.success(result)) + } + } - return fetchedArticles - } + } - func buildTimelineItems(articles: [Article]) -> TimelineItems { + static func buildTimelineItems(articles: [Article]) -> TimelineItems { var items = TimelineItems() for (position, article) in articles.enumerated() { items.append(TimelineItem(position: position, article: article))