Implement multiplatform settings

This commit is contained in:
davide 2022-07-18 23:25:10 +02:00
parent e4fbdce30e
commit bbec7745fe
16 changed files with 126 additions and 179 deletions

View File

@ -174,6 +174,9 @@ dependencies {
implementation("org.kodein.di:kodein-di:7.12.0") implementation("org.kodein.di:kodein-di:7.12.0")
implementation("org.kodein.di:kodein-di-framework-android-x:7.12.0") implementation("org.kodein.di:kodein-di-framework-android-x:7.12.0")
//Settings
implementation("com.russhwolf:multiplatform-settings-no-arg:0.9")
//PhotoView //PhotoView
implementation("com.github.chrisbanes:PhotoView:2.3.0") implementation("com.github.chrisbanes:PhotoView:2.3.0")

View File

@ -1,9 +1,7 @@
package bou.amine.apps.readerforselfossv2.android package bou.amine.apps.readerforselfossv2.android
import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.preference.PreferenceManager
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import android.view.View import android.view.View
@ -24,6 +22,7 @@ import bou.amine.apps.readerforselfossv2.android.databinding.ActivityAddSourceBi
import bou.amine.apps.readerforselfossv2.rest.SelfossApiImpl 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.russhwolf.settings.Settings
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -39,6 +38,7 @@ class AddSourceActivity : AppCompatActivity(), DIAware {
private lateinit var appColors: AppColors private lateinit var appColors: AppColors
private lateinit var binding: ActivityAddSourceBinding private lateinit var binding: ActivityAddSourceBinding
private val settings = Settings()
override val di by closestDI() override val di by closestDI()
private val apiDetailsService : ApiDetailsService by instance() private val apiDetailsService : ApiDetailsService by instance()
@ -78,9 +78,6 @@ class AddSourceActivity : AppCompatActivity(), DIAware {
supportActionBar?.setDisplayShowHomeEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true)
try { try {
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
val settings =
getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
api = SelfossApiImpl( api = SelfossApiImpl(
// this, // this,
// this@AddSourceActivity, // this@AddSourceActivity,
@ -103,7 +100,7 @@ class AddSourceActivity : AppCompatActivity(), DIAware {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
val config = Config(this) val config = Config()
if (config.baseUrl.isEmpty() || !config.baseUrl.isBaseUrlValid(this@AddSourceActivity)) { if (config.baseUrl.isEmpty() || !config.baseUrl.isBaseUrlValid(this@AddSourceActivity)) {
mustLoginToAddSource() mustLoginToAddSource()
@ -199,7 +196,7 @@ class AddSourceActivity : AppCompatActivity(), DIAware {
mSpoutsValue!!, mSpoutsValue!!,
tags.text.toString(), tags.text.toString(),
"", "",
PreferenceManager.getDefaultSharedPreferences(this@AddSourceActivity).getInt("apiVersionMajor", 0) settings.getInt("apiVersionMajor", 0)
) )
if (response != null) { if (response != null) {
finish() finish()

View File

@ -1,14 +1,11 @@
package bou.amine.apps.readerforselfossv2.android package bou.amine.apps.readerforselfossv2.android
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable import android.graphics.drawable.GradientDrawable
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import androidx.preference.PreferenceManager
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
@ -79,6 +76,7 @@ import com.mikepenz.materialdrawer.util.DrawerImageLoader
import com.mikepenz.materialdrawer.util.addStickyFooterItem import com.mikepenz.materialdrawer.util.addStickyFooterItem
import com.mikepenz.materialdrawer.util.updateBadge import com.mikepenz.materialdrawer.util.updateBadge
import com.mikepenz.materialdrawer.widget.AccountHeaderView import com.mikepenz.materialdrawer.widget.AccountHeaderView
import com.russhwolf.settings.Settings
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -132,13 +130,11 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
private lateinit var tabStarredBadge: TextBadgeItem private lateinit var tabStarredBadge: TextBadgeItem
private lateinit var api: SelfossApiImpl private lateinit var api: SelfossApiImpl
private lateinit var customTabActivityHelper: CustomTabActivityHelper private lateinit var customTabActivityHelper: CustomTabActivityHelper
private lateinit var editor: SharedPreferences.Editor
private lateinit var sharedPref: SharedPreferences
private lateinit var appColors: AppColors private lateinit var appColors: AppColors
private var offset: Int = 0 private var offset: Int = 0
private var firstVisible: Int = 0 private var firstVisible: Int = 0
private lateinit var recyclerViewScrollListener: RecyclerView.OnScrollListener private lateinit var recyclerViewScrollListener: RecyclerView.OnScrollListener
private lateinit var settings: SharedPreferences private var settings = Settings()
private lateinit var binding: ActivityHomeBinding private lateinit var binding: ActivityHomeBinding
private var recyclerAdapter: RecyclerView.Adapter<*>? = null private var recyclerAdapter: RecyclerView.Adapter<*>? = null
@ -164,7 +160,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
appColors = AppColors(this@HomeActivity) appColors = AppColors(this@HomeActivity)
config = Config(this@HomeActivity) config = Config()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityHomeBinding.inflate(layoutInflater) binding = ActivityHomeBinding.inflate(layoutInflater)
@ -196,9 +192,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
customTabActivityHelper = CustomTabActivityHelper() customTabActivityHelper = CustomTabActivityHelper()
sharedPref = PreferenceManager.getDefaultSharedPreferences(this)
settings = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
api = SelfossApiImpl( api = SelfossApiImpl(
// this, // this,
// this@HomeActivity, // this@HomeActivity,
@ -219,7 +212,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
handleSwipeRefreshLayout() handleSwipeRefreshLayout()
handleSharedPrefs() handleSettings()
getApiMajorVersion() getApiMajorVersion()
@ -358,7 +351,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
val version = api.version() val version = api.version()
if (version != null) { if (version != null) {
apiVersionMajor = version.getApiMajorVersion() apiVersionMajor = version.getApiMajorVersion()
sharedPref.edit().putInt("apiVersionMajor", apiVersionMajor).apply() settings.putInt("apiVersionMajor", apiVersionMajor)
} }
} }
} }
@ -369,10 +362,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
// TODO: Make this the only appcolors init // TODO: Make this the only appcolors init
appColors = AppColors(this@HomeActivity) appColors = AppColors(this@HomeActivity)
sharedPref = PreferenceManager.getDefaultSharedPreferences(this)
editor = settings.edit()
handleDrawerItems() handleDrawerItems()
handleThemeUpdate() handleThemeUpdate()
@ -399,34 +388,34 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
customTabActivityHelper.unbindCustomTabsService(this) customTabActivityHelper.unbindCustomTabsService(this)
} }
private fun handleSharedPrefs() { private fun handleSettings() {
internalBrowser = sharedPref.getBoolean("prefer_internal_browser", true) internalBrowser = settings.getBoolean("prefer_internal_browser", true)
articleViewer = sharedPref.getBoolean("prefer_article_viewer", true) articleViewer = settings.getBoolean("prefer_article_viewer", true)
shouldBeCardView = sharedPref.getBoolean("card_view_active", false) shouldBeCardView = settings.getBoolean("card_view_active", false)
displayUnreadCount = sharedPref.getBoolean("display_unread_count", true) displayUnreadCount = settings.getBoolean("display_unread_count", true)
displayAllCount = sharedPref.getBoolean("display_other_count", false) displayAllCount = settings.getBoolean("display_other_count", false)
fullHeightCards = sharedPref.getBoolean("full_height_cards", false) fullHeightCards = settings.getBoolean("full_height_cards", false)
itemsNumber = sharedPref.getString("prefer_api_items_number", "200")!!.toInt() itemsNumber = settings.getString("prefer_api_items_number", "200").toInt()
userIdentifier = sharedPref.getString("unique_id", "")!! userIdentifier = settings.getString("unique_id", "")
displayAccountHeader = sharedPref.getBoolean("account_header_displaying", false) displayAccountHeader = settings.getBoolean("account_header_displaying", false)
infiniteScroll = sharedPref.getBoolean("infinite_loading", false) infiniteScroll = settings.getBoolean("infinite_loading", false)
searchService.itemsCaching = sharedPref.getBoolean("items_caching", false) searchService.itemsCaching = settings.getBoolean("items_caching", false)
updateSources = sharedPref.getBoolean("update_sources", true) updateSources = settings.getBoolean("update_sources", true)
markOnScroll = sharedPref.getBoolean("mark_on_scroll", false) markOnScroll = settings.getBoolean("mark_on_scroll", false)
hiddenTags = if (sharedPref.getString("hidden_tags", "")!!.isNotEmpty()) { hiddenTags = if (settings.getString("hidden_tags", "").isNotEmpty()) {
sharedPref.getString("hidden_tags", "")!!.replace("\\s".toRegex(), "").split(",") settings.getString("hidden_tags", "").replace("\\s".toRegex(), "").split(",")
} else { } else {
emptyList() emptyList()
} }
periodicRefresh = sharedPref.getBoolean("periodic_refresh", false) periodicRefresh = settings.getBoolean("periodic_refresh", false)
refreshWhenChargingOnly = sharedPref.getBoolean("refresh_when_charging", false) refreshWhenChargingOnly = settings.getBoolean("refresh_when_charging", false)
refreshMinutes = sharedPref.getString("periodic_refresh_minutes", "360")!!.toLong() refreshMinutes = settings.getString("periodic_refresh_minutes", "360").toLong()
if (refreshMinutes <= 15) { if (refreshMinutes <= 15) {
refreshMinutes = 15 refreshMinutes = 15
} }
apiVersionMajor = sharedPref.getInt("apiVersionMajor", 0) apiVersionMajor = settings.getInt("apiVersionMajor", 0)
} }
private fun handleThemeBinding() { private fun handleThemeBinding() {
@ -481,8 +470,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
binding.drawerContainer.addDrawerListener(drawerListener) binding.drawerContainer.addDrawerListener(drawerListener)
displayAccountHeader = displayAccountHeader =
PreferenceManager.getDefaultSharedPreferences(this) settings.getBoolean("account_header_displaying", false)
.getBoolean("account_header_displaying", false)
binding.mainDrawer.addStickyFooterItem( binding.mainDrawer.addStickyFooterItem(
PrimaryDrawerItem().apply { PrimaryDrawerItem().apply {
@ -512,7 +500,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
attachToSliderView(binding.mainDrawer) attachToSliderView(binding.mainDrawer)
addProfiles( addProfiles(
ProfileDrawerItem().apply { ProfileDrawerItem().apply {
nameText = settings.getString("url", "").toString() nameText = settings.getString("url", "")
setBackgroundResource(R.drawable.bg) setBackgroundResource(R.drawable.bg)
iconRes = R.mipmap.ic_launcher iconRes = R.mipmap.ic_launcher
selectionListEnabledForSingleProfile = false selectionListEnabledForSingleProfile = false
@ -1211,7 +1199,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
return true return true
} }
R.id.action_disconnect -> { R.id.action_disconnect -> {
return Config.logoutAndRedirect(this, this@HomeActivity, editor) return Config.logoutAndRedirect(this, this@HomeActivity)
} }
else -> return super.onOptionsItemSelected(item) else -> return super.onOptionsItemSelected(item)
} }

View File

@ -3,7 +3,6 @@ package bou.amine.apps.readerforselfossv2.android
import android.animation.Animator import android.animation.Animator
import android.animation.AnimatorListenerAdapter import android.animation.AnimatorListenerAdapter
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
@ -14,7 +13,6 @@ 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 androidx.preference.PreferenceManager
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
@ -22,6 +20,7 @@ import bou.amine.apps.readerforselfossv2.android.utils.network.isNetworkAvailabl
import bou.amine.apps.readerforselfossv2.rest.SelfossApiImpl 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 com.russhwolf.settings.Settings
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -35,8 +34,7 @@ class LoginActivity() : AppCompatActivity(), DIAware {
private var isWithLogin = false private var isWithLogin = false
private var isWithHTTPLogin = false private var isWithHTTPLogin = false
private lateinit var settings: SharedPreferences private val settings = Settings()
private lateinit var editor: SharedPreferences.Editor
private lateinit var userIdentifier: String private lateinit var userIdentifier: String
private lateinit var appColors: AppColors private lateinit var appColors: AppColors
private lateinit var binding: ActivityLoginBinding private lateinit var binding: ActivityLoginBinding
@ -57,12 +55,9 @@ class LoginActivity() : AppCompatActivity(), DIAware {
handleBaseUrlFail() handleBaseUrlFail()
settings = PreferenceManager.getDefaultSharedPreferences(applicationContext) userIdentifier = settings.getString("unique_id", "")
userIdentifier = settings.getString("unique_id", "")!!
editor = settings.edit() if (settings.getString("url", "").isNotEmpty()) {
if (settings.getString("url", "")!!.isNotEmpty()) {
goToMain() goToMain()
} }
@ -127,12 +122,11 @@ class LoginActivity() : AppCompatActivity(), DIAware {
} }
private fun preferenceError(t: Throwable) { private fun preferenceError(t: Throwable) {
editor.remove("url") settings.remove("url")
editor.remove("login") settings.remove("login")
editor.remove("httpUserName") settings.remove("httpUserName")
editor.remove("password") settings.remove("password")
editor.remove("httpPassword") settings.remove("httpPassword")
editor.apply()
binding.urlView.error = getString(R.string.wrong_infos) binding.urlView.error = getString(R.string.wrong_infos)
binding.loginView.error = getString(R.string.wrong_infos) binding.loginView.error = getString(R.string.wrong_infos)
binding.passwordView.error = getString(R.string.wrong_infos) binding.passwordView.error = getString(R.string.wrong_infos)
@ -210,13 +204,12 @@ class LoginActivity() : AppCompatActivity(), DIAware {
} else { } else {
showProgress(true) showProgress(true)
editor.putString("url", url) settings.putString("url", url)
editor.putString("login", login) settings.putString("login", login)
editor.putString("httpUserName", httpLogin) settings.putString("httpUserName", httpLogin)
editor.putString("password", password) settings.putString("password", password)
editor.putString("httpPassword", httpPassword) settings.putString("httpPassword", httpPassword)
editor.putBoolean("isSelfSignedCert", isWithSelfSignedCert) settings.putBoolean("isSelfSignedCert", isWithSelfSignedCert)
editor.apply()
apiDetailsService.refresh() apiDetailsService.refresh()
val api = SelfossApiImpl( val api = SelfossApiImpl(

View File

@ -6,40 +6,38 @@ import android.content.Context
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
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 androidx.preference.PreferenceManager
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 bou.amine.apps.readerforselfossv2.service.ApiDetailsService
import bou.amine.apps.readerforselfossv2.service.ApiDetailsServiceImpl
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 com.russhwolf.settings.Settings
import org.kodein.di.* import org.kodein.di.*
import java.util.UUID.randomUUID import java.util.UUID.randomUUID
class MyApp : MultiDexApplication(), DIAware { class MyApp : MultiDexApplication(), DIAware {
override val di by DI.lazy { override val di by DI.lazy {
bind<Context>() with instance(this@MyApp.applicationContext) bind<ApiDetailsService>() with singleton { ApiDetailsServiceImpl() }
bind<ApiDetailsService>() with singleton { AndroidApiDetailsService(instance()) }
} }
private lateinit var config: Config private lateinit var config: Config
private lateinit var settings : Settings
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
config = Config(baseContext) config = Config()
settings = Settings()
val prefs = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE) if (settings.getString("unique_id", "").isEmpty()) {
if (prefs.getString("unique_id", "")!!.isEmpty()) { settings.putString("unique_id", randomUUID().toString())
val editor = prefs.edit()
editor.putString("unique_id", randomUUID().toString())
editor.apply()
} }
initDrawerImageLoader() initDrawerImageLoader()

View File

@ -1,7 +1,5 @@
package bou.amine.apps.readerforselfossv2.android package bou.amine.apps.readerforselfossv2.android
import android.content.Context
import android.content.SharedPreferences
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.view.KeyEvent import android.view.KeyEvent
@ -10,7 +8,6 @@ import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.preference.PreferenceManager
import androidx.room.Room import androidx.room.Room
import androidx.viewpager2.adapter.FragmentStateAdapter import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2 import androidx.viewpager2.widget.ViewPager2
@ -22,12 +19,12 @@ import bou.amine.apps.readerforselfossv2.android.persistence.migrations.MIGRATIO
import bou.amine.apps.readerforselfossv2.android.persistence.migrations.MIGRATION_3_4 import bou.amine.apps.readerforselfossv2.android.persistence.migrations.MIGRATION_3_4
import bou.amine.apps.readerforselfossv2.android.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.toggleStar import bou.amine.apps.readerforselfossv2.android.utils.toggleStar
import bou.amine.apps.readerforselfossv2.rest.SelfossApiImpl 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
import com.russhwolf.settings.Settings
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -47,7 +44,6 @@ class ReaderActivity : AppCompatActivity(), DIAware {
private lateinit var toolbarMenu: Menu private lateinit var toolbarMenu: Menu
private lateinit var db: AppDatabase private lateinit var db: AppDatabase
private lateinit var prefs: SharedPreferences
private lateinit var binding: ActivityReaderBinding private lateinit var binding: ActivityReaderBinding
private var activeAlignment: Int = 1 private var activeAlignment: Int = 1
@ -73,7 +69,7 @@ class ReaderActivity : AppCompatActivity(), DIAware {
showMenuItem(false) showMenuItem(false)
} }
private lateinit var editor: SharedPreferences.Editor private var settings = Settings()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -96,15 +92,9 @@ class ReaderActivity : AppCompatActivity(), DIAware {
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true)
val settings = userIdentifier = settings.getString("unique_id", "")
getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE) markOnScroll = settings.getBoolean("mark_on_scroll", false)
activeAlignment = settings.getInt("text_align", JUSTIFY)
prefs = PreferenceManager.getDefaultSharedPreferences(this)
editor = prefs.edit()
userIdentifier = prefs.getString("unique_id", "")!!
markOnScroll = prefs.getBoolean("mark_on_scroll", false)
activeAlignment = prefs.getInt("text_align", JUSTIFY)
api = SelfossApiImpl( api = SelfossApiImpl(
// this, // this,
@ -246,14 +236,12 @@ class ReaderActivity : AppCompatActivity(), DIAware {
} }
} }
R.id.align_left -> { R.id.align_left -> {
editor.putInt("text_align", ALIGN_LEFT) settings.putInt("text_align", ALIGN_LEFT)
editor.apply()
alignmentMenu(true) alignmentMenu(true)
refreshFragment() refreshFragment()
} }
R.id.align_justify -> { R.id.align_justify -> {
editor.putInt("text_align", JUSTIFY) settings.putInt("text_align", JUSTIFY)
editor.apply()
alignmentMenu(false) alignmentMenu(false)
refreshFragment() refreshFragment()
} }

View File

@ -1,18 +1,15 @@
package bou.amine.apps.readerforselfossv2.android package bou.amine.apps.readerforselfossv2.android
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.os.Bundle import android.os.Bundle
import androidx.preference.PreferenceManager import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import android.widget.Toast
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.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.SelfossApiImpl import bou.amine.apps.readerforselfossv2.rest.SelfossApiImpl
import bou.amine.apps.readerforselfossv2.rest.SelfossModel import bou.amine.apps.readerforselfossv2.rest.SelfossModel
@ -24,7 +21,6 @@ import kotlinx.coroutines.launch
import org.kodein.di.DIAware import org.kodein.di.DIAware
import org.kodein.di.android.closestDI import org.kodein.di.android.closestDI
import org.kodein.di.instance import org.kodein.di.instance
import java.util.ArrayList
class SourcesActivity : AppCompatActivity(), DIAware { class SourcesActivity : AppCompatActivity(), DIAware {
@ -64,10 +60,6 @@ class SourcesActivity : AppCompatActivity(), DIAware {
super.onResume() super.onResume()
val mLayoutManager = LinearLayoutManager(this) val mLayoutManager = LinearLayoutManager(this)
val settings =
getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
val api = SelfossApiImpl( val api = SelfossApiImpl(
// this, // this,
// this@SourcesActivity, // this@SourcesActivity,

View File

@ -43,7 +43,7 @@ class SourcesListAdapter(
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val itm = items[position] val itm = items[position]
config = Config(c) config = Config()
if (itm.getIcon(apiDetailsService.getBaseUrl()).isEmpty()) { if (itm.getIcon(apiDetailsService.getBaseUrl()).isEmpty()) {
val color = generator.getColor(itm.getTitleDecoded()) val color = generator.getColor(itm.getTitleDecoded())

View File

@ -5,7 +5,6 @@ import android.app.PendingIntent
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build import android.os.Build
import androidx.preference.PreferenceManager
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationCompat.PRIORITY_DEFAULT import androidx.core.app.NotificationCompat.PRIORITY_DEFAULT
import androidx.core.app.NotificationCompat.PRIORITY_LOW import androidx.core.app.NotificationCompat.PRIORITY_LOW
@ -32,6 +31,7 @@ import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
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
import bou.amine.apps.readerforselfossv2.utils.DateUtils import bou.amine.apps.readerforselfossv2.utils.DateUtils
import com.russhwolf.settings.Settings
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -48,10 +48,8 @@ class LoadingWorker(val context: Context, params: WorkerParameters) : Worker(con
private val apiDetailsService : ApiDetailsService by instance() private val apiDetailsService : ApiDetailsService by instance()
override fun doWork(): Result { override fun doWork(): Result {
val settings = val settings = Settings()
this.context.getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE) val periodicRefresh = settings.getBoolean("periodic_refresh", false)
val sharedPref = PreferenceManager.getDefaultSharedPreferences(this.context)
val periodicRefresh = sharedPref.getBoolean("periodic_refresh", false)
if (periodicRefresh) { if (periodicRefresh) {
val api = SelfossApiImpl( val api = SelfossApiImpl(
// this.context, // this.context,
@ -82,7 +80,7 @@ override fun doWork(): Result {
notificationManager.notify(1, notification.build()) notificationManager.notify(1, notification.build())
val notifyNewItems = sharedPref.getBoolean("notify_new_items", false) val notifyNewItems = settings.getBoolean("notify_new_items", false)
db = Room.databaseBuilder( db = Room.databaseBuilder(
applicationContext, applicationContext,

View File

@ -1,8 +1,6 @@
package bou.amine.apps.readerforselfossv2.android.fragments package bou.amine.apps.readerforselfossv2.android.fragments
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.content.res.TypedArray import android.content.res.TypedArray
import android.graphics.Bitmap import android.graphics.Bitmap
@ -18,7 +16,6 @@ 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.preference.PreferenceManager
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
@ -51,6 +48,7 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.RequestOptions
import com.github.rubensousa.floatingtoolbar.FloatingToolbar import com.github.rubensousa.floatingtoolbar.FloatingToolbar
import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.russhwolf.settings.Settings
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -76,7 +74,6 @@ class ArticleFragment : Fragment(), DIAware {
private lateinit var contentImage: String private lateinit var contentImage: String
private lateinit var contentTitle: String private lateinit var contentTitle: String
private lateinit var allImages : ArrayList<String> private lateinit var allImages : ArrayList<String>
private lateinit var editor: SharedPreferences.Editor
private lateinit var fab: FloatingActionButton private lateinit var fab: FloatingActionButton
private lateinit var appColors: AppColors private lateinit var appColors: AppColors
private lateinit var db: AppDatabase private lateinit var db: AppDatabase
@ -88,7 +85,7 @@ class ArticleFragment : Fragment(), DIAware {
override val di : DI by closestDI() override val di : DI by closestDI()
private val apiDetailsService : ApiDetailsService by instance() private val apiDetailsService : ApiDetailsService by instance()
private lateinit var prefs: SharedPreferences private var settings = Settings()
private var typeface: Typeface? = null private var typeface: Typeface? = null
private var resId: Int = 0 private var resId: Int = 0
@ -104,7 +101,7 @@ class ArticleFragment : Fragment(), DIAware {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
appColors = AppColors(requireActivity()) appColors = AppColors(requireActivity())
config = Config(requireActivity()) config = Config()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -137,12 +134,10 @@ class ArticleFragment : Fragment(), DIAware {
contentSource = item.sourceAndDateText(DateUtils(apiDetailsService)) contentSource = item.sourceAndDateText(DateUtils(apiDetailsService))
allImages = item.getImages() allImages = item.getImages()
prefs = PreferenceManager.getDefaultSharedPreferences(activity) fontSize = settings.getString("reader_font_size", "16").toInt()
editor = prefs.edit() staticBar = settings.getBoolean("reader_static_bar", false)
fontSize = prefs.getString("reader_font_size", "16")!!.toInt()
staticBar = prefs.getBoolean("reader_static_bar", false)
font = prefs.getString("reader_font", "")!! font = settings.getString("reader_font", "")
if (font.isNotEmpty()) { if (font.isNotEmpty()) {
resId = requireContext().resources.getIdentifier(font, "font", requireContext().packageName) resId = requireContext().resources.getIdentifier(font, "font", requireContext().packageName)
typeface = try { typeface = try {
@ -156,8 +151,6 @@ class ArticleFragment : Fragment(), DIAware {
refreshAlignment() refreshAlignment()
val settings = requireActivity().getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
val api = SelfossApiImpl( val api = SelfossApiImpl(
// requireContext(), // requireContext(),
// requireActivity(), // requireActivity(),
@ -277,10 +270,7 @@ class ArticleFragment : Fragment(), DIAware {
.setTitle(requireContext().getString(R.string.webview_dialog_issue_title)) .setTitle(requireContext().getString(R.string.webview_dialog_issue_title))
.setPositiveButton(android.R.string.ok .setPositiveButton(android.R.string.ok
) { _, _ -> ) { _, _ ->
val sharedPref = PreferenceManager.getDefaultSharedPreferences(requireContext()) settings.putBoolean("prefer_article_viewer", false)
val editor = sharedPref.edit()
editor.putBoolean("prefer_article_viewer", false)
editor.apply()
requireActivity().finish() requireActivity().finish()
} }
.create() .create()
@ -296,7 +286,7 @@ class ArticleFragment : Fragment(), DIAware {
} }
private fun refreshAlignment() { private fun refreshAlignment() {
textAlignment = when (prefs.getInt("text_align", 1)) { textAlignment = when (settings.getInt("text_align", 1)) {
1 -> "justify" 1 -> "justify"
2 -> "left" 2 -> "left"
else -> "justify" else -> "justify"

View File

@ -17,6 +17,7 @@ import bou.amine.apps.readerforselfossv2.android.databinding.ActivitySettingsBin
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 com.ftinc.scoop.Scoop import com.ftinc.scoop.Scoop
import com.russhwolf.settings.Settings
import java.lang.NumberFormatException import java.lang.NumberFormatException
private const val TITLE_TAG = "settingsActivityTitle" private const val TITLE_TAG = "settingsActivityTitle"
@ -173,14 +174,12 @@ class SettingsActivity : AppCompatActivity(),
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
val id = item.itemId val id = item.itemId
if (id == R.id.clear) { if (id == R.id.clear) {
val pref = PreferenceManager.getDefaultSharedPreferences(activity) val settings = Settings()
val editor = pref.edit() settings.remove("color_primary")
editor.remove("color_primary") settings.remove("color_primary_dark")
editor.remove("color_primary_dark") settings.remove("color_accent")
editor.remove("color_accent") settings.remove("color_accent_dark")
editor.remove("color_accent_dark") settings.remove("dark_theme")
editor.remove("dark_theme")
editor.apply()
requireActivity().recreate() requireActivity().recreate()
} }
return super.onOptionsItemSelected(item) return super.onOptionsItemSelected(item)

View File

@ -2,8 +2,8 @@ package bou.amine.apps.readerforselfossv2.android.themes
import android.app.Activity import android.app.Activity
import androidx.annotation.ColorInt import androidx.annotation.ColorInt
import androidx.preference.PreferenceManager
import bou.amine.apps.readerforselfossv2.android.R import bou.amine.apps.readerforselfossv2.android.R
import com.russhwolf.settings.Settings
class AppColors(a: Activity) { class AppColors(a: Activity) {
@ -16,30 +16,30 @@ class AppColors(a: Activity) {
val isDarkTheme: Boolean val isDarkTheme: Boolean
init { init {
val sharedPref = PreferenceManager.getDefaultSharedPreferences(a) val settings = Settings()
colorPrimary = colorPrimary =
sharedPref.getInt( settings.getInt(
"color_primary", "color_primary",
a.resources.getColor(R.color.colorPrimary) a.resources.getColor(R.color.colorPrimary)
) )
colorPrimaryDark = colorPrimaryDark =
sharedPref.getInt( settings.getInt(
"color_primary_dark", "color_primary_dark",
a.resources.getColor(R.color.colorPrimaryDark) a.resources.getColor(R.color.colorPrimaryDark)
) )
colorAccent = colorAccent =
sharedPref.getInt( settings.getInt(
"color_accent", "color_accent",
a.resources.getColor(R.color.colorAccent) a.resources.getColor(R.color.colorAccent)
) )
colorAccentDark = colorAccentDark =
sharedPref.getInt( settings.getInt(
"color_accent_dark", "color_accent_dark",
a.resources.getColor(R.color.colorAccentDark) a.resources.getColor(R.color.colorAccentDark)
) )
isDarkTheme = isDarkTheme =
sharedPref.getBoolean( settings.getBoolean(
"dark_theme", "dark_theme",
false false
) )

View File

@ -3,28 +3,27 @@ package bou.amine.apps.readerforselfossv2.android.utils
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences
import androidx.preference.PreferenceManager
import bou.amine.apps.readerforselfossv2.android.LoginActivity import bou.amine.apps.readerforselfossv2.android.LoginActivity
import com.russhwolf.settings.Settings
class Config(c: Context) { class Config {
val settings: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(c) val settings = Settings()
val baseUrl: String val baseUrl: String
get() = settings.getString("url", "")!! get() = settings.getString("url", "")
val userLogin: String val userLogin: String
get() = settings.getString("login", "")!! get() = settings.getString("login", "")
val userPassword: String val userPassword: String
get() = settings.getString("password", "")!! get() = settings.getString("password", "")
val httpUserLogin: String val httpUserLogin: String
get() = settings.getString("httpUserName", "")!! get() = settings.getString("httpUserName", "")
val httpUserPassword: String val httpUserPassword: String
get() = settings.getString("httpPassword", "")!! get() = settings.getString("httpPassword", "")
companion object { companion object {
const val settingsName = "paramsselfoss" const val settingsName = "paramsselfoss"
@ -47,11 +46,10 @@ class Config(c: Context) {
fun logoutAndRedirect( fun logoutAndRedirect(
c: Context, c: Context,
callingActivity: Activity, callingActivity: Activity,
editor: SharedPreferences.Editor,
baseUrlFail: Boolean = false baseUrlFail: Boolean = false
): Boolean { ): Boolean {
val settings = PreferenceManager.getDefaultSharedPreferences(c) val settings = Settings()
settings.edit().clear().commit() settings.clear()
val intent = Intent(c, LoginActivity::class.java) val intent = Intent(c, LoginActivity::class.java)
if (baseUrlFail) { if (baseUrlFail) {
intent.putExtra("baseUrlFail", baseUrlFail) intent.putExtra("baseUrlFail", baseUrlFail)

View File

@ -1,13 +1,13 @@
package bou.amine.apps.readerforselfossv2.android.utils.glide package bou.amine.apps.readerforselfossv2.android.utils.glide
import android.content.Context import android.content.Context
import bou.amine.apps.readerforselfossv2.android.utils.Config
import bou.amine.apps.readerforselfossv2.android.utils.getUnsafeHttpClient import bou.amine.apps.readerforselfossv2.android.utils.getUnsafeHttpClient
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.GlideBuilder import com.bumptech.glide.GlideBuilder
import com.bumptech.glide.Registry import com.bumptech.glide.Registry
import com.bumptech.glide.load.model.GlideUrl import com.bumptech.glide.load.model.GlideUrl
import com.bumptech.glide.module.GlideModule import com.bumptech.glide.module.GlideModule
import com.russhwolf.settings.Settings
import java.io.InputStream import java.io.InputStream
class SelfSignedGlideModule : GlideModule { class SelfSignedGlideModule : GlideModule {
@ -18,8 +18,8 @@ class SelfSignedGlideModule : GlideModule {
override fun registerComponents(context: Context?, glide: Glide?, registry: Registry?) { override fun registerComponents(context: Context?, glide: Glide?, registry: Registry?) {
if (context != null) { if (context != null) {
val pref = context?.getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE) val settings = Settings()
if (pref.getBoolean("isSelfSignedCert", false)) { if (settings.getBoolean("isSelfSignedCert", false)) {
val client = getUnsafeHttpClient().build() val client = getUnsafeHttpClient().build()
registry?.append( registry?.append(

View File

@ -30,6 +30,12 @@ kotlin {
//Dependency Injection //Dependency Injection
implementation("org.kodein.di:kodein-di:7.12.0") implementation("org.kodein.di:kodein-di:7.12.0")
//Settings
implementation("com.russhwolf:multiplatform-settings-no-arg:0.9")
//Logging
implementation("io.github.aakira:napier:2.6.1")
} }
} }
val commonTest by getting { val commonTest by getting {

View File

@ -1,19 +1,16 @@
package bou.amine.apps.readerforselfossv2.android.service package bou.amine.apps.readerforselfossv2.service
import android.content.Context import com.russhwolf.settings.Settings
import android.content.SharedPreferences import io.github.aakira.napier.Napier
import android.util.Log
import androidx.preference.PreferenceManager
import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
class AndroidApiDetailsService(c: Context) : ApiDetailsService { class ApiDetailsServiceImpl : ApiDetailsService {
val settings: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(c) val settings: Settings = Settings()
private var _apiVersion: Int = -1 private var _apiVersion: Int = -1
private var _baseUrl: String = "" private var _baseUrl: String = ""
private var _userName: String = "" private var _userName: String = ""
private var _password: String = "" private var _password: String = ""
override fun logApiCalls(message: String) { override fun logApiCalls(message: String) {
Log.d("LogApiCalls", message) Napier.d(message, tag = "LogApiCalls")
} }
@ -27,30 +24,30 @@ class AndroidApiDetailsService(c: Context) : ApiDetailsService {
override fun getBaseUrl(): String { override fun getBaseUrl(): String {
if (_baseUrl.isEmpty()) { if (_baseUrl.isEmpty()) {
_baseUrl = settings.getString("url", "")!! _baseUrl = settings.getString("url", "")
} }
return _baseUrl return _baseUrl
} }
override fun getUserName(): String { override fun getUserName(): String {
if (_userName.isEmpty()) { if (_userName.isEmpty()) {
_userName = settings.getString("login", "")!! _userName = settings.getString("login", "")
} }
return _userName return _userName
} }
override fun getPassword(): String { override fun getPassword(): String {
if (_password.isEmpty()) { if (_password.isEmpty()) {
_password = settings.getString("password", "")!! _password = settings.getString("password", "")
} }
return _password return _password
} }
override fun refresh() { override fun refresh() {
_password = settings.getString("password", "")!! _password = settings.getString("password", "")
_userName = settings.getString("login", "")!! _userName = settings.getString("login", "")
_baseUrl = settings.getString("url", "")!! _baseUrl = settings.getString("url", "")
_baseUrl = settings.getString("url", "")!! _baseUrl = settings.getString("url", "")
_apiVersion = settings.getInt("apiVersionMajor", -1) _apiVersion = settings.getInt("apiVersionMajor", -1)
} }
} }