EhPanda-Team / EhPanda

An unofficial E-Hentai App for iOS built with SwiftUI & TCA.
https://ehpanda.app
MIT License
3.12k stars 208 forks source link

[BUG] (And solution?) Failed to fetch more galleries. #285

Closed Butanediol closed 1 year ago

Butanediol commented 1 year ago

Describe the bug

Due to a recent change of exhentai.org, app failed to fetch more galleries.

More specifically, exhentai.org now use next and prev to do pagination, ditched the page parameter.

To Reproduce

Steps to reproduce the behavior:

  1. Go to 'search'
  2. Search any keyword that has more than one page
  3. Scroll down to bottom
  4. No new items

To Fix 🥳

I've done a little digging. Fortunately, EhPanda already passed the parameter of lastID to moreSearchList URL Builder. 🥳

Note Please note that all the changes below are to let exhentai.org work. You might want to judge whether the user is using e-hentai or exhentai.

Add a new parameter field

All we need to do is to add another parameter ( I call it nextId cuz next looks like a reserved keyword) in Tools/Defaults.swift: Defaults.URL.Component.Keys

  case fSearch = "f_search"
+ case nextId = "next"

Use that parameter

In Network/Request.swift: MoreSearchGalleriesRequest.publisher

URLSession.shared.dataTaskPublisher(for: URLUtil.moreSearchList(
-    keyword: keyword, filter: filter, pageNum: pageNum, lastID: lastID
+    keyword: keyword, filter: filter, lastID: lastID
))

Modify URL Builder

In Tools/Utilities/URLUtil.swift: URLUtil.moreSearchList

-   static func moreSearchList(keyword: String, filter: Filter, pageNum: Int, lastID: String) -> URL {
+   static func moreSearchList(keyword: String, filter: Filter, lastID: String) -> URL {
        Defaults.URL.host.appending(queryItems: [
-           .fSearch: keyword, .page: String(pageNum), .from: lastID
+           .fSearch: keyword, .nextId: lastID
        ])
        .applyingFilter(filter)
    }

Modify reducer

In View/Search/SearchStore.swift: searchReducer

        case .fetchMoreGalleries:
-           let pageNumber = state.pageNumber
-           guard pageNumber.current + 1 <= pageNumber.maximum,
-                 state.footerLoadingState != .loading,
-                 let lastID = state.galleries.last?.id
-           else { return .none }
            state.footerLoadingState = .loading
-           let pageNum = pageNumber.current + 1
+           guard let lastID = state.galleries.last?.id else { return .none }
            let filter = environment.databaseClient.fetchFilterSynchronously(range: .search)
            return MoreSearchGalleriesRequest(
-               keyword: state.lastKeyword, filter: filter, lastID: lastID, pageNum: pageNum
+               keyword: state.lastKeyword, filter: filter, lastID: lastID, pageNum: 0 // I put a 0 here but it actually does nothing
            )
            .effect.map(SearchAction.fetchMoreGalleriesDone).cancellable(id: SearchState.CancelID())

And we are good to go! 🎆

tatsuz0u commented 1 year ago

Thanks for your feedback.

cc @chihchy need further investigation.

qingxu-thu commented 1 year ago

Have the solution been updated to current ver? I can still not fetch more and see only one page