feat: Use /sources/stats in the home (#133)

## Types of changes

- [x] I have read the **CONTRIBUTING** document.
- [x] My code follows the code style of this project.
- [ ] I have updated the documentation accordingly.
- [x] I have added tests to cover my changes.
- [x] All new and existing tests passed.
- [x] This is **NOT** translation related.

This is implements feature #131 and it will allow implementing #132
With this, public mode functions perfectly and also has source filtering.

Co-authored-by: davidoskky <davidoskky@yahoo.it>
Reviewed-on: https://gitea.amine-louveau.fr/Louvorg/ReaderForSelfoss-multiplatform/pulls/133
Co-authored-by: davidoskky <davidoskky@hidden.hidden>
Co-committed-by: davidoskky <davidoskky@hidden.hidden>
This commit is contained in:
2023-03-13 16:26:54 +00:00
committed by Amine Louveau
parent 9d2cc32bc9
commit e21906e70d
9 changed files with 130 additions and 75 deletions

View File

@ -49,13 +49,13 @@ class SourcesActivity : AppCompatActivity(), DIAware {
super.onResume()
val mLayoutManager = LinearLayoutManager(this)
var items: ArrayList<SelfossModel.Source>
var items: ArrayList<SelfossModel.SourceDetail>
binding.recyclerView.setHasFixedSize(true)
binding.recyclerView.layoutManager = mLayoutManager
CoroutineScope(Dispatchers.Main).launch {
val response = repository.getSources()
val response = repository.getSourcesDetails()
if (response.isNotEmpty()) {
items = response
val mAdapter = SourcesListAdapter(

View File

@ -24,7 +24,7 @@ import org.kodein.di.instance
class UpsertSourceActivity : AppCompatActivity(), DIAware {
private var existingSource: SelfossModel.Source? = null
private var existingSource: SelfossModel.SourceDetail? = null
private var mSpoutsValue: String? = null
private lateinit var binding: ActivityUpsertSourceBinding
@ -68,7 +68,7 @@ class UpsertSourceActivity : AppCompatActivity(), DIAware {
private fun initFields(items: Map<String, SelfossModel.Spout>) {
binding.nameInput.setText(existingSource!!.title)
binding.tags.setText(existingSource!!.tags.joinToString(", "))
binding.tags.setText(existingSource!!.tags?.joinToString(", "))
binding.sourceUri.setText(existingSource!!.params?.url)
binding.spoutsSpinner.setSelection(items.keys.indexOf(existingSource!!.spout))
binding.progress.visibility = View.GONE

View File

@ -31,7 +31,7 @@ import org.kodein.di.instance
class SourcesListAdapter(
private val app: Activity,
private val items: ArrayList<SelfossModel.Source>
private val items: ArrayList<SelfossModel.SourceDetail>
) : RecyclerView.Adapter<SourcesListAdapter.ViewHolder>(), DIAware {
private val c: Context = app.baseContext
private val generator: ColorGenerator = ColorGenerator.MATERIAL
@ -61,7 +61,7 @@ class SourcesListAdapter(
c.circularBitmapDrawable(itm.getIcon(repository.baseUrl), binding.itemImage)
}
if (itm.error.isNotBlank()) {
if (!itm.error.isNullOrBlank()) {
binding.errorText.visibility = View.VISIBLE
binding.errorText.text = itm.error
} else {

View File

@ -82,7 +82,7 @@ class FilterSheetFragment : BottomSheetDialogFragment(), DIAware {
) {
val sourceGroup = binding.sourcesGroup
repository.getSources().forEach { source ->
repository.getSourcesDetailsOrStats().forEach { source ->
val c = Chip(context)
c.ellipsize = TextUtils.TruncateAt.END
@ -127,9 +127,9 @@ class FilterSheetFragment : BottomSheetDialogFragment(), DIAware {
selectedChip = c
}
c.isEnabled = source.error.isBlank()
c.isEnabled = source.error.isNullOrBlank()
if (source.error.isNotBlank() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (!source.error.isNullOrBlank() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
c.tooltipText = source.error
}

View File

@ -300,9 +300,10 @@ class RepositoryTest {
every { appSettingsService.isItemCachingEnabled() } returns true
initializeRepository(MutableStateFlow(false))
repository.setSourceFilter(SelfossModel.Source(
repository.setSourceFilter(SelfossModel.SourceDetail(
1,
"Test",
null,
listOf("tags"),
SPOUT,
"",
@ -609,30 +610,32 @@ class RepositoryTest {
fun get_sources() {
val (sources, sourcesDB) = prepareSources()
initializeRepository()
var testSources: List<SelfossModel.Source>?
var testSources: List<SelfossModel.Source>
runBlocking {
testSources = repository.getSources()
testSources = repository.getSourcesDetails()
}
assertSame(sources, testSources)
assertEquals(sources, testSources)
assertNotEquals(sourcesDB.map { it.toView() }, testSources)
coVerify(exactly = 1) { api.sources() }
coVerify(exactly = 1) { api.sourcesDetailed() }
}
private fun prepareSources(): Pair<ArrayList<SelfossModel.Source>, List<SOURCE>> {
private fun prepareSources(): Pair<ArrayList<SelfossModel.SourceDetail>, List<SOURCE>> {
val sources = arrayListOf(
SelfossModel.Source(
SelfossModel.SourceDetail(
1,
"First source",
null,
listOf("Test", "second"),
SPOUT,
"",
IMAGE_URL_2,
SelfossModel.SourceParams("url")
),
SelfossModel.Source(
SelfossModel.SourceDetail(
2,
"Second source",
null,
listOf("second"),
SPOUT,
"",
@ -661,7 +664,7 @@ class RepositoryTest {
)
)
coEvery { api.sources() } returns StatusAndData(success = true, data = sources)
coEvery { api.sourcesDetailed() } returns StatusAndData(success = true, data = sources)
every { db.sourcesQueries.sources().executeAsList() } returns sourcesDB
return Pair(sources, sourcesDB)
}
@ -675,13 +678,13 @@ class RepositoryTest {
initializeRepository()
var testSources: List<SelfossModel.Source>?
runBlocking {
testSources = repository.getSources()
testSources = repository.getSourcesDetails()
// Sources will be fetched from the database on the second call, thus testSources != sources
testSources = repository.getSources()
testSources = repository.getSourcesDetails()
}
coVerify(exactly = 1) { api.sources() }
assertNotSame(sources, testSources)
coVerify(exactly = 1) { api.sourcesDetailed() }
assertNotEquals(sources, testSources)
assertEquals(sourcesDB.map { it.toView() }, testSources)
verify(atLeast = 1) { db.sourcesQueries.sources().executeAsList() }
}
@ -693,13 +696,13 @@ class RepositoryTest {
every { appSettingsService.isUpdateSourcesEnabled() } returns true
every { appSettingsService.isItemCachingEnabled() } returns false
initializeRepository()
var testSources: List<SelfossModel.Source>?
var testSources: List<SelfossModel.Source>
runBlocking {
testSources = repository.getSources()
testSources = repository.getSourcesDetails()
}
assertSame(sources, testSources)
coVerify(exactly = 1) { api.sources() }
assertEquals(sources, testSources)
coVerify(exactly = 1) { api.sourcesDetailed() }
verify(exactly = 0) { db.sourcesQueries }
}
@ -710,13 +713,13 @@ class RepositoryTest {
every { appSettingsService.isUpdateSourcesEnabled() } returns false
every { appSettingsService.isItemCachingEnabled() } returns false
initializeRepository()
var testSources: List<SelfossModel.Source>?
var testSources: List<SelfossModel.Source>
runBlocking {
testSources = repository.getSources()
testSources = repository.getSourcesDetails()
}
assertSame(sources, testSources)
coVerify(exactly = 1) { api.sources() }
assertEquals(sources, testSources)
coVerify(exactly = 1) { api.sourcesDetailed() }
verify(atLeast = 1) { db.sourcesQueries }
}
@ -724,13 +727,13 @@ class RepositoryTest {
fun get_sources_without_connection() {
val (_, sourcesDB) = prepareSources()
initializeRepository(MutableStateFlow(false))
var testSources: List<SelfossModel.Source>?
var testSources: List<SelfossModel.Source>
runBlocking {
testSources = repository.getSources()
testSources = repository.getSourcesDetails()
}
assertEquals(sourcesDB.map { it.toView() }, testSources)
coVerify(exactly = 0) { api.sources() }
coVerify(exactly = 0) { api.sourcesDetailed() }
verify(atLeast = 1) { db.sourcesQueries.sources().executeAsList() }
}
@ -741,13 +744,13 @@ class RepositoryTest {
every { appSettingsService.isItemCachingEnabled() } returns false
every { appSettingsService.isUpdateSourcesEnabled() } returns true
initializeRepository(MutableStateFlow(false))
var testSources: List<SelfossModel.Source>?
var testSources: List<SelfossModel.Source>
runBlocking {
testSources = repository.getSources()
testSources = repository.getSourcesDetails()
}
assertEquals(emptyList<SelfossModel.Source>(), testSources)
coVerify(exactly = 0) { api.sources() }
coVerify(exactly = 0) { api.sourcesDetailed() }
verify(exactly = 0) { db.sourcesQueries.sources().executeAsList() }
}
@ -758,13 +761,13 @@ class RepositoryTest {
every { appSettingsService.isItemCachingEnabled() } returns true
every { appSettingsService.isUpdateSourcesEnabled() } returns false
initializeRepository(MutableStateFlow(false))
var testSources: List<SelfossModel.Source>?
var testSources: List<SelfossModel.Source>
runBlocking {
testSources = repository.getSources()
testSources = repository.getSourcesDetails()
}
assertEquals(sourcesDB.map { it.toView() }, testSources)
coVerify(exactly = 0) { api.sources() }
coVerify(exactly = 0) { api.sourcesDetailed() }
verify(atLeast = 1) { db.sourcesQueries.sources().executeAsList() }
}
@ -775,13 +778,13 @@ class RepositoryTest {
every { appSettingsService.isItemCachingEnabled() } returns false
every { appSettingsService.isUpdateSourcesEnabled() } returns false
initializeRepository(MutableStateFlow(false))
var testSources: List<SelfossModel.Source>?
var testSources: List<SelfossModel.Source>
runBlocking {
testSources = repository.getSources()
testSources = repository.getSourcesDetails()
}
assertEquals(sourcesDB.map { it.toView() }, testSources)
coVerify(exactly = 0) { api.sources() }
coVerify(exactly = 0) { api.sourcesDetailed() }
verify(atLeast = 1) { db.sourcesQueries.sources().executeAsList() }
}
@ -1102,9 +1105,10 @@ class RepositoryTest {
private fun prepareSearch() {
repository.setTagFilter(SelfossModel.Tag("Tag", "read", 0))
repository.setSourceFilter(
SelfossModel.Source(
SelfossModel.SourceDetail(
1,
"First source",
5,
listOf("Test", "second"),
SPOUT,
"",