Compare commits
19 Commits
17f7d58aed
...
49abc081b6
Author | SHA1 | Date | |
---|---|---|---|
49abc081b6 | |||
1290d3c4dd | |||
faac7fc621 | |||
59267e6759 | |||
9a33ba0dbb | |||
e60ed92c6d | |||
3a2fab8e68 | |||
e7172853dc | |||
1390ff264f | |||
daaaf902f5 | |||
f78ee18e79 | |||
86dbe06eaa | |||
c5826466ad | |||
88debf068b | |||
5ab9db586d | |||
2105044920 | |||
|
e1e43adde4 | ||
|
1392e2a571 | ||
|
e9cb3d2f37 |
@ -190,13 +190,18 @@ dependencies {
|
|||||||
//PhotoView
|
//PhotoView
|
||||||
implementation("com.github.chrisbanes:PhotoView:2.3.0")
|
implementation("com.github.chrisbanes:PhotoView:2.3.0")
|
||||||
|
|
||||||
implementation("androidx.core:core-ktx:1.7.0")
|
implementation("androidx.core:core-ktx:1.8.0")
|
||||||
|
|
||||||
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.4.0")
|
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.5.1")
|
||||||
implementation("androidx.lifecycle:lifecycle-common-java8:2.4.0")
|
implementation("androidx.lifecycle:lifecycle-common-java8:2.5.1")
|
||||||
|
implementation("androidx.lifecycle:lifecycle-runtime:2.5.1")
|
||||||
|
implementation("androidx.lifecycle:lifecycle-extensions:2.2.0")
|
||||||
|
|
||||||
implementation("androidx.room:room-ktx:2.4.0-beta01")
|
implementation("androidx.room:room-ktx:2.4.0-beta01")
|
||||||
kapt("androidx.room:room-compiler:2.4.0-beta01")
|
kapt("androidx.room:room-compiler:2.4.0-beta01")
|
||||||
|
|
||||||
implementation("android.arch.work:work-runtime-ktx:1.0.1")
|
implementation("android.arch.work:work-runtime-ktx:1.0.1")
|
||||||
|
|
||||||
|
// Network information
|
||||||
|
implementation("com.github.ln-12:multiplatform-connectivity-status:1.1.0")
|
||||||
}
|
}
|
@ -44,7 +44,6 @@ import bou.amine.apps.readerforselfossv2.android.utils.Config
|
|||||||
import bou.amine.apps.readerforselfossv2.android.utils.bottombar.maybeShow
|
import bou.amine.apps.readerforselfossv2.android.utils.bottombar.maybeShow
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.bottombar.removeBadge
|
import bou.amine.apps.readerforselfossv2.android.utils.bottombar.removeBadge
|
||||||
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.network.isNetworkAvailable
|
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.persistence.toEntity
|
import bou.amine.apps.readerforselfossv2.android.utils.persistence.toEntity
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.persistence.toView
|
import bou.amine.apps.readerforselfossv2.android.utils.persistence.toView
|
||||||
import bou.amine.apps.readerforselfossv2.repository.Repository
|
import bou.amine.apps.readerforselfossv2.repository.Repository
|
||||||
@ -126,7 +125,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
private var recyclerAdapter: RecyclerView.Adapter<*>? = null
|
private var recyclerAdapter: RecyclerView.Adapter<*>? = null
|
||||||
|
|
||||||
private var fromTabShortcut: Boolean = false
|
private var fromTabShortcut: Boolean = false
|
||||||
private var offlineShortcut: Boolean = false
|
|
||||||
|
|
||||||
private lateinit var tagsBadge: Map<Long, Int>
|
private lateinit var tagsBadge: Map<Long, Int>
|
||||||
|
|
||||||
@ -153,7 +151,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
val view = binding.root
|
val view = binding.root
|
||||||
|
|
||||||
fromTabShortcut = intent.getIntExtra("shortcutTab", -1) != -1
|
fromTabShortcut = intent.getIntExtra("shortcutTab", -1) != -1
|
||||||
offlineShortcut = intent.getBooleanExtra("startOffline", false)
|
repository.offlineOverride = intent.getBooleanExtra("startOffline", false)
|
||||||
|
|
||||||
if (fromTabShortcut) {
|
if (fromTabShortcut) {
|
||||||
elementsShown = ItemType.fromInt(intent.getIntExtra("shortcutTab", ItemType.UNREAD.position))
|
elementsShown = ItemType.fromInt(intent.getIntExtra("shortcutTab", ItemType.UNREAD.position))
|
||||||
@ -197,7 +195,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
R.color.refresh_progress_3
|
R.color.refresh_progress_3
|
||||||
)
|
)
|
||||||
binding.swipeRefreshLayout.setOnRefreshListener {
|
binding.swipeRefreshLayout.setOnRefreshListener {
|
||||||
offlineShortcut = false
|
repository.offlineOverride = false
|
||||||
lastFetchDone = false
|
lastFetchDone = false
|
||||||
handleDrawerItems()
|
handleDrawerItems()
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
@ -408,6 +406,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
|
|
||||||
val drawerListener = object : DrawerLayout.DrawerListener {
|
val drawerListener = object : DrawerLayout.DrawerListener {
|
||||||
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
|
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
|
||||||
|
// We do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDrawerOpened(drawerView: View) {
|
override fun onDrawerOpened(drawerView: View) {
|
||||||
@ -419,6 +418,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDrawerStateChanged(newState: Int) {
|
override fun onDrawerStateChanged(newState: Int) {
|
||||||
|
// We do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -469,6 +469,45 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
private fun handleDrawerItems() {
|
private fun handleDrawerItems() {
|
||||||
tagsBadge = emptyMap()
|
tagsBadge = emptyMap()
|
||||||
fun handleDrawerData(maybeDrawerData: DrawerData?, loadedFromCache: Boolean = false) {
|
fun handleDrawerData(maybeDrawerData: DrawerData?, loadedFromCache: Boolean = false) {
|
||||||
|
fun createDrawerItem(
|
||||||
|
it: SelfossModel.Tag
|
||||||
|
) {
|
||||||
|
val gd = GradientDrawable()
|
||||||
|
val gdColor = try {
|
||||||
|
Color.parseColor(it.color)
|
||||||
|
} catch (e: IllegalArgumentException) {
|
||||||
|
appColors.colorPrimary
|
||||||
|
}
|
||||||
|
|
||||||
|
gd.setColor(gdColor)
|
||||||
|
gd.shape = GradientDrawable.RECTANGLE
|
||||||
|
gd.setSize(30, 30)
|
||||||
|
gd.cornerRadius = 30F
|
||||||
|
|
||||||
|
val drawerItem = PrimaryDrawerItem()
|
||||||
|
.apply {
|
||||||
|
nameText = it.getTitleDecoded()
|
||||||
|
identifier = it.tag.longHash()
|
||||||
|
iconDrawable = gd
|
||||||
|
badgeStyle = BadgeStyle().apply {
|
||||||
|
textColor = ColorHolder.fromColor(Color.WHITE)
|
||||||
|
color = ColorHolder.fromColor(appColors.colorAccent)
|
||||||
|
}
|
||||||
|
onDrawerItemClickListener = { _, _, _ ->
|
||||||
|
repository.tagFilter = it
|
||||||
|
repository.sourceFilter = null
|
||||||
|
getElementsAccordingToTab()
|
||||||
|
fetchOnEmptyList()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (it.unread > 0) {
|
||||||
|
drawerItem.badgeText = it.unread.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.mainDrawer.itemAdapter.add(drawerItem)
|
||||||
|
}
|
||||||
|
|
||||||
fun handleTags(maybeTags: List<SelfossModel.Tag>?) {
|
fun handleTags(maybeTags: List<SelfossModel.Tag>?) {
|
||||||
if (maybeTags == null) {
|
if (maybeTags == null) {
|
||||||
if (loadedFromCache) {
|
if (loadedFromCache) {
|
||||||
@ -482,38 +521,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
.filterNot { hiddenTags.contains(it.tag) }
|
.filterNot { hiddenTags.contains(it.tag) }
|
||||||
.sortedBy { it.unread == 0 }
|
.sortedBy { it.unread == 0 }
|
||||||
tagsBadge = filteredTags.map {
|
tagsBadge = filteredTags.map {
|
||||||
val gd = GradientDrawable()
|
createDrawerItem(it)
|
||||||
val gdColor = try {
|
|
||||||
Color.parseColor(it.color)
|
|
||||||
} catch (e: IllegalArgumentException) {
|
|
||||||
appColors.colorPrimary
|
|
||||||
}
|
|
||||||
|
|
||||||
gd.setColor(gdColor)
|
|
||||||
gd.shape = GradientDrawable.RECTANGLE
|
|
||||||
gd.setSize(30, 30)
|
|
||||||
gd.cornerRadius = 30F
|
|
||||||
val drawerItem =
|
|
||||||
PrimaryDrawerItem()
|
|
||||||
.apply {
|
|
||||||
nameText = it.getTitleDecoded()
|
|
||||||
identifier = it.tag.longHash()
|
|
||||||
iconDrawable = gd
|
|
||||||
badgeStyle = BadgeStyle().apply {
|
|
||||||
textColor = ColorHolder.fromColor(Color.WHITE)
|
|
||||||
color = ColorHolder.fromColor(appColors.colorAccent) }
|
|
||||||
onDrawerItemClickListener = { _,_,_ ->
|
|
||||||
repository.tagFilter = it
|
|
||||||
repository.sourceFilter = null
|
|
||||||
getElementsAccordingToTab()
|
|
||||||
fetchOnEmptyList()
|
|
||||||
false
|
|
||||||
} }
|
|
||||||
if (it.unread > 0) {
|
|
||||||
drawerItem.badgeText = it.unread.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.mainDrawer.itemAdapter.add(drawerItem)
|
|
||||||
|
|
||||||
(it.tag.longHash() to it.unread)
|
(it.tag.longHash() to it.unread)
|
||||||
}.toMap()
|
}.toMap()
|
||||||
@ -534,37 +542,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
val filteredHiddenTags: List<SelfossModel.Tag> =
|
val filteredHiddenTags: List<SelfossModel.Tag> =
|
||||||
maybeTags.filter { hiddenTags.contains(it.tag) }
|
maybeTags.filter { hiddenTags.contains(it.tag) }
|
||||||
tagsBadge = filteredHiddenTags.map {
|
tagsBadge = filteredHiddenTags.map {
|
||||||
val gd = GradientDrawable()
|
createDrawerItem(it)
|
||||||
val gdColor = try {
|
|
||||||
Color.parseColor(it.color)
|
|
||||||
} catch (e: IllegalArgumentException) {
|
|
||||||
appColors.colorPrimary
|
|
||||||
}
|
|
||||||
|
|
||||||
gd.setColor(gdColor)
|
|
||||||
gd.shape = GradientDrawable.RECTANGLE
|
|
||||||
gd.setSize(30, 30)
|
|
||||||
gd.cornerRadius = 30F
|
|
||||||
val drawerItem =
|
|
||||||
PrimaryDrawerItem().apply {
|
|
||||||
nameText = it.getTitleDecoded()
|
|
||||||
identifier = it.tag.longHash()
|
|
||||||
iconDrawable = gd
|
|
||||||
badgeStyle = BadgeStyle().apply {
|
|
||||||
textColor = ColorHolder.fromColor(Color.WHITE)
|
|
||||||
color = ColorHolder.fromColor(appColors.colorAccent) }
|
|
||||||
onDrawerItemClickListener = { _,_,_ ->
|
|
||||||
repository.tagFilter = it
|
|
||||||
repository.sourceFilter = null
|
|
||||||
getElementsAccordingToTab()
|
|
||||||
fetchOnEmptyList()
|
|
||||||
false
|
|
||||||
} }
|
|
||||||
|
|
||||||
if (it.unread > 0) {
|
|
||||||
drawerItem.badgeText = it.unread.toString()
|
|
||||||
}
|
|
||||||
binding.mainDrawer.itemAdapter.add(drawerItem)
|
|
||||||
|
|
||||||
(it.tag.longHash() to it.unread)
|
(it.tag.longHash() to it.unread)
|
||||||
}.toMap()
|
}.toMap()
|
||||||
@ -709,7 +687,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
var sources: List<SelfossModel.Source>?
|
var sources: List<SelfossModel.Source>?
|
||||||
|
|
||||||
fun sourcesApiCall() {
|
fun sourcesApiCall() {
|
||||||
if (this@HomeActivity.isNetworkAvailable(null, offlineShortcut) && updateSources) {
|
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
val response = repository.getSources()
|
val response = repository.getSources()
|
||||||
if (response != null) {
|
if (response != null) {
|
||||||
@ -726,15 +703,12 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (this@HomeActivity.isNetworkAvailable(null, offlineShortcut) && updateSources) {
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
tags = repository.getTags()
|
tags = repository.getTags()
|
||||||
sourcesApiCall()
|
sourcesApiCall()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
binding.mainDrawer.itemAdapter.add(
|
binding.mainDrawer.itemAdapter.add(
|
||||||
PrimaryDrawerItem().apply {
|
PrimaryDrawerItem().apply {
|
||||||
@ -964,13 +938,11 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
private fun reloadBadges() {
|
private fun reloadBadges() {
|
||||||
if (displayUnreadCount || displayAllCount) {
|
if (displayUnreadCount || displayAllCount) {
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
if (applicationContext.isNetworkAvailable()) {
|
|
||||||
repository.reloadBadges()
|
repository.reloadBadges()
|
||||||
reloadBadgeContent()
|
reloadBadgeContent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun reloadBadgeContent() {
|
private fun reloadBadgeContent() {
|
||||||
if (displayUnreadCount) {
|
if (displayUnreadCount) {
|
||||||
@ -1041,13 +1013,14 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.refresh -> {
|
R.id.refresh -> {
|
||||||
if (this@HomeActivity.isNetworkAvailable(null, offlineShortcut)) {
|
|
||||||
needsConfirmation(R.string.menu_home_refresh, R.string.refresh_dialog_message) {
|
needsConfirmation(R.string.menu_home_refresh, R.string.refresh_dialog_message) {
|
||||||
Toast.makeText(this, R.string.refresh_in_progress, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, R.string.refresh_in_progress, Toast.LENGTH_SHORT).show()
|
||||||
// TODO: Use Dispatchers.IO
|
// TODO: Use Dispatchers.IO
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
|
repository.offlineOverride = false
|
||||||
val updatedRemote = repository.updateRemote()
|
val updatedRemote = repository.updateRemote()
|
||||||
if (updatedRemote) {
|
if (updatedRemote) {
|
||||||
|
// TODO: Send toast messages from the repository
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
this@HomeActivity,
|
this@HomeActivity,
|
||||||
R.string.refresh_success_response, Toast.LENGTH_LONG
|
R.string.refresh_success_response, Toast.LENGTH_LONG
|
||||||
@ -1063,16 +1036,12 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
R.id.readAll -> {
|
R.id.readAll -> {
|
||||||
if (elementsShown == ItemType.UNREAD) {
|
if (elementsShown == ItemType.UNREAD) {
|
||||||
needsConfirmation(R.string.readAll, R.string.markall_dialog_message) {
|
needsConfirmation(R.string.readAll, R.string.markall_dialog_message) {
|
||||||
binding.swipeRefreshLayout.isRefreshing = true
|
binding.swipeRefreshLayout.isRefreshing = true
|
||||||
|
|
||||||
if (this@HomeActivity.isNetworkAvailable(null, offlineShortcut)) {
|
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
val success = repository.markAllAsRead(items)
|
val success = repository.markAllAsRead(items)
|
||||||
if (success) {
|
if (success) {
|
||||||
@ -1098,7 +1067,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
R.id.action_disconnect -> {
|
R.id.action_disconnect -> {
|
||||||
@ -1147,7 +1115,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this@HomeActivity.isNetworkAvailable(null, offlineShortcut)) {
|
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
val actions = db.actionsDao().actions()
|
val actions = db.actionsDao().actions()
|
||||||
|
|
||||||
@ -1162,5 +1129,4 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -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,7 +201,6 @@ 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) {
|
||||||
@ -213,7 +211,6 @@ class LoginActivity() : AppCompatActivity(), DIAware {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
showProgress(false)
|
showProgress(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,9 @@ import android.graphics.drawable.Drawable
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
|
import androidx.lifecycle.DefaultLifecycleObserver
|
||||||
|
import androidx.lifecycle.LifecycleOwner
|
||||||
|
import androidx.lifecycle.ProcessLifecycleOwner
|
||||||
import androidx.multidex.MultiDexApplication
|
import androidx.multidex.MultiDexApplication
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import bou.amine.apps.readerforselfossv2.DI.networkModule
|
import bou.amine.apps.readerforselfossv2.DI.networkModule
|
||||||
@ -16,6 +19,7 @@ import bou.amine.apps.readerforselfossv2.repository.Repository
|
|||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.request.RequestOptions
|
import com.bumptech.glide.request.RequestOptions
|
||||||
import com.ftinc.scoop.Scoop
|
import com.ftinc.scoop.Scoop
|
||||||
|
import com.github.`ln-12`.library.ConnectivityStatus
|
||||||
import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader
|
import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader
|
||||||
import com.mikepenz.materialdrawer.util.DrawerImageLoader
|
import com.mikepenz.materialdrawer.util.DrawerImageLoader
|
||||||
import com.russhwolf.settings.Settings
|
import com.russhwolf.settings.Settings
|
||||||
@ -25,9 +29,10 @@ class MyApp : MultiDexApplication(), DIAware {
|
|||||||
|
|
||||||
override val di by DI.lazy {
|
override val di by DI.lazy {
|
||||||
import(networkModule)
|
import(networkModule)
|
||||||
bind<Repository>() with singleton { Repository(instance(), instance()) }
|
bind<Repository>() with singleton { Repository(instance(), instance(), ConnectivityStatus(applicationContext)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val repository: Repository by instance()
|
||||||
private lateinit var config: Config
|
private lateinit var config: Config
|
||||||
private lateinit var settings : Settings
|
private lateinit var settings : Settings
|
||||||
|
|
||||||
@ -43,6 +48,8 @@ class MyApp : MultiDexApplication(), DIAware {
|
|||||||
tryToHandleBug()
|
tryToHandleBug()
|
||||||
|
|
||||||
handleNotificationChannels()
|
handleNotificationChannels()
|
||||||
|
|
||||||
|
ProcessLifecycleOwner.get().lifecycle.addObserver(AppLifeCycleObserver(repository))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleNotificationChannels() {
|
private fun handleNotificationChannels() {
|
||||||
@ -102,4 +109,17 @@ class MyApp : MultiDexApplication(), DIAware {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AppLifeCycleObserver(val repository: Repository) : DefaultLifecycleObserver {
|
||||||
|
|
||||||
|
override fun onResume(owner: LifecycleOwner) {
|
||||||
|
super.onResume(owner)
|
||||||
|
repository.startNetwork()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause(owner: LifecycleOwner) {
|
||||||
|
repository.stopNetwork()
|
||||||
|
super.onPause(owner)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -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,7 +63,6 @@ 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) {
|
||||||
@ -89,7 +87,6 @@ class SourcesActivity : AppCompatActivity(), DIAware {
|
|||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
binding.fab.setOnClickListener {
|
binding.fab.setOnClickListener {
|
||||||
startActivity(Intent(this@SourcesActivity, AddSourceActivity::class.java))
|
startActivity(Intent(this@SourcesActivity, AddSourceActivity::class.java))
|
||||||
|
@ -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,7 +109,6 @@ 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)
|
||||||
@ -127,7 +125,6 @@ class ItemCardAdapter(
|
|||||||
binding.favButton.isSelected = true
|
binding.favButton.isSelected = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
binding.shareBtn.setOnClickListener {
|
binding.shareBtn.setOnClickListener {
|
||||||
val item = items[bindingAdapterPosition]
|
val item = items[bindingAdapterPosition]
|
||||||
|
@ -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,7 +77,6 @@ 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)
|
||||||
@ -98,4 +96,3 @@ class SourcesListAdapter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -21,7 +21,7 @@ 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.android.utils.network.isNetworkAccessible
|
||||||
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
|
||||||
@ -44,9 +44,7 @@ class LoadingWorker(val context: Context, params: WorkerParameters) : Worker(con
|
|||||||
override fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
val settings = Settings()
|
val settings = Settings()
|
||||||
val periodicRefresh = settings.getBoolean("periodic_refresh", false)
|
val periodicRefresh = settings.getBoolean("periodic_refresh", false)
|
||||||
if (periodicRefresh) {
|
if (periodicRefresh && isNetworkAccessible(context)) {
|
||||||
|
|
||||||
if (context.isNetworkAvailable()) {
|
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
val notificationManager =
|
val notificationManager =
|
||||||
@ -94,7 +92,6 @@ override fun doWork(): Result {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.isNetworkAvailable()) {
|
|
||||||
launch {
|
launch {
|
||||||
try {
|
try {
|
||||||
val newItems = repository.allItems(ItemType.UNREAD)
|
val newItems = repository.allItems(ItemType.UNREAD)
|
||||||
@ -106,8 +103,6 @@ override fun doWork(): Result {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return Result.success()
|
return Result.success()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,7 +275,7 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getContentFromMercury(customTabsIntent: CustomTabsIntent) {
|
private fun getContentFromMercury(customTabsIntent: CustomTabsIntent) {
|
||||||
if ((context != null && requireContext().isNetworkAvailable(null)) || context == null) {
|
if (repository.isNetworkAvailable()) {
|
||||||
binding.progressBar.visibility = View.VISIBLE
|
binding.progressBar.visibility = View.VISIBLE
|
||||||
val parser = MercuryApi()
|
val parser = MercuryApi()
|
||||||
|
|
||||||
@ -317,7 +316,10 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
Glide
|
Glide
|
||||||
.with(requireContext())
|
.with(requireContext())
|
||||||
.asBitmap()
|
.asBitmap()
|
||||||
.loadMaybeBasicAuth(config, response.body()!!.lead_image_url.orEmpty())
|
.loadMaybeBasicAuth(
|
||||||
|
config,
|
||||||
|
response.body()!!.lead_image_url.orEmpty()
|
||||||
|
)
|
||||||
.apply(RequestOptions.fitCenterTransform())
|
.apply(RequestOptions.fitCenterTransform())
|
||||||
.into(binding.imageView)
|
.into(binding.imageView)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
@ -1,52 +1,14 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.android.utils.network
|
package bou.amine.apps.readerforselfossv2.android.utils.network
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Color
|
|
||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
import android.net.NetworkCapabilities
|
import android.net.NetworkCapabilities
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.view.View
|
|
||||||
import android.widget.TextView
|
|
||||||
import bou.amine.apps.readerforselfossv2.android.R
|
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
|
|
||||||
var snackBarShown = false
|
|
||||||
var view: View? = null
|
|
||||||
lateinit var s: Snackbar
|
lateinit var s: Snackbar
|
||||||
|
|
||||||
fun Context.isNetworkAvailable(
|
fun isNetworkAccessible(context: Context): Boolean {
|
||||||
v: View? = null,
|
|
||||||
overrideOffline: Boolean = false
|
|
||||||
): Boolean {
|
|
||||||
val networkIsAccessible = isNetworkAccessible(this)
|
|
||||||
|
|
||||||
if (v != null && (!networkIsAccessible || overrideOffline) && (!snackBarShown || v != view)) {
|
|
||||||
view = v
|
|
||||||
s = Snackbar
|
|
||||||
.make(
|
|
||||||
v,
|
|
||||||
R.string.no_network_connectivity,
|
|
||||||
Snackbar.LENGTH_INDEFINITE
|
|
||||||
)
|
|
||||||
|
|
||||||
s.setAction(android.R.string.ok) {
|
|
||||||
snackBarShown = false
|
|
||||||
s.dismiss()
|
|
||||||
}
|
|
||||||
|
|
||||||
val view = s.view
|
|
||||||
val tv: TextView = view.findViewById(com.google.android.material.R.id.snackbar_text)
|
|
||||||
tv.setTextColor(Color.WHITE)
|
|
||||||
s.show()
|
|
||||||
snackBarShown = true
|
|
||||||
}
|
|
||||||
if (snackBarShown && networkIsAccessible && !overrideOffline) {
|
|
||||||
s.dismiss()
|
|
||||||
}
|
|
||||||
return if(overrideOffline) overrideOffline else networkIsAccessible
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isNetworkAccessible(context: Context): Boolean {
|
|
||||||
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
@ -36,6 +36,9 @@ kotlin {
|
|||||||
|
|
||||||
//Logging
|
//Logging
|
||||||
implementation("io.github.aakira:napier:2.6.1")
|
implementation("io.github.aakira:napier:2.6.1")
|
||||||
|
|
||||||
|
// Network information
|
||||||
|
implementation("com.github.ln-12:multiplatform-connectivity-status:1.1.0")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val commonTest by getting {
|
val commonTest by getting {
|
||||||
|
@ -5,16 +5,18 @@ import bou.amine.apps.readerforselfossv2.rest.SelfossModel
|
|||||||
import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
|
import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
|
||||||
import bou.amine.apps.readerforselfossv2.utils.DateUtils
|
import bou.amine.apps.readerforselfossv2.utils.DateUtils
|
||||||
import bou.amine.apps.readerforselfossv2.utils.ItemType
|
import bou.amine.apps.readerforselfossv2.utils.ItemType
|
||||||
|
import com.github.`ln-12`.library.ConnectivityStatus
|
||||||
import com.russhwolf.settings.Settings
|
import com.russhwolf.settings.Settings
|
||||||
import io.github.aakira.napier.Napier
|
import io.github.aakira.napier.Napier
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class Repository(private val api: SelfossApi, private val apiDetails: ApiDetailsService) {
|
class Repository(private val api: SelfossApi, private val apiDetails: ApiDetailsService, val connectivityStatus: ConnectivityStatus) {
|
||||||
val settings = Settings()
|
val settings = Settings()
|
||||||
|
|
||||||
var items = ArrayList<SelfossModel.Item>()
|
var items = ArrayList<SelfossModel.Item>()
|
||||||
|
private val isConnectionAvailable = connectivityStatus.isNetworkConnected
|
||||||
|
|
||||||
var baseUrl = apiDetails.getBaseUrl()
|
var baseUrl = apiDetails.getBaseUrl()
|
||||||
lateinit var dateUtils: DateUtils
|
lateinit var dateUtils: DateUtils
|
||||||
@ -26,6 +28,7 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
|||||||
var searchFilter: String? = null
|
var searchFilter: String? = null
|
||||||
|
|
||||||
var itemsCaching = settings.getBoolean("items_caching", false)
|
var itemsCaching = settings.getBoolean("items_caching", false)
|
||||||
|
var offlineOverride = false
|
||||||
|
|
||||||
var apiMajorVersion = 0
|
var apiMajorVersion = 0
|
||||||
var badgeUnread = 0
|
var badgeUnread = 0
|
||||||
@ -45,14 +48,21 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getNewerItems(): ArrayList<SelfossModel.Item> {
|
suspend fun getNewerItems(): ArrayList<SelfossModel.Item> {
|
||||||
// TODO: Check connectivity, use the updatedSince parameter
|
// TODO: Use the updatedSince parameter
|
||||||
val fetchedItems = api.getItems(displayedItems.type,
|
var fetchedItems: List<SelfossModel.Item>? = null
|
||||||
|
if (isNetworkAvailable()) {
|
||||||
|
fetchedItems = api.getItems(
|
||||||
|
displayedItems.type,
|
||||||
settings.getString("prefer_api_items_number", "200").toInt(),
|
settings.getString("prefer_api_items_number", "200").toInt(),
|
||||||
offset = 0,
|
offset = 0,
|
||||||
tagFilter?.tag,
|
tagFilter?.tag,
|
||||||
sourceFilter?.id?.toLong(),
|
sourceFilter?.id?.toLong(),
|
||||||
searchFilter,
|
searchFilter,
|
||||||
null)
|
null
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// TODO: Get items from the database
|
||||||
|
}
|
||||||
|
|
||||||
if (fetchedItems != null) {
|
if (fetchedItems != null) {
|
||||||
items = ArrayList(fetchedItems)
|
items = ArrayList(fetchedItems)
|
||||||
@ -61,15 +71,21 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getOlderItems(): ArrayList<SelfossModel.Item> {
|
suspend fun getOlderItems(): ArrayList<SelfossModel.Item> {
|
||||||
// TODO: Check connectivity
|
var fetchedItems: List<SelfossModel.Item>? = null
|
||||||
|
if (isNetworkAvailable()) {
|
||||||
val offset = items.size
|
val offset = items.size
|
||||||
val fetchedItems = api.getItems(displayedItems.type,
|
fetchedItems = api.getItems(
|
||||||
|
displayedItems.type,
|
||||||
settings.getString("prefer_api_items_number", "200").toInt(),
|
settings.getString("prefer_api_items_number", "200").toInt(),
|
||||||
offset,
|
offset,
|
||||||
tagFilter?.tag,
|
tagFilter?.tag,
|
||||||
sourceFilter?.id?.toLong(),
|
sourceFilter?.id?.toLong(),
|
||||||
searchFilter,
|
searchFilter,
|
||||||
null)
|
null
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// TODO: Get items from the database
|
||||||
|
}
|
||||||
|
|
||||||
if (fetchedItems != null) {
|
if (fetchedItems != null) {
|
||||||
appendItems(fetchedItems)
|
appendItems(fetchedItems)
|
||||||
@ -77,8 +93,22 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
|||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun allItems(itemType: ItemType): List<SelfossModel.Item>? =
|
suspend fun allItems(itemType: ItemType): List<SelfossModel.Item>? {
|
||||||
api.getItems(itemType.type, 200, 0, tagFilter?.tag, sourceFilter?.id?.toLong(), searchFilter, null)
|
return if (isNetworkAvailable()) {
|
||||||
|
api.getItems(
|
||||||
|
itemType.type,
|
||||||
|
200,
|
||||||
|
0,
|
||||||
|
tagFilter?.tag,
|
||||||
|
sourceFilter?.id?.toLong(),
|
||||||
|
searchFilter,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// TODO: Provide an error message
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun appendItems(fetchedItems: List<SelfossModel.Item>) {
|
private fun appendItems(fetchedItems: List<SelfossModel.Item>) {
|
||||||
// TODO: Store in DB if enabled by user
|
// TODO: Store in DB if enabled by user
|
||||||
@ -94,8 +124,8 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun reloadBadges(): Boolean {
|
suspend fun reloadBadges(): Boolean {
|
||||||
// TODO: Check connectivity, calculate from DB
|
|
||||||
var success = false
|
var success = false
|
||||||
|
if (isNetworkAvailable()) {
|
||||||
val response = api.stats()
|
val response = api.stats()
|
||||||
if (response != null) {
|
if (response != null) {
|
||||||
badgeUnread = response.unread
|
badgeUnread = response.unread
|
||||||
@ -103,26 +133,43 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
|||||||
badgeStarred = response.starred
|
badgeStarred = response.starred
|
||||||
success = true
|
success = true
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: Compute badges from database
|
||||||
|
}
|
||||||
return success
|
return success
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getTags(): List<SelfossModel.Tag>? {
|
suspend fun getTags(): List<SelfossModel.Tag>? {
|
||||||
// TODO: Check success, store in DB
|
// TODO: Store in DB
|
||||||
return api.tags()
|
return if (isNetworkAvailable()) {
|
||||||
|
api.tags()
|
||||||
|
} else {
|
||||||
|
// TODO: Compute from database
|
||||||
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getSpouts(): Map<String, SelfossModel.Spout>? {
|
suspend fun getSpouts(): Map<String, SelfossModel.Spout>? {
|
||||||
// TODO: Check success, store in DB
|
// TODO: Store in DB
|
||||||
return api.spouts()
|
return if (isNetworkAvailable()) {
|
||||||
|
api.spouts()
|
||||||
|
} else {
|
||||||
|
// TODO: Compute from database
|
||||||
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getSources(): ArrayList<SelfossModel.Source>? {
|
suspend fun getSources(): ArrayList<SelfossModel.Source>? {
|
||||||
// TODO: Check success
|
// TODO: Store in DB
|
||||||
return api.sources()
|
return if (isNetworkAvailable()) {
|
||||||
|
api.sources()
|
||||||
|
} else {
|
||||||
|
// TODO: Compute from database
|
||||||
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun markAsRead(item: SelfossModel.Item): Boolean {
|
suspend fun markAsRead(item: SelfossModel.Item): Boolean {
|
||||||
// TODO: Check internet connection
|
|
||||||
val success = markAsReadById(item.id)
|
val success = markAsReadById(item.id)
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
@ -132,8 +179,11 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun markAsReadById(id: Int): Boolean {
|
suspend fun markAsReadById(id: Int): Boolean {
|
||||||
// TODO: Check internet connection
|
var success = false
|
||||||
return api.markAsRead(id.toString())?.isSuccess == true
|
if (isNetworkAvailable()) {
|
||||||
|
success = api.markAsRead(id.toString())?.isSuccess == true
|
||||||
|
}
|
||||||
|
return success
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun unmarkAsRead(item: SelfossModel.Item): Boolean {
|
suspend fun unmarkAsRead(item: SelfossModel.Item): Boolean {
|
||||||
@ -146,8 +196,11 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun unmarkAsReadById(id: Int): Boolean {
|
suspend fun unmarkAsReadById(id: Int): Boolean {
|
||||||
// TODO: Check internet connection
|
var success = false
|
||||||
return api.unmarkAsRead(id.toString())?.isSuccess == true
|
if (isNetworkAvailable()) {
|
||||||
|
success = api.unmarkAsRead(id.toString())?.isSuccess == true
|
||||||
|
}
|
||||||
|
return success
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun starr(item: SelfossModel.Item): Boolean {
|
suspend fun starr(item: SelfossModel.Item): Boolean {
|
||||||
@ -160,8 +213,11 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun starrById(id: Int): Boolean {
|
suspend fun starrById(id: Int): Boolean {
|
||||||
// TODO: Check success, store in DB
|
var success = false
|
||||||
return api.starr(id.toString())?.isSuccess == true
|
if (isNetworkAvailable()) {
|
||||||
|
success = api.starr(id.toString())?.isSuccess == true
|
||||||
|
}
|
||||||
|
return success
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun unstarr(item: SelfossModel.Item): Boolean {
|
suspend fun unstarr(item: SelfossModel.Item): Boolean {
|
||||||
@ -174,14 +230,19 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun unstarrById(id: Int): Boolean {
|
suspend fun unstarrById(id: Int): Boolean {
|
||||||
// TODO: Check internet connection
|
var success = false
|
||||||
return api.unstarr(id.toString())?.isSuccess == true
|
if (isNetworkAvailable()) {
|
||||||
|
success = api.unstarr(id.toString())?.isSuccess == true
|
||||||
|
}
|
||||||
|
return success
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun markAllAsRead(items: ArrayList<SelfossModel.Item>): Boolean {
|
|
||||||
// TODO: Check Internet connectivity, store in DB
|
|
||||||
|
|
||||||
val success = api.markAllAsRead(items.map { it.id.toString() })?.isSuccess == true
|
suspend fun markAllAsRead(items: ArrayList<SelfossModel.Item>): Boolean {
|
||||||
|
var success = false
|
||||||
|
if (isNetworkAvailable()) {
|
||||||
|
success = api.markAllAsRead(items.map { it.id.toString() })?.isSuccess == true
|
||||||
|
}
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
for (item in items) {
|
for (item in items) {
|
||||||
@ -230,46 +291,52 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
|||||||
tags: String,
|
tags: String,
|
||||||
filter: String
|
filter: String
|
||||||
): Boolean {
|
): Boolean {
|
||||||
// TODO: Check connectivity
|
var response = false
|
||||||
val response = api.createSourceForVersion(
|
if (isNetworkAvailable()) {
|
||||||
|
response = api.createSourceForVersion(
|
||||||
title,
|
title,
|
||||||
url,
|
url,
|
||||||
spout,
|
spout,
|
||||||
tags,
|
tags,
|
||||||
filter,
|
filter,
|
||||||
apiMajorVersion
|
apiMajorVersion
|
||||||
)
|
)?.isSuccess == true
|
||||||
|
}
|
||||||
|
|
||||||
return response != null
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun deleteSource(id: Int): Boolean {
|
suspend fun deleteSource(id: Int): Boolean {
|
||||||
// TODO: Check connectivity, store in DB
|
// TODO: Store in DB
|
||||||
var success = false
|
var success = false
|
||||||
|
if (isNetworkAvailable()) {
|
||||||
val response = api.deleteSource(id)
|
val response = api.deleteSource(id)
|
||||||
if (response != null) {
|
if (response != null) {
|
||||||
success = response.isSuccess
|
success = response.isSuccess
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return success
|
return success
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun updateRemote(): Boolean {
|
suspend fun updateRemote(): Boolean {
|
||||||
// TODO: Handle connectivity issues
|
var response = false
|
||||||
val response = api.update()
|
if (isConnectionAvailable.value) {
|
||||||
return response?.isSuccess ?: false
|
response = api.update()?.isSuccess == true
|
||||||
|
}
|
||||||
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun login(): Boolean {
|
suspend fun login(): Boolean {
|
||||||
var result = false
|
var result = false
|
||||||
|
if (isNetworkAvailable()) {
|
||||||
try {
|
try {
|
||||||
val response = api.login()
|
val response = api.login()
|
||||||
if (response != null && response.isSuccess) {
|
result = response?.isSuccess == true
|
||||||
result = true
|
|
||||||
}
|
|
||||||
} catch (cause: Throwable) {
|
} catch (cause: Throwable) {
|
||||||
Napier.e(cause.stackTraceToString(), tag = "RepositoryImpl.updateRemote")
|
Napier.e(cause.stackTraceToString(), tag = "RepositoryImpl.updateRemote")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,15 +354,26 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
|||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun updateApiVersion() {
|
private suspend fun updateApiVersion() {
|
||||||
// TODO: Handle connectivity issues
|
apiMajorVersion = settings.getInt("apiVersionMajor", 0)
|
||||||
|
|
||||||
|
if (isNetworkAvailable()) {
|
||||||
val fetchedVersion = api.version()
|
val fetchedVersion = api.version()
|
||||||
if (fetchedVersion != null) {
|
if (fetchedVersion != null) {
|
||||||
apiMajorVersion = fetchedVersion.getApiMajorVersion()
|
apiMajorVersion = fetchedVersion.getApiMajorVersion()
|
||||||
settings.putInt("apiVersionMajor", apiMajorVersion)
|
settings.putInt("apiVersionMajor", apiMajorVersion)
|
||||||
} else {
|
|
||||||
apiMajorVersion = settings.getInt("apiVersionMajor", 0)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isNetworkAvailable() = isConnectionAvailable.value && !offlineOverride
|
||||||
|
|
||||||
|
fun startNetwork() {
|
||||||
|
connectivityStatus.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stopNetwork() {
|
||||||
|
connectivityStatus.stop()
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Handle offline actions
|
// TODO: Handle offline actions
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user