Commit 3088922f authored by Christophe Henry's avatar Christophe Henry

Fix multiple display bugs:

- Articles not sorted by publication date
- Display a message stating all articles have been read after comming back from a feed with a single unread article
parent 7ef529c4
...@@ -84,9 +84,9 @@ dependencies { ...@@ -84,9 +84,9 @@ dependencies {
implementation "com.android.support:support-core-ui:$android_support_version" implementation "com.android.support:support-core-ui:$android_support_version"
// AndroidX layout // AndroidX layout
implementation "androidx.appcompat:appcompat:1.1.0-alpha02" implementation "androidx.appcompat:appcompat:1.1.0-alpha03"
implementation "androidx.core:core-ktx:1.1.0-alpha03" implementation "androidx.core:core-ktx:1.1.0-alpha05"
implementation "com.google.android.material:material:1.0.0-beta01" implementation "com.google.android.material:material:1.1.0-alpha04"
implementation "androidx.constraintlayout:constraintlayout:1.1.3" implementation "androidx.constraintlayout:constraintlayout:1.1.3"
implementation "androidx.recyclerview:recyclerview:1.0.0" implementation "androidx.recyclerview:recyclerview:1.0.0"
......
package fr.chenry.android.freshrss.components.subscriptionarticles package fr.chenry.android.freshrss.components.subscriptionarticles
import android.view.* import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import fr.chenry.android.freshrss.BR import fr.chenry.android.freshrss.BR
import fr.chenry.android.freshrss.R import fr.chenry.android.freshrss.R
import fr.chenry.android.freshrss.databinding.FragmentSubscriptionArticleBinding import fr.chenry.android.freshrss.databinding.FragmentSubscriptionArticleBinding
import fr.chenry.android.freshrss.store.*
import fr.chenry.android.freshrss.store.database.models.Article import fr.chenry.android.freshrss.store.database.models.Article
import fr.chenry.android.freshrss.store.database.models.Articles import fr.chenry.android.freshrss.store.database.models.Articles
...@@ -14,6 +14,7 @@ class RecyclerViewAdapter(private val fragment: SubscriptionArticlesFragment): ...@@ -14,6 +14,7 @@ class RecyclerViewAdapter(private val fragment: SubscriptionArticlesFragment):
RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>() RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>()
{ {
var articles: Articles = listOf() var articles: Articles = listOf()
val subscription get() = fragment.model.subscription
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context) val layoutInflater = LayoutInflater.from(parent.context)
...@@ -35,6 +36,7 @@ class RecyclerViewAdapter(private val fragment: SubscriptionArticlesFragment): ...@@ -35,6 +36,7 @@ class RecyclerViewAdapter(private val fragment: SubscriptionArticlesFragment):
inner class ViewHolder(val binding: FragmentSubscriptionArticleBinding): RecyclerView.ViewHolder(binding.root) { inner class ViewHolder(val binding: FragmentSubscriptionArticleBinding): RecyclerView.ViewHolder(binding.root) {
fun bind(article: Article) { fun bind(article: Article) {
binding.setVariable(BR.article, article) binding.setVariable(BR.article, article)
binding.setVariable(BR.subscription, subscription)
binding.executePendingBindings() binding.executePendingBindings()
} }
} }
......
...@@ -15,8 +15,8 @@ import fr.chenry.android.freshrss.store.Store ...@@ -15,8 +15,8 @@ import fr.chenry.android.freshrss.store.Store
import fr.chenry.android.freshrss.store.database.models.Article import fr.chenry.android.freshrss.store.database.models.Article
import fr.chenry.android.freshrss.store.database.models.ReadStatus import fr.chenry.android.freshrss.store.database.models.ReadStatus
import fr.chenry.android.freshrss.store.database.models.ReadStatus.UNREAD import fr.chenry.android.freshrss.store.database.models.ReadStatus.UNREAD
import fr.chenry.android.freshrss.store.viewmodels.SubscriptionArticlesVM import fr.chenry.android.freshrss.store.viewmodels.SubscriptionArticleVM
import fr.chenry.android.freshrss.store.viewmodels.SubscriptionArticlesVMF import fr.chenry.android.freshrss.store.viewmodels.SubscriptionArticleVMF
import fr.chenry.android.freshrss.utils.capitalizeFull import fr.chenry.android.freshrss.utils.capitalizeFull
import fr.chenry.android.freshrss.utils.e import fr.chenry.android.freshrss.utils.e
import kotlinx.android.synthetic.main.fragment_subscription_article_detail.* import kotlinx.android.synthetic.main.fragment_subscription_article_detail.*
...@@ -27,10 +27,10 @@ import kotlin.text.RegexOption.IGNORE_CASE ...@@ -27,10 +27,10 @@ import kotlin.text.RegexOption.IGNORE_CASE
class SubscriptionArticlesDetailFragment: Fragment() { class SubscriptionArticlesDetailFragment: Fragment() {
private lateinit var articleId: String private lateinit var articleId: String
private val model: SubscriptionArticlesVM by lazy { private val model: SubscriptionArticleVM by lazy {
ViewModelProviders ViewModelProviders
.of(this, SubscriptionArticlesVMF(articleId)) .of(this, SubscriptionArticleVMF(articleId))
.get(SubscriptionArticlesVM::class.java) .get(SubscriptionArticleVM::class.java)
} }
private var isFetching = MutableLiveData<Boolean>().apply {value = false} private var isFetching = MutableLiveData<Boolean>().apply {value = false}
private val article: Article get() = model.liveData.value!! private val article: Article get() = model.liveData.value!!
......
...@@ -3,41 +3,41 @@ package fr.chenry.android.freshrss.components.subscriptionarticles ...@@ -3,41 +3,41 @@ package fr.chenry.android.freshrss.components.subscriptionarticles
import android.os.Bundle import android.os.Bundle
import android.view.* import android.view.*
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import androidx.navigation.findNavController import androidx.navigation.findNavController
import androidx.navigation.fragment.navArgs import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import fr.chenry.android.freshrss.R import fr.chenry.android.freshrss.R
import fr.chenry.android.freshrss.store.database.FreshRSSDabatabase import fr.chenry.android.freshrss.store.Store
import fr.chenry.android.freshrss.store.database.models.Articles import fr.chenry.android.freshrss.store.database.models.Articles
import fr.chenry.android.freshrss.store.database.models.ReadStatus import fr.chenry.android.freshrss.store.database.models.ReadStatus
import fr.chenry.android.freshrss.store.database.models.ReadStatus.READ import fr.chenry.android.freshrss.store.viewmodels.SubscriptionArticlesVM
import fr.chenry.android.freshrss.store.database.models.ReadStatus.UNREAD import fr.chenry.android.freshrss.store.viewmodels.SubscriptionArticlesVMF
import kotlinx.android.synthetic.main.fragment_subscription_articles.* import kotlinx.android.synthetic.main.fragment_subscription_articles.*
open class SubscriptionArticlesFragment: Fragment(), Observer<Articles> { open class SubscriptionArticlesFragment: Fragment(), Observer<Articles> {
private val args: SubscriptionArticlesFragmentArgs by navArgs()
private val streamId: String by lazy {args.id} private val streamId: String by lazy {args.id}
private val readStatus: ReadStatus by lazy {args.readStatus} private val readStatus: ReadStatus by lazy {args.readStatus}
private val args: SubscriptionArticlesFragmentArgs by navArgs()
private val model: LiveData<Articles> by lazy { val model: SubscriptionArticlesVM by lazy {
when(readStatus) { ViewModelProviders
READ -> FreshRSSDabatabase.instance.getArticleByStreamId(streamId) .of(this, SubscriptionArticlesVMF(streamId, readStatus))
UNREAD -> FreshRSSDabatabase.instance.getArticleByStreamIdAndUnread(streamId) .get(SubscriptionArticlesVM::class.java)
}
} }
private val adapter by lazy { private val adapter by lazy {
RecyclerViewAdapter(this).apply { RecyclerViewAdapter(this).apply {
model.observe(this@SubscriptionArticlesFragment, this@SubscriptionArticlesFragment) model.liveData.observe(this@SubscriptionArticlesFragment, this@SubscriptionArticlesFragment)
} }
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_subscription_articles, container, false) val view = inflater.inflate(R.layout.fragment_subscription_articles, container, false)
model.observe(this, this) model.liveData.observe(this, this)
view.findViewById<RecyclerView>(R.id.fragment_subscription_article_recycler).apply { view.findViewById<RecyclerView>(R.id.fragment_subscription_article_recycler).apply {
layoutManager = LinearLayoutManager(context) layoutManager = LinearLayoutManager(context)
...@@ -49,8 +49,7 @@ open class SubscriptionArticlesFragment: Fragment(), Observer<Articles> { ...@@ -49,8 +49,7 @@ open class SubscriptionArticlesFragment: Fragment(), Observer<Articles> {
override fun onChanged(articles: Articles?) { override fun onChanged(articles: Articles?) {
(articles ?: listOf()).let { (articles ?: listOf()).let {
fragment_subscription_article_waiting.visibility = if(it.isNotEmpty()) View.GONE else View.VISIBLE toggleProgressCircle(it)
fragment_subscription_article_recycler.visibility = if(it.isEmpty()) View.GONE else View.VISIBLE
adapter.articles = it adapter.articles = it
adapter.notifyDataSetChanged() adapter.notifyDataSetChanged()
} }
...@@ -62,4 +61,21 @@ open class SubscriptionArticlesFragment: Fragment(), Observer<Articles> { ...@@ -62,4 +61,21 @@ open class SubscriptionArticlesFragment: Fragment(), Observer<Articles> {
.actionSubscriptionArticlesFragmentToSubscriptionArticlesDetailFragment(articleId) .actionSubscriptionArticlesFragmentToSubscriptionArticlesDetailFragment(articleId)
view?.findNavController()?.navigate(direction) view?.findNavController()?.navigate(direction)
} }
private fun toggleProgressCircle(articles: Articles) {
fragment_subscription_article_empty_list.text = when(readStatus) {
ReadStatus.READ -> context?.getString(R.string.empty_subscription_list, model.subscription.title)
ReadStatus.UNREAD -> context?.getString(R.string.empty_subscription_unread_list, model.subscription.title)
}
if(Store.refreshingPromise.value == null) {
fragment_subscription_article_recycler.visibility = if(articles.isNotEmpty()) View.VISIBLE else View.GONE
fragment_subscription_article_empty_list.visibility = if(articles.isEmpty()) View.VISIBLE else View.GONE
fragment_subscription_article_waiting.visibility = View.GONE
} else {
fragment_subscription_article_recycler.visibility = if(articles.isNotEmpty()) View.VISIBLE else View.GONE
fragment_subscription_article_waiting.visibility = if(articles.isEmpty()) View.VISIBLE else View.GONE
fragment_subscription_article_empty_list.visibility = View.GONE
}
}
} }
...@@ -18,7 +18,6 @@ import fr.chenry.android.freshrss.store.viewmodels.* ...@@ -18,7 +18,6 @@ import fr.chenry.android.freshrss.store.viewmodels.*
import kotlinx.android.synthetic.main.fragment_subscriptions.* import kotlinx.android.synthetic.main.fragment_subscriptions.*
class SubscriptionsFragment: Fragment(), Observer<Subscriptions> { class SubscriptionsFragment: Fragment(), Observer<Subscriptions> {
val subscriptions get() = model.liveData.value ?: listOf()
private val subscriptionSection by lazy { private val subscriptionSection by lazy {
arguments?.getParcelable(argumentKey) ?: SubscriptionSection.ALL arguments?.getParcelable(argumentKey) ?: SubscriptionSection.ALL
} }
...@@ -36,7 +35,7 @@ class SubscriptionsFragment: Fragment(), Observer<Subscriptions> { ...@@ -36,7 +35,7 @@ class SubscriptionsFragment: Fragment(), Observer<Subscriptions> {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_subscriptions, container, false) val view = inflater.inflate(R.layout.fragment_subscriptions, container, false)
Store.refreshingPromise.observe(this, Observer {toggleProgressCircle()}) Store.refreshingPromise.observe(this, Observer {toggleProgressCircle(model.liveData.value ?: listOf())})
model.liveData.observe(this, this) model.liveData.observe(this, this)
view.findViewById<RecyclerView>(R.id.subscriptions_list).let { view.findViewById<RecyclerView>(R.id.subscriptions_list).let {
...@@ -45,13 +44,13 @@ class SubscriptionsFragment: Fragment(), Observer<Subscriptions> { ...@@ -45,13 +44,13 @@ class SubscriptionsFragment: Fragment(), Observer<Subscriptions> {
} }
when(subscriptionSection) { when(subscriptionSection) {
ALL -> FreshRSSApplication.getStringR(R.string.empty_subscription_list_all) ALL -> FreshRSSApplication.getStringR(R.string.empty_subscriptions_all_category)
UNREAD -> FreshRSSApplication.getStringR(R.string.empty_subscription_list_unread) UNREAD -> FreshRSSApplication.getStringR(R.string.empty_subscriptions_unread_category)
FAVORITES -> FreshRSSApplication.getStringR(R.string.empty_subscription_list_favorites) FAVORITES -> FreshRSSApplication.getStringR(R.string.empty_subscriptions_favorites_categeory)
}.let { }.let {
view view
.findViewById<TextView>(R.id.fragment_subscriptions_empty_list) .findViewById<TextView>(R.id.fragment_subscriptions_empty_list)
.text = FreshRSSApplication.getStringR(R.string.empty_subscription_list, it) .text = FreshRSSApplication.getStringR(R.string.empty_subscriptions_category_list, it)
} }
return view return view
...@@ -59,7 +58,7 @@ class SubscriptionsFragment: Fragment(), Observer<Subscriptions> { ...@@ -59,7 +58,7 @@ class SubscriptionsFragment: Fragment(), Observer<Subscriptions> {
override fun onChanged(subscriptions: Subscriptions?) { override fun onChanged(subscriptions: Subscriptions?) {
(subscriptions ?: listOf()).let { (subscriptions ?: listOf()).let {
toggleProgressCircle() toggleProgressCircle(it)
adapter.notifyDataSetChanged() adapter.notifyDataSetChanged()
} }
} }
...@@ -72,7 +71,7 @@ class SubscriptionsFragment: Fragment(), Observer<Subscriptions> { ...@@ -72,7 +71,7 @@ class SubscriptionsFragment: Fragment(), Observer<Subscriptions> {
}.let {view?.findNavController()?.navigate(it)} }.let {view?.findNavController()?.navigate(it)}
} }
private fun toggleProgressCircle() { private fun toggleProgressCircle(subscriptions: Subscriptions) {
if(Store.refreshingPromise.value == null) { if(Store.refreshingPromise.value == null) {
subscriptions_list.visibility = if(subscriptions.isNotEmpty()) View.VISIBLE else View.GONE subscriptions_list.visibility = if(subscriptions.isNotEmpty()) View.VISIBLE else View.GONE
fragment_subscriptions_empty_list.visibility = if(subscriptions.isEmpty()) View.VISIBLE else View.GONE fragment_subscriptions_empty_list.visibility = if(subscriptions.isEmpty()) View.VISIBLE else View.GONE
......
...@@ -14,7 +14,7 @@ import nl.komponents.kovenant.functional.bind ...@@ -14,7 +14,7 @@ import nl.komponents.kovenant.functional.bind
import org.joda.time.LocalDateTime import org.joda.time.LocalDateTime
import kotlin.reflect.KProperty import kotlin.reflect.KProperty
@Database(version = 4, entities = [Account::class, Article::class, Subscription::class]) @Database(version = 5, entities = [Account::class, Article::class, Subscription::class])
@TypeConverters(Converters::class) @TypeConverters(Converters::class)
@GenerateRoomMigrations @GenerateRoomMigrations
abstract class FreshRSSDabatabase: RoomDatabase() { abstract class FreshRSSDabatabase: RoomDatabase() {
...@@ -67,6 +67,7 @@ abstract class FreshRSSDabatabase: RoomDatabase() { ...@@ -67,6 +67,7 @@ abstract class FreshRSSDabatabase: RoomDatabase() {
fun incrementSubscriptionCount(id: String) = getSubscriptionsDAO().incrementCount(id) fun incrementSubscriptionCount(id: String) = getSubscriptionsDAO().incrementCount(id)
fun decrementSubscriptionCount(id: String) = getSubscriptionsDAO().decrementCount(id) fun decrementSubscriptionCount(id: String) = getSubscriptionsDAO().decrementCount(id)
fun insertSubscriptionImage(id: String, bitmap: Bitmap) = getSubscriptionsDAO().insertImage(id, bitmap) fun insertSubscriptionImage(id: String, bitmap: Bitmap) = getSubscriptionsDAO().insertImage(id, bitmap)
fun getSubcriptionsById(id: String) = getSubscriptionsDAO().byId(id)
fun getAllSubcriptions() = getSubscriptionsDAO().getAll() fun getAllSubcriptions() = getSubscriptionsDAO().getAll()
fun getAllUnreadSubcriptions() = getSubscriptionsDAO().getAllUnread() fun getAllUnreadSubcriptions() = getSubscriptionsDAO().getAllUnread()
fun getAllSubcriptionsIds() = getSubscriptionsDAO().getAllIds() fun getAllSubcriptionsIds() = getSubscriptionsDAO().getAllIds()
......
{
"formatVersion": 1,
"database": {
"version": 5,
"identityHash": "b2015cd8bc68ba0a77910e0c7e793bc2",
"entities": [
{
"tableName": "accounts",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `SID` TEXT NOT NULL, `Auth` TEXT NOT NULL, `login` TEXT NOT NULL, `serverInstance` TEXT NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "SID",
"columnName": "SID",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "Auth",
"columnName": "Auth",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "login",
"columnName": "login",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "serverInstance",
"columnName": "serverInstance",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "articles",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `title` TEXT NOT NULL, `href` TEXT NOT NULL, `categories` TEXT NOT NULL, `author` TEXT NOT NULL, `content` TEXT NOT NULL, `streamId` TEXT NOT NULL, `readStatus` TEXT NOT NULL, `crawled` INTEGER NOT NULL, `published` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "href",
"columnName": "href",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "categories",
"columnName": "categories",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "author",
"columnName": "author",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "content",
"columnName": "content",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "streamId",
"columnName": "streamId",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "readStatus",
"columnName": "readStatus",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "crawled",
"columnName": "crawled",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "published",
"columnName": "published",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "subscriptions",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`imageBitmap` BLOB, `id` TEXT NOT NULL, `title` TEXT NOT NULL, `iconUrl` TEXT NOT NULL, `unreadCount` INTEGER NOT NULL, `newestArticleDate` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "imageBitmap",
"columnName": "imageBitmap",
"affinity": "BLOB",
"notNull": false
},
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "iconUrl",
"columnName": "iconUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "unreadCount",
"columnName": "unreadCount",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "newestArticleDate",
"columnName": "newestArticleDate",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"b2015cd8bc68ba0a77910e0c7e793bc2\")"
]
}
}
\ No newline at end of file
...@@ -3,7 +3,6 @@ package fr.chenry.android.freshrss.store.database.models ...@@ -3,7 +3,6 @@ package fr.chenry.android.freshrss.store.database.models
import android.net.Uri import android.net.Uri
import android.os.Parcelable import android.os.Parcelable
import androidx.databinding.BaseObservable import androidx.databinding.BaseObservable
import androidx.databinding.Bindable
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.room.* import androidx.room.*
import fr.chenry.android.freshrss.store.api.models.ContentItem import fr.chenry.android.freshrss.store.api.models.ContentItem
...@@ -27,7 +26,8 @@ data class Article( ...@@ -27,7 +26,8 @@ data class Article(
val content: String, val content: String,
val streamId: StreamId, val streamId: StreamId,
val readStatus: ReadStatus = ReadStatus.READ, val readStatus: ReadStatus = ReadStatus.READ,
val crawled: LocalDateTime = LocalDateTime(0) val crawled: LocalDateTime = LocalDateTime(0),
val published: LocalDateTime = LocalDateTime(0)
): BaseObservable() { ): BaseObservable() {
@Ignore @Ignore
val url = Try{Uri.parse(href)}.getOrNull() val url = Try{Uri.parse(href)}.getOrNull()
...@@ -41,7 +41,8 @@ data class Article( ...@@ -41,7 +41,8 @@ data class Article(
item.author, item.author,
item.summary.content, item.summary.content,
item.origin.streamId, item.origin.streamId,
crawled = item.crawled crawled = item.crawled,
published = item.published
) )
} }
} }
......
...@@ -76,7 +76,7 @@ interface SubscriptionsDAO { ...@@ -76,7 +76,7 @@ interface SubscriptionsDAO {
fun getAllUnread(): Flowable<Subscriptions> fun getAllUnread(): Flowable<Subscriptions>
@Query("SELECT * FROM subscriptions WHERE id = :id") @Query("SELECT * FROM subscriptions WHERE id = :id")
fun byId(id: String): Flowable<Subscription> fun byId(id: String): Flowable<Subscriptions>
@Query("SELECT * FROM subscriptions WHERE LENGTH(imageBitmap) IS NULL") @Query("SELECT * FROM subscriptions WHERE LENGTH(imageBitmap) IS NULL")
fun withImageToUpdate(): Flowable<Subscriptions> fun withImageToUpdate(): Flowable<Subscriptions>
......
package fr.chenry.android.freshrss.store.viewmodels
import androidx.lifecycle.*
import fr.chenry.android.freshrss.store.database.FreshRSSDabatabase
import fr.chenry.android.freshrss.store.database.models.*
class SubscriptionArticleVM(private val articleId: ItemId): ViewModel() {
private val flowable by lazy { FreshRSSDabatabase.instance.getArticleById(articleId) }
private val source: LiveData<Articles> by lazy { flowable.toLiveData() }
val liveData: LiveData<Article> by lazy {
MutableLiveData<Article>().apply {
value = flowable.blockingFirst().first()
source.observeForever { value = it.first() }
}
}
}
class SubscriptionArticleVMF(private val articleId: ItemId): ViewModelProvider.NewInstanceFactory() {
override fun <T: ViewModel?> create(modelClass: Class<T>): T {
@Suppress("UNCHECKED_CAST")
return SubscriptionArticleVM(articleId) as T
}
}
\ No newline at end of file
package fr.chenry.android.freshrss.store.viewmodels package fr.chenry.android.freshrss.store.viewmodels
import androidx.lifecycle.* import androidx.lifecycle.*
import fr.chenry.android.freshrss.store.database.FreshRSSDabatabase import fr.chenry.android.freshrss.FreshRSSApplication
import fr.chenry.android.freshrss.store.database.models.* import fr.chenry.android.freshrss.store.database.models.*
class SubscriptionArticlesVM(private val articleId: ItemId): ViewModel() { class SubscriptionArticlesVM(streamId: String, readStatus: ReadStatus): ViewModel() {
private val flowable by lazy { FreshRSSDabatabase.instance.getArticleById(articleId) } val liveData: LiveData<Articles>
private val source: LiveData<Articles> by lazy { flowable.toLiveData() } var subscription: Subscription
val liveData: LiveData<Article> by lazy { private set
MutableLiveData<Article>().apply {
value = flowable.blockingFirst().first() private val subscriptionLiveData: LiveData<Subscriptions>
source.observeForever { value = it.first() } private val source: LiveData<Articles>
init {
val flowable = FreshRSSApplication.database.getSubcriptionsById(streamId)
subscription = flowable.blockingFirst().first()
subscriptionLiveData = flowable.toLiveData()
subscriptionLiveData.observeForever{if(it.isNotEmpty()) subscription = it.first()}
source = when(readStatus) {
ReadStatus.READ -> FreshRSSApplication.database.getArticleByStreamId(streamId)
ReadStatus.UNREAD -> FreshRSSApplication.database.getArticleByStreamIdAndUnread(streamId)
}
liveData = MutableLiveData<Articles>().apply {
value = listOf()
source.observeForever {value = it.sortedByDescending {article -> article.published}}
} }
} }
} }
class SubscriptionArticlesVMF(private val articleId: ItemId): ViewModelProvider.NewInstanceFactory() { class SubscriptionArticlesVMF(private val streamId: String, private val readStatus: ReadStatus): ViewModelProvider.NewInstanceFactory() {
override fun <T: ViewModel?> create(modelClass: Class<T>): T { override fun <T: ViewModel?> create(modelClass: Class<T>): T {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
return SubscriptionArticlesVM(articleId) as T return SubscriptionArticlesVM(streamId, readStatus) as T