diff --git a/app/src/main/java/io/legado/app/model/Rss.kt b/app/src/main/java/io/legado/app/model/Rss.kt index 4caca495d..c2568f458 100644 --- a/app/src/main/java/io/legado/app/model/Rss.kt +++ b/app/src/main/java/io/legado/app/model/Rss.kt @@ -5,6 +5,7 @@ import io.legado.app.data.entities.RssSource import io.legado.app.help.coroutine.Coroutine import io.legado.app.model.analyzeRule.AnalyzeRule import io.legado.app.model.analyzeRule.AnalyzeUrl +import io.legado.app.model.rss.Result import io.legado.app.model.rss.RssParserByRule import io.legado.app.utils.NetworkUtils import kotlinx.coroutines.CoroutineScope @@ -18,7 +19,7 @@ object Rss { pageUrl: String? = null, scope: CoroutineScope = Coroutine.DEFAULT, context: CoroutineContext = Dispatchers.IO - ): Coroutine> { + ): Coroutine { return Coroutine.async(scope, context) { val analyzeUrl = AnalyzeUrl(pageUrl ?: rssSource.sourceUrl) val body = analyzeUrl.getResponseAwait(rssSource.sourceUrl).body diff --git a/app/src/main/java/io/legado/app/model/rss/Result.kt b/app/src/main/java/io/legado/app/model/rss/Result.kt new file mode 100644 index 000000000..4d7f67c0a --- /dev/null +++ b/app/src/main/java/io/legado/app/model/rss/Result.kt @@ -0,0 +1,5 @@ +package io.legado.app.model.rss + +import io.legado.app.data.entities.RssArticle + +data class Result(val articles: MutableList, val nextPageUrl: String?) \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/model/rss/RssParser.kt b/app/src/main/java/io/legado/app/model/rss/RssParser.kt index 3656ed69f..7606bd43e 100644 --- a/app/src/main/java/io/legado/app/model/rss/RssParser.kt +++ b/app/src/main/java/io/legado/app/model/rss/RssParser.kt @@ -12,7 +12,7 @@ import java.io.StringReader object RssParser { @Throws(XmlPullParserException::class, IOException::class) - fun parseXML(xml: String, sourceUrl: String): MutableList { + fun parseXML(xml: String, sourceUrl: String): Result { val articleList = mutableListOf() var currentArticle = RssArticle() @@ -105,7 +105,7 @@ object RssParser { Debug.log(sourceUrl, "┌获取文章链接") Debug.log(sourceUrl, "└${it.link}") } - return articleList + return Result(articleList, null) } /** diff --git a/app/src/main/java/io/legado/app/model/rss/RssParserByRule.kt b/app/src/main/java/io/legado/app/model/rss/RssParserByRule.kt index 571445d86..ed8cbf4bf 100644 --- a/app/src/main/java/io/legado/app/model/rss/RssParserByRule.kt +++ b/app/src/main/java/io/legado/app/model/rss/RssParserByRule.kt @@ -6,12 +6,14 @@ import io.legado.app.data.entities.RssArticle import io.legado.app.data.entities.RssSource import io.legado.app.model.Debug import io.legado.app.model.analyzeRule.AnalyzeRule +import io.legado.app.utils.NetworkUtils object RssParserByRule { @Throws(Exception::class) - fun parseXML(body: String?, rssSource: RssSource): MutableList { + fun parseXML(body: String?, rssSource: RssSource): Result { val sourceUrl = rssSource.sourceUrl + var nextUrl: String? = null if (body.isNullOrBlank()) { throw Exception( App.INSTANCE.getString( @@ -37,6 +39,14 @@ object RssParserByRule { Debug.log(sourceUrl, "┌获取列表") val collections = analyzeRule.getElements(ruleArticles) Debug.log(sourceUrl, "└列表大小:${collections.size}") + if (!rssSource.ruleNextPage.isNullOrEmpty()) { + Debug.log(sourceUrl, "┌获取下一页Url") + nextUrl = analyzeRule.getString(rssSource.ruleNextPage) + if (nextUrl.isNotEmpty()) { + nextUrl = NetworkUtils.getAbsoluteURL(sourceUrl, nextUrl) + } + Debug.log(sourceUrl, "└获取下一页Url:$nextUrl") + } val ruleTitle = analyzeRule.splitSourceRule(rssSource.ruleTitle) val rulePubDate = analyzeRule.splitSourceRule(rssSource.rulePubDate) val ruleDescription = analyzeRule.splitSourceRule(rssSource.ruleDescription) @@ -54,7 +64,7 @@ object RssParserByRule { if (reverse) { articleList.reverse() } - return articleList + return Result(articleList, nextUrl) } } diff --git a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesActivity.kt b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesActivity.kt index f0a8ebfa0..0682fd32c 100644 --- a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesActivity.kt @@ -110,13 +110,13 @@ class RssArticlesActivity : VMBaseActivity(R.layout.activi if (viewModel.isLoading) return if (loadMoreView.hasMore && adapter.getActualItemCount() > 0) { loadMoreView.rotate_loading.show() - viewModel.loadContent() + viewModel.loadMore() } } - override fun loadFinally() { + override fun loadFinally(hasMore: Boolean) { refresh_recycler_view.stopLoading() - if (viewModel.hasMore) { + if (hasMore) { loadMoreView.startLoad() } else { loadMoreView.noMore() diff --git a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesViewModel.kt b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesViewModel.kt index 5c5775bd1..4e41bf979 100644 --- a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesViewModel.kt @@ -9,6 +9,8 @@ import io.legado.app.data.entities.RssArticle import io.legado.app.data.entities.RssSource import io.legado.app.model.Rss import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.Dispatchers.Main +import kotlinx.coroutines.withContext class RssArticlesViewModel(application: Application) : BaseViewModel(application) { @@ -18,6 +20,7 @@ class RssArticlesViewModel(application: Application) : BaseViewModel(application val titleLiveData = MutableLiveData() var isLoading = true var order = System.currentTimeMillis() + var nextPageUrl: String? = null fun initData(intent: Intent, finally: () -> Unit) { execute { @@ -40,15 +43,24 @@ class RssArticlesViewModel(application: Application) : BaseViewModel(application rssSource?.let { rssSource -> Rss.getArticles(rssSource, null) .onSuccess(IO) { - it?.let { - it.forEach { rssArticle -> + nextPageUrl = it?.nextPageUrl + it?.articles?.let { list -> + list.forEach { rssArticle -> rssArticle.order = order-- } - App.db.rssArticleDao().insert(*it.toTypedArray()) + App.db.rssArticleDao().insert(*list.toTypedArray()) if (!rssSource.ruleNextPage.isNullOrEmpty()) { App.db.rssArticleDao().clearOld(url!!, order) + withContext(Main) { + callBack?.loadFinally(true) + } + } else { + withContext(Main) { + callBack?.loadFinally(false) + } } isLoading = false + } }.onError { toast(it.localizedMessage) @@ -56,6 +68,27 @@ class RssArticlesViewModel(application: Application) : BaseViewModel(application } } + fun loadMore() { + isLoading = true + val source = rssSource + val pageUrl = nextPageUrl + if (source != null && pageUrl != null) { + Rss.getArticles(source, pageUrl) + .onSuccess(IO) { + nextPageUrl = it?.nextPageUrl + it?.articles?.let { list -> + list.forEach { rssArticle -> + rssArticle.order = order-- + } + App.db.rssArticleDao().insert(*list.toTypedArray()) + isLoading = false + } + } + } else { + callBack?.loadFinally(false) + } + } + fun read(rssArticle: RssArticle) { execute { rssArticle.read = true @@ -76,6 +109,6 @@ class RssArticlesViewModel(application: Application) : BaseViewModel(application interface CallBack { var adapter: RssArticlesAdapter - fun loadFinally() + fun loadFinally(hasMore: Boolean) } } \ No newline at end of file