|
|
@ -9,7 +9,7 @@ import android.view.Menu |
|
|
|
import android.view.MenuInflater |
|
|
|
import android.view.MenuInflater |
|
|
|
import android.view.MenuItem |
|
|
|
import android.view.MenuItem |
|
|
|
import android.view.View |
|
|
|
import android.view.View |
|
|
|
import androidx.activity.result.contract.ActivityResultContracts |
|
|
|
import android.widget.SeekBar |
|
|
|
import androidx.documentfile.provider.DocumentFile |
|
|
|
import androidx.documentfile.provider.DocumentFile |
|
|
|
import androidx.preference.Preference |
|
|
|
import androidx.preference.Preference |
|
|
|
import io.legado.app.R |
|
|
|
import io.legado.app.R |
|
|
@ -18,6 +18,7 @@ import io.legado.app.constant.AppConst |
|
|
|
import io.legado.app.constant.EventBus |
|
|
|
import io.legado.app.constant.EventBus |
|
|
|
import io.legado.app.constant.PreferKey |
|
|
|
import io.legado.app.constant.PreferKey |
|
|
|
import io.legado.app.databinding.DialogEditTextBinding |
|
|
|
import io.legado.app.databinding.DialogEditTextBinding |
|
|
|
|
|
|
|
import io.legado.app.databinding.DialogImageBlurringBinding |
|
|
|
import io.legado.app.help.AppConfig |
|
|
|
import io.legado.app.help.AppConfig |
|
|
|
import io.legado.app.help.LauncherIconHelp |
|
|
|
import io.legado.app.help.LauncherIconHelp |
|
|
|
import io.legado.app.help.ThemeConfig |
|
|
|
import io.legado.app.help.ThemeConfig |
|
|
@ -26,8 +27,10 @@ import io.legado.app.lib.dialogs.selector |
|
|
|
import io.legado.app.lib.permission.Permissions |
|
|
|
import io.legado.app.lib.permission.Permissions |
|
|
|
import io.legado.app.lib.permission.PermissionsCompat |
|
|
|
import io.legado.app.lib.permission.PermissionsCompat |
|
|
|
import io.legado.app.lib.theme.ATH |
|
|
|
import io.legado.app.lib.theme.ATH |
|
|
|
|
|
|
|
import io.legado.app.ui.widget.image.CoverImageView |
|
|
|
import io.legado.app.ui.widget.number.NumberPickerDialog |
|
|
|
import io.legado.app.ui.widget.number.NumberPickerDialog |
|
|
|
import io.legado.app.ui.widget.prefs.ColorPreference |
|
|
|
import io.legado.app.ui.widget.prefs.ColorPreference |
|
|
|
|
|
|
|
import io.legado.app.ui.widget.seekbar.SeekBarChangeListener |
|
|
|
import io.legado.app.utils.* |
|
|
|
import io.legado.app.utils.* |
|
|
|
import java.io.File |
|
|
|
import java.io.File |
|
|
|
|
|
|
|
|
|
|
@ -35,17 +38,21 @@ import java.io.File |
|
|
|
@Suppress("SameParameterValue") |
|
|
|
@Suppress("SameParameterValue") |
|
|
|
class ThemeConfigFragment : BasePreferenceFragment(), |
|
|
|
class ThemeConfigFragment : BasePreferenceFragment(), |
|
|
|
SharedPreferences.OnSharedPreferenceChangeListener { |
|
|
|
SharedPreferences.OnSharedPreferenceChangeListener { |
|
|
|
|
|
|
|
private val requestCodeCover = 111 |
|
|
|
private val selectLightBg = registerForActivityResult(ActivityResultContracts.GetContent()) { |
|
|
|
private val requestCodeCoverDark = 112 |
|
|
|
it ?: return@registerForActivityResult |
|
|
|
private val requestCodeBgLight = 121 |
|
|
|
setBgFromUri(it, PreferKey.bgImage) { |
|
|
|
private val requestCodeBgDark = 122 |
|
|
|
upTheme(false) |
|
|
|
private val selectImage = registerForActivityResult(ActivityResultContractUtils.SelectImage()) { |
|
|
|
} |
|
|
|
val uri = it?.second ?: return@registerForActivityResult |
|
|
|
} |
|
|
|
when (it.first) { |
|
|
|
private val selectDarkBg = registerForActivityResult(ActivityResultContracts.GetContent()) { |
|
|
|
requestCodeCover -> setCoverFromUri(PreferKey.defaultCover, uri) |
|
|
|
it ?: return@registerForActivityResult |
|
|
|
requestCodeCoverDark -> setCoverFromUri(PreferKey.defaultCoverDark, uri) |
|
|
|
setBgFromUri(it, PreferKey.bgImageN) { |
|
|
|
requestCodeBgLight -> setBgFromUri(uri, PreferKey.bgImage) { |
|
|
|
upTheme(true) |
|
|
|
upTheme(false) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
requestCodeBgDark -> setBgFromUri(uri, PreferKey.bgImageN) { |
|
|
|
|
|
|
|
upTheme(true) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -57,6 +64,8 @@ class ThemeConfigFragment : BasePreferenceFragment(), |
|
|
|
upPreferenceSummary(PreferKey.bgImage, getPrefString(PreferKey.bgImage)) |
|
|
|
upPreferenceSummary(PreferKey.bgImage, getPrefString(PreferKey.bgImage)) |
|
|
|
upPreferenceSummary(PreferKey.bgImageN, getPrefString(PreferKey.bgImageN)) |
|
|
|
upPreferenceSummary(PreferKey.bgImageN, getPrefString(PreferKey.bgImageN)) |
|
|
|
upPreferenceSummary(PreferKey.barElevation, AppConfig.elevation.toString()) |
|
|
|
upPreferenceSummary(PreferKey.barElevation, AppConfig.elevation.toString()) |
|
|
|
|
|
|
|
upPreferenceSummary(PreferKey.defaultCover, getPrefString(PreferKey.defaultCover)) |
|
|
|
|
|
|
|
upPreferenceSummary(PreferKey.defaultCoverDark, getPrefString(PreferKey.defaultCoverDark)) |
|
|
|
findPreference<ColorPreference>(PreferKey.cBackground)?.let { |
|
|
|
findPreference<ColorPreference>(PreferKey.cBackground)?.let { |
|
|
|
it.onSaveColor = { color -> |
|
|
|
it.onSaveColor = { color -> |
|
|
|
if (!ColorUtils.isColorLight(color)) { |
|
|
|
if (!ColorUtils.isColorLight(color)) { |
|
|
@ -85,14 +94,14 @@ class ThemeConfigFragment : BasePreferenceFragment(), |
|
|
|
setHasOptionsMenu(true) |
|
|
|
setHasOptionsMenu(true) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
override fun onResume() { |
|
|
|
override fun onCreate(savedInstanceState: Bundle?) { |
|
|
|
super.onResume() |
|
|
|
super.onCreate(savedInstanceState) |
|
|
|
preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(this) |
|
|
|
preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(this) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
override fun onPause() { |
|
|
|
override fun onDestroy() { |
|
|
|
|
|
|
|
super.onDestroy() |
|
|
|
preferenceManager.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this) |
|
|
|
preferenceManager.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this) |
|
|
|
super.onPause() |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { |
|
|
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { |
|
|
@ -128,6 +137,12 @@ class ThemeConfigFragment : BasePreferenceFragment(), |
|
|
|
PreferKey.cNBBackground -> { |
|
|
|
PreferKey.cNBBackground -> { |
|
|
|
upTheme(true) |
|
|
|
upTheme(true) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
PreferKey.bgImage, |
|
|
|
|
|
|
|
PreferKey.bgImageN, |
|
|
|
|
|
|
|
PreferKey.defaultCover, |
|
|
|
|
|
|
|
PreferKey.defaultCoverDark -> { |
|
|
|
|
|
|
|
upPreferenceSummary(key, getPrefString(key)) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
@ -151,29 +166,58 @@ class ThemeConfigFragment : BasePreferenceFragment(), |
|
|
|
"themeList" -> ThemeListDialog().show(childFragmentManager, "themeList") |
|
|
|
"themeList" -> ThemeListDialog().show(childFragmentManager, "themeList") |
|
|
|
"saveDayTheme", "saveNightTheme" -> saveThemeAlert(key) |
|
|
|
"saveDayTheme", "saveNightTheme" -> saveThemeAlert(key) |
|
|
|
PreferKey.bgImage -> if (getPrefString(PreferKey.bgImage).isNullOrEmpty()) { |
|
|
|
PreferKey.bgImage -> if (getPrefString(PreferKey.bgImage).isNullOrEmpty()) { |
|
|
|
selectLightBg.launch("image/*") |
|
|
|
selectImage.launch(requestCodeBgLight) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
selector(items = arrayListOf("删除图片", "选择图片")) { _, i -> |
|
|
|
selector(items = arrayListOf("删除图片", "选择图片")) { _, i -> |
|
|
|
if (i == 0) { |
|
|
|
if (i == 0) { |
|
|
|
removePref(PreferKey.bgImage) |
|
|
|
removePref(PreferKey.bgImage) |
|
|
|
upTheme(false) |
|
|
|
upTheme(false) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
selectLightBg.launch("image/*") |
|
|
|
selectImage.launch(requestCodeBgLight) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
PreferKey.bgImageN -> if (getPrefString(PreferKey.bgImageN).isNullOrEmpty()) { |
|
|
|
PreferKey.bgImageN -> if (getPrefString(PreferKey.bgImageN).isNullOrEmpty()) { |
|
|
|
selectDarkBg.launch("image/*") |
|
|
|
selectImage.launch(requestCodeBgDark) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
selector(items = arrayListOf("删除图片", "选择图片")) { _, i -> |
|
|
|
selector(items = arrayListOf("删除图片", "选择图片")) { _, i -> |
|
|
|
if (i == 0) { |
|
|
|
if (i == 0) { |
|
|
|
removePref(PreferKey.bgImageN) |
|
|
|
removePref(PreferKey.bgImageN) |
|
|
|
upTheme(true) |
|
|
|
upTheme(true) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
selectDarkBg.launch("image/*") |
|
|
|
selectImage.launch(requestCodeBgDark) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
PreferKey.bgImageBlurring -> alertImageBlurring(PreferKey.bgImageBlurring) { |
|
|
|
|
|
|
|
upTheme(false) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
PreferKey.bgImageNBlurring -> alertImageBlurring(PreferKey.bgImageNBlurring) { |
|
|
|
|
|
|
|
upTheme(true) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
PreferKey.defaultCover -> if (getPrefString(PreferKey.defaultCover).isNullOrEmpty()) { |
|
|
|
|
|
|
|
selectImage.launch(requestCodeCover) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
selector(items = arrayListOf("删除图片", "选择图片")) { _, i -> |
|
|
|
|
|
|
|
if (i == 0) { |
|
|
|
|
|
|
|
removePref(PreferKey.defaultCover) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
selectImage.launch(requestCodeCover) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
PreferKey.defaultCoverDark -> |
|
|
|
|
|
|
|
if (getPrefString(PreferKey.defaultCoverDark).isNullOrEmpty()) { |
|
|
|
|
|
|
|
selectImage.launch(requestCodeCoverDark) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
selector(items = arrayListOf("删除图片", "选择图片")) { _, i -> |
|
|
|
|
|
|
|
if (i == 0) { |
|
|
|
|
|
|
|
removePref(PreferKey.defaultCoverDark) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
selectImage.launch(requestCodeCoverDark) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return super.onPreferenceTreeClick(preference) |
|
|
|
return super.onPreferenceTreeClick(preference) |
|
|
|
} |
|
|
|
} |
|
|
@ -181,7 +225,9 @@ class ThemeConfigFragment : BasePreferenceFragment(), |
|
|
|
@SuppressLint("InflateParams") |
|
|
|
@SuppressLint("InflateParams") |
|
|
|
private fun saveThemeAlert(key: String) { |
|
|
|
private fun saveThemeAlert(key: String) { |
|
|
|
alert(R.string.theme_name) { |
|
|
|
alert(R.string.theme_name) { |
|
|
|
val alertBinding = DialogEditTextBinding.inflate(layoutInflater) |
|
|
|
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { |
|
|
|
|
|
|
|
textInputLayout.hint = "name" |
|
|
|
|
|
|
|
} |
|
|
|
customView { alertBinding.root } |
|
|
|
customView { alertBinding.root } |
|
|
|
okButton { |
|
|
|
okButton { |
|
|
|
alertBinding.editView.text?.toString()?.let { themeName -> |
|
|
|
alertBinding.editView.text?.toString()?.let { themeName -> |
|
|
@ -199,6 +245,34 @@ class ThemeConfigFragment : BasePreferenceFragment(), |
|
|
|
}.show() |
|
|
|
}.show() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun alertImageBlurring(preferKey: String, success: () -> Unit) { |
|
|
|
|
|
|
|
alert(R.string.background_image_blurring) { |
|
|
|
|
|
|
|
val alertBinding = DialogImageBlurringBinding.inflate(layoutInflater).apply { |
|
|
|
|
|
|
|
getPrefInt(preferKey, 0).let { |
|
|
|
|
|
|
|
seekBar.progress = it |
|
|
|
|
|
|
|
textViewValue.text = it.toString() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
seekBar.setOnSeekBarChangeListener(object : SeekBarChangeListener { |
|
|
|
|
|
|
|
override fun onProgressChanged( |
|
|
|
|
|
|
|
seekBar: SeekBar, |
|
|
|
|
|
|
|
progress: Int, |
|
|
|
|
|
|
|
fromUser: Boolean |
|
|
|
|
|
|
|
) { |
|
|
|
|
|
|
|
textViewValue.text = progress.toString() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
customView { alertBinding.root } |
|
|
|
|
|
|
|
okButton { |
|
|
|
|
|
|
|
alertBinding.seekBar.progress.let { |
|
|
|
|
|
|
|
putPrefInt(preferKey, it) |
|
|
|
|
|
|
|
success.invoke() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
noButton() |
|
|
|
|
|
|
|
}.show() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private fun upTheme(isNightTheme: Boolean) { |
|
|
|
private fun upTheme(isNightTheme: Boolean) { |
|
|
|
if (AppConfig.isNightTheme == isNightTheme) { |
|
|
|
if (AppConfig.isNightTheme == isNightTheme) { |
|
|
|
listView.post { |
|
|
|
listView.post { |
|
|
@ -217,6 +291,14 @@ class ThemeConfigFragment : BasePreferenceFragment(), |
|
|
|
when (preferenceKey) { |
|
|
|
when (preferenceKey) { |
|
|
|
PreferKey.barElevation -> preference.summary = |
|
|
|
PreferKey.barElevation -> preference.summary = |
|
|
|
getString(R.string.bar_elevation_s, value) |
|
|
|
getString(R.string.bar_elevation_s, value) |
|
|
|
|
|
|
|
PreferKey.bgImage, |
|
|
|
|
|
|
|
PreferKey.bgImageN, |
|
|
|
|
|
|
|
PreferKey.defaultCover, |
|
|
|
|
|
|
|
PreferKey.defaultCoverDark -> preference.summary = if (value.isNullOrBlank()) { |
|
|
|
|
|
|
|
getString(R.string.select_image) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
value |
|
|
|
|
|
|
|
} |
|
|
|
else -> preference.summary = value |
|
|
|
else -> preference.summary = value |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -232,7 +314,6 @@ class ThemeConfigFragment : BasePreferenceFragment(), |
|
|
|
}.getOrNull()?.let { byteArray -> |
|
|
|
}.getOrNull()?.let { byteArray -> |
|
|
|
file.writeBytes(byteArray) |
|
|
|
file.writeBytes(byteArray) |
|
|
|
putPrefString(preferenceKey, file.absolutePath) |
|
|
|
putPrefString(preferenceKey, file.absolutePath) |
|
|
|
upPreferenceSummary(preferenceKey, file.absolutePath) |
|
|
|
|
|
|
|
success() |
|
|
|
success() |
|
|
|
} ?: toastOnUi("获取文件出错") |
|
|
|
} ?: toastOnUi("获取文件出错") |
|
|
|
} |
|
|
|
} |
|
|
@ -251,7 +332,6 @@ class ThemeConfigFragment : BasePreferenceFragment(), |
|
|
|
file = FileUtils.createFileIfNotExist(file, preferenceKey, imgFile.name) |
|
|
|
file = FileUtils.createFileIfNotExist(file, preferenceKey, imgFile.name) |
|
|
|
file.writeBytes(imgFile.readBytes()) |
|
|
|
file.writeBytes(imgFile.readBytes()) |
|
|
|
putPrefString(preferenceKey, file.absolutePath) |
|
|
|
putPrefString(preferenceKey, file.absolutePath) |
|
|
|
upPreferenceSummary(preferenceKey, file.absolutePath) |
|
|
|
|
|
|
|
success() |
|
|
|
success() |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -260,4 +340,41 @@ class ThemeConfigFragment : BasePreferenceFragment(), |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun setCoverFromUri(preferenceKey: String, uri: Uri) { |
|
|
|
|
|
|
|
if (uri.isContentScheme()) { |
|
|
|
|
|
|
|
val doc = DocumentFile.fromSingleUri(requireContext(), uri) |
|
|
|
|
|
|
|
doc?.name?.let { |
|
|
|
|
|
|
|
var file = requireContext().externalFiles |
|
|
|
|
|
|
|
file = FileUtils.createFileIfNotExist(file, "covers", it) |
|
|
|
|
|
|
|
kotlin.runCatching { |
|
|
|
|
|
|
|
DocumentUtils.readBytes(requireContext(), doc.uri) |
|
|
|
|
|
|
|
}.getOrNull()?.let { byteArray -> |
|
|
|
|
|
|
|
file.writeBytes(byteArray) |
|
|
|
|
|
|
|
putPrefString(preferenceKey, file.absolutePath) |
|
|
|
|
|
|
|
CoverImageView.upDefaultCover() |
|
|
|
|
|
|
|
} ?: toastOnUi("获取文件出错") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
PermissionsCompat.Builder(this) |
|
|
|
|
|
|
|
.addPermissions( |
|
|
|
|
|
|
|
Permissions.READ_EXTERNAL_STORAGE, |
|
|
|
|
|
|
|
Permissions.WRITE_EXTERNAL_STORAGE |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
.rationale(R.string.bg_image_per) |
|
|
|
|
|
|
|
.onGranted { |
|
|
|
|
|
|
|
RealPathUtil.getPath(requireContext(), uri)?.let { path -> |
|
|
|
|
|
|
|
val imgFile = File(path) |
|
|
|
|
|
|
|
if (imgFile.exists()) { |
|
|
|
|
|
|
|
var file = requireContext().externalFiles |
|
|
|
|
|
|
|
file = FileUtils.createFileIfNotExist(file, "covers", imgFile.name) |
|
|
|
|
|
|
|
file.writeBytes(imgFile.readBytes()) |
|
|
|
|
|
|
|
putPrefString(PreferKey.defaultCover, file.absolutePath) |
|
|
|
|
|
|
|
CoverImageView.upDefaultCover() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
.request() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |