Initial Dependency Injection implementation

This commit is contained in:
davide 2022-07-18 01:28:56 +02:00
parent 8cbb225e6d
commit c0e7b1fa0e
17 changed files with 146 additions and 79 deletions

View File

@ -170,6 +170,9 @@ dependencies {
implementation("me.relex:circleindicator:2.1.6") implementation("me.relex:circleindicator:2.1.6")
implementation("androidx.viewpager2:viewpager2:1.1.0-beta01") implementation("androidx.viewpager2:viewpager2:1.1.0-beta01")
//Dependency Injection
implementation("org.kodein.di:kodein-di:7.12.0")
//PhotoView //PhotoView
implementation("com.github.chrisbanes:PhotoView:2.3.0") implementation("com.github.chrisbanes:PhotoView:2.3.0")

View File

@ -19,13 +19,10 @@ 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 com.ftinc.scoop.Scoop import com.ftinc.scoop.Scoop
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import bou.amine.apps.readerforselfossv2.android.databinding.ActivityAddSourceBinding import bou.amine.apps.readerforselfossv2.android.databinding.ActivityAddSourceBinding
import bou.amine.apps.readerforselfossv2.android.service.AndroidApiDetailsService import bou.amine.apps.readerforselfossv2.android.service.AndroidApiDetailsService
import bou.amine.apps.readerforselfossv2.rest.SelfossApi import bou.amine.apps.readerforselfossv2.rest.SelfossApiImpl
import bou.amine.apps.readerforselfossv2.rest.SelfossModel import bou.amine.apps.readerforselfossv2.rest.SelfossModel
import bou.amine.apps.readerforselfossv2.service.ApiDetailsService import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -37,7 +34,7 @@ class AddSourceActivity : AppCompatActivity() {
private lateinit var apiDetailsService: ApiDetailsService private lateinit var apiDetailsService: ApiDetailsService
private var mSpoutsValue: String? = null private var mSpoutsValue: String? = null
private lateinit var api: SelfossApi private lateinit var api: SelfossApiImpl
private lateinit var appColors: AppColors private lateinit var appColors: AppColors
private lateinit var binding: ActivityAddSourceBinding private lateinit var binding: ActivityAddSourceBinding
@ -81,7 +78,7 @@ class AddSourceActivity : AppCompatActivity() {
val settings = val settings =
getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE) getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
apiDetailsService = AndroidApiDetailsService(this@AddSourceActivity) apiDetailsService = AndroidApiDetailsService(this@AddSourceActivity)
api = SelfossApi( api = SelfossApiImpl(
// this, // this,
// this@AddSourceActivity, // this@AddSourceActivity,
// settings.getBoolean("isSelfSignedCert", false), // settings.getBoolean("isSelfSignedCert", false),
@ -114,7 +111,7 @@ class AddSourceActivity : AppCompatActivity() {
private fun handleSpoutsSpinner( private fun handleSpoutsSpinner(
spoutsSpinner: Spinner, spoutsSpinner: Spinner,
api: SelfossApi?, api: SelfossApiImpl?,
mProgress: ProgressBar, mProgress: ProgressBar,
formContainer: ConstraintLayout formContainer: ConstraintLayout
) { ) {
@ -182,7 +179,7 @@ class AddSourceActivity : AppCompatActivity() {
finish() finish()
} }
private fun handleSaveSource(tags: EditText, title: String, url: String, api: SelfossApi) { private fun handleSaveSource(tags: EditText, title: String, url: String, api: SelfossApiImpl) {
val sourceDetailsUnavailable = val sourceDetailsUnavailable =
title.isEmpty() || url.isEmpty() || mSpoutsValue == null || mSpoutsValue!!.isEmpty() title.isEmpty() || url.isEmpty() || mSpoutsValue == null || mSpoutsValue!!.isEmpty()

View File

@ -54,7 +54,7 @@ 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.utils.DateUtils import bou.amine.apps.readerforselfossv2.utils.DateUtils
import bou.amine.apps.readerforselfossv2.rest.SelfossApi import bou.amine.apps.readerforselfossv2.rest.SelfossApiImpl
import bou.amine.apps.readerforselfossv2.rest.SelfossModel 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.service.SearchService import bou.amine.apps.readerforselfossv2.service.SearchService
@ -129,7 +129,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
private lateinit var tabNewBadge: TextBadgeItem private lateinit var tabNewBadge: TextBadgeItem
private lateinit var tabArchiveBadge: TextBadgeItem private lateinit var tabArchiveBadge: TextBadgeItem
private lateinit var tabStarredBadge: TextBadgeItem private lateinit var tabStarredBadge: TextBadgeItem
private lateinit var api: SelfossApi private lateinit var api: SelfossApiImpl
private lateinit var customTabActivityHelper: CustomTabActivityHelper private lateinit var customTabActivityHelper: CustomTabActivityHelper
private lateinit var editor: SharedPreferences.Editor private lateinit var editor: SharedPreferences.Editor
private lateinit var sharedPref: SharedPreferences private lateinit var sharedPref: SharedPreferences
@ -196,7 +196,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
settings = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE) settings = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
apiDetailsService = AndroidApiDetailsService(applicationContext) apiDetailsService = AndroidApiDetailsService(applicationContext)
api = SelfossApi( api = SelfossApiImpl(
// this, // this,
// this@HomeActivity, // this@HomeActivity,
// settings.getBoolean("isSelfSignedCert", false), // settings.getBoolean("isSelfSignedCert", false),

View File

@ -15,24 +15,19 @@ import android.view.View
import android.view.inputmethod.EditorInfo import android.view.inputmethod.EditorInfo
import android.widget.TextView import android.widget.TextView
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.work.Logger
import bou.amine.apps.readerforselfossv2.android.databinding.ActivityLoginBinding import bou.amine.apps.readerforselfossv2.android.databinding.ActivityLoginBinding
import bou.amine.apps.readerforselfossv2.android.service.AndroidApiDetailsService
import bou.amine.apps.readerforselfossv2.android.themes.AppColors import bou.amine.apps.readerforselfossv2.android.themes.AppColors
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.utils.network.isNetworkAvailable import bou.amine.apps.readerforselfossv2.android.utils.network.isNetworkAvailable
import bou.amine.apps.readerforselfossv2.rest.SelfossApi import bou.amine.apps.readerforselfossv2.rest.SelfossApiImpl
import bou.amine.apps.readerforselfossv2.service.ApiDetailsService import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
import com.mikepenz.aboutlibraries.LibsBuilder import com.mikepenz.aboutlibraries.LibsBuilder
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import retrofit2.Call import org.kodein.di.*
import retrofit2.Callback
import retrofit2.Response
class LoginActivity : AppCompatActivity() { class LoginActivity() : AppCompatActivity(), DIAware {
private var inValidCount: Int = 0 private var inValidCount: Int = 0
private var isWithSelfSignedCert = false private var isWithSelfSignedCert = false
@ -45,6 +40,10 @@ class LoginActivity : AppCompatActivity() {
private lateinit var appColors: AppColors private lateinit var appColors: AppColors
private lateinit var binding: ActivityLoginBinding private lateinit var binding: ActivityLoginBinding
override val diContext: DIContext<*> = diContext(this)
override val di by lazy { (application as MyApp).di }
private val apiDetailsService : ApiDetailsService by instance()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
appColors = AppColors(this@LoginActivity) appColors = AppColors(this@LoginActivity)
@ -139,7 +138,6 @@ class LoginActivity : AppCompatActivity() {
binding.passwordView.error = getString(R.string.wrong_infos) binding.passwordView.error = getString(R.string.wrong_infos)
binding.httpLoginView.error = getString(R.string.wrong_infos) binding.httpLoginView.error = getString(R.string.wrong_infos)
binding.httpPasswordView.error = getString(R.string.wrong_infos) binding.httpPasswordView.error = getString(R.string.wrong_infos)
showProgress(false)
} }
private fun attemptLogin() { private fun attemptLogin() {
@ -219,9 +217,9 @@ class LoginActivity : AppCompatActivity() {
editor.putString("httpPassword", httpPassword) editor.putString("httpPassword", httpPassword)
editor.putBoolean("isSelfSignedCert", isWithSelfSignedCert) editor.putBoolean("isSelfSignedCert", isWithSelfSignedCert)
editor.apply() editor.apply()
apiDetailsService.refresh()
val apiDetailsService = AndroidApiDetailsService(this@LoginActivity) val api = SelfossApiImpl(
val api = SelfossApi(
// this, // this,
// this@LoginActivity, // this@LoginActivity,
// isWithSelfSignedCert, // isWithSelfSignedCert,
@ -236,17 +234,19 @@ class LoginActivity : AppCompatActivity() {
if (result != null && result.isSuccess) { if (result != null && result.isSuccess) {
goToMain() goToMain()
} else { } else {
CoroutineScope(Dispatchers.Main).launch {
preferenceError(Exception("Not success")) preferenceError(Exception("Not success"))
} }
}
} catch (cause: Throwable) { } catch (cause: Throwable) {
Log.e("1", "LOL") Log.e("1", cause.message!!)
Log.e("1", cause.stackTraceToString())
}
} }
} }
} else {
showProgress(false) showProgress(false)
} }
} }
}
private fun showProgress(show: Boolean) { private fun showProgress(show: Boolean) {
val shortAnimTime = resources.getInteger(android.R.integer.config_shortAnimTime) val shortAnimTime = resources.getInteger(android.R.integer.config_shortAnimTime)

View File

@ -9,16 +9,26 @@ import android.os.Build
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import android.widget.ImageView import android.widget.ImageView
import androidx.multidex.MultiDexApplication import androidx.multidex.MultiDexApplication
import bou.amine.apps.readerforselfossv2.android.service.AndroidApiDetailsService
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.service.ApiDetailsService
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.mikepenz.materialdrawer.util.AbstractDrawerImageLoader import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader
import com.mikepenz.materialdrawer.util.DrawerImageLoader import com.mikepenz.materialdrawer.util.DrawerImageLoader
import org.kodein.di.*
import java.util.UUID.randomUUID import java.util.UUID.randomUUID
class MyApp : MultiDexApplication() { class MyApp : MultiDexApplication(), DIAware {
override val di by DI.lazy {
bind<Context>() with instance(this@MyApp.applicationContext)
bind<ApiDetailsService>() with singleton { AndroidApiDetailsService(instance()) }
}
private lateinit var config: Config private lateinit var config: Config
override fun onCreate() { override fun onCreate() {

View File

@ -25,7 +25,7 @@ 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.toggleStar import bou.amine.apps.readerforselfossv2.android.utils.toggleStar
import bou.amine.apps.readerforselfossv2.rest.SelfossApi import bou.amine.apps.readerforselfossv2.rest.SelfossApiImpl
import bou.amine.apps.readerforselfossv2.rest.SelfossModel import bou.amine.apps.readerforselfossv2.rest.SelfossModel
import bou.amine.apps.readerforselfossv2.service.ApiDetailsService import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
import com.ftinc.scoop.Scoop import com.ftinc.scoop.Scoop
@ -40,7 +40,7 @@ class ReaderActivity : AppCompatActivity() {
private lateinit var userIdentifier: String private lateinit var userIdentifier: String
private lateinit var appColors: AppColors private lateinit var appColors: AppColors
private lateinit var api: SelfossApi private lateinit var api: SelfossApiImpl
private lateinit var toolbarMenu: Menu private lateinit var toolbarMenu: Menu
@ -101,7 +101,7 @@ class ReaderActivity : AppCompatActivity() {
markOnScroll = prefs.getBoolean("mark_on_scroll", false) markOnScroll = prefs.getBoolean("mark_on_scroll", false)
activeAlignment = prefs.getInt("text_align", JUSTIFY) activeAlignment = prefs.getInt("text_align", JUSTIFY)
api = SelfossApi( api = SelfossApiImpl(
// this, // this,
// this@ReaderActivity, // this@ReaderActivity,
// settings.getBoolean("isSelfSignedCert", false), // settings.getBoolean("isSelfSignedCert", false),

View File

@ -15,16 +15,12 @@ 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.network.isNetworkAvailable import bou.amine.apps.readerforselfossv2.android.utils.network.isNetworkAvailable
import bou.amine.apps.readerforselfossv2.rest.SelfossApi import bou.amine.apps.readerforselfossv2.rest.SelfossApiImpl
import bou.amine.apps.readerforselfossv2.rest.SelfossModel import bou.amine.apps.readerforselfossv2.rest.SelfossModel
import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
import com.ftinc.scoop.Scoop import com.ftinc.scoop.Scoop
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.util.ArrayList import java.util.ArrayList
class SourcesActivity : AppCompatActivity() { class SourcesActivity : AppCompatActivity() {
@ -67,7 +63,7 @@ class SourcesActivity : AppCompatActivity() {
val prefs = PreferenceManager.getDefaultSharedPreferences(this) val prefs = PreferenceManager.getDefaultSharedPreferences(this)
val apiDetailsService = AndroidApiDetailsService(this@SourcesActivity) val apiDetailsService = AndroidApiDetailsService(this@SourcesActivity)
val api = SelfossApi( val api = SelfossApiImpl(
// this, // this,
// this@SourcesActivity, // this@SourcesActivity,
// settings.getBoolean("isSelfSignedCert", false), // settings.getBoolean("isSelfSignedCert", false),

View File

@ -17,7 +17,7 @@ import bou.amine.apps.readerforselfossv2.android.utils.customtabs.CustomTabActiv
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.android.utils.network.isNetworkAvailable
import bou.amine.apps.readerforselfossv2.rest.SelfossApi import bou.amine.apps.readerforselfossv2.rest.SelfossApiImpl
import bou.amine.apps.readerforselfossv2.rest.SelfossModel 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.service.SearchService import bou.amine.apps.readerforselfossv2.service.SearchService
@ -32,7 +32,7 @@ import kotlinx.coroutines.launch
class ItemCardAdapter( class ItemCardAdapter(
override val app: Activity, override val app: Activity,
override var items: ArrayList<SelfossModel.Item>, override var items: ArrayList<SelfossModel.Item>,
override val api: SelfossApi, override val api: SelfossApiImpl,
override val apiDetailsService: ApiDetailsService, override val apiDetailsService: ApiDetailsService,
override val db: AppDatabase, override val db: AppDatabase,
private val helper: CustomTabActivityHelper, private val helper: CustomTabActivityHelper,

View File

@ -13,7 +13,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.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.rest.SelfossApi import bou.amine.apps.readerforselfossv2.rest.SelfossApiImpl
import bou.amine.apps.readerforselfossv2.rest.SelfossModel 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.service.SearchService import bou.amine.apps.readerforselfossv2.service.SearchService
@ -24,7 +24,7 @@ import com.amulyakhare.textdrawable.util.ColorGenerator
class ItemListAdapter( class ItemListAdapter(
override val app: Activity, override val app: Activity,
override var items: ArrayList<SelfossModel.Item>, override var items: ArrayList<SelfossModel.Item>,
override val api: SelfossApi, override val api: SelfossApiImpl,
override val apiDetailsService: ApiDetailsService, override val apiDetailsService: ApiDetailsService,
override val db: AppDatabase, override val db: AppDatabase,
private val helper: CustomTabActivityHelper, private val helper: CustomTabActivityHelper,

View File

@ -8,7 +8,7 @@ import bou.amine.apps.readerforselfossv2.android.R
import bou.amine.apps.readerforselfossv2.android.persistence.database.AppDatabase import bou.amine.apps.readerforselfossv2.android.persistence.database.AppDatabase
import bou.amine.apps.readerforselfossv2.android.themes.AppColors import bou.amine.apps.readerforselfossv2.android.themes.AppColors
import bou.amine.apps.readerforselfossv2.android.utils.Config import bou.amine.apps.readerforselfossv2.android.utils.Config
import bou.amine.apps.readerforselfossv2.rest.SelfossApi import bou.amine.apps.readerforselfossv2.rest.SelfossApiImpl
import bou.amine.apps.readerforselfossv2.rest.SelfossModel 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.service.SearchService import bou.amine.apps.readerforselfossv2.service.SearchService
@ -19,7 +19,7 @@ import kotlinx.coroutines.launch
abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapter<VH>() { abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapter<VH>() {
abstract var items: ArrayList<SelfossModel.Item> abstract var items: ArrayList<SelfossModel.Item>
abstract val api: SelfossApi abstract val api: SelfossApiImpl
abstract val apiDetailsService: ApiDetailsService abstract val apiDetailsService: ApiDetailsService
abstract val db: AppDatabase abstract val db: AppDatabase
abstract val userIdentifier: String abstract val userIdentifier: String

View File

@ -16,7 +16,7 @@ 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.network.isNetworkAvailable
import bou.amine.apps.readerforselfossv2.android.utils.toTextDrawableString import bou.amine.apps.readerforselfossv2.android.utils.toTextDrawableString
import bou.amine.apps.readerforselfossv2.rest.SelfossApi import bou.amine.apps.readerforselfossv2.rest.SelfossApiImpl
import bou.amine.apps.readerforselfossv2.rest.SelfossModel import bou.amine.apps.readerforselfossv2.rest.SelfossModel
import bou.amine.apps.readerforselfossv2.service.ApiDetailsService import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
import com.amulyakhare.textdrawable.TextDrawable import com.amulyakhare.textdrawable.TextDrawable
@ -28,7 +28,7 @@ import kotlinx.coroutines.launch
class SourcesListAdapter( class SourcesListAdapter(
private val app: Activity, private val app: Activity,
private val items: ArrayList<SelfossModel.Source>, private val items: ArrayList<SelfossModel.Source>,
private val api: SelfossApi, private val api: SelfossApiImpl,
private val apiDetailsService: ApiDetailsService private val apiDetailsService: ApiDetailsService
) : RecyclerView.Adapter<SourcesListAdapter.ViewHolder>() { ) : RecyclerView.Adapter<SourcesListAdapter.ViewHolder>() {
private val c: Context = app.baseContext private val c: Context = app.baseContext

View File

@ -26,7 +26,7 @@ import bou.amine.apps.readerforselfossv2.android.service.AndroidApiDetailsServic
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.isNetworkAvailable
import bou.amine.apps.readerforselfossv2.rest.SelfossApi import bou.amine.apps.readerforselfossv2.rest.SelfossApiImpl
import bou.amine.apps.readerforselfossv2.rest.SelfossModel import bou.amine.apps.readerforselfossv2.rest.SelfossModel
import bou.amine.apps.readerforselfossv2.service.SearchService import bou.amine.apps.readerforselfossv2.service.SearchService
import bou.amine.apps.readerforselfossv2.service.SelfossService import bou.amine.apps.readerforselfossv2.service.SelfossService
@ -48,7 +48,7 @@ override fun doWork(): Result {
val periodicRefresh = sharedPref.getBoolean("periodic_refresh", false) val periodicRefresh = sharedPref.getBoolean("periodic_refresh", false)
if (periodicRefresh) { if (periodicRefresh) {
val apiDetailsService = AndroidApiDetailsService(this.context) val apiDetailsService = AndroidApiDetailsService(this.context)
val api = SelfossApi( val api = SelfossApiImpl(
// this.context, // this.context,
// null, // null,
// settings.getBoolean("isSelfSignedCert", false), // settings.getBoolean("isSelfSignedCert", false),

View File

@ -40,7 +40,7 @@ import bou.amine.apps.readerforselfossv2.android.utils.customtabs.CustomTabActiv
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.android.utils.network.isNetworkAvailable
import bou.amine.apps.readerforselfossv2.rest.SelfossApi import bou.amine.apps.readerforselfossv2.rest.SelfossApiImpl
import bou.amine.apps.readerforselfossv2.rest.SelfossModel 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.service.SearchService import bou.amine.apps.readerforselfossv2.service.SearchService
@ -109,7 +109,7 @@ class ArticleFragment : Fragment() {
dbService = AndroidDeviceDatabaseService(AndroidDeviceDatabase(requireContext()), SearchService(DateUtils(apiDetailsService))) dbService = AndroidDeviceDatabaseService(AndroidDeviceDatabase(requireContext()), SearchService(DateUtils(apiDetailsService)))
service = SelfossService(SelfossApi(apiDetailsService), dbService, SearchService(DateUtils(apiDetailsService))) service = SelfossService(SelfossApiImpl(apiDetailsService), dbService, SearchService(DateUtils(apiDetailsService)))
val pi: ParecelableItem = requireArguments().getParcelable(ARG_ITEMS)!! val pi: ParecelableItem = requireArguments().getParcelable(ARG_ITEMS)!!
@ -157,7 +157,7 @@ class ArticleFragment : Fragment() {
val settings = requireActivity().getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE) val settings = requireActivity().getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
val api = SelfossApi( val api = SelfossApiImpl(
// requireContext(), // requireContext(),
// requireActivity(), // requireActivity(),
// settings.getBoolean("isSelfSignedCert", false), // settings.getBoolean("isSelfSignedCert", false),

View File

@ -19,8 +19,8 @@ class AndroidApiDetailsService(c: Context) : ApiDetailsService {
override fun getApiVersion(): Int { override fun getApiVersion(): Int {
if (_apiVersion == -1) { if (_apiVersion == -1) {
_apiVersion = settings.getInt("apiVersionMajor", -1)!! _apiVersion = settings.getInt("apiVersionMajor", -1)
return settings.getInt("apiVersionMajor", -1)!! return _apiVersion
} }
return _apiVersion return _apiVersion
} }
@ -45,4 +45,12 @@ class AndroidApiDetailsService(c: Context) : ApiDetailsService {
} }
return _password return _password
} }
override fun refresh() {
_password = settings.getString("password", "")!!
_userName = settings.getString("login", "")!!
_baseUrl = settings.getString("url", "")!!
_baseUrl = settings.getString("url", "")!!
_apiVersion = settings.getInt("apiVersionMajor", -1)
}
} }

View File

@ -27,6 +27,9 @@ kotlin {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0")
implementation("io.ktor:ktor-client-auth:2.0.1") implementation("io.ktor:ktor-client-auth:2.0.1")
implementation("org.jsoup:jsoup:1.14.3") implementation("org.jsoup:jsoup:1.14.3")
//Dependency Injection
implementation("org.kodein.di:kodein-di:7.12.0")
} }
} }
val commonTest by getting { val commonTest by getting {
@ -38,6 +41,9 @@ kotlin {
val androidMain by getting { val androidMain by getting {
dependencies { dependencies {
implementation("io.ktor:ktor-client-android:2.0.1") implementation("io.ktor:ktor-client-android:2.0.1")
//Dependency Injection
implementation("org.kodein.di:kodein-di:7.12.0")
} }
} }
val androidTest by getting { val androidTest by getting {

View File

@ -3,10 +3,6 @@ package bou.amine.apps.readerforselfossv2.rest
import bou.amine.apps.readerforselfossv2.service.ApiDetailsService import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
import io.ktor.client.* import io.ktor.client.*
import io.ktor.client.call.* import io.ktor.client.call.*
import io.ktor.client.engine.*
import io.ktor.client.engine.ProxyBuilder.http
import io.ktor.client.plugins.auth.*
import io.ktor.client.plugins.auth.providers.*
import io.ktor.client.plugins.cache.* import io.ktor.client.plugins.cache.*
import io.ktor.client.request.* import io.ktor.client.request.*
import io.ktor.client.request.forms.* import io.ktor.client.request.forms.*
@ -16,9 +12,59 @@ import io.ktor.client.plugins.logging.*
import io.ktor.serialization.kotlinx.json.* import io.ktor.serialization.kotlinx.json.*
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
class SelfossApi(private val apiDetailsService: ApiDetailsService) { interface SelfossApi {
val client: HttpClient
fun url(path: String): String
private val client = HttpClient() { suspend fun login(): SelfossModel.SuccessResponse?
suspend fun getItems(
type: String,
items: Int,
offset: Int,
tag: String? = "",
source: Long? = null,
search: String? = "",
updatedSince: String? = ""
): List<SelfossModel.Item>?
suspend fun stats(): SelfossModel.Stats?
suspend fun tags(): List<SelfossModel.Tag>?
suspend fun update(): SelfossModel.SuccessResponse?
suspend fun spouts(): Map<String, SelfossModel.Spout>?
suspend fun sources(): ArrayList<SelfossModel.Source>?
suspend fun version(): SelfossModel.ApiVersion?
suspend fun markAsRead(id: String): SelfossModel.SuccessResponse?
suspend fun unmarkAsRead(id: String): SelfossModel.SuccessResponse?
suspend fun starr(id: String): SelfossModel.SuccessResponse?
suspend fun unstarr(id: String): SelfossModel.SuccessResponse?
suspend fun markAllAsRead(ids: List<String>): SelfossModel.SuccessResponse?
suspend fun createSourceForVersion(
title: String,
url: String,
spout: String,
tags: String,
filter: String,
version: Int
): SelfossModel.SuccessResponse?
suspend fun deleteSource(id: Int): SelfossModel.SuccessResponse?
}
class SelfossApiImpl(private val apiDetailsService: ApiDetailsService) : SelfossApi {
override val client = HttpClient() {
install(ContentNegotiation) { install(ContentNegotiation) {
install(HttpCache) install(HttpCache)
json(Json { json(Json {
@ -52,24 +98,24 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) {
expectSuccess = false expectSuccess = false
} }
private fun url(path: String) = override fun url(path: String) =
"${apiDetailsService.getBaseUrl()}$path" "${apiDetailsService.getBaseUrl()}$path"
suspend fun login(): SelfossModel.SuccessResponse? = override suspend fun login(): SelfossModel.SuccessResponse? =
client.get(url("/login")) { client.get(url("/login")) {
parameter("username", apiDetailsService.getUserName()) parameter("username", apiDetailsService.getUserName())
parameter("password", apiDetailsService.getPassword()) parameter("password", apiDetailsService.getPassword())
}.body() }.body()
suspend fun getItems( override suspend fun getItems(
type: String, type: String,
items: Int, items: Int,
offset: Int, offset: Int,
tag: String? = "", tag: String?,
source: Long? = null, source: Long?,
search: String? = "", search: String?,
updatedSince: String? = "" updatedSince: String?
): List<SelfossModel.Item>? = ): List<SelfossModel.Item>? =
client.get(url("/items")) { client.get(url("/items")) {
parameter("username", apiDetailsService.getUserName()) parameter("username", apiDetailsService.getUserName())
@ -83,64 +129,64 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) {
parameter("offset", offset) parameter("offset", offset)
}.body() }.body()
suspend fun stats(): SelfossModel.Stats? = override suspend fun stats(): SelfossModel.Stats? =
client.get(url("/stats")) { client.get(url("/stats")) {
parameter("username", apiDetailsService.getUserName()) parameter("username", apiDetailsService.getUserName())
parameter("password", apiDetailsService.getPassword()) parameter("password", apiDetailsService.getPassword())
}.body() }.body()
suspend fun tags(): List<SelfossModel.Tag>? = override suspend fun tags(): List<SelfossModel.Tag>? =
client.get(url("/tags")) { client.get(url("/tags")) {
parameter("username", apiDetailsService.getUserName()) parameter("username", apiDetailsService.getUserName())
parameter("password", apiDetailsService.getPassword()) parameter("password", apiDetailsService.getPassword())
}.body() }.body()
suspend fun update(): SelfossModel.SuccessResponse? = override suspend fun update(): SelfossModel.SuccessResponse? =
client.get(url("/update")) { client.get(url("/update")) {
parameter("username", apiDetailsService.getUserName()) parameter("username", apiDetailsService.getUserName())
parameter("password", apiDetailsService.getPassword()) parameter("password", apiDetailsService.getPassword())
}.body() }.body()
suspend fun spouts(): Map<String, SelfossModel.Spout>? = override suspend fun spouts(): Map<String, SelfossModel.Spout>? =
client.get(url("/sources/spouts")) { client.get(url("/sources/spouts")) {
parameter("username", apiDetailsService.getUserName()) parameter("username", apiDetailsService.getUserName())
parameter("password", apiDetailsService.getPassword()) parameter("password", apiDetailsService.getPassword())
}.body() }.body()
suspend fun sources(): ArrayList<SelfossModel.Source>? = override suspend fun sources(): ArrayList<SelfossModel.Source>? =
client.get(url("/sources/list")) { client.get(url("/sources/list")) {
parameter("username", apiDetailsService.getUserName()) parameter("username", apiDetailsService.getUserName())
parameter("password", apiDetailsService.getPassword()) parameter("password", apiDetailsService.getPassword())
}.body() }.body()
suspend fun version(): SelfossModel.ApiVersion? = override suspend fun version(): SelfossModel.ApiVersion? =
client.get(url("/api/about")).body() client.get(url("/api/about")).body()
suspend fun markAsRead(id: String): SelfossModel.SuccessResponse? = override suspend fun markAsRead(id: String): SelfossModel.SuccessResponse? =
client.post(url("/mark/$id")) { client.post(url("/mark/$id")) {
parameter("username", apiDetailsService.getUserName()) parameter("username", apiDetailsService.getUserName())
parameter("password", apiDetailsService.getPassword()) parameter("password", apiDetailsService.getPassword())
}.body() }.body()
suspend fun unmarkAsRead(id: String): SelfossModel.SuccessResponse? = override suspend fun unmarkAsRead(id: String): SelfossModel.SuccessResponse? =
client.post(url("/unmark/$id")) { client.post(url("/unmark/$id")) {
parameter("username", apiDetailsService.getUserName()) parameter("username", apiDetailsService.getUserName())
parameter("password", apiDetailsService.getPassword()) parameter("password", apiDetailsService.getPassword())
}.body() }.body()
suspend fun starr(id: String): SelfossModel.SuccessResponse? = override suspend fun starr(id: String): SelfossModel.SuccessResponse? =
client.post(url("/starr/$id")) { client.post(url("/starr/$id")) {
parameter("username", apiDetailsService.getUserName()) parameter("username", apiDetailsService.getUserName())
parameter("password", apiDetailsService.getPassword()) parameter("password", apiDetailsService.getPassword())
}.body() }.body()
suspend fun unstarr(id: String): SelfossModel.SuccessResponse? = override suspend fun unstarr(id: String): SelfossModel.SuccessResponse? =
client.post(url("/unstarr/$id")) { client.post(url("/unstarr/$id")) {
parameter("username", apiDetailsService.getUserName()) parameter("username", apiDetailsService.getUserName())
parameter("password", apiDetailsService.getPassword()) parameter("password", apiDetailsService.getPassword())
}.body() }.body()
suspend fun markAllAsRead(ids: List<String>): SelfossModel.SuccessResponse? = override suspend fun markAllAsRead(ids: List<String>): SelfossModel.SuccessResponse? =
client.submitForm( client.submitForm(
url = url("/mark"), url = url("/mark"),
formParameters = Parameters.build { formParameters = Parameters.build {
@ -150,7 +196,7 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) {
} }
).body() ).body()
suspend fun createSourceForVersion( override suspend fun createSourceForVersion(
title: String, title: String,
url: String, url: String,
spout: String, spout: String,
@ -164,7 +210,7 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) {
createSource(title, url, spout, tags, filter) createSource(title, url, spout, tags, filter)
} }
private suspend fun createSource( suspend fun createSource(
title: String, title: String,
url: String, url: String,
spout: String, spout: String,
@ -182,7 +228,7 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) {
} }
).body() ).body()
private suspend fun createSource2( suspend fun createSource2(
title: String, title: String,
url: String, url: String,
spout: String, spout: String,
@ -200,7 +246,7 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) {
} }
).body() ).body()
suspend fun deleteSource(id: Int): SelfossModel.SuccessResponse? = override suspend fun deleteSource(id: Int): SelfossModel.SuccessResponse? =
client.delete(url("/source/$id")) { client.delete(url("/source/$id")) {
parameter("username", apiDetailsService.getUserName()) parameter("username", apiDetailsService.getUserName())
parameter("password", apiDetailsService.getPassword()) parameter("password", apiDetailsService.getPassword())

View File

@ -6,4 +6,5 @@ interface ApiDetailsService {
fun getBaseUrl(): String fun getBaseUrl(): String
fun getUserName(): String fun getUserName(): String
fun getPassword(): String fun getPassword(): String
fun refresh()
} }