parent
06fcfc94b6
commit
1cd3bc1f69
@ -1,124 +1,85 @@ |
||||
package io.legado.app.ui.rss.article |
||||
|
||||
import android.app.Application |
||||
import android.content.Intent |
||||
import android.os.Bundle |
||||
import androidx.lifecycle.MutableLiveData |
||||
import io.legado.app.App |
||||
import io.legado.app.base.BaseViewModel |
||||
import io.legado.app.data.entities.RssArticle |
||||
import io.legado.app.data.entities.RssReadRecord |
||||
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.Dispatchers |
||||
import kotlinx.coroutines.withContext |
||||
|
||||
|
||||
class RssArticlesViewModel(application: Application) : BaseViewModel(application) { |
||||
var callBack: CallBack? = null |
||||
var url: String? = null |
||||
var rssSource: RssSource? = null |
||||
val titleLiveData = MutableLiveData<String>() |
||||
val loadFinally = MutableLiveData<Boolean>() |
||||
var isLoading = true |
||||
var order = System.currentTimeMillis() |
||||
private var nextPageUrl: String? = null |
||||
private val articles = arrayListOf<RssArticle>() |
||||
var sortName: String = "" |
||||
var sortUrl: String = "" |
||||
|
||||
fun initData(intent: Intent, finally: () -> Unit) { |
||||
execute { |
||||
url = intent.getStringExtra("url") |
||||
url?.let { url -> |
||||
rssSource = App.db.rssSourceDao().getByKey(url) |
||||
rssSource?.let { |
||||
titleLiveData.postValue(it.sourceName) |
||||
} ?: let { |
||||
rssSource = RssSource(sourceUrl = url) |
||||
} |
||||
} |
||||
}.onFinally { |
||||
finally() |
||||
fun init(bundle: Bundle?) { |
||||
bundle?.let { |
||||
sortName = it.getString("sortName") ?: "" |
||||
sortUrl = it.getString("sortUrl") ?: "" |
||||
} |
||||
} |
||||
|
||||
fun loadContent() { |
||||
|
||||
fun loadContent(rssSource: RssSource) { |
||||
isLoading = true |
||||
rssSource?.let { rssSource -> |
||||
Rss.getArticles(rssSource, null) |
||||
.onSuccess(IO) { |
||||
nextPageUrl = it.nextPageUrl |
||||
it.articles.let { list -> |
||||
list.forEach { rssArticle -> |
||||
rssArticle.order = order-- |
||||
} |
||||
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) |
||||
} |
||||
Rss.getArticles(sortName, sortUrl, rssSource, null) |
||||
.onSuccess(Dispatchers.IO) { |
||||
nextPageUrl = it.nextPageUrl |
||||
it.articles.let { list -> |
||||
list.forEach { rssArticle -> |
||||
rssArticle.order = order-- |
||||
} |
||||
App.db.rssArticleDao().insert(*list.toTypedArray()) |
||||
if (!rssSource.ruleNextPage.isNullOrEmpty()) { |
||||
App.db.rssArticleDao().clearOld(rssSource.sourceUrl, order) |
||||
loadFinally.postValue(true) |
||||
} else { |
||||
withContext(Dispatchers.Main) { |
||||
loadFinally.postValue(false) |
||||
} |
||||
isLoading = false |
||||
|
||||
} |
||||
}.onError { |
||||
toast(it.localizedMessage) |
||||
isLoading = false |
||||
} |
||||
} |
||||
}.onError { |
||||
toast(it.localizedMessage) |
||||
} |
||||
} |
||||
|
||||
fun loadMore() { |
||||
fun loadMore(rssSource: RssSource) { |
||||
isLoading = true |
||||
val source = rssSource |
||||
val pageUrl = nextPageUrl |
||||
if (source != null && !pageUrl.isNullOrEmpty()) { |
||||
Rss.getArticles(source, pageUrl) |
||||
.onSuccess(IO) { |
||||
if (!pageUrl.isNullOrEmpty()) { |
||||
Rss.getArticles(sortName, sortUrl, rssSource, pageUrl) |
||||
.onSuccess(Dispatchers.IO) { |
||||
nextPageUrl = it.nextPageUrl |
||||
it.articles.let { list -> |
||||
if (list.isEmpty()) { |
||||
callBack?.loadFinally(false) |
||||
loadFinally.postValue(true) |
||||
return@let |
||||
} |
||||
callBack?.adapter?.getItems()?.let { adapterItems -> |
||||
if (adapterItems.contains(list.first())) { |
||||
callBack?.loadFinally(false) |
||||
} else { |
||||
list.forEach { rssArticle -> |
||||
rssArticle.order = order-- |
||||
} |
||||
App.db.rssArticleDao().insert(*list.toTypedArray()) |
||||
if (articles.contains(list.first())) { |
||||
loadFinally.postValue(false) |
||||
} else { |
||||
list.forEach { rssArticle -> |
||||
rssArticle.order = order-- |
||||
} |
||||
App.db.rssArticleDao().insert(*list.toTypedArray()) |
||||
} |
||||
} |
||||
isLoading = false |
||||
} |
||||
} else { |
||||
callBack?.loadFinally(false) |
||||
loadFinally.postValue(false) |
||||
} |
||||
} |
||||
|
||||
fun read(rssArticle: RssArticle) { |
||||
execute { |
||||
App.db.rssArticleDao().insertRecord(RssReadRecord(rssArticle.link)) |
||||
} |
||||
} |
||||
|
||||
fun clearArticles() { |
||||
execute { |
||||
url?.let { |
||||
App.db.rssArticleDao().delete(it) |
||||
} |
||||
order = System.currentTimeMillis() |
||||
}.onSuccess { |
||||
loadContent() |
||||
} |
||||
} |
||||
|
||||
interface CallBack { |
||||
var adapter: RssArticlesAdapter |
||||
fun loadFinally(hasMore: Boolean) |
||||
} |
||||
} |
@ -0,0 +1,102 @@ |
||||
package io.legado.app.ui.rss.article |
||||
|
||||
import android.app.Activity |
||||
import android.content.Intent |
||||
import android.os.Bundle |
||||
import android.view.Menu |
||||
import android.view.MenuItem |
||||
import androidx.fragment.app.Fragment |
||||
import androidx.fragment.app.FragmentManager |
||||
import androidx.fragment.app.FragmentStatePagerAdapter |
||||
import androidx.lifecycle.Observer |
||||
import io.legado.app.R |
||||
import io.legado.app.base.VMBaseActivity |
||||
import io.legado.app.ui.rss.source.edit.RssSourceEditActivity |
||||
import io.legado.app.utils.getViewModel |
||||
import io.legado.app.utils.gone |
||||
import io.legado.app.utils.visible |
||||
import kotlinx.android.synthetic.main.activity_rss_artivles.* |
||||
import kotlinx.android.synthetic.main.view_refresh_recycler.* |
||||
import org.jetbrains.anko.startActivityForResult |
||||
|
||||
class RssSortActivity : VMBaseActivity<RssSortViewModel>(R.layout.activity_rss_artivles) { |
||||
|
||||
override val viewModel: RssSortViewModel |
||||
get() = getViewModel(RssSortViewModel::class.java) |
||||
private val editSource = 12319 |
||||
private val fragments = linkedMapOf<String, RssArticlesFragment>() |
||||
private lateinit var adapter: TabFragmentPageAdapter |
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) { |
||||
adapter = TabFragmentPageAdapter(supportFragmentManager) |
||||
tab_layout.setupWithViewPager(view_pager) |
||||
view_pager.adapter = adapter |
||||
viewModel.titleLiveData.observe(this, Observer { |
||||
title_bar.title = it |
||||
}) |
||||
viewModel.initData(intent) { |
||||
upFragments() |
||||
} |
||||
} |
||||
|
||||
override fun onCompatCreateOptionsMenu(menu: Menu): Boolean { |
||||
menuInflater.inflate(R.menu.rss_articles, menu) |
||||
return super.onCompatCreateOptionsMenu(menu) |
||||
} |
||||
|
||||
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { |
||||
when (item.itemId) { |
||||
R.id.menu_edit_source -> viewModel.rssSource?.sourceUrl?.let { |
||||
startActivityForResult<RssSourceEditActivity>(editSource, Pair("data", it)) |
||||
} |
||||
R.id.menu_clear -> { |
||||
viewModel.url?.let { |
||||
refresh_progress_bar.isAutoLoading = true |
||||
viewModel.clearArticles() |
||||
} |
||||
} |
||||
} |
||||
return super.onCompatOptionsItemSelected(item) |
||||
} |
||||
|
||||
private fun upFragments() { |
||||
fragments.clear() |
||||
viewModel.rssSource?.sortUrls()?.forEach { |
||||
fragments[it.key] = RssArticlesFragment.create(it.key, it.value) |
||||
} |
||||
if (fragments.size == 1) { |
||||
tab_layout.gone() |
||||
} else { |
||||
tab_layout.visible() |
||||
} |
||||
adapter.notifyDataSetChanged() |
||||
} |
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { |
||||
super.onActivityResult(requestCode, resultCode, data) |
||||
when (requestCode) { |
||||
editSource -> if (resultCode == Activity.RESULT_OK) { |
||||
viewModel.initData(intent) { |
||||
upFragments() |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
private inner class TabFragmentPageAdapter internal constructor(fm: FragmentManager) : |
||||
FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { |
||||
|
||||
override fun getPageTitle(position: Int): CharSequence? { |
||||
return fragments.keys.elementAt(position) |
||||
} |
||||
|
||||
override fun getItem(position: Int): Fragment { |
||||
return fragments.values.elementAt(position) |
||||
} |
||||
|
||||
override fun getCount(): Int { |
||||
return fragments.size |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,52 @@ |
||||
package io.legado.app.ui.rss.article |
||||
|
||||
import android.app.Application |
||||
import android.content.Intent |
||||
import androidx.lifecycle.MutableLiveData |
||||
import io.legado.app.App |
||||
import io.legado.app.base.BaseViewModel |
||||
import io.legado.app.data.entities.RssArticle |
||||
import io.legado.app.data.entities.RssReadRecord |
||||
import io.legado.app.data.entities.RssSource |
||||
|
||||
|
||||
class RssSortViewModel(application: Application) : BaseViewModel(application) { |
||||
var url: String? = null |
||||
var rssSource: RssSource? = null |
||||
val titleLiveData = MutableLiveData<String>() |
||||
var order = System.currentTimeMillis() |
||||
|
||||
fun initData(intent: Intent, finally: () -> Unit) { |
||||
execute { |
||||
url = intent.getStringExtra("url") |
||||
url?.let { url -> |
||||
rssSource = App.db.rssSourceDao().getByKey(url) |
||||
rssSource?.let { |
||||
titleLiveData.postValue(it.sourceName) |
||||
} ?: let { |
||||
rssSource = RssSource(sourceUrl = url) |
||||
} |
||||
} |
||||
}.onFinally { |
||||
finally() |
||||
} |
||||
} |
||||
|
||||
fun read(rssArticle: RssArticle) { |
||||
execute { |
||||
App.db.rssArticleDao().insertRecord(RssReadRecord(rssArticle.link)) |
||||
} |
||||
} |
||||
|
||||
fun clearArticles() { |
||||
execute { |
||||
url?.let { |
||||
App.db.rssArticleDao().delete(it) |
||||
} |
||||
order = System.currentTimeMillis() |
||||
}.onSuccess { |
||||
|
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,15 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<io.legado.app.ui.widget.dynamiclayout.DynamicFrameLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
android:id="@+id/content_view" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="0dp" |
||||
app:layout_constraintBottom_toBottomOf="parent" |
||||
app:layout_constraintTop_toBottomOf="@id/title_bar"> |
||||
|
||||
<io.legado.app.ui.widget.recycler.RefreshRecyclerView |
||||
android:id="@+id/refresh_recycler_view" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" /> |
||||
|
||||
</io.legado.app.ui.widget.dynamiclayout.DynamicFrameLayout> |
Loading…
Reference in new issue