Commit c10d31db authored by Christophe Henry's avatar Christophe Henry

Merge branch 'fix-lint-issues' into 'develop'

Fix ktlint offenses

See merge request !26
parents 7ffac0ae 92a1d655
......@@ -9,7 +9,11 @@
* [#50](https://git.feneas.org/christophehenry/freshrss-android/issues/50): Categories are not alphabetically sorted
* [#51](https://git.feneas.org/christophehenry/freshrss-android/issues/51): Unread subscription time groups are not time-sorted
* [#55]()https://git.feneas.org/christophehenry/freshrss-android/issues/55: Links click open page in the webview ([!18](https://git.feneas.org/christophehenry/freshrss-android/merge_requests/18))
* [#55](https://git.feneas.org/christophehenry/freshrss-android/issues/55): Links click open page in the webview ([!18](https://git.feneas.org/christophehenry/freshrss-android/merge_requests/18))
## Refactoring
* [#18](https://git.feneas.org/christophehenry/freshrss-android/issues/18): Setup a code linter and run lints ([!24](https://git.feneas.org/christophehenry/freshrss-android/merge_requests/24), [!26](https://git.feneas.org/christophehenry/freshrss-android/merge_requests/26))
# 1.1.0
......
......@@ -69,10 +69,32 @@ Please read the [Android localization guide](https://developer.android.com/guide
Ensure you ran the linters:
```
```sh
./gradlew spotlessApply lintFix
```
You can automatically configure Android studio to respect the Kotlin lint rules.
First, download and instal [ktlint](https://ktlint.github.io/) whereever you wish.
Then, run:
```sh
ktlint --apply-to-idea-project --android
```
You can also add a git hook the will warn you of lint offenses before you commit:
```sh
ktlint --install-git-pre-commit-hook --android
```
To run the Kotlin lint rules alone:
```sh
ktlint -F "app/src/**/*.kt"
```
This will autocorrect what can be autocorrected. Other errors will be printed.
# Contributors
## The community and the users
......
......@@ -2,12 +2,10 @@ package fr.chenry.android.freshrss
import androidx.test.InstrumentationRegistry
import androidx.test.runner.AndroidJUnit4
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
......
......@@ -27,7 +27,7 @@ abstract class FreshRSSDabatabaseBaseTest {
private lateinit var _database: SQLiteDatabase
val database: SQLiteDatabase
get() {
if(!::_database.isInitialized || !_database.isOpen) {
if (!::_database.isInitialized || !_database.isOpen) {
_database = SQLiteDatabase.openDatabase(
targetContext.getDatabasePath(testDB).absolutePath,
null, SQLiteDatabase.OPEN_READWRITE
......@@ -47,24 +47,24 @@ abstract class FreshRSSDabatabaseBaseTest {
fun migrateDatabase(database: SupportSQLiteDatabase, from: Int, to: Int) {
val migrations = FreshRSSDabatabase_Migrations.build()
(from until to).forEach {version ->
(from until to).forEach { version ->
val migration = migrations[version - 1]
val nextPreMigrationScript = "migration-test-${migration.endVersion}-before.sql"
val nextPostMigrationScript = "migration-test-${migration.endVersion}-after.sql"
assets.list("database")?.find {it == nextPreMigrationScript}?.let {execSQLWithImports(database, it)}
assets.list("database")?.find { it == nextPreMigrationScript }?.let { execSQLWithImports(database, it) }
helper.runMigrationsAndValidate(testDB, migration.endVersion, true, migration)
assets.list("database")?.find {it == nextPostMigrationScript}?.let {execSQLWithImports(database, it)}
assets.list("database")?.find { it == nextPostMigrationScript }?.let { execSQLWithImports(database, it) }
}
}
fun execSQLWithImports(sqlMgr: SupportSQLiteDatabase, name: String) {
val importRegex = "^--\\s*import\\s*:\\s*(\\S+).*$"
assets.open("database/${name.replace(".sql", "")}.sql").bufferedReader().lines().forEachOrdered {sql ->
if(sql.matches(importRegex.toRegex())) {
assets.open("database/${name.replace(".sql", "")}.sql").bufferedReader().lines().forEachOrdered { sql ->
if (sql.matches(importRegex.toRegex())) {
val matcher = importRegex.toPattern().matcher(sql)
while(matcher.find()) execSQLWithImports(sqlMgr, matcher.group(1))
} else if(!sql.startsWith("--", true)) {
while (matcher.find()) execSQLWithImports(sqlMgr, matcher.group(1))
} else if (!sql.startsWith("--", true)) {
sqlMgr.execSQL(sql)
}
}
......
package fr.chenry.android.freshrss
import android.app.Application
import android.content.*
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.content.SharedPreferences
import android.os.Handler
import android.os.IBinder
import androidx.core.app.NotificationManagerCompat
......@@ -20,7 +24,7 @@ import nl.komponents.kovenant.android.stopKovenant
import nl.komponents.kovenant.deferred
import java.util.Properties
class FreshRSSApplication: Application() {
class FreshRSSApplication : Application() {
private val refreshDelay: Long get() = 30
private val _refresherService = MutableLiveData<RefresherService>()
private val serviceConnection = RefresherServiceConnection()
......@@ -50,7 +54,7 @@ class FreshRSSApplication: Application() {
}.getOrDefault(false)
// Debug
//Stetho.initializeWithDefaults(this)
// Stetho.initializeWithDefaults(this)
}
override fun onTerminate() {
......@@ -68,12 +72,12 @@ class FreshRSSApplication: Application() {
val stateSharedPreferences: SharedPreferences
get() = context.getSharedPreferences("STATE", Context.MODE_PRIVATE)
fun getStringR(id: Int, vararg formatArgs: Any = arrayOf()) = if(formatArgs.isEmpty())
fun getStringR(id: Int, vararg formatArgs: Any = arrayOf()) = if (formatArgs.isEmpty())
application.resources.getString(id) else
application.resources.getString(id, *formatArgs)
}
inner class RefresherServiceConnection: ServiceConnection {
inner class RefresherServiceConnection : ServiceConnection {
private val handler = Handler()
private val token = object {}
......
......@@ -5,17 +5,16 @@ import android.app.Service
import android.content.Intent
import android.os.Binder
import androidx.core.app.NotificationCompat
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import fr.chenry.android.freshrss.store.Store
import fr.chenry.android.freshrss.utils.NotificationChanels
import fr.chenry.android.freshrss.utils.NotificationHelper
import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.all
import nl.komponents.kovenant.functional.bind
import nl.komponents.kovenant.ui.*
import nl.komponents.kovenant.ui.alwaysUi
import nl.komponents.kovenant.ui.failUi
class RefresherService: Service() {
class RefresherService : Service() {
private val refreshNotification =
createNotification(R.string.notification_refresh_title, R.string.notification_refresh_description)
.setCategory(Notification.CATEGORY_PROGRESS)
......@@ -28,32 +27,32 @@ class RefresherService: Service() {
override fun onBind(intent: Intent) = RefresherBinder()
fun refresh(): Promise<Unit, Exception> {
if(Store.refreshingPromise.value != null) return Store.refreshingPromise.value!!
if (Store.refreshingPromise.value != null) return Store.refreshingPromise.value!!
this.startForeground(NotificationHelper.ONGOING_REFRESH_NOTIFICATION, refreshNotification)
Store.ensureToken()
val promise = Store.getSubscriptions()
.bind {Store.getUnreadCount()}
.bind { Store.getUnreadCount() }
.bind {
FreshRSSApplication
.database
.getAllSubcriptionsIds()
.blockingFirst()
.map {Store.getStreamContents(it)}
.let {all(it, cancelOthersOnError = false)}
.map { Store.getStreamContents(it) }
.let { all(it, cancelOthersOnError = false) }
}
.bind {Store.getUnreadItems()}
.bind { Store.getUnreadItems() }
Store.refreshingPromise.postValue(promise)
promise.always {Store.refreshingPromise.postValue(null)}
promise.always { Store.refreshingPromise.postValue(null) }
.failUi {
FreshRSSApplication
.notificationManager
.notify(NotificationHelper.FAIL_REFRESH_NOTIFICATION, failNotification)
}
.alwaysUi {stopForeground(true)}
.alwaysUi { stopForeground(true) }
return promise
}
......@@ -70,7 +69,7 @@ class RefresherService: Service() {
.setShowWhen(false)
.setContentInfo(FreshRSSApplication.getStringR(title))
inner class RefresherBinder: Binder() {
inner class RefresherBinder : Binder() {
val service: RefresherService get() = this@RefresherService
}
}
......@@ -8,13 +8,17 @@ import android.os.Bundle
import android.view.View
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.*
import android.widget.AdapterView
import android.widget.AdapterView.OnItemSelectedListener
import android.widget.ArrayAdapter
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.widget.addTextChangedListener
import fr.chenry.android.freshrss.R
import fr.chenry.android.freshrss.store.Store
import fr.chenry.android.freshrss.utils.*
import fr.chenry.android.freshrss.utils.InstanceUrl
import fr.chenry.android.freshrss.utils.Try
import fr.chenry.android.freshrss.utils.e
import kotlinx.android.synthetic.main.activity_login.*
import nl.komponents.kovenant.ui.failUi
import nl.komponents.kovenant.ui.successUi
......@@ -23,7 +27,7 @@ import java.util.Properties
/**
* A login screen that offers login via email/password.
*/
class LoginActivity: AppCompatActivity() {
class LoginActivity : AppCompatActivity() {
private lateinit var instanceUrl: InstanceUrl
override fun onCreate(savedInstanceState: Bundle?) {
......@@ -31,15 +35,15 @@ class LoginActivity: AppCompatActivity() {
setContentView(R.layout.activity_login)
// Set up the login form.
password.setOnEditorActionListener(TextView.OnEditorActionListener {_, id, _ ->
if(id == EditorInfo.IME_ACTION_DONE || id == EditorInfo.IME_NULL) {
password.setOnEditorActionListener(TextView.OnEditorActionListener { _, id, _ ->
if (id == EditorInfo.IME_ACTION_DONE || id == EditorInfo.IME_NULL) {
attemptLogin()
return@OnEditorActionListener true
}
false
})
email_sign_in_button.setOnClickListener {attemptLogin()}
email_sign_in_button.setOnClickListener { attemptLogin() }
instanceUrl = InstanceUrl(InstanceUrl.authorizedProtocols[0], resources.getString(R.string.instance_exemple))
activity_login_protocol_selection.adapter =
ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, InstanceUrl.authorizedProtocols)
......@@ -50,14 +54,14 @@ class LoginActivity: AppCompatActivity() {
instanceUrl = InstanceUrl.parse(properties.getProperty("instance"))
instance.setText(instanceUrl.base)
val protocolIdx = InstanceUrl.authorizedProtocols.indexOf(instanceUrl.protocole)
activity_login_protocol_selection.setSelection(if(protocolIdx >= 0) protocolIdx else 0)
activity_login_protocol_selection.setSelection(if (protocolIdx >= 0) protocolIdx else 0)
login.setText(properties.getProperty("login"))
password.setText(properties.getProperty("password"))
}
computeInstanceURLHint()
instance.addTextChangedListener {computeInstanceURLHint()}
activity_login_protocol_selection.onItemSelectedListener = object: OnItemSelectedListener {
instance.addTextChangedListener { computeInstanceURLHint() }
activity_login_protocol_selection.onItemSelectedListener = object : OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) = computeInstanceURLHint()
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) =
computeInstanceURLHint()
......@@ -72,7 +76,7 @@ class LoginActivity: AppCompatActivity() {
var cancel = false
var focusView: View? = null
if(instanceUrl.isMalformed) {
if (instanceUrl.isMalformed) {
instance.error = getString(R.string.instance_url_malformed)
focusView = instance
cancel = true
......@@ -83,20 +87,20 @@ class LoginActivity: AppCompatActivity() {
val passwordStr = password.text.toString()
// Check for a valid password, if the user entered one.
if(passwordStr.isBlank()) {
if (passwordStr.isBlank()) {
password.error = getString(R.string.error_invalid_password)
focusView = password
cancel = true
}
// Check for a valid email address.
if(loginStr.isBlank()) {
if (loginStr.isBlank()) {
login.error = getString(R.string.error_field_required)
focusView = login
cancel = true
}
if(cancel) {
if (cancel) {
focusView?.requestFocus()
} else {
showProgress(true)
......@@ -113,7 +117,7 @@ class LoginActivity: AppCompatActivity() {
private fun computeInstanceURLHint() {
val instanceStr = instance.text.toString().let {
if(it.isBlank()) resources.getString(R.string.instance_exemple) else it
if (it.isBlank()) resources.getString(R.string.instance_exemple) else it
}
val protocole = activity_login_protocol_selection.selectedItem.toString()
......@@ -142,16 +146,16 @@ class LoginActivity: AppCompatActivity() {
val shortAnimTime = resources.getInteger(android.R.integer.config_shortAnimTime).toLong()
login_form.visibility = if(show) View.GONE else View.VISIBLE
login_form.visibility = if (show) View.GONE else View.VISIBLE
login_form.animate()
.setDuration(shortAnimTime)
.alpha((if(show) 0 else 1).toFloat())
.setListener(object: AnimatorListenerAdapter() {
.alpha((if (show) 0 else 1).toFloat())
.setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
login_form.visibility = if(show) View.GONE else View.VISIBLE
login_form.visibility = if (show) View.GONE else View.VISIBLE
}
})
login_progress.visibility = if(show) View.VISIBLE else View.GONE
login_progress.visibility = if (show) View.VISIBLE else View.GONE
}
}
......@@ -14,19 +14,19 @@ import fr.chenry.android.freshrss.utils.whenNotNull
const val SUBSCRIPTION_SECTION = "SUBSCRIPTION_SECTION"
class MainActivity: AppCompatActivity() {
class MainActivity : AppCompatActivity() {
private val navigation: NavController by lazy {
Navigation.findNavController(this, R.id.main_activity_host_fragment)
}
private val appBarConfiguration by lazy {AppBarConfiguration(navigation.graph)}
private val appBarConfiguration by lazy { AppBarConfiguration(navigation.graph) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
restoreState()
setContentView(R.layout.activity_main)
setupActionBarWithNavController(navigation, appBarConfiguration)
FreshRSSApplication.application.refresherService.value.whenNotNull {it.refresh()}
FreshRSSApplication.application.refresherService.value.whenNotNull { it.refresh() }
}
override fun onResume() {
......
......@@ -7,23 +7,27 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.os.postDelayed
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import fr.chenry.android.freshrss.*
import fr.chenry.android.freshrss.FreshRSSApplication
import fr.chenry.android.freshrss.R
import fr.chenry.android.freshrss.RefresherService
import fr.chenry.android.freshrss.store.database.models.VoidAccount
import fr.chenry.android.freshrss.store.viewmodels.AccountVM
import fr.chenry.android.freshrss.utils.*
import fr.chenry.android.freshrss.utils.e
import fr.chenry.android.freshrss.utils.whenNotNull
import fr.chenry.android.freshrss.utils.whenNull
import kotlinx.android.synthetic.main.activity_start.*
import nl.komponents.kovenant.ui.alwaysUi
import nl.komponents.kovenant.ui.failUi
import org.joda.time.LocalDateTime
class StartActivity: AppCompatActivity() {
private val model by lazy {ViewModelProviders.of(this).get(AccountVM::class.java)}
private val observer = object: Observer<RefresherService> {
class StartActivity : AppCompatActivity() {
private val model by lazy { ViewModelProviders.of(this).get(AccountVM::class.java) }
private val observer = object : Observer<RefresherService> {
override fun onChanged(t: RefresherService?) {
t.whenNotNull {
it.refresh()
.failUi {err -> this.e(err)}
.alwaysUi {FreshRSSApplication.application.refresherService.removeObserver(this)}
.failUi { err -> this.e(err) }
.alwaysUi { FreshRSSApplication.application.refresherService.removeObserver(this) }
}
}
}
......@@ -38,7 +42,7 @@ class StartActivity: AppCompatActivity() {
FreshRSSApplication.application.refresherService.observeForever(observer)
}
when(it) {
when (it) {
null -> ""
VoidAccount -> ""
else -> " ${it.login}"
......
......@@ -10,17 +10,16 @@ import fr.chenry.android.freshrss.databinding.FragmentSubscriptionArticleBinding
import fr.chenry.android.freshrss.store.database.models.Article
import fr.chenry.android.freshrss.store.database.models.Articles
class RecyclerViewAdapter(private val fragment: SubscriptionArticlesFragment):
RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>()
{
class RecyclerViewAdapter(private val fragment: SubscriptionArticlesFragment) :
RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>() {
var articles: Articles = listOf()
val subscription get() = fragment.model.subscription
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding: FragmentSubscriptionArticleBinding
= DataBindingUtil.inflate(layoutInflater, R.layout.fragment_subscription_article, parent, false)
val binding: FragmentSubscriptionArticleBinding =
DataBindingUtil.inflate(layoutInflater, R.layout.fragment_subscription_article, parent, false)
return ViewHolder(binding)
}
......@@ -28,12 +27,12 @@ class RecyclerViewAdapter(private val fragment: SubscriptionArticlesFragment):
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val article = articles[position]
holder.bind(article)
holder.binding.root.setOnClickListener{fragment.navigateToArticle(article.id)}
holder.binding.root.setOnClickListener { fragment.navigateToArticle(article.id) }
}
override fun getItemCount(): Int = articles.size
inner class ViewHolder(val binding: FragmentSubscriptionArticleBinding): RecyclerView.ViewHolder(binding.root) {
inner class ViewHolder(val binding: FragmentSubscriptionArticleBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(article: Article) {
binding.setVariable(BR.article, article)
binding.setVariable(BR.subscription, subscription)
......
......@@ -2,36 +2,43 @@ package fr.chenry.android.freshrss.components.subscriptionarticles
import android.content.Intent
import android.os.Bundle
import android.view.*
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.View
import android.view.ViewGroup
import android.webkit.WebView
import android.widget.Toast
import android.widget.Toast.LENGTH_SHORT
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.*
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import fr.chenry.android.freshrss.FreshRSSApplication
import fr.chenry.android.freshrss.R
import fr.chenry.android.freshrss.components.subscriptionarticles.webviewutils.FRSSWebViewClient
import fr.chenry.android.freshrss.components.subscriptionarticles.webviewutils.ShareIntent
import fr.chenry.android.freshrss.store.Store
import fr.chenry.android.freshrss.store.database.models.*
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.UNREAD
import fr.chenry.android.freshrss.store.database.models.Subscription
import fr.chenry.android.freshrss.store.viewmodels.SubscriptionArticleVM
import fr.chenry.android.freshrss.store.viewmodels.SubscriptionArticleVMF
import fr.chenry.android.freshrss.utils.e
import nl.komponents.kovenant.ui.alwaysUi
import nl.komponents.kovenant.ui.failUi
class SubscriptionArticlesDetailFragment: Fragment() {
class SubscriptionArticlesDetailFragment : Fragment() {
private lateinit var articleId: String
private val model: SubscriptionArticleVM by lazy {
ViewModelProviders
.of(this, SubscriptionArticleVMF(articleId))
.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 subscription: Subscription get() = model.subscription
......@@ -44,12 +51,12 @@ class SubscriptionArticlesDetailFragment: Fragment() {
articleId = arguments?.getString("articleId")!!
activity
.let {activity -> activity as AppCompatActivity}.supportActionBar
?.apply {subtitle = article.title}
.let { activity -> activity as AppCompatActivity }.supportActionBar
?.apply { subtitle = article.title }
val view = inflater.inflate(R.layout.fragment_subscription_article_detail, container, false)
view.findViewById<WebView>(R.id.fragment_subscription_article_detail_web_view).let {wv ->
view.findViewById<WebView>(R.id.fragment_subscription_article_detail_web_view).let { wv ->
"""
|<!DOCTYPE html>
|<html>
......@@ -60,7 +67,7 @@ class SubscriptionArticlesDetailFragment: Fragment() {
| </head>
| <body>
| <h1 id="article-title">${article.title}</h1>
| ${if(article.author.isNotEmpty()) "<h3 id='article-authors'>${article.author}</h3>" else ""}
| ${if (article.author.isNotEmpty()) "<h3 id='article-authors'>${article.author}</h3>" else ""}
| <div id="main-content">${article.content}</div>
| </body>
|</html>
......@@ -86,11 +93,11 @@ class SubscriptionArticlesDetailFragment: Fragment() {
override fun onResume() {
super.onResume()
if(article.readStatus == UNREAD) setReadStatus(ReadStatus.READ)
if (article.readStatus == UNREAD) setReadStatus(ReadStatus.READ)
}
override fun onDestroyView() {
activity.let {it as AppCompatActivity}.supportActionBar?.subtitle = null
activity.let { it as AppCompatActivity }.supportActionBar?.subtitle = null
super.onDestroyView()
}
......@@ -104,9 +111,9 @@ class SubscriptionArticlesDetailFragment: Fragment() {
private fun setupOpenInBrowser(view: View) {
view.findViewById<ExtendedFloatingActionButton>(R.id.fab_open_browser).let {
it.visibility = if(article.url != null) View.VISIBLE else View.GONE
it.visibility = if (article.url != null) View.VISIBLE else View.GONE
it.setOnClickListener {
val intent = Intent(Intent.ACTION_VIEW).apply {data = article.url}
val intent = Intent(Intent.ACTION_VIEW).apply { data = article.url }
startActivity(intent)
}
}
......@@ -115,7 +122,7 @@ class SubscriptionArticlesDetailFragment: Fragment() {
private fun setUpReadStatusButton(menu: Menu) {
menu.findItem(R.id.action_mark_read_status)?.let {
fun mutateUi(article: Article) {
when(article.readStatus) {
when (article.readStatus) {
ReadStatus.READ -> {
it.icon = context?.getDrawable(R.drawable.ic_is_read_24dp)
it.title = context?.getString(R.string.mark_unread)
......@@ -130,12 +137,12 @@ class SubscriptionArticlesDetailFragment: Fragment() {
mutateUi(article)
model.liveData.observe(this, Observer(::mutateUi))
it.setOnMenuItemClickListener {setReadStatus(article.readStatus.toggle())}
it.setOnMenuItemClickListener { setReadStatus(article.readStatus.toggle()) }
}
}
private fun setReadStatus(readStatus: ReadStatus): Boolean {
if(isFetching.value!!) {
if (isFetching.value!!) {
Toast.makeText(context, R.string.request_already_ongoing, LENGTH_SHORT).show()
return false
}
......@@ -143,17 +150,17 @@ class SubscriptionArticlesDetailFragment: Fragment() {
isFetching.value = true
Store.postReadStatus(article, readStatus)
.failUi {e ->
.failUi { e ->
this.e(e)
val readText = when(readStatus) {
val readText = when (readStatus) {
ReadStatus.READ -> this.getString(R.string.read)
ReadStatus.UNREAD -> this.getString(R.string.unread)
}.let {this.getString(R.string.mark_read_status_authorization, it)}
}.let { this.getString(R.string.mark_read_status_authorization, it) }
val toastText = context?.getString(R.string.unable_to, readText)
Toast.makeText(context, toastText, LENGTH_SHORT).show()
} alwaysUi {isFetching.value = false}
} alwaysUi { isFetching.value = false }
return true
}
......
package fr.chenry.android.freshrss.components.subscriptionarticles
import android.os.Bundle
import android.view.*
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
......@@ -17,10 +19,10 @@ import fr.chenry.android.freshrss.store.viewmodels.SubscriptionArticlesVM
import fr.chenry.android.freshrss.store.viewmodels.SubscriptionArticlesVMF
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 readStatus: ReadStatus by lazy {args.readStatus}
private val streamId: String by lazy { args.id }
private val readStatus: ReadStatus by lazy { args.readStatus }
val model: SubscriptionArticlesVM by lazy {
ViewModelProviders
......@@ -63,18 +65,18 @@ open class SubscriptionArticlesFragment: Fragment(), Observer<Articles> {
}
private fun toggleProgressCircle(articles: Articles) {
fragment_subscription_article_empty_list.text = when(readStatus) {
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
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