Compare commits
3 Commits
9d0bb452e3
...
24c22a72e6
Author | SHA1 | Date | |
---|---|---|---|
24c22a72e6 | |||
aff5729041 | |||
fbfb775f7f |
@ -181,8 +181,9 @@ dependencies {
|
|||||||
implementation("androidx.viewpager2:viewpager2:1.1.0-beta01")
|
implementation("androidx.viewpager2:viewpager2:1.1.0-beta01")
|
||||||
|
|
||||||
//Dependency Injection
|
//Dependency Injection
|
||||||
implementation("org.kodein.di:kodein-di:7.12.0")
|
implementation("org.kodein.di:kodein-di:7.14.0")
|
||||||
implementation("org.kodein.di:kodein-di-framework-android-x:7.12.0")
|
implementation("org.kodein.di:kodein-di-framework-android-x:7.14.0")
|
||||||
|
implementation("org.kodein.di:kodein-di-framework-android-x-viewmodel:7.14.0")
|
||||||
|
|
||||||
//Settings
|
//Settings
|
||||||
implementation("com.russhwolf:multiplatform-settings-no-arg:0.9")
|
implementation("com.russhwolf:multiplatform-settings-no-arg:0.9")
|
||||||
@ -204,5 +205,7 @@ dependencies {
|
|||||||
|
|
||||||
// Network information
|
// Network information
|
||||||
// TODO: When updating this library, check if the todo in RepositoryImpl.startNetwork can be resolved
|
// TODO: When updating this library, check if the todo in RepositoryImpl.startNetwork can be resolved
|
||||||
implementation("com.github.ln-12:multiplatform-connectivity-status:1.1.0")
|
// TODO: Include this library once this is merged https://github.com/ln-12/multiplatform-connectivity-status/pull/4
|
||||||
|
// implementation("com.github.ln-12:multiplatform-connectivity-status:1.1.0")
|
||||||
|
implementation(project(":connectionstatus"))
|
||||||
}
|
}
|
@ -6,11 +6,13 @@ import android.view.View
|
|||||||
import android.widget.*
|
import android.widget.*
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import bou.amine.apps.readerforselfossv2.android.databinding.ActivityAddSourceBinding
|
import bou.amine.apps.readerforselfossv2.android.databinding.ActivityAddSourceBinding
|
||||||
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.Config
|
import bou.amine.apps.readerforselfossv2.android.utils.Config
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.isBaseUrlValid
|
import bou.amine.apps.readerforselfossv2.android.utils.isBaseUrlValid
|
||||||
|
import bou.amine.apps.readerforselfossv2.android.viewmodel.AppViewModel
|
||||||
import bou.amine.apps.readerforselfossv2.repository.Repository
|
import bou.amine.apps.readerforselfossv2.repository.Repository
|
||||||
import com.ftinc.scoop.Scoop
|
import com.ftinc.scoop.Scoop
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@ -30,6 +32,7 @@ class AddSourceActivity : AppCompatActivity(), DIAware {
|
|||||||
|
|
||||||
override val di by closestDI()
|
override val di by closestDI()
|
||||||
private val repository : Repository by instance()
|
private val repository : Repository by instance()
|
||||||
|
private val viewModel : AppViewModel by instance()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
appColors = AppColors(this@AddSourceActivity)
|
appColors = AppColors(this@AddSourceActivity)
|
||||||
@ -76,6 +79,16 @@ class AddSourceActivity : AppCompatActivity(), DIAware {
|
|||||||
binding.sourceUri.text.toString()
|
binding.sourceUri.text.toString()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lifecycleScope.launch {
|
||||||
|
viewModel.toastMessageProvider.collect { toastMessage ->
|
||||||
|
Toast.makeText(
|
||||||
|
this@AddSourceActivity,
|
||||||
|
toastMessage,
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
|
@ -17,6 +17,7 @@ import androidx.appcompat.app.AppCompatActivity
|
|||||||
import androidx.appcompat.widget.SearchView
|
import androidx.appcompat.widget.SearchView
|
||||||
import androidx.core.view.doOnNextLayout
|
import androidx.core.view.doOnNextLayout
|
||||||
import androidx.drawerlayout.widget.DrawerLayout
|
import androidx.drawerlayout.widget.DrawerLayout
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.recyclerview.widget.*
|
import androidx.recyclerview.widget.*
|
||||||
import androidx.room.Room
|
import androidx.room.Room
|
||||||
import androidx.work.Constraints
|
import androidx.work.Constraints
|
||||||
@ -46,6 +47,7 @@ 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.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.android.viewmodel.AppViewModel
|
||||||
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
|
||||||
@ -134,6 +136,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
|
|
||||||
override val di by closestDI()
|
override val di by closestDI()
|
||||||
private val repository : Repository by instance()
|
private val repository : Repository by instance()
|
||||||
|
private val viewModel : AppViewModel by instance()
|
||||||
|
|
||||||
data class DrawerData(val tags: List<SelfossModel.Tag>?, val sources: List<SelfossModel.Source>?)
|
data class DrawerData(val tags: List<SelfossModel.Tag>?, val sources: List<SelfossModel.Source>?)
|
||||||
|
|
||||||
@ -173,6 +176,15 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
AppDatabase::class.java, "selfoss-database"
|
AppDatabase::class.java, "selfoss-database"
|
||||||
).addMigrations(MIGRATION_1_2).addMigrations(MIGRATION_2_3).addMigrations(MIGRATION_3_4).build()
|
).addMigrations(MIGRATION_1_2).addMigrations(MIGRATION_2_3).addMigrations(MIGRATION_3_4).build()
|
||||||
|
|
||||||
|
lifecycleScope.launch {
|
||||||
|
viewModel.toastMessageProvider.collect { toastMessage ->
|
||||||
|
Toast.makeText(
|
||||||
|
this@HomeActivity,
|
||||||
|
toastMessage,
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
customTabActivityHelper = CustomTabActivityHelper()
|
customTabActivityHelper = CustomTabActivityHelper()
|
||||||
|
|
||||||
|
@ -10,11 +10,14 @@ import android.view.MenuItem
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.inputmethod.EditorInfo
|
import android.view.inputmethod.EditorInfo
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
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.viewmodel.AppViewModel
|
||||||
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
|
||||||
@ -38,6 +41,7 @@ class LoginActivity() : AppCompatActivity(), DIAware {
|
|||||||
|
|
||||||
override val di by closestDI()
|
override val di by closestDI()
|
||||||
private val repository : Repository by instance()
|
private val repository : Repository by instance()
|
||||||
|
private val viewModel : AppViewModel by instance()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
appColors = AppColors(this@LoginActivity)
|
appColors = AppColors(this@LoginActivity)
|
||||||
@ -57,6 +61,16 @@ class LoginActivity() : AppCompatActivity(), DIAware {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleActions()
|
handleActions()
|
||||||
|
|
||||||
|
lifecycleScope.launch {
|
||||||
|
viewModel.toastMessageProvider.collect { toastMessage ->
|
||||||
|
Toast.makeText(
|
||||||
|
this@LoginActivity,
|
||||||
|
toastMessage,
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleActions() {
|
private fun handleActions() {
|
||||||
|
@ -15,11 +15,12 @@ import androidx.preference.PreferenceManager
|
|||||||
import bou.amine.apps.readerforselfossv2.DI.networkModule
|
import bou.amine.apps.readerforselfossv2.DI.networkModule
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.Config
|
import bou.amine.apps.readerforselfossv2.android.utils.Config
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.glide.loadMaybeBasicAuth
|
import bou.amine.apps.readerforselfossv2.android.utils.glide.loadMaybeBasicAuth
|
||||||
|
import bou.amine.apps.readerforselfossv2.android.viewmodel.AppViewModel
|
||||||
import bou.amine.apps.readerforselfossv2.repository.Repository
|
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.github.ln12.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
|
||||||
@ -30,6 +31,7 @@ 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(), ConnectivityStatus(applicationContext)) }
|
bind<Repository>() with singleton { Repository(instance(), instance(), ConnectivityStatus(applicationContext)) }
|
||||||
|
bind<AppViewModel>() with singleton { AppViewModel(repository = instance()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val repository: Repository by instance()
|
private val repository: Repository by instance()
|
||||||
|
@ -5,11 +5,13 @@ import android.content.res.ColorStateList
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import bou.amine.apps.readerforselfossv2.android.adapters.SourcesListAdapter
|
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.viewmodel.AppViewModel
|
||||||
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
|
||||||
@ -27,6 +29,7 @@ class SourcesActivity : AppCompatActivity(), DIAware {
|
|||||||
|
|
||||||
override val di by closestDI()
|
override val di by closestDI()
|
||||||
private val repository : Repository by instance()
|
private val repository : Repository by instance()
|
||||||
|
private val viewModel : AppViewModel by instance()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
appColors = AppColors(this@SourcesActivity)
|
appColors = AppColors(this@SourcesActivity)
|
||||||
@ -47,6 +50,16 @@ class SourcesActivity : AppCompatActivity(), DIAware {
|
|||||||
|
|
||||||
binding.fab.rippleColor = appColors.colorAccentDark
|
binding.fab.rippleColor = appColors.colorAccentDark
|
||||||
binding.fab.backgroundTintList = ColorStateList.valueOf(appColors.colorAccent)
|
binding.fab.backgroundTintList = ColorStateList.valueOf(appColors.colorAccent)
|
||||||
|
|
||||||
|
lifecycleScope.launch {
|
||||||
|
viewModel.toastMessageProvider.collect { toastMessage ->
|
||||||
|
Toast.makeText(
|
||||||
|
this@SourcesActivity,
|
||||||
|
toastMessage,
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStop() {
|
override fun onStop() {
|
||||||
|
@ -19,6 +19,7 @@ import androidx.browser.customtabs.CustomTabsIntent
|
|||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import androidx.core.widget.NestedScrollView
|
import androidx.core.widget.NestedScrollView
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.room.Room
|
import androidx.room.Room
|
||||||
import bou.amine.apps.readerforselfossv2.android.ImageActivity
|
import bou.amine.apps.readerforselfossv2.android.ImageActivity
|
||||||
import bou.amine.apps.readerforselfossv2.android.R
|
import bou.amine.apps.readerforselfossv2.android.R
|
||||||
@ -35,6 +36,7 @@ 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.viewmodel.AppViewModel
|
||||||
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
|
||||||
@ -79,6 +81,7 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
|
|
||||||
override val di : DI by closestDI()
|
override val di : DI by closestDI()
|
||||||
private val repository: Repository by instance()
|
private val repository: Repository by instance()
|
||||||
|
private val viewModel : AppViewModel by instance()
|
||||||
|
|
||||||
private var settings = Settings()
|
private var settings = Settings()
|
||||||
|
|
||||||
@ -108,6 +111,16 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
requireContext(),
|
requireContext(),
|
||||||
AppDatabase::class.java, "selfoss-database"
|
AppDatabase::class.java, "selfoss-database"
|
||||||
).addMigrations(MIGRATION_1_2).addMigrations(MIGRATION_2_3).addMigrations(MIGRATION_3_4).build()
|
).addMigrations(MIGRATION_1_2).addMigrations(MIGRATION_2_3).addMigrations(MIGRATION_3_4).build()
|
||||||
|
|
||||||
|
lifecycleScope.launch {
|
||||||
|
viewModel.toastMessageProvider.collect { toastMessage ->
|
||||||
|
Toast.makeText(
|
||||||
|
context,
|
||||||
|
toastMessage,
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
package bou.amine.apps.readerforselfossv2.android.viewmodel
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import bou.amine.apps.readerforselfossv2.repository.Repository
|
||||||
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
|
import kotlinx.coroutines.flow.asSharedFlow
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class AppViewModel(private val repository: Repository) : ViewModel() {
|
||||||
|
private val _toastMessageProvider = MutableSharedFlow<String>()
|
||||||
|
val toastMessageProvider = _toastMessageProvider.asSharedFlow()
|
||||||
|
private var wasConnected = true
|
||||||
|
|
||||||
|
init {
|
||||||
|
viewModelScope.launch {
|
||||||
|
repository.isConnectionAvailable.collect { isConnected ->
|
||||||
|
if (isConnected && !wasConnected && repository.connectionMonitored) {
|
||||||
|
_toastMessageProvider.emit("Network connection is now available")
|
||||||
|
wasConnected = true
|
||||||
|
} else if (!isConnected && wasConnected && repository.connectionMonitored){
|
||||||
|
_toastMessageProvider.emit("Network connection lost")
|
||||||
|
wasConnected = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
connectionstatus/.gitignore
vendored
Normal file
1
connectionstatus/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/build
|
65
connectionstatus/build.gradle.kts
Normal file
65
connectionstatus/build.gradle.kts
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
plugins {
|
||||||
|
id("com.android.library")
|
||||||
|
kotlin("multiplatform")
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "com.github.ln-12"
|
||||||
|
version = "1.1.0"
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
android {
|
||||||
|
compilations.all {
|
||||||
|
kotlinOptions.jvmTarget = "1.8"
|
||||||
|
}
|
||||||
|
|
||||||
|
publishLibraryVariants("release", "debug")
|
||||||
|
}
|
||||||
|
ios()
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
val commonMain by getting {
|
||||||
|
dependencies {
|
||||||
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val commonTest by getting {
|
||||||
|
dependencies {
|
||||||
|
implementation(kotlin("test-common"))
|
||||||
|
implementation(kotlin("test-annotations-common"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val androidMain by getting
|
||||||
|
val androidTest by getting {
|
||||||
|
dependencies {
|
||||||
|
implementation(kotlin("test-junit"))
|
||||||
|
implementation("junit:junit:4.13.2")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val iosMain by getting
|
||||||
|
val iosTest by getting
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdk = 31
|
||||||
|
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
|
||||||
|
defaultConfig {
|
||||||
|
minSdk = 21
|
||||||
|
targetSdk = 31
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// metadata is currently not supported for iOS
|
||||||
|
// https://youtrack.jetbrains.com/issue/KT-44459#focus=Comments-27-4645829.0-0
|
||||||
|
kotlin.metadata {
|
||||||
|
compilations.matching { it.name == "iosMain" }.all {
|
||||||
|
compileKotlinTaskProvider.configure { enabled = false }
|
||||||
|
}
|
||||||
|
}
|
4
connectionstatus/src/androidMain/AndroidManifest.xml
Normal file
4
connectionstatus/src/androidMain/AndroidManifest.xml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.github.ln12.library">
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
|
</manifest>
|
@ -0,0 +1,85 @@
|
|||||||
|
package com.github.ln12.library
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.net.ConnectivityManager
|
||||||
|
import android.net.Network
|
||||||
|
import android.net.NetworkCapabilities
|
||||||
|
import android.net.NetworkRequest
|
||||||
|
import android.os.Build
|
||||||
|
import android.util.Log
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
||||||
|
// From library com.github.ln-12:multiplatform-connectivity-status:1.1.0
|
||||||
|
// https://github.com/ln-12/multiplatform-connectivity-status
|
||||||
|
// Copyright 2021 Lorenzo Neumann
|
||||||
|
// Edited by davidoskky as here: https://github.com/ln-12/multiplatform-connectivity-status/pull/4
|
||||||
|
actual class ConnectivityStatus(private val context: Context) {
|
||||||
|
actual val isNetworkConnected = MutableStateFlow(false)
|
||||||
|
|
||||||
|
private var connectivityManager: ConnectivityManager? = null
|
||||||
|
private val networkCallback = object : ConnectivityManager.NetworkCallback() {
|
||||||
|
override fun onAvailable(network: Network) {
|
||||||
|
Log.d("Connectivity status", "Connected")
|
||||||
|
isNetworkConnected.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLost(network: Network) {
|
||||||
|
Log.d("Connectivity status", "Disconnected")
|
||||||
|
isNetworkConnected.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun start() {
|
||||||
|
try {
|
||||||
|
if (connectivityManager == null) {
|
||||||
|
connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||||
|
}
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
// API 24 and above
|
||||||
|
connectivityManager!!.registerDefaultNetworkCallback(networkCallback)
|
||||||
|
|
||||||
|
val currentNetwork = connectivityManager!!.activeNetwork
|
||||||
|
|
||||||
|
if(currentNetwork == null) {
|
||||||
|
isNetworkConnected.value = false
|
||||||
|
|
||||||
|
Log.d("Connectivity status", "Disconnected")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// API 23 and below
|
||||||
|
val networkRequest = NetworkRequest.Builder().apply {
|
||||||
|
addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||||
|
addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
|
||||||
|
}
|
||||||
|
}.build()
|
||||||
|
|
||||||
|
connectivityManager!!.registerNetworkCallback(networkRequest, networkCallback)
|
||||||
|
|
||||||
|
val currentNetwork = connectivityManager!!.activeNetworkInfo
|
||||||
|
|
||||||
|
if(currentNetwork == null || (
|
||||||
|
currentNetwork.type != ConnectivityManager.TYPE_ETHERNET &&
|
||||||
|
currentNetwork.type != ConnectivityManager.TYPE_WIFI &&
|
||||||
|
currentNetwork.type != ConnectivityManager.TYPE_MOBILE
|
||||||
|
)) {
|
||||||
|
isNetworkConnected.value = false
|
||||||
|
|
||||||
|
Log.d("Connectivity status", "Disconnected")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d("Connectivity status", "Started")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.d("Connectivity status", "Failed to start: ${e.message.toString()}")
|
||||||
|
e.printStackTrace()
|
||||||
|
isNetworkConnected.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun stop() {
|
||||||
|
connectivityManager?.unregisterNetworkCallback(networkCallback)
|
||||||
|
Log.d("Connectivity status", "Stopped")
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.github.ln12.library
|
||||||
|
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
||||||
|
// From library com.github.ln-12:multiplatform-connectivity-status:1.1.0
|
||||||
|
// https://github.com/ln-12/multiplatform-connectivity-status
|
||||||
|
// Copyright 2021 Lorenzo Neumann
|
||||||
|
expect class ConnectivityStatus {
|
||||||
|
val isNetworkConnected: MutableStateFlow<Boolean>
|
||||||
|
fun start()
|
||||||
|
fun stop()
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package com.github.ln12.library
|
||||||
|
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import cocoapods.Reachability.*
|
||||||
|
import kotlinx.coroutines.MainScope
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import platform.Foundation.NSLog
|
||||||
|
import platform.darwin.dispatch_async
|
||||||
|
import platform.darwin.dispatch_get_main_queue
|
||||||
|
import kotlin.native.concurrent.freeze
|
||||||
|
|
||||||
|
|
||||||
|
// From library com.github.ln-12:multiplatform-connectivity-status:1.1.0
|
||||||
|
// https://github.com/ln-12/multiplatform-connectivity-status
|
||||||
|
// Copyright 2021 Lorenzo Neumann
|
||||||
|
actual class ConnectivityStatus {
|
||||||
|
actual val isNetworkConnected = MutableStateFlow(false)
|
||||||
|
|
||||||
|
private var reachability: Reachability? = null
|
||||||
|
|
||||||
|
// Swift can't directly use a MutableStateFlow, so the status
|
||||||
|
// is exposed via a lambda/closure
|
||||||
|
fun getStatus(success: (Boolean) -> Unit) {
|
||||||
|
MainScope().launch {
|
||||||
|
isNetworkConnected.collect { status ->
|
||||||
|
success(status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun start() {
|
||||||
|
dispatch_async(dispatch_get_main_queue()) {
|
||||||
|
reachability = Reachability.reachabilityForInternetConnection()
|
||||||
|
|
||||||
|
val reachableCallback = { reach: Reachability? ->
|
||||||
|
dispatch_async(dispatch_get_main_queue(), {
|
||||||
|
NSLog("Connected")
|
||||||
|
|
||||||
|
isNetworkConnected.value = true
|
||||||
|
}.freeze())
|
||||||
|
}.freeze()
|
||||||
|
reachability?.reachableBlock = reachableCallback
|
||||||
|
|
||||||
|
val unreachableCallback = { reach: Reachability? ->
|
||||||
|
dispatch_async(dispatch_get_main_queue(), {
|
||||||
|
NSLog("Disconnected")
|
||||||
|
|
||||||
|
isNetworkConnected.value = false
|
||||||
|
}.freeze())
|
||||||
|
}.freeze()
|
||||||
|
reachability?.unreachableBlock = unreachableCallback
|
||||||
|
|
||||||
|
reachability?.startNotifier()
|
||||||
|
|
||||||
|
dispatch_async(dispatch_get_main_queue(), {
|
||||||
|
isNetworkConnected.value = reachability?.isReachable() ?: false
|
||||||
|
|
||||||
|
NSLog("Initial reachability: ${reachability?.isReachable()}")
|
||||||
|
}.freeze())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun stop() {
|
||||||
|
reachability?.stopNotifier()
|
||||||
|
}
|
||||||
|
}
|
@ -8,4 +8,5 @@ pluginManagement {
|
|||||||
|
|
||||||
rootProject.name = "ReaderForSelfossV2"
|
rootProject.name = "ReaderForSelfossV2"
|
||||||
include(":androidApp")
|
include(":androidApp")
|
||||||
include(":shared")
|
include(":shared")
|
||||||
|
include(":connectionstatus")
|
@ -38,7 +38,9 @@ kotlin {
|
|||||||
implementation("io.github.aakira:napier:2.6.1")
|
implementation("io.github.aakira:napier:2.6.1")
|
||||||
|
|
||||||
// Network information
|
// Network information
|
||||||
implementation("com.github.ln-12:multiplatform-connectivity-status:1.1.0")
|
// TODO: Include this library once this is merged https://github.com/ln-12/multiplatform-connectivity-status/pull/4
|
||||||
|
//implementation("com.github.ln-12:multiplatform-connectivity-status:1.1.0")
|
||||||
|
implementation(project(":connectionstatus"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val commonTest by getting {
|
val commonTest by getting {
|
||||||
|
@ -5,7 +5,7 @@ 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.github.ln12.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
|
||||||
@ -16,7 +16,8 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
|||||||
val settings = Settings()
|
val settings = Settings()
|
||||||
|
|
||||||
var items = ArrayList<SelfossModel.Item>()
|
var items = ArrayList<SelfossModel.Item>()
|
||||||
private val isConnectionAvailable = connectivityStatus.isNetworkConnected
|
val isConnectionAvailable = connectivityStatus.isNetworkConnected
|
||||||
|
var connectionMonitored = false
|
||||||
|
|
||||||
var baseUrl = apiDetails.getBaseUrl()
|
var baseUrl = apiDetails.getBaseUrl()
|
||||||
lateinit var dateUtils: DateUtils
|
lateinit var dateUtils: DateUtils
|
||||||
@ -347,10 +348,12 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails
|
|||||||
// com.github.ln-12:multiplatform-connectivity-status:1.1.0
|
// com.github.ln-12:multiplatform-connectivity-status:1.1.0
|
||||||
// https://github.com/ln-12/multiplatform-connectivity-status/issues/2
|
// https://github.com/ln-12/multiplatform-connectivity-status/issues/2
|
||||||
fun startNetwork() {
|
fun startNetwork() {
|
||||||
|
connectionMonitored = true
|
||||||
connectivityStatus.start()
|
connectivityStatus.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopNetwork() {
|
fun stopNetwork() {
|
||||||
|
connectionMonitored = false
|
||||||
connectivityStatus.stop()
|
connectivityStatus.stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user