From 7ca4418a502d7c8bc20ee2911c70a281ce9256a5 Mon Sep 17 00:00:00 2001 From: tom5079 Date: Sun, 30 Aug 2020 19:52:51 +0900 Subject: [PATCH] Added global preferences object --- app/build.gradle | 1 + app/src/main/java/xyz/quaver/pupil/Pupil.kt | 31 +++--- .../pupil/adapters/GalleryBlockAdapter.kt | 4 +- .../quaver/pupil/adapters/MirrorAdapter.kt | 5 +- .../quaver/pupil/adapters/ReaderAdapter.kt | 8 +- .../pupil/reciever/UpdateBroadcastReciever.kt | 6 +- .../quaver/pupil/services/DownloadService.kt | 21 ++--- .../java/xyz/quaver/pupil/ui/LockActivity.kt | 4 +- .../java/xyz/quaver/pupil/ui/MainActivity.kt | 31 ++---- .../xyz/quaver/pupil/ui/ReaderActivity.kt | 9 +- .../xyz/quaver/pupil/ui/SettingsActivity.kt | 14 +-- .../pupil/ui/dialog/DefaultQueryDialog.kt | 5 +- .../pupil/ui/dialog/DownloadLocationDialog.kt | 5 +- .../quaver/pupil/ui/dialog/MirrorDialog.kt | 7 +- .../xyz/quaver/pupil/ui/dialog/ProxyDialog.kt | 12 +-- .../pupil/ui/fragment/LockSettingsFragment.kt | 4 +- .../pupil/ui/fragment/SettingsFragment.kt | 28 ++---- .../java/xyz/quaver/pupil/util/Preferences.kt | 55 +++++++++++ .../main/java/xyz/quaver/pupil/util/file.kt | 94 +------------------ .../main/java/xyz/quaver/pupil/util/misc.kt | 10 +- .../main/java/xyz/quaver/pupil/util/proxy.kt | 32 +++---- .../main/java/xyz/quaver/pupil/util/update.kt | 16 ++-- app/src/main/res/xml/root_preferences.xml | 3 +- 23 files changed, 157 insertions(+), 248 deletions(-) create mode 100644 app/src/main/java/xyz/quaver/pupil/util/Preferences.kt diff --git a/app/build.gradle b/app/build.gradle index fa0b6548..a565780b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -99,6 +99,7 @@ dependencies { implementation ("xyz.quaver:libpupil:1.1") { exclude group: 'org.jetbrains.kotlinx', module: 'kotlinx-serialization-core-jvm' } + implementation "xyz.quaver:documentfilex:0.2" testImplementation 'junit:junit:4.13' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test:rules:1.3.0' diff --git a/app/src/main/java/xyz/quaver/pupil/Pupil.kt b/app/src/main/java/xyz/quaver/pupil/Pupil.kt index 1151b7e9..6f4a61bc 100644 --- a/app/src/main/java/xyz/quaver/pupil/Pupil.kt +++ b/app/src/main/java/xyz/quaver/pupil/Pupil.kt @@ -35,12 +35,10 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import okhttp3.Dispatcher import okhttp3.Interceptor import okhttp3.OkHttpClient import okhttp3.Response -import xyz.quaver.pupil.util.GalleryList -import xyz.quaver.pupil.util.getProxyInfo +import xyz.quaver.pupil.util.* import xyz.quaver.setClient import java.io.File import java.util.* @@ -72,25 +70,18 @@ class Pupil : Application() { } override fun onCreate() { - val preference = PreferenceManager.getDefaultSharedPreferences(this) + preferences = PreferenceManager.getDefaultSharedPreferences(this) - val userID = - if (preference.getString("user_id", "").isNullOrEmpty()) { - UUID.randomUUID().toString().also { - preference.edit().putString("user_id", it).apply() - } - } else - preference.getString("user_id", "") ?: "" + val userID = Preferences["user_id", UUID.randomUUID().toString(), true] FirebaseCrashlytics.getInstance().setUserId(userID) - val proxyInfo = getProxyInfo(this) + val proxyInfo = getProxyInfo() clientBuilder = OkHttpClient.Builder() .connectTimeout(0, TimeUnit.SECONDS) .readTimeout(0, TimeUnit.SECONDS) - .proxy(proxyInfo.proxy()) - .proxyAuthenticator(proxyInfo.authenticator()) + .proxyInfo(proxyInfo) .addInterceptor { chain -> val request = chain.request() val tag = request.tag() ?: return@addInterceptor chain.proceed(request) @@ -99,18 +90,18 @@ class Pupil : Application() { } try { - preference.getString("dl_location", null).also { - if (!File(it!!).canWrite()) + Preferences.get("dl_location").also { + if (!File(it).canWrite()) throw Exception() } } catch (e: Exception) { - preference.edit().remove("dl_location").apply() + Preferences.remove("dl_location") } histories = GalleryList(File(ContextCompat.getDataDir(this), "histories.json")) favorites = GalleryList(File(ContextCompat.getDataDir(this), "favorites.json")) - if (preference.getBoolean("old_history", true)) { + if (Preferences["new_history"]) { CoroutineScope(Dispatchers.IO).launch { histories.reversed().let { histories.clear() @@ -121,7 +112,7 @@ class Pupil : Application() { favorites.addAll(it) } } - preference.edit().putBoolean("old_history", false).apply() + Preferences["new_history"] = true } if (BuildConfig.DEBUG) @@ -167,7 +158,7 @@ class Pupil : Application() { }) } - AppCompatDelegate.setDefaultNightMode(when (preference.getBoolean("dark_mode", false)) { + AppCompatDelegate.setDefaultNightMode(when (Preferences.get("dark_mode")) { true -> AppCompatDelegate.MODE_NIGHT_YES false -> AppCompatDelegate.MODE_NIGHT_NO }) diff --git a/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt b/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt index 5de9354b..8b0c1b50 100644 --- a/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt +++ b/app/src/main/java/xyz/quaver/pupil/adapters/GalleryBlockAdapter.kt @@ -31,7 +31,6 @@ import android.view.ViewGroup import android.widget.LinearLayout import androidx.cardview.widget.CardView import androidx.core.content.ContextCompat -import androidx.preference.PreferenceManager import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.CircularProgressDrawable import androidx.vectordrawable.graphics.drawable.Animatable2Compat @@ -55,6 +54,7 @@ import xyz.quaver.pupil.R import xyz.quaver.pupil.favorites import xyz.quaver.pupil.types.Tag import xyz.quaver.pupil.util.GalleryList +import xyz.quaver.pupil.util.Preferences import xyz.quaver.pupil.util.download.Cache import xyz.quaver.pupil.util.wordCapitalize import java.util.* @@ -80,7 +80,7 @@ class GalleryBlockAdapter(private val glide: RequestManager, private val galleri val reader = Cache(context).getReaderOrNull(galleryID) CoroutineScope(Dispatchers.Main).launch { - if (reader == null || PreferenceManager.getDefaultSharedPreferences(context).getBoolean("cache_disable", false)) { + if (reader == null || Preferences["cache_disable"]) { view.galleryblock_progressbar.visibility = View.GONE view.galleryblock_progress_complete.visibility = View.GONE return@launch diff --git a/app/src/main/java/xyz/quaver/pupil/adapters/MirrorAdapter.kt b/app/src/main/java/xyz/quaver/pupil/adapters/MirrorAdapter.kt index 91362fb6..c6d77518 100644 --- a/app/src/main/java/xyz/quaver/pupil/adapters/MirrorAdapter.kt +++ b/app/src/main/java/xyz/quaver/pupil/adapters/MirrorAdapter.kt @@ -24,10 +24,10 @@ import android.view.LayoutInflater import android.view.MotionEvent import android.view.View import android.view.ViewGroup -import androidx.preference.PreferenceManager import androidx.recyclerview.widget.RecyclerView import kotlinx.android.synthetic.main.item_mirrors.view.* import xyz.quaver.pupil.R +import xyz.quaver.pupil.util.Preferences import java.util.* class MirrorAdapter(context: Context) : RecyclerView.Adapter() { @@ -41,8 +41,7 @@ class MirrorAdapter(context: Context) : RecyclerView.Adapter("mirrors") .split(">") .reversed() .forEach { diff --git a/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt b/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt index 7fe1d6fa..4b4cb94c 100644 --- a/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt +++ b/app/src/main/java/xyz/quaver/pupil/adapters/ReaderAdapter.kt @@ -18,12 +18,10 @@ package xyz.quaver.pupil.adapters -import android.app.Activity import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.constraintlayout.widget.ConstraintLayout -import androidx.preference.PreferenceManager import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.RequestManager import com.bumptech.glide.load.engine.DiskCacheStrategy @@ -41,6 +39,7 @@ import xyz.quaver.hiyobi.cookie import xyz.quaver.hiyobi.createImgList import xyz.quaver.hiyobi.user_agent import xyz.quaver.pupil.R +import xyz.quaver.pupil.util.Preferences import xyz.quaver.pupil.util.download.Cache import xyz.quaver.pupil.util.download.DownloadWorker import java.util.* @@ -96,9 +95,8 @@ class ReaderAdapter(private val glide: RequestManager, holder.view.reader_index.text = (position+1).toString() - val preferences = PreferenceManager.getDefaultSharedPreferences(holder.view.context) - if (preferences.getBoolean("cache_disable", false)) { - val lowQuality = preferences.getBoolean("low_quality", false) + if (Preferences["cache_disable"]) { + val lowQuality: Boolean = Preferences["low_quality"] val url = when (reader!!.code) { Code.HITOMI -> diff --git a/app/src/main/java/xyz/quaver/pupil/reciever/UpdateBroadcastReciever.kt b/app/src/main/java/xyz/quaver/pupil/reciever/UpdateBroadcastReciever.kt index 7787e713..c06fdc09 100644 --- a/app/src/main/java/xyz/quaver/pupil/reciever/UpdateBroadcastReciever.kt +++ b/app/src/main/java/xyz/quaver/pupil/reciever/UpdateBroadcastReciever.kt @@ -28,8 +28,8 @@ import android.webkit.MimeTypeMap import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.core.content.FileProvider -import androidx.preference.PreferenceManager import xyz.quaver.pupil.R +import xyz.quaver.pupil.util.Preferences import java.io.File class UpdateBroadcastReciever : BroadcastReceiver() { @@ -41,9 +41,7 @@ class UpdateBroadcastReciever : BroadcastReceiver() { DownloadManager.ACTION_DOWNLOAD_COMPLETE -> { // Validate download - - val preference = PreferenceManager.getDefaultSharedPreferences(context) - val downloadID = preference.getLong("update_download_id", -1) + val downloadID: Long = Preferences["update_download_id"] val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager if (intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1) != downloadID) diff --git a/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt b/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt index 95212beb..66c52661 100644 --- a/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt +++ b/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt @@ -33,9 +33,11 @@ import kotlinx.coroutines.launch import okhttp3.Interceptor import okhttp3.ResponseBody import okio.* +import xyz.quaver.pupil.PupilInterceptor import xyz.quaver.pupil.R +import xyz.quaver.pupil.interceptors -private typealias ProgressListener = (Any?, Long, Long, Boolean) -> Unit +private typealias ProgressListener = (DownloadService.Tag, Long, Long, Boolean) -> Unit class Cache(context: Context) : ContextWrapper(context) { @@ -45,6 +47,8 @@ class Cache(context: Context) : ContextWrapper(context) { class DownloadService : Service() { + data class Tag(val galleryID: Int, val index: Int) + //region Notification private val notificationManager by lazy { NotificationManagerCompat.from(this) @@ -61,9 +65,7 @@ class DownloadService : Service() { //region ProgressListener @Suppress("UNCHECKED_CAST") - private val progressListener: ProgressListener = listener@{ tag, bytesRead, contentLength, done -> - val (galleryID, index) = (tag as? Pair) ?: return@listener - + private val progressListener: ProgressListener = { (galleryID, index), bytesRead, contentLength, done -> if (!done && progress[galleryID]?.get(index)?.isFinite() == true) progress[galleryID]?.set(index, bytesRead * 100F / contentLength) } @@ -92,14 +94,14 @@ class DownloadService : Service() { val bytesRead = super.read(sink, byteCount) totalBytesRead += if (bytesRead == -1L) 0L else bytesRead - progressListener.invoke(tag, totalBytesRead, responseBody.contentLength(), bytesRead == -1L) + progressListener.invoke(tag as Tag, totalBytesRead, responseBody.contentLength(), bytesRead == -1L) return bytesRead } } } - val interceptor = Interceptor { chain -> + private val interceptor: PupilInterceptor = { chain -> val request = chain.request() var response = chain.proceed(request) @@ -131,10 +133,7 @@ class DownloadService : Service() { override fun onCreate() { startForeground(R.id.downloader_notification_id, serviceNotification.build()) - } - - override fun onDestroy() { - + interceptors[Tag::class] = interceptor } @@ -146,7 +145,7 @@ class DownloadService : Service() { override fun onBind(p0: Intent?) = binder fun load(galleryID: Int) { - + } fun download(galleryID: Int) = CoroutineScope(Dispatchers.IO).launch { diff --git a/app/src/main/java/xyz/quaver/pupil/ui/LockActivity.kt b/app/src/main/java/xyz/quaver/pupil/ui/LockActivity.kt index 144ec79d..90948629 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/LockActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/LockActivity.kt @@ -27,7 +27,6 @@ import androidx.appcompat.app.AppCompatActivity import androidx.biometric.BiometricManager import androidx.biometric.BiometricPrompt import androidx.core.content.ContextCompat -import androidx.preference.PreferenceManager import com.andrognito.patternlockview.PatternLockView import com.google.android.material.snackbar.Snackbar import kotlinx.android.synthetic.main.activity_lock.* @@ -38,6 +37,7 @@ import xyz.quaver.pupil.ui.fragment.PINLockFragment import xyz.quaver.pupil.ui.fragment.PatternLockFragment import xyz.quaver.pupil.util.Lock import xyz.quaver.pupil.util.LockManager +import xyz.quaver.pupil.util.Preferences class LockActivity : AppCompatActivity() { @@ -195,7 +195,7 @@ class LockActivity : AppCompatActivity() { } if ( - PreferenceManager.getDefaultSharedPreferences(this).getBoolean("lock_fingerprint", false) + Preferences["lock_fingerprint"] && BiometricManager.from(this).canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS ) { lock_fingerprint.apply { diff --git a/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt b/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt index 3bbc8701..4f259a3b 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/MainActivity.kt @@ -22,7 +22,6 @@ import android.annotation.SuppressLint import android.app.Activity import android.content.Intent import android.graphics.drawable.Animatable -import android.net.Proxy import android.net.Uri import android.os.Build import android.os.Bundle @@ -41,7 +40,6 @@ import androidx.cardview.widget.CardView import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat import androidx.core.view.GravityCompat -import androidx.preference.PreferenceManager import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat import com.arlib.floatingsearchview.FloatingSearchView import com.arlib.floatingsearchview.FloatingSearchViewDayNight @@ -88,7 +86,7 @@ class MainActivity : AppCompatActivity() { DOWNLOAD, FAVORITE } - + enum class SortMode { NEWEST, POPULAR @@ -134,17 +132,15 @@ class MainActivity : AppCompatActivity() { if (lockManager.isNotEmpty()) startActivityForResult(Intent(this, LockActivity::class.java), R.id.request_lock.normalizeID()) - val preference = PreferenceManager.getDefaultSharedPreferences(this) - if (Locale.getDefault().language == "ko") { - if (!preference.getBoolean("https_block_alert", false)) { + if (Preferences["https_block_alert"]) { android.app.AlertDialog.Builder(this).apply { setTitle(R.string.https_block_alert_title) setMessage(R.string.https_block_alert) setPositiveButton(android.R.string.ok) { _, _ -> } }.show() - preference.edit().putBoolean("https_block_alert", true).apply() + Preferences["https_block_alert"] = false } } @@ -199,9 +195,7 @@ class MainActivity : AppCompatActivity() { } override fun onResume() { - val preferences = PreferenceManager.getDefaultSharedPreferences(this) - - if (preferences.getBoolean("security_mode", false)) + if (Preferences["security_mode"]) window.setFlags( WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE) @@ -212,8 +206,7 @@ class MainActivity : AppCompatActivity() { } override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { - val preference = PreferenceManager.getDefaultSharedPreferences(this) - val perPage = preference.getString("per_page", "25")!!.toIntOrNull() ?: 25 + val perPage = Preferences["per_page", "25"].toInt() val maxPage = ceil(totalItems / perPage.toDouble()).roundToInt() return when(keyCode) { @@ -362,8 +355,7 @@ class MainActivity : AppCompatActivity() { with(main_fab_jump) { setImageResource(R.drawable.ic_jump) setOnClickListener { - val preference = PreferenceManager.getDefaultSharedPreferences(context) - val perPage = preference.getString("per_page", "25")!!.toIntOrNull() ?: 25 + val perPage = Preferences["per_page", "25"].toInt() val editText = EditText(context) AlertDialog.Builder(context).apply { @@ -469,7 +461,7 @@ class MainActivity : AppCompatActivity() { onDownloadClickedHandler = { position -> val galleryID = galleries[position].id val worker = DownloadWorker.getInstance(context) - if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("cache_disable", false)) + if (Preferences["cache_disable"]) Toast.makeText(context, R.string.settings_download_when_cache_disable_warning, Toast.LENGTH_SHORT).show() else { if (worker.progress.indexOfKey(galleryID) >= 0 && Cache(context).isDownloading(galleryID)) { //download in progress @@ -554,8 +546,7 @@ class MainActivity : AppCompatActivity() { var origin = 0f var target = -1 - val preferences = PreferenceManager.getDefaultSharedPreferences(context) - val perPage = preferences.getString("per_page", "25")!!.toInt() + val perPage = Preferences["per_page", "25"].toInt() setOnTouchListener { _, event -> when(event.action) { MotionEvent.ACTION_UP -> { @@ -1006,8 +997,7 @@ class MainActivity : AppCompatActivity() { } private fun fetchGalleries(query: String, sortMode: SortMode) { - val preference = PreferenceManager.getDefaultSharedPreferences(this) - val defaultQuery = preference.getString("default_query", "")!! + val defaultQuery: String = Preferences["default_query"] if (query != queryStack.lastOrNull()) { queryStack.remove(query) @@ -1104,8 +1094,7 @@ class MainActivity : AppCompatActivity() { } private fun loadBlocks() { - val preference = PreferenceManager.getDefaultSharedPreferences(this) - val perPage = preference.getString("per_page", "25")?.toInt() ?: 25 + val perPage = Preferences["per_page", "25"].toInt() loadingJob = CoroutineScope(Dispatchers.IO).launch { val galleryIDs = try { diff --git a/app/src/main/java/xyz/quaver/pupil/ui/ReaderActivity.kt b/app/src/main/java/xyz/quaver/pupil/ui/ReaderActivity.kt index dc9dbaf9..07480739 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/ReaderActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/ReaderActivity.kt @@ -43,12 +43,11 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import xyz.quaver.Code -import xyz.quaver.pupil.Pupil import xyz.quaver.pupil.R import xyz.quaver.pupil.adapters.ReaderAdapter import xyz.quaver.pupil.favorites import xyz.quaver.pupil.histories -import xyz.quaver.pupil.util.GalleryList +import xyz.quaver.pupil.util.Preferences import xyz.quaver.pupil.util.download.Cache import xyz.quaver.pupil.util.download.DownloadWorker import java.util.* @@ -103,7 +102,7 @@ class ReaderActivity : AppCompatActivity() { } initView() - if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("cache_disable", false)) { + if (Preferences["cache_disable"]) { reader_download_progressbar.visibility = View.GONE CoroutineScope(Dispatchers.IO).launch { val reader = Cache(this@ReaderActivity).getReader(galleryID) @@ -159,9 +158,7 @@ class ReaderActivity : AppCompatActivity() { } override fun onResume() { - val preferences = PreferenceManager.getDefaultSharedPreferences(this) - - if (preferences.getBoolean("security_mode", false)) + if (Preferences["security_mode"]) window.setFlags( WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE) diff --git a/app/src/main/java/xyz/quaver/pupil/ui/SettingsActivity.kt b/app/src/main/java/xyz/quaver/pupil/ui/SettingsActivity.kt index 98f4f592..bf87262d 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/SettingsActivity.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/SettingsActivity.kt @@ -27,12 +27,14 @@ import android.os.Bundle import android.view.MenuItem import android.view.WindowManager import androidx.appcompat.app.AppCompatActivity +import androidx.preference.Preference import androidx.preference.PreferenceManager import com.google.android.material.snackbar.Snackbar import kotlinx.android.synthetic.main.settings_activity.* import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json import net.rdrei.android.dirchooser.DirectoryChooserActivity +import xyz.quaver.io.util.toFile import xyz.quaver.pupil.Pupil import xyz.quaver.pupil.R import xyz.quaver.pupil.favorites @@ -60,9 +62,7 @@ class SettingsActivity : AppCompatActivity() { } override fun onResume() { - val preferences = PreferenceManager.getDefaultSharedPreferences(this) - - if (preferences.getBoolean("security_mode", false)) + if (Preferences["security_mode"]) window.setFlags( WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE) @@ -135,9 +135,7 @@ class SettingsActivity : AppCompatActivity() { Snackbar.LENGTH_LONG ).show() else - PreferenceManager.getDefaultSharedPreferences(this).edit() - .putString("dl_location", file.canonicalPath) - .apply() + Preferences["dl_location"] = file.canonicalPath } } } @@ -152,9 +150,7 @@ class SettingsActivity : AppCompatActivity() { Snackbar.LENGTH_LONG ).show() else - PreferenceManager.getDefaultSharedPreferences(this).edit() - .putString("dl_location", File(directory).canonicalPath) - .apply() + Preferences["dl_location"] = File(directory).canonicalPath } } else -> super.onActivityResult(requestCode, resultCode, data) diff --git a/app/src/main/java/xyz/quaver/pupil/ui/dialog/DefaultQueryDialog.kt b/app/src/main/java/xyz/quaver/pupil/ui/dialog/DefaultQueryDialog.kt index 94029cd5..789e5f3c 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/dialog/DefaultQueryDialog.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/dialog/DefaultQueryDialog.kt @@ -28,11 +28,11 @@ import android.view.LayoutInflater import android.view.View import android.widget.ArrayAdapter import androidx.appcompat.app.AlertDialog -import androidx.preference.PreferenceManager import kotlinx.android.synthetic.main.dialog_default_query.* import kotlinx.android.synthetic.main.dialog_default_query.view.* import xyz.quaver.pupil.R import xyz.quaver.pupil.types.Tags +import xyz.quaver.pupil.util.Preferences class DefaultQueryDialog(context : Context) : AlertDialog(context) { @@ -82,9 +82,8 @@ class DefaultQueryDialog(context : Context) : AlertDialog(context) { @SuppressLint("InflateParams") private fun build() : View { - val preferences = PreferenceManager.getDefaultSharedPreferences(context) val tags = Tags.parse( - preferences.getString("default_query", "") ?: "" + Preferences["default_query"] ) val view = LayoutInflater.from(context).inflate(R.layout.dialog_default_query, null) diff --git a/app/src/main/java/xyz/quaver/pupil/ui/dialog/DownloadLocationDialog.kt b/app/src/main/java/xyz/quaver/pupil/ui/dialog/DownloadLocationDialog.kt index c2e64dbe..e2f42e3e 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/dialog/DownloadLocationDialog.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/dialog/DownloadLocationDialog.kt @@ -32,7 +32,6 @@ import android.widget.RadioButton import androidx.appcompat.app.AlertDialog import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat -import androidx.preference.PreferenceManager import kotlinx.android.synthetic.main.item_dl_location.view.* import net.rdrei.android.dirchooser.DirectoryChooserActivity import net.rdrei.android.dirchooser.DirectoryChooserConfig @@ -42,8 +41,6 @@ import java.io.File @SuppressLint("InflateParams") class DownloadLocationDialog(val activity: Activity) : AlertDialog(activity) { - - private val preference = PreferenceManager.getDefaultSharedPreferences(context) private val buttons = mutableListOf>() override fun onCreate(savedInstanceState: Bundle?) { @@ -79,7 +76,7 @@ class DownloadLocationDialog(val activity: Activity) : AlertDialog(activity) { pair.first.isChecked = false } button.performClick() - preference.edit().putString("dl_location", dir.canonicalPath).apply() + Preferences["dl_location"] = dir.canonicalPath } buttons.add(button to dir) }) diff --git a/app/src/main/java/xyz/quaver/pupil/ui/dialog/MirrorDialog.kt b/app/src/main/java/xyz/quaver/pupil/ui/dialog/MirrorDialog.kt index d20b61df..e7f79cf9 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/dialog/MirrorDialog.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/dialog/MirrorDialog.kt @@ -24,13 +24,13 @@ import android.content.Context import android.os.Bundle import android.view.View import androidx.appcompat.app.AlertDialog -import androidx.preference.PreferenceManager import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import xyz.quaver.pupil.R import xyz.quaver.pupil.adapters.MirrorAdapter +import xyz.quaver.pupil.util.Preferences class MirrorDialog(context: Context) : AlertDialog(context) { @@ -82,10 +82,7 @@ class MirrorDialog(context: Context) : AlertDialog(context) { } onItemMoved = { - PreferenceManager.getDefaultSharedPreferences(context) - .edit() - .putString("mirrors", it.joinToString(">")) - .apply() + Preferences["mirrors", it.joinToString(">")] } } } diff --git a/app/src/main/java/xyz/quaver/pupil/ui/dialog/ProxyDialog.kt b/app/src/main/java/xyz/quaver/pupil/ui/dialog/ProxyDialog.kt index 275e52fb..dd26b4a2 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/dialog/ProxyDialog.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/dialog/ProxyDialog.kt @@ -27,7 +27,6 @@ import android.view.View import android.view.ViewGroup import android.widget.AdapterView import android.widget.ArrayAdapter -import androidx.preference.PreferenceManager import kotlinx.android.synthetic.main.dialog_proxy.view.* import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json @@ -35,8 +34,10 @@ import xyz.quaver.pupil.R import xyz.quaver.pupil.client import xyz.quaver.pupil.clientBuilder import xyz.quaver.pupil.clientHolder +import xyz.quaver.pupil.util.Preferences import xyz.quaver.pupil.util.ProxyInfo import xyz.quaver.pupil.util.getProxyInfo +import xyz.quaver.pupil.util.proxyInfo import java.net.Proxy class ProxyDialog(context: Context) : Dialog(context) { @@ -54,7 +55,7 @@ class ProxyDialog(context: Context) : Dialog(context) { @SuppressLint("InflateParams") private fun build() : View { - val proxyInfo = getProxyInfo(context) + val proxyInfo = getProxyInfo() val view = LayoutInflater.from(context).inflate(R.layout.dialog_proxy, null) @@ -119,13 +120,10 @@ class ProxyDialog(context: Context) : Dialog(context) { } ProxyInfo(type, addr, port, username, password).let { - PreferenceManager.getDefaultSharedPreferences(context).edit().putString("proxy", - Json.encodeToString(it) - ).apply() + Preferences["proxy"] = Json.encodeToString(it) clientBuilder - .proxy(it.proxy()) - .proxyAuthenticator(it.authenticator()) + .proxyInfo(it) clientHolder = null client } diff --git a/app/src/main/java/xyz/quaver/pupil/ui/fragment/LockSettingsFragment.kt b/app/src/main/java/xyz/quaver/pupil/ui/fragment/LockSettingsFragment.kt index 67300e0a..13feb403 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/fragment/LockSettingsFragment.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/fragment/LockSettingsFragment.kt @@ -24,12 +24,12 @@ import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat -import androidx.preference.PreferenceManager import androidx.preference.SwitchPreferenceCompat import xyz.quaver.pupil.R import xyz.quaver.pupil.ui.LockActivity import xyz.quaver.pupil.util.Lock import xyz.quaver.pupil.util.LockManager +import xyz.quaver.pupil.util.Preferences class LockSettingsFragment : PreferenceFragmentCompat() { @@ -53,7 +53,7 @@ class LockSettingsFragment : PreferenceFragmentCompat() { if (lockManager.isEmpty()) { (findPreference("lock_fingerprint") as SwitchPreferenceCompat).isChecked = false - PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean("lock_fingerprint", false).apply() + Preferences["lock_fingerprint"] = false } } diff --git a/app/src/main/java/xyz/quaver/pupil/ui/fragment/SettingsFragment.kt b/app/src/main/java/xyz/quaver/pupil/ui/fragment/SettingsFragment.kt index fe8f4f13..7dbd761b 100644 --- a/app/src/main/java/xyz/quaver/pupil/ui/fragment/SettingsFragment.kt +++ b/app/src/main/java/xyz/quaver/pupil/ui/fragment/SettingsFragment.kt @@ -18,27 +18,17 @@ package xyz.quaver.pupil.ui.fragment -import android.Manifest import android.content.* -import android.content.pm.PackageManager -import android.os.Build import android.os.Bundle import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatDelegate -import androidx.core.app.ActivityCompat -import androidx.core.content.ContextCompat import androidx.preference.Preference import androidx.preference.PreferenceCategory import androidx.preference.PreferenceFragmentCompat -import androidx.preference.PreferenceManager -import com.google.android.material.snackbar.Snackbar import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import net.rdrei.android.dirchooser.DirectoryChooserActivity -import net.rdrei.android.dirchooser.DirectoryChooserConfig -import xyz.quaver.pupil.Pupil import xyz.quaver.pupil.R import xyz.quaver.pupil.histories import xyz.quaver.pupil.ui.LockActivity @@ -52,15 +42,12 @@ import java.io.BufferedReader import java.io.File import java.io.InputStreamReader - class SettingsFragment : PreferenceFragmentCompat(), Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener, SharedPreferences.OnSharedPreferenceChangeListener { - lateinit var sharedPreference: SharedPreferences - override fun onResume() { super.onResume() @@ -160,7 +147,7 @@ class SettingsFragment : "default_query" -> { DefaultQueryDialog(requireContext()).apply { onPositiveButtonClickListener = { newTags -> - sharedPreferences.edit().putString("default_query", newTags.toString()).apply() + Preferences["default_query"] = newTags.toString() summary = newTags.toString() } }.show() @@ -182,7 +169,7 @@ class SettingsFragment : } "user_id" -> { (context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager).setPrimaryClip( - ClipData.newPlainText("user_id", sharedPreference.getString("user_id", "")) + ClipData.newPlainText("user_id", Preferences.get("user_id")) ) Toast.makeText(context, R.string.settings_user_id_toast, Toast.LENGTH_SHORT).show() } @@ -219,7 +206,7 @@ class SettingsFragment : when (key) { "proxy" -> { - summary = context?.let { getProxyInfo(it).type.name } + summary = context?.let { getProxyInfo().type.name } } "dl_location" -> { summary = context?.let { getDownloadDirectory(it).canonicalPath } @@ -231,8 +218,7 @@ class SettingsFragment : override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.root_preferences, rootKey) - sharedPreference = PreferenceManager.getDefaultSharedPreferences(requireContext()) - sharedPreference.registerOnSharedPreferenceChangeListener(this) + Preferences.registerOnSharedPreferenceChangeListener(this) initPreferences() } @@ -295,7 +281,7 @@ class SettingsFragment : onPreferenceClickListener = this@SettingsFragment } "default_query" -> { - summary = sharedPreference.getString("default_query", "") ?: "" + summary = Preferences.get("default_query") onPreferenceClickListener = this@SettingsFragment } @@ -320,7 +306,7 @@ class SettingsFragment : onPreferenceClickListener = this@SettingsFragment } "proxy" -> { - summary = getProxyInfo(requireContext()).type.name + summary = getProxyInfo().type.name onPreferenceClickListener = this@SettingsFragment } @@ -334,7 +320,7 @@ class SettingsFragment : onPreferenceClickListener = this@SettingsFragment } "user_id" -> { - summary = sharedPreference.getString("user_id", "") + summary = Preferences.get("user_id") onPreferenceClickListener = this@SettingsFragment } } diff --git a/app/src/main/java/xyz/quaver/pupil/util/Preferences.kt b/app/src/main/java/xyz/quaver/pupil/util/Preferences.kt new file mode 100644 index 00000000..8d979435 --- /dev/null +++ b/app/src/main/java/xyz/quaver/pupil/util/Preferences.kt @@ -0,0 +1,55 @@ +/* + * Pupil, Hitomi.la viewer for Android + * Copyright (C) 2020 tom5079 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package xyz.quaver.pupil.util + +import android.content.SharedPreferences +import kotlin.reflect.KClass + +lateinit var preferences: SharedPreferences + +object Preferences: SharedPreferences by preferences { + + @Suppress("UNCHECKED_CAST") + val putMap = mapOf, (String, Any) -> Unit>( + String::class to { k, v -> edit().putString(k, v as String).apply() }, + Int::class to { k, v -> edit().putBoolean(k, v as Boolean).apply() }, + Long::class to { k, v -> edit().putLong(k, v as Long).apply() }, + Boolean::class to { k, v -> edit().putBoolean(k, v as Boolean).apply() }, + Set::class to { k, v -> edit().putStringSet(k, v as Set).apply() } + ) + + val defMap = mapOf( + String::class to "", + Int::class to -1, + Long::class to -1, + Boolean::class to false, + Set::class to emptySet() + ) + + inline operator fun set(key: String, value: T) { + putMap[T::class]?.invoke(key, value) + } + + inline operator fun get(key: String, defaultVal: T = defMap[T::class] as T, setIfNull: Boolean = false): T = + (all[key] as? T) ?: defaultVal.also { if (setIfNull) set(key, defaultVal) } + + fun remove(key: String) { + edit().remove(key).apply() + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/quaver/pupil/util/file.kt b/app/src/main/java/xyz/quaver/pupil/util/file.kt index 4ed014e2..2f4e1654 100644 --- a/app/src/main/java/xyz/quaver/pupil/util/file.kt +++ b/app/src/main/java/xyz/quaver/pupil/util/file.kt @@ -25,7 +25,6 @@ import android.os.Build import android.os.storage.StorageManager import android.provider.DocumentsContract import androidx.core.content.ContextCompat -import androidx.preference.PreferenceManager import java.io.File import java.io.FileOutputStream import java.lang.reflect.Array @@ -41,8 +40,8 @@ fun getCachedGallery(context: Context, galleryID: Int) = } fun getDownloadDirectory(context: Context) = - PreferenceManager.getDefaultSharedPreferences(context).getString("dl_location", null).let { - if (it != null && !it.startsWith("content")) + Preferences.get("dl_location").let { + if (it.isNotEmpty() && !it.startsWith("content")) File(it) else context.getExternalFilesDir(null)!! @@ -124,94 +123,5 @@ fun getVolumePath(context: Context, volumeID: String?): String? { }.getOrNull() } -// Credits go to https://stackoverflow.com/questions/34927748/android-5-0-documentfile-from-tree-uri/36162691#36162691 -@TargetApi(Build.VERSION_CODES.LOLLIPOP) -fun getVolumeIdFromTreeUri(uri: Uri) = - DocumentsContract.getTreeDocumentId(uri).split(':').let { - if (it.isNotEmpty()) - it[0] - else - null - } - -@TargetApi(Build.VERSION_CODES.LOLLIPOP) -fun getDocumentPathFromTreeUri(uri: Uri) = - DocumentsContract.getTreeDocumentId(uri).split(':').let { - if (it.size >= 2) - it[1] - else - File.separator - } - -fun getFullPathFromTreeUri(context: Context, uri: Uri) : String? { - val volumePath = getVolumePath(context, getVolumeIdFromTreeUri(uri) ?: return null).let { - it ?: return File.separator - - if (it.endsWith(File.separator)) - it.dropLast(1) - else - it - } - - val documentPath = getDocumentPathFromTreeUri(uri).let { - if (it.endsWith(File.separator)) - it.dropLast(1) - else - it - } - - return if (documentPath.isNotEmpty()) { - if (documentPath.startsWith(File.separator)) - volumePath + documentPath - else - volumePath + File.separator + documentPath - } else - volumePath -} - -// Huge thanks to avluis(https://github.com/avluis) -// This code is originated from Hentoid(https://github.com/avluis/Hentoid) under Apache-2.0 license. -fun Uri.toFile(context: Context): File? { - val path = this.path ?: return null - - val pathSeparator = path.indexOf(':') - val folderName = path.substring(pathSeparator+1) - - // Determine whether the designated file is - // - on a removable media (e.g. SD card, OTG) - // or - // - on the internal phone memory - val removableMediaFolderRoots = getExtSdCardPaths(context) - - /* First test is to compare root names with known roots of removable media - * In many cases, the SD card root name is shared between pre-SAF (File) and SAF (DocumentFile) frameworks - * (e.g. /storage/3437-3934 vs. /tree/3437-3934) - * This is what the following block is trying to do - */ - for (s in removableMediaFolderRoots) { - val sRoot = s.substring(s.lastIndexOf(File.separatorChar)) - val root = path.substring(0, pathSeparator).let { - it.substring(it.lastIndexOf(File.separatorChar)) - } - - if (sRoot.equals(root, true)) { - return File(s + File.separatorChar + folderName) - } - } - /* In some other cases, there is no common name (e.g. /storage/sdcard1 vs. /tree/3437-3934) - * We can use a slower method to translate the Uri obtained with SAF into a pre-SAF path - * and compare it to the known removable media volume names - */ - val root = getFullPathFromTreeUri(context, this) - - for (s in removableMediaFolderRoots) { - if (root?.startsWith(s) == true) { - return File(root) - } - } - - return File(context.getExternalFilesDir(null)?.canonicalPath?.substringBeforeLast("/Android/data") ?: return null, folderName) -} - fun File.isParentOf(another: File) = another.absolutePath.startsWith(this.absolutePath) \ No newline at end of file diff --git a/app/src/main/java/xyz/quaver/pupil/util/misc.kt b/app/src/main/java/xyz/quaver/pupil/util/misc.kt index 9beb641a..43cba0ab 100644 --- a/app/src/main/java/xyz/quaver/pupil/util/misc.kt +++ b/app/src/main/java/xyz/quaver/pupil/util/misc.kt @@ -19,6 +19,7 @@ package xyz.quaver.pupil.util import android.annotation.SuppressLint +import okhttp3.OkHttpClient import java.util.* import kotlin.collections.ArrayList @@ -59,4 +60,11 @@ fun byteToString(byte: Long, precision : Int = 1) : String { * * https://stackoverflow.com/questions/38072322/generate-16-bit-unique-ids-in-android-for-startactivityforresult */ -fun Int.normalizeID() = this.and(0xFFFF) \ No newline at end of file +fun Int.normalizeID() = this.and(0xFFFF) + +fun OkHttpClient.Builder.proxyInfo(proxyInfo: ProxyInfo) = this.apply { + proxy(proxyInfo.proxy()) + proxyInfo.authenticator()?.let { + proxyAuthenticator(it) + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/quaver/pupil/util/proxy.kt b/app/src/main/java/xyz/quaver/pupil/util/proxy.kt index 061fc280..778ff2ee 100644 --- a/app/src/main/java/xyz/quaver/pupil/util/proxy.kt +++ b/app/src/main/java/xyz/quaver/pupil/util/proxy.kt @@ -19,11 +19,12 @@ package xyz.quaver.pupil.util import android.content.Context -import androidx.preference.PreferenceManager import kotlinx.serialization.Serializable import kotlinx.serialization.decodeFromString +import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json -import okhttp3.* +import okhttp3.Authenticator +import okhttp3.Credentials import java.net.InetSocketAddress import java.net.Proxy @@ -36,29 +37,22 @@ data class ProxyInfo( val password: String? = null ) { fun proxy() : Proxy { - return if (host == null || port == null) + return if (host.isNullOrBlank() || port == null) return Proxy.NO_PROXY else Proxy(type, InetSocketAddress.createUnresolved(host, port)) } - fun authenticator() = Authenticator { _, response -> - val credential = Credentials.basic(username ?: "", password ?: "") + fun authenticator(): Authenticator? = if (username.isNullOrBlank() || password.isNullOrBlank()) null else + Authenticator { _, response -> + val credential = Credentials.basic(username, password) - response.request().newBuilder() - .header("Proxy-Authorization", credential) - .build() - } + response.request().newBuilder() + .header("Proxy-Authorization", credential) + .build() + } } -fun getProxy(context: Context) = - getProxyInfo(context).proxy() - -fun getProxyInfo(context: Context) = - PreferenceManager.getDefaultSharedPreferences(context).getString("proxy", null).let { - if (it == null) - ProxyInfo(Proxy.Type.DIRECT) - else - Json.decodeFromString(it) - } \ No newline at end of file +fun getProxyInfo(): ProxyInfo = + Json.decodeFromString(Preferences["proxy", Json.encodeToString(ProxyInfo(Proxy.Type.DIRECT))]) \ No newline at end of file diff --git a/app/src/main/java/xyz/quaver/pupil/util/update.kt b/app/src/main/java/xyz/quaver/pupil/util/update.kt index 3efaa876..df894253 100644 --- a/app/src/main/java/xyz/quaver/pupil/util/update.kt +++ b/app/src/main/java/xyz/quaver/pupil/util/update.kt @@ -24,14 +24,15 @@ import android.net.Uri import android.webkit.URLUtil import androidx.appcompat.app.AlertDialog import androidx.preference.PreferenceManager -import com.google.android.material.snackbar.Snackbar -import kotlinx.android.synthetic.main.activity_main_content.* import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.* -import okhttp3.* +import okhttp3.Call +import okhttp3.Callback +import okhttp3.Request +import okhttp3.Response import ru.noties.markwon.Markwon import xyz.quaver.pupil.BuildConfig import xyz.quaver.pupil.R @@ -51,17 +52,14 @@ fun getReleases(url: String) : JsonArray { } } -fun checkUpdate(context: Context, url: String) : JsonObject? { +fun checkUpdate(url: String) : JsonObject? { val releases = getReleases(url) if (releases.isEmpty()) return null return releases.firstOrNull { - if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("beta", false)) - true - else - it.jsonObject["prerelease"]?.jsonPrimitive?.booleanOrNull == false + Preferences["beta"] || it.jsonObject["prerelease"]?.jsonPrimitive?.booleanOrNull == false }?.let { if (it.jsonObject["tag_name"]?.jsonPrimitive?.contentOrNull == BuildConfig.VERSION_NAME) null @@ -130,7 +128,7 @@ fun checkUpdate(context: Context, force: Boolean = false) { CoroutineScope(Dispatchers.Default).launch { val update = - checkUpdate(context, context.getString(R.string.release_url)) ?: return@launch + checkUpdate(context.getString(R.string.release_url)) ?: return@launch val url = getApkUrl(update) ?: return@launch diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml index 966fbe1b..5fafab5d 100644 --- a/app/src/main/res/xml/root_preferences.xml +++ b/app/src/main/res/xml/root_preferences.xml @@ -88,8 +88,7 @@ + app:summary="@string/settings_security_mode_summary"/>