From c0e7b1fa0e035fddb91fec447ec947961ca96a4a Mon Sep 17 00:00:00 2001 From: davide Date: Mon, 18 Jul 2022 01:28:56 +0200 Subject: [PATCH] Initial Dependency Injection implementation --- androidApp/build.gradle.kts | 3 + .../android/AddSourceActivity.kt | 13 +-- .../android/HomeActivity.kt | 6 +- .../android/LoginActivity.kt | 30 +++--- .../apps/readerforselfossv2/android/MyApp.kt | 12 ++- .../android/ReaderActivity.kt | 6 +- .../android/SourcesActivity.kt | 8 +- .../android/adapters/ItemCardAdapter.kt | 4 +- .../android/adapters/ItemListAdapter.kt | 4 +- .../android/adapters/ItemsAdapter.kt | 4 +- .../android/adapters/SourcesListAdapter.kt | 4 +- .../android/background/background.kt | 4 +- .../android/fragments/ArticleFragment.kt | 6 +- .../service/AndroidApiDetailsService.kt | 12 ++- shared/build.gradle.kts | 6 ++ .../rest/{SelfossApi.kt => SelfossApiImpl.kt} | 102 +++++++++++++----- .../service/ApiDetailsService.kt | 1 + 17 files changed, 146 insertions(+), 79 deletions(-) rename shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/rest/{SelfossApi.kt => SelfossApiImpl.kt} (76%) diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts index f675617..c2c5c6a 100644 --- a/androidApp/build.gradle.kts +++ b/androidApp/build.gradle.kts @@ -170,6 +170,9 @@ dependencies { implementation("me.relex:circleindicator:2.1.6") implementation("androidx.viewpager2:viewpager2:1.1.0-beta01") + //Dependency Injection + implementation("org.kodein.di:kodein-di:7.12.0") + //PhotoView implementation("com.github.chrisbanes:PhotoView:2.3.0") diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/AddSourceActivity.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/AddSourceActivity.kt index 681b285..eeedf5f 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/AddSourceActivity.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/AddSourceActivity.kt @@ -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.isBaseUrlValid 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.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.service.ApiDetailsService import kotlinx.coroutines.CoroutineScope @@ -37,7 +34,7 @@ class AddSourceActivity : AppCompatActivity() { private lateinit var apiDetailsService: ApiDetailsService private var mSpoutsValue: String? = null - private lateinit var api: SelfossApi + private lateinit var api: SelfossApiImpl private lateinit var appColors: AppColors private lateinit var binding: ActivityAddSourceBinding @@ -81,7 +78,7 @@ class AddSourceActivity : AppCompatActivity() { val settings = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE) apiDetailsService = AndroidApiDetailsService(this@AddSourceActivity) - api = SelfossApi( + api = SelfossApiImpl( // this, // this@AddSourceActivity, // settings.getBoolean("isSelfSignedCert", false), @@ -114,7 +111,7 @@ class AddSourceActivity : AppCompatActivity() { private fun handleSpoutsSpinner( spoutsSpinner: Spinner, - api: SelfossApi?, + api: SelfossApiImpl?, mProgress: ProgressBar, formContainer: ConstraintLayout ) { @@ -182,7 +179,7 @@ class AddSourceActivity : AppCompatActivity() { 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 = title.isEmpty() || url.isEmpty() || mSpoutsValue == null || mSpoutsValue!!.isEmpty() diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/HomeActivity.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/HomeActivity.kt index 81fd1b9..ad657ab 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/HomeActivity.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/HomeActivity.kt @@ -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.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.service.ApiDetailsService import bou.amine.apps.readerforselfossv2.service.SearchService @@ -129,7 +129,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { private lateinit var tabNewBadge: TextBadgeItem private lateinit var tabArchiveBadge: TextBadgeItem private lateinit var tabStarredBadge: TextBadgeItem - private lateinit var api: SelfossApi + private lateinit var api: SelfossApiImpl private lateinit var customTabActivityHelper: CustomTabActivityHelper private lateinit var editor: SharedPreferences.Editor private lateinit var sharedPref: SharedPreferences @@ -196,7 +196,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { settings = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE) apiDetailsService = AndroidApiDetailsService(applicationContext) - api = SelfossApi( + api = SelfossApiImpl( // this, // this@HomeActivity, // settings.getBoolean("isSelfSignedCert", false), diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/LoginActivity.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/LoginActivity.kt index a1eadc2..1b3e222 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/LoginActivity.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/LoginActivity.kt @@ -15,24 +15,19 @@ import android.view.View import android.view.inputmethod.EditorInfo import android.widget.TextView import androidx.preference.PreferenceManager -import androidx.work.Logger 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.utils.Config import bou.amine.apps.readerforselfossv2.android.utils.isBaseUrlValid 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 com.mikepenz.aboutlibraries.LibsBuilder import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import retrofit2.Call -import retrofit2.Callback -import retrofit2.Response +import org.kodein.di.* -class LoginActivity : AppCompatActivity() { +class LoginActivity() : AppCompatActivity(), DIAware { private var inValidCount: Int = 0 private var isWithSelfSignedCert = false @@ -45,6 +40,10 @@ class LoginActivity : AppCompatActivity() { private lateinit var appColors: AppColors 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?) { appColors = AppColors(this@LoginActivity) @@ -139,7 +138,6 @@ class LoginActivity : AppCompatActivity() { binding.passwordView.error = getString(R.string.wrong_infos) binding.httpLoginView.error = getString(R.string.wrong_infos) binding.httpPasswordView.error = getString(R.string.wrong_infos) - showProgress(false) } private fun attemptLogin() { @@ -219,9 +217,9 @@ class LoginActivity : AppCompatActivity() { editor.putString("httpPassword", httpPassword) editor.putBoolean("isSelfSignedCert", isWithSelfSignedCert) editor.apply() + apiDetailsService.refresh() - val apiDetailsService = AndroidApiDetailsService(this@LoginActivity) - val api = SelfossApi( + val api = SelfossApiImpl( // this, // this@LoginActivity, // isWithSelfSignedCert, @@ -236,15 +234,17 @@ class LoginActivity : AppCompatActivity() { if (result != null && result.isSuccess) { goToMain() } else { - preferenceError(Exception("Not success")) + CoroutineScope(Dispatchers.Main).launch { + preferenceError(Exception("Not success")) + } } } catch (cause: Throwable) { - Log.e("1", "LOL") + Log.e("1", cause.message!!) + Log.e("1", cause.stackTraceToString()) } } - } else { - showProgress(false) } + showProgress(false) } } diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/MyApp.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/MyApp.kt index 7d19deb..b18a683 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/MyApp.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/MyApp.kt @@ -9,16 +9,26 @@ import android.os.Build import androidx.preference.PreferenceManager import android.widget.ImageView 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.glide.loadMaybeBasicAuth +import bou.amine.apps.readerforselfossv2.service.ApiDetailsService import com.bumptech.glide.Glide import com.bumptech.glide.request.RequestOptions import com.ftinc.scoop.Scoop import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader import com.mikepenz.materialdrawer.util.DrawerImageLoader +import org.kodein.di.* import java.util.UUID.randomUUID -class MyApp : MultiDexApplication() { +class MyApp : MultiDexApplication(), DIAware { + + override val di by DI.lazy { + bind() with instance(this@MyApp.applicationContext) + + bind() with singleton { AndroidApiDetailsService(instance()) } + } + private lateinit var config: Config override fun onCreate() { diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/ReaderActivity.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/ReaderActivity.kt index 7a945bd..dea9ffe 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/ReaderActivity.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/ReaderActivity.kt @@ -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.utils.Config 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.service.ApiDetailsService import com.ftinc.scoop.Scoop @@ -40,7 +40,7 @@ class ReaderActivity : AppCompatActivity() { private lateinit var userIdentifier: String private lateinit var appColors: AppColors - private lateinit var api: SelfossApi + private lateinit var api: SelfossApiImpl private lateinit var toolbarMenu: Menu @@ -101,7 +101,7 @@ class ReaderActivity : AppCompatActivity() { markOnScroll = prefs.getBoolean("mark_on_scroll", false) activeAlignment = prefs.getInt("text_align", JUSTIFY) - api = SelfossApi( + api = SelfossApiImpl( // this, // this@ReaderActivity, // settings.getBoolean("isSelfSignedCert", false), diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/SourcesActivity.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/SourcesActivity.kt index eb949e0..b2580c5 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/SourcesActivity.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/SourcesActivity.kt @@ -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.utils.Config 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.service.ApiDetailsService import com.ftinc.scoop.Scoop import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import retrofit2.Call -import retrofit2.Callback -import retrofit2.Response import java.util.ArrayList class SourcesActivity : AppCompatActivity() { @@ -67,7 +63,7 @@ class SourcesActivity : AppCompatActivity() { val prefs = PreferenceManager.getDefaultSharedPreferences(this) val apiDetailsService = AndroidApiDetailsService(this@SourcesActivity) - val api = SelfossApi( + val api = SelfossApiImpl( // this, // this@SourcesActivity, // settings.getBoolean("isSelfSignedCert", false), diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt index 368e7d7..8fad61e 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt @@ -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.circularBitmapDrawable 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.service.ApiDetailsService import bou.amine.apps.readerforselfossv2.service.SearchService @@ -32,7 +32,7 @@ import kotlinx.coroutines.launch class ItemCardAdapter( override val app: Activity, override var items: ArrayList, - override val api: SelfossApi, + override val api: SelfossApiImpl, override val apiDetailsService: ApiDetailsService, override val db: AppDatabase, private val helper: CustomTabActivityHelper, diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt index e4c52fd..f440180 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt @@ -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.glide.bitmapCenterCrop 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.service.ApiDetailsService import bou.amine.apps.readerforselfossv2.service.SearchService @@ -24,7 +24,7 @@ import com.amulyakhare.textdrawable.util.ColorGenerator class ItemListAdapter( override val app: Activity, override var items: ArrayList, - override val api: SelfossApi, + override val api: SelfossApiImpl, override val apiDetailsService: ApiDetailsService, override val db: AppDatabase, private val helper: CustomTabActivityHelper, diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemsAdapter.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemsAdapter.kt index 82a3cd1..c7f8da0 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemsAdapter.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemsAdapter.kt @@ -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.themes.AppColors 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.service.ApiDetailsService import bou.amine.apps.readerforselfossv2.service.SearchService @@ -19,7 +19,7 @@ import kotlinx.coroutines.launch abstract class ItemsAdapter : RecyclerView.Adapter() { abstract var items: ArrayList - abstract val api: SelfossApi + abstract val api: SelfossApiImpl abstract val apiDetailsService: ApiDetailsService abstract val db: AppDatabase abstract val userIdentifier: String diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/SourcesListAdapter.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/SourcesListAdapter.kt index b49168e..aaff569 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/SourcesListAdapter.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/SourcesListAdapter.kt @@ -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.network.isNetworkAvailable 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.service.ApiDetailsService import com.amulyakhare.textdrawable.TextDrawable @@ -28,7 +28,7 @@ import kotlinx.coroutines.launch class SourcesListAdapter( private val app: Activity, private val items: ArrayList, - private val api: SelfossApi, + private val api: SelfossApiImpl, private val apiDetailsService: ApiDetailsService ) : RecyclerView.Adapter() { private val c: Context = app.baseContext diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/background/background.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/background/background.kt index e929f99..4cc9028 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/background/background.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/background/background.kt @@ -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.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.service.SearchService import bou.amine.apps.readerforselfossv2.service.SelfossService @@ -48,7 +48,7 @@ override fun doWork(): Result { val periodicRefresh = sharedPref.getBoolean("periodic_refresh", false) if (periodicRefresh) { val apiDetailsService = AndroidApiDetailsService(this.context) - val api = SelfossApi( + val api = SelfossApiImpl( // this.context, // null, // settings.getBoolean("isSelfSignedCert", false), diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt index c9628aa..b1297b7 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt @@ -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.loadMaybeBasicAuth 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.service.ApiDetailsService import bou.amine.apps.readerforselfossv2.service.SearchService @@ -109,7 +109,7 @@ class ArticleFragment : Fragment() { 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)!! @@ -157,7 +157,7 @@ class ArticleFragment : Fragment() { val settings = requireActivity().getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE) - val api = SelfossApi( + val api = SelfossApiImpl( // requireContext(), // requireActivity(), // settings.getBoolean("isSelfSignedCert", false), diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/service/AndroidApiDetailsService.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/service/AndroidApiDetailsService.kt index 77e6e31..8e64e10 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/service/AndroidApiDetailsService.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/service/AndroidApiDetailsService.kt @@ -19,8 +19,8 @@ class AndroidApiDetailsService(c: Context) : ApiDetailsService { override fun getApiVersion(): Int { if (_apiVersion == -1) { - _apiVersion = settings.getInt("apiVersionMajor", -1)!! - return settings.getInt("apiVersionMajor", -1)!! + _apiVersion = settings.getInt("apiVersionMajor", -1) + return _apiVersion } return _apiVersion } @@ -45,4 +45,12 @@ class AndroidApiDetailsService(c: Context) : ApiDetailsService { } 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) + } } \ No newline at end of file diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index f09de7c..ee7aa5b 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -27,6 +27,9 @@ kotlin { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0") implementation("io.ktor:ktor-client-auth:2.0.1") implementation("org.jsoup:jsoup:1.14.3") + + //Dependency Injection + implementation("org.kodein.di:kodein-di:7.12.0") } } val commonTest by getting { @@ -38,6 +41,9 @@ kotlin { val androidMain by getting { dependencies { implementation("io.ktor:ktor-client-android:2.0.1") + + //Dependency Injection + implementation("org.kodein.di:kodein-di:7.12.0") } } val androidTest by getting { diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/rest/SelfossApi.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/rest/SelfossApiImpl.kt similarity index 76% rename from shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/rest/SelfossApi.kt rename to shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/rest/SelfossApiImpl.kt index 23fc2bd..d01fc94 100644 --- a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/rest/SelfossApi.kt +++ b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/rest/SelfossApiImpl.kt @@ -3,10 +3,6 @@ package bou.amine.apps.readerforselfossv2.rest import bou.amine.apps.readerforselfossv2.service.ApiDetailsService import io.ktor.client.* 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.request.* import io.ktor.client.request.forms.* @@ -16,9 +12,59 @@ import io.ktor.client.plugins.logging.* import io.ktor.serialization.kotlinx.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? + + suspend fun stats(): SelfossModel.Stats? + + suspend fun tags(): List? + + suspend fun update(): SelfossModel.SuccessResponse? + + suspend fun spouts(): Map? + + suspend fun sources(): ArrayList? + + 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): 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(HttpCache) json(Json { @@ -52,24 +98,24 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) { expectSuccess = false } - private fun url(path: String) = + override fun url(path: String) = "${apiDetailsService.getBaseUrl()}$path" - suspend fun login(): SelfossModel.SuccessResponse? = + override suspend fun login(): SelfossModel.SuccessResponse? = client.get(url("/login")) { parameter("username", apiDetailsService.getUserName()) parameter("password", apiDetailsService.getPassword()) }.body() - suspend fun getItems( + override suspend fun getItems( type: String, items: Int, offset: Int, - tag: String? = "", - source: Long? = null, - search: String? = "", - updatedSince: String? = "" + tag: String?, + source: Long?, + search: String?, + updatedSince: String? ): List? = client.get(url("/items")) { parameter("username", apiDetailsService.getUserName()) @@ -83,64 +129,64 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) { parameter("offset", offset) }.body() - suspend fun stats(): SelfossModel.Stats? = + override suspend fun stats(): SelfossModel.Stats? = client.get(url("/stats")) { parameter("username", apiDetailsService.getUserName()) parameter("password", apiDetailsService.getPassword()) }.body() - suspend fun tags(): List? = + override suspend fun tags(): List? = client.get(url("/tags")) { parameter("username", apiDetailsService.getUserName()) parameter("password", apiDetailsService.getPassword()) }.body() - suspend fun update(): SelfossModel.SuccessResponse? = + override suspend fun update(): SelfossModel.SuccessResponse? = client.get(url("/update")) { parameter("username", apiDetailsService.getUserName()) parameter("password", apiDetailsService.getPassword()) }.body() - suspend fun spouts(): Map? = + override suspend fun spouts(): Map? = client.get(url("/sources/spouts")) { parameter("username", apiDetailsService.getUserName()) parameter("password", apiDetailsService.getPassword()) }.body() - suspend fun sources(): ArrayList? = + override suspend fun sources(): ArrayList? = client.get(url("/sources/list")) { parameter("username", apiDetailsService.getUserName()) parameter("password", apiDetailsService.getPassword()) }.body() - suspend fun version(): SelfossModel.ApiVersion? = + override suspend fun version(): SelfossModel.ApiVersion? = 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")) { parameter("username", apiDetailsService.getUserName()) parameter("password", apiDetailsService.getPassword()) }.body() - suspend fun unmarkAsRead(id: String): SelfossModel.SuccessResponse? = + override suspend fun unmarkAsRead(id: String): SelfossModel.SuccessResponse? = client.post(url("/unmark/$id")) { parameter("username", apiDetailsService.getUserName()) parameter("password", apiDetailsService.getPassword()) }.body() - suspend fun starr(id: String): SelfossModel.SuccessResponse? = + override suspend fun starr(id: String): SelfossModel.SuccessResponse? = client.post(url("/starr/$id")) { parameter("username", apiDetailsService.getUserName()) parameter("password", apiDetailsService.getPassword()) }.body() - suspend fun unstarr(id: String): SelfossModel.SuccessResponse? = + override suspend fun unstarr(id: String): SelfossModel.SuccessResponse? = client.post(url("/unstarr/$id")) { parameter("username", apiDetailsService.getUserName()) parameter("password", apiDetailsService.getPassword()) }.body() - suspend fun markAllAsRead(ids: List): SelfossModel.SuccessResponse? = + override suspend fun markAllAsRead(ids: List): SelfossModel.SuccessResponse? = client.submitForm( url = url("/mark"), formParameters = Parameters.build { @@ -150,7 +196,7 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) { } ).body() - suspend fun createSourceForVersion( + override suspend fun createSourceForVersion( title: String, url: String, spout: String, @@ -164,7 +210,7 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) { createSource(title, url, spout, tags, filter) } - private suspend fun createSource( + suspend fun createSource( title: String, url: String, spout: String, @@ -182,7 +228,7 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) { } ).body() - private suspend fun createSource2( + suspend fun createSource2( title: String, url: String, spout: String, @@ -200,7 +246,7 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) { } ).body() - suspend fun deleteSource(id: Int): SelfossModel.SuccessResponse? = + override suspend fun deleteSource(id: Int): SelfossModel.SuccessResponse? = client.delete(url("/source/$id")) { parameter("username", apiDetailsService.getUserName()) parameter("password", apiDetailsService.getPassword()) diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/service/ApiDetailsService.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/service/ApiDetailsService.kt index 77214c9..48e477e 100644 --- a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/service/ApiDetailsService.kt +++ b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/service/ApiDetailsService.kt @@ -6,4 +6,5 @@ interface ApiDetailsService { fun getBaseUrl(): String fun getUserName(): String fun getPassword(): String + fun refresh() } \ No newline at end of file