From 95af59f3642cce7846aaa86e47617a204e18eb89 Mon Sep 17 00:00:00 2001 From: JeffreyCA Date: Sat, 4 Dec 2021 22:37:20 -0800 Subject: [PATCH 1/2] Prevent duplicate posts from showing in feed --- App/Feed/FeedViewModel.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/App/Feed/FeedViewModel.swift b/App/Feed/FeedViewModel.swift index e5337303..0702a70f 100644 --- a/App/Feed/FeedViewModel.swift +++ b/App/Feed/FeedViewModel.swift @@ -11,6 +11,7 @@ import PromiseKit class FeedViewModel { var posts: [Post] = [] + var postIds: Set = Set() var postType: PostType = .news var pageIndex = 1 var isFetching = false @@ -29,13 +30,17 @@ class FeedViewModel { return firstly { HackersKit.shared.getPosts(type: postType, page: pageIndex) }.done { posts in - self.posts.append(contentsOf: posts) + let newPosts = posts.filter { !self.postIds.contains($0.id) } + let newPostIds = newPosts.map { $0.id } + self.posts.append(contentsOf: newPosts) + self.postIds.formUnion(newPostIds) self.isFetching = false } } func reset() { posts = [] + postIds = Set() pageIndex = 1 isFetching = false } From 5089154ae43d3b24b488fdcb0a3d9569a8a232fb Mon Sep 17 00:00:00 2001 From: JeffreyCA Date: Sat, 4 Dec 2021 22:38:28 -0800 Subject: [PATCH 2/2] Fix next page fetching for "New" and "Jobs" posts --- App/Feed/FeedViewModel.swift | 10 ++++++++-- .../HackersKit/HackersKit+PostsList.swift | 13 +++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/App/Feed/FeedViewModel.swift b/App/Feed/FeedViewModel.swift index 0702a70f..ee75bfc3 100644 --- a/App/Feed/FeedViewModel.swift +++ b/App/Feed/FeedViewModel.swift @@ -14,6 +14,7 @@ class FeedViewModel { var postIds: Set = Set() var postType: PostType = .news var pageIndex = 1 + var lastPostId = 0 var isFetching = false func fetchFeed(fetchNextPage: Bool = false) -> Promise { @@ -22,13 +23,17 @@ class FeedViewModel { } if fetchNextPage { - pageIndex += 1 + if postType == .newest || postType == .jobs { + lastPostId = posts.last?.id ?? lastPostId + } else { + pageIndex += 1 + } } isFetching = true return firstly { - HackersKit.shared.getPosts(type: postType, page: pageIndex) + HackersKit.shared.getPosts(type: postType, page: pageIndex, nextId: lastPostId) }.done { posts in let newPosts = posts.filter { !self.postIds.contains($0.id) } let newPostIds = newPosts.map { $0.id } @@ -42,6 +47,7 @@ class FeedViewModel { posts = [] postIds = Set() pageIndex = 1 + lastPostId = 0 isFetching = false } diff --git a/Shared Frameworks/HackersKit/HackersKit+PostsList.swift b/Shared Frameworks/HackersKit/HackersKit+PostsList.swift index 30fe361c..8f73afc4 100644 --- a/Shared Frameworks/HackersKit/HackersKit+PostsList.swift +++ b/Shared Frameworks/HackersKit/HackersKit+PostsList.swift @@ -11,9 +11,9 @@ import PromiseKit import SwiftSoup extension HackersKit { - func getPosts(type: PostType, page: Int = 1) -> Promise<[Post]> { + func getPosts(type: PostType, page: Int = 1, nextId: Int = 0) -> Promise<[Post]> { firstly { - fetchPostsHtml(type: type, page: page) + fetchPostsHtml(type: type, page: page, nextId: nextId) }.map { html in try HtmlParser.postsTableElement(from: html) }.compactMap { tableElement in @@ -21,8 +21,13 @@ extension HackersKit { } } - private func fetchPostsHtml(type: PostType, page: Int) -> Promise { - let url = URL(string: "https://news.ycombinator.com/\(type.rawValue)?p=\(page)")! + private func fetchPostsHtml(type: PostType, page: Int, nextId: Int) -> Promise { + var url: URL + if type == .newest || type == .jobs { + url = URL(string: "https://news.ycombinator.com/\(type.rawValue)?next=\(nextId)")! + } else { + url = URL(string: "https://news.ycombinator.com/\(type.rawValue)?p=\(page)")! + } return fetchHtml(url: url) } }