Remove all connectivity checks outside the repository

This commit is contained in:
davidoskky 2022-08-17 20:20:44 +02:00
parent e71f8718d7
commit 0145349817
6 changed files with 166 additions and 187 deletions

View File

@ -15,7 +15,6 @@ import androidx.appcompat.app.AppCompatActivity
import bou.amine.apps.readerforselfossv2.android.databinding.ActivityLoginBinding import bou.amine.apps.readerforselfossv2.android.databinding.ActivityLoginBinding
import bou.amine.apps.readerforselfossv2.android.themes.AppColors import bou.amine.apps.readerforselfossv2.android.themes.AppColors
import bou.amine.apps.readerforselfossv2.android.utils.isBaseUrlValid import bou.amine.apps.readerforselfossv2.android.utils.isBaseUrlValid
import bou.amine.apps.readerforselfossv2.android.utils.network.isNetworkAvailable
import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.repository.Repository
import com.mikepenz.aboutlibraries.LibsBuilder import com.mikepenz.aboutlibraries.LibsBuilder
import com.russhwolf.settings.Settings import com.russhwolf.settings.Settings
@ -202,15 +201,13 @@ class LoginActivity() : AppCompatActivity(), DIAware {
repository.refreshLoginInformation(url, login, password, httpLogin, httpPassword, isWithSelfSignedCert) repository.refreshLoginInformation(url, login, password, httpLogin, httpPassword, isWithSelfSignedCert)
if (this@LoginActivity.isNetworkAvailable(this@LoginActivity.findViewById(R.id.loginForm))) { CoroutineScope(Dispatchers.IO).launch {
CoroutineScope(Dispatchers.IO).launch { val result = repository.login()
val result = repository.login() if (result) {
if (result) { goToMain()
goToMain() } else {
} else { CoroutineScope(Dispatchers.Main).launch {
CoroutineScope(Dispatchers.Main).launch { preferenceError(Exception("Not success"))
preferenceError(Exception("Not success"))
}
} }
} }
} }

View File

@ -10,7 +10,6 @@ import bou.amine.apps.readerforselfossv2.android.adapters.SourcesListAdapter
import bou.amine.apps.readerforselfossv2.android.databinding.ActivitySourcesBinding import bou.amine.apps.readerforselfossv2.android.databinding.ActivitySourcesBinding
import bou.amine.apps.readerforselfossv2.android.themes.AppColors import bou.amine.apps.readerforselfossv2.android.themes.AppColors
import bou.amine.apps.readerforselfossv2.android.themes.Toppings import bou.amine.apps.readerforselfossv2.android.themes.Toppings
import bou.amine.apps.readerforselfossv2.android.utils.network.isNetworkAvailable
import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.repository.Repository
import bou.amine.apps.readerforselfossv2.rest.SelfossModel import bou.amine.apps.readerforselfossv2.rest.SelfossModel
import com.ftinc.scoop.Scoop import com.ftinc.scoop.Scoop
@ -64,30 +63,28 @@ class SourcesActivity : AppCompatActivity(), DIAware {
binding.recyclerView.setHasFixedSize(true) binding.recyclerView.setHasFixedSize(true)
binding.recyclerView.layoutManager = mLayoutManager binding.recyclerView.layoutManager = mLayoutManager
if (this@SourcesActivity.isNetworkAvailable(binding.recyclerView)) { CoroutineScope(Dispatchers.Main).launch {
CoroutineScope(Dispatchers.Main).launch { val response = repository.getSources()
val response = repository.getSources() if (response != null) {
if (response != null) { items = response
items = response val mAdapter = SourcesListAdapter(
val mAdapter = SourcesListAdapter( this@SourcesActivity, items
this@SourcesActivity, items )
) binding.recyclerView.adapter = mAdapter
binding.recyclerView.adapter = mAdapter mAdapter.notifyDataSetChanged()
mAdapter.notifyDataSetChanged() if (items.isEmpty()) {
if (items.isEmpty()) {
Toast.makeText(
this@SourcesActivity,
R.string.nothing_here,
Toast.LENGTH_SHORT
).show()
}
} else {
Toast.makeText( Toast.makeText(
this@SourcesActivity, this@SourcesActivity,
R.string.cant_get_sources, R.string.nothing_here,
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
} }
} else {
Toast.makeText(
this@SourcesActivity,
R.string.cant_get_sources,
Toast.LENGTH_SHORT
).show()
} }
} }

View File

@ -16,7 +16,6 @@ import bou.amine.apps.readerforselfossv2.android.utils.*
import bou.amine.apps.readerforselfossv2.android.utils.customtabs.CustomTabActivityHelper import bou.amine.apps.readerforselfossv2.android.utils.customtabs.CustomTabActivityHelper
import bou.amine.apps.readerforselfossv2.android.utils.glide.bitmapCenterCrop import bou.amine.apps.readerforselfossv2.android.utils.glide.bitmapCenterCrop
import bou.amine.apps.readerforselfossv2.android.utils.glide.circularBitmapDrawable import bou.amine.apps.readerforselfossv2.android.utils.glide.circularBitmapDrawable
import bou.amine.apps.readerforselfossv2.android.utils.network.isNetworkAvailable
import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.repository.Repository
import bou.amine.apps.readerforselfossv2.rest.SelfossModel import bou.amine.apps.readerforselfossv2.rest.SelfossModel
import com.amulyakhare.textdrawable.TextDrawable import com.amulyakhare.textdrawable.TextDrawable
@ -110,22 +109,20 @@ class ItemCardAdapter(
binding.favButton.setOnClickListener { binding.favButton.setOnClickListener {
val item = items[bindingAdapterPosition] val item = items[bindingAdapterPosition]
if (c.isNetworkAvailable()) { if (item.starred) {
if (item.starred) { CoroutineScope(Dispatchers.IO).launch {
CoroutineScope(Dispatchers.IO).launch { repository.unstarr(item)
repository.unstarr(item) // TODO: Handle failure
// TODO: Handle failure
}
item.starred = false
binding.favButton.isSelected = false
} else {
CoroutineScope(Dispatchers.IO).launch {
repository.starr(item)
// TODO: Handle failure
}
item.starred = true
binding.favButton.isSelected = true
} }
item.starred = false
binding.favButton.isSelected = false
} else {
CoroutineScope(Dispatchers.IO).launch {
repository.starr(item)
// TODO: Handle failure
}
item.starred = true
binding.favButton.isSelected = true
} }
} }

View File

@ -14,7 +14,6 @@ import bou.amine.apps.readerforselfossv2.android.model.getIcon
import bou.amine.apps.readerforselfossv2.android.model.getTitleDecoded import bou.amine.apps.readerforselfossv2.android.model.getTitleDecoded
import bou.amine.apps.readerforselfossv2.android.utils.Config import bou.amine.apps.readerforselfossv2.android.utils.Config
import bou.amine.apps.readerforselfossv2.android.utils.glide.circularBitmapDrawable import bou.amine.apps.readerforselfossv2.android.utils.glide.circularBitmapDrawable
import bou.amine.apps.readerforselfossv2.android.utils.network.isNetworkAvailable
import bou.amine.apps.readerforselfossv2.android.utils.toTextDrawableString import bou.amine.apps.readerforselfossv2.android.utils.toTextDrawableString
import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.repository.Repository
import bou.amine.apps.readerforselfossv2.rest.SelfossModel import bou.amine.apps.readerforselfossv2.rest.SelfossModel
@ -78,21 +77,19 @@ class SourcesListAdapter(
val deleteBtn: Button = mView.findViewById(R.id.deleteBtn) val deleteBtn: Button = mView.findViewById(R.id.deleteBtn)
deleteBtn.setOnClickListener { deleteBtn.setOnClickListener {
if (c.isNetworkAvailable(null)) { val (id) = items[adapterPosition]
val (id) = items[adapterPosition] CoroutineScope(Dispatchers.IO).launch {
CoroutineScope(Dispatchers.IO).launch { val successfullyDeletedSource = repository.deleteSource(id)
val successfullyDeletedSource = repository.deleteSource(id) if (successfullyDeletedSource) {
if (successfullyDeletedSource) { items.removeAt(adapterPosition)
items.removeAt(adapterPosition) notifyItemRemoved(adapterPosition)
notifyItemRemoved(adapterPosition) notifyItemRangeChanged(adapterPosition, itemCount)
notifyItemRangeChanged(adapterPosition, itemCount) } else {
} else { Toast.makeText(
Toast.makeText( app,
app, R.string.can_delete_source,
R.string.can_delete_source, Toast.LENGTH_SHORT
Toast.LENGTH_SHORT ).show()
).show()
}
} }
} }
} }

View File

@ -21,7 +21,6 @@ import bou.amine.apps.readerforselfossv2.android.persistence.migrations.MIGRATIO
import bou.amine.apps.readerforselfossv2.android.persistence.migrations.MIGRATION_2_3 import bou.amine.apps.readerforselfossv2.android.persistence.migrations.MIGRATION_2_3
import bou.amine.apps.readerforselfossv2.android.persistence.migrations.MIGRATION_3_4 import bou.amine.apps.readerforselfossv2.android.persistence.migrations.MIGRATION_3_4
import bou.amine.apps.readerforselfossv2.android.utils.Config import bou.amine.apps.readerforselfossv2.android.utils.Config
import bou.amine.apps.readerforselfossv2.android.utils.network.isNetworkAvailable
import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.repository.Repository
import bou.amine.apps.readerforselfossv2.rest.SelfossModel import bou.amine.apps.readerforselfossv2.rest.SelfossModel
import bou.amine.apps.readerforselfossv2.utils.ItemType import bou.amine.apps.readerforselfossv2.utils.ItemType
@ -46,65 +45,60 @@ override fun doWork(): Result {
val periodicRefresh = settings.getBoolean("periodic_refresh", false) val periodicRefresh = settings.getBoolean("periodic_refresh", false)
if (periodicRefresh) { if (periodicRefresh) {
if (context.isNetworkAvailable()) { CoroutineScope(Dispatchers.IO).launch {
val notificationManager =
applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
CoroutineScope(Dispatchers.IO).launch { val notification =
val notificationManager = NotificationCompat.Builder(applicationContext, Config.syncChannelId)
applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager .setContentTitle(context.getString(R.string.loading_notification_title))
.setContentText(context.getString(R.string.loading_notification_text))
.setOngoing(true)
.setPriority(PRIORITY_LOW)
.setChannelId(Config.syncChannelId)
.setSmallIcon(R.drawable.ic_stat_cloud_download_black_24dp)
val notification = notificationManager.notify(1, notification.build())
NotificationCompat.Builder(applicationContext, Config.syncChannelId)
.setContentTitle(context.getString(R.string.loading_notification_title))
.setContentText(context.getString(R.string.loading_notification_text))
.setOngoing(true)
.setPriority(PRIORITY_LOW)
.setChannelId(Config.syncChannelId)
.setSmallIcon(R.drawable.ic_stat_cloud_download_black_24dp)
notificationManager.notify(1, notification.build()) val notifyNewItems = settings.getBoolean("notify_new_items", false)
val notifyNewItems = settings.getBoolean("notify_new_items", false) db = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java, "selfoss-database"
).addMigrations(MIGRATION_1_2).addMigrations(MIGRATION_2_3)
.addMigrations(MIGRATION_3_4).build()
db = Room.databaseBuilder( val actions = db.actionsDao().actions()
applicationContext,
AppDatabase::class.java, "selfoss-database"
).addMigrations(MIGRATION_1_2).addMigrations(MIGRATION_2_3)
.addMigrations(MIGRATION_3_4).build()
val actions = db.actionsDao().actions() actions.forEach { action ->
when {
actions.forEach { action -> action.read -> doAndReportOnFail(
when { repository.markAsReadById(action.articleId.toInt()),
action.read -> doAndReportOnFail( action
repository.markAsReadById(action.articleId.toInt()), )
action action.unread -> doAndReportOnFail(
) repository.unmarkAsReadById(action.articleId.toInt()),
action.unread -> doAndReportOnFail( action
repository.unmarkAsReadById(action.articleId.toInt()), )
action action.starred -> doAndReportOnFail(
) repository.starrById(action.articleId.toInt()),
action.starred -> doAndReportOnFail( action
repository.starrById(action.articleId.toInt()), )
action action.unstarred -> doAndReportOnFail(
) repository.unstarrById(action.articleId.toInt()),
action.unstarred -> doAndReportOnFail( action
repository.unstarrById(action.articleId.toInt()), )
action
)
}
} }
}
if (context.isNetworkAvailable()) { launch {
launch { try {
try { val newItems = repository.allItems(ItemType.UNREAD)
val newItems = repository.allItems(ItemType.UNREAD) handleNewItemsNotification(newItems, notifyNewItems, notificationManager)
handleNewItemsNotification(newItems, notifyNewItems, notificationManager) val readItems = repository.allItems(ItemType.ALL)
val readItems = repository.allItems(ItemType.ALL) val starredItems = repository.allItems(ItemType.STARRED)
val starredItems = repository.allItems(ItemType.STARRED) // TODO: save all to DB
// TODO: save all to DB } catch (e: Throwable) {}
} catch (e: Throwable) {}
}
}
} }
} }
} }

View File

@ -35,7 +35,6 @@ import bou.amine.apps.readerforselfossv2.android.utils.*
import bou.amine.apps.readerforselfossv2.android.utils.customtabs.CustomTabActivityHelper import bou.amine.apps.readerforselfossv2.android.utils.customtabs.CustomTabActivityHelper
import bou.amine.apps.readerforselfossv2.android.utils.glide.getBitmapInputStream import bou.amine.apps.readerforselfossv2.android.utils.glide.getBitmapInputStream
import bou.amine.apps.readerforselfossv2.android.utils.glide.loadMaybeBasicAuth import bou.amine.apps.readerforselfossv2.android.utils.glide.loadMaybeBasicAuth
import bou.amine.apps.readerforselfossv2.android.utils.network.isNetworkAvailable
import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.repository.Repository
import bou.amine.apps.readerforselfossv2.rest.SelfossModel import bou.amine.apps.readerforselfossv2.rest.SelfossModel
import bou.amine.apps.readerforselfossv2.utils.isEmptyOrNullOrNullString import bou.amine.apps.readerforselfossv2.utils.isEmptyOrNullOrNullString
@ -276,89 +275,87 @@ class ArticleFragment : Fragment(), DIAware {
} }
private fun getContentFromMercury(customTabsIntent: CustomTabsIntent) { private fun getContentFromMercury(customTabsIntent: CustomTabsIntent) {
if ((context != null && requireContext().isNetworkAvailable(null)) || context == null) { binding.progressBar.visibility = View.VISIBLE
binding.progressBar.visibility = View.VISIBLE val parser = MercuryApi()
val parser = MercuryApi()
parser.parseUrl(url).enqueue( parser.parseUrl(url).enqueue(
object : Callback<ParsedContent> { object : Callback<ParsedContent> {
override fun onResponse( override fun onResponse(
call: Call<ParsedContent>, call: Call<ParsedContent>,
response: Response<ParsedContent> response: Response<ParsedContent>
) { ) {
// TODO: clean all the following after finding the mercury content issue // TODO: clean all the following after finding the mercury content issue
try { try {
if (response.body() != null && response.body()!!.content != null && !response.body()!!.content.isNullOrEmpty()) { if (response.body() != null && response.body()!!.content != null && !response.body()!!.content.isNullOrEmpty()) {
try {
binding.titleView.text = response.body()!!.title
if (typeface != null) {
binding.titleView.typeface = typeface
}
try { try {
binding.titleView.text = response.body()!!.title // Note: Mercury may return relative urls... If it does the url val will not be changed.
if (typeface != null) { URL(response.body()!!.url)
binding.titleView.typeface = typeface url = response.body()!!.url
} } catch (e: MalformedURLException) {
// Mercury returned a relative url. We do nothing.
}
} catch (e: Exception) {
}
try {
contentText = response.body()!!.content.orEmpty()
htmlToWebview()
} catch (e: Exception) {
}
try {
if (response.body()!!.lead_image_url != null && !response.body()!!.lead_image_url.isNullOrEmpty() && context != null) {
binding.imageView.visibility = View.VISIBLE
try { try {
// Note: Mercury may return relative urls... If it does the url val will not be changed. Glide
URL(response.body()!!.url) .with(requireContext())
url = response.body()!!.url .asBitmap()
} catch (e: MalformedURLException) { .loadMaybeBasicAuth(config, response.body()!!.lead_image_url.orEmpty())
// Mercury returned a relative url. We do nothing. .apply(RequestOptions.fitCenterTransform())
.into(binding.imageView)
} catch (e: Exception) {
} }
} catch (e: Exception) { } else {
binding.imageView.visibility = View.GONE
} }
} catch (e: Exception) {
try { if (context != null) {
contentText = response.body()!!.content.orEmpty()
htmlToWebview()
} catch (e: Exception) {
}
try {
if (response.body()!!.lead_image_url != null && !response.body()!!.lead_image_url.isNullOrEmpty() && context != null) {
binding.imageView.visibility = View.VISIBLE
try {
Glide
.with(requireContext())
.asBitmap()
.loadMaybeBasicAuth(config, response.body()!!.lead_image_url.orEmpty())
.apply(RequestOptions.fitCenterTransform())
.into(binding.imageView)
} catch (e: Exception) {
}
} else {
binding.imageView.visibility = View.GONE
}
} catch (e: Exception) {
if (context != null) {
}
}
try {
binding.nestedScrollView.scrollTo(0, 0)
binding.progressBar.visibility = View.GONE
} catch (e: Exception) {
if (context != null) {
}
}
} else {
try {
openInBrowserAfterFailing(customTabsIntent)
} catch (e: Exception) {
if (context != null) {
}
} }
} }
} catch (e: Exception) {
if (context != null) { try {
binding.nestedScrollView.scrollTo(0, 0)
binding.progressBar.visibility = View.GONE
} catch (e: Exception) {
if (context != null) {
}
}
} else {
try {
openInBrowserAfterFailing(customTabsIntent)
} catch (e: Exception) {
if (context != null) {
}
} }
} }
} catch (e: Exception) {
if (context != null) {
}
} }
override fun onFailure(
call: Call<ParsedContent>,
t: Throwable
) = openInBrowserAfterFailing(customTabsIntent)
} }
)
} override fun onFailure(
call: Call<ParsedContent>,
t: Throwable
) = openInBrowserAfterFailing(customTabsIntent)
}
)
} }
private fun htmlToWebview() { private fun htmlToWebview() {