封面设置移到主题里面,白天和夜间可分别设置

pull/1217/head
gedoor 3 years ago
parent fba167eb3d
commit e3216921a3
  1. 1
      app/src/main/assets/updateLog.md
  2. 1
      app/src/main/java/io/legado/app/constant/PreferKey.kt
  3. 3
      app/src/main/java/io/legado/app/help/storage/Restore.kt
  4. 70
      app/src/main/java/io/legado/app/ui/config/OtherConfigFragment.kt
  5. 117
      app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt
  6. 5
      app/src/main/java/io/legado/app/ui/widget/image/CoverImageView.kt
  7. 32
      app/src/main/java/io/legado/app/utils/ActivityResultContractUtils.kt
  8. 14
      app/src/main/res/xml/pref_config_other.xml
  9. 23
      app/src/main/res/xml/pref_config_theme.xml

@ -17,6 +17,7 @@
1. 换源界面功能添加:置顶,置底,删除 by h11128 1. 换源界面功能添加:置顶,置底,删除 by h11128
2. Cronet:优化 by ag2s20150909 2. Cronet:优化 by ag2s20150909
3. 优化自动翻页 by jiuZhouWorlds 3. 优化自动翻页 by jiuZhouWorlds
4. 封面设置移到主题里面,白天和夜间可分别设置
**2021/08/01** **2021/08/01**

@ -66,6 +66,7 @@ object PreferKey {
const val transparentStatusBar = "transparentStatusBar" const val transparentStatusBar = "transparentStatusBar"
const val immNavigationBar = "immNavigationBar" const val immNavigationBar = "immNavigationBar"
const val defaultCover = "defaultCover" const val defaultCover = "defaultCover"
const val defaultCoverDark = "defaultCoverDark"
const val replaceEnableDefault = "replaceEnableDefault" const val replaceEnableDefault = "replaceEnableDefault"
const val showBrightnessView = "showBrightnessView" const val showBrightnessView = "showBrightnessView"
const val autoClearExpired = "autoClearExpired" const val autoClearExpired = "autoClearExpired"

@ -58,7 +58,8 @@ object Restore {
//默认忽略keys //默认忽略keys
private val ignorePrefKeys = arrayOf( private val ignorePrefKeys = arrayOf(
PreferKey.defaultCover PreferKey.defaultCover,
PreferKey.defaultCoverDark
) )
private val readPrefKeys = arrayOf( private val readPrefKeys = arrayOf(
PreferKey.readStyleSelect, PreferKey.readStyleSelect,

@ -5,12 +5,9 @@ import android.content.ComponentName
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.os.Process import android.os.Process
import android.view.View import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.documentfile.provider.DocumentFile
import androidx.preference.ListPreference import androidx.preference.ListPreference
import androidx.preference.Preference import androidx.preference.Preference
import io.legado.app.R import io.legado.app.R
@ -21,18 +18,13 @@ import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.dialogs.selector
import io.legado.app.lib.permission.Permissions
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.receiver.SharedReceiverActivity import io.legado.app.receiver.SharedReceiverActivity
import io.legado.app.service.WebService import io.legado.app.service.WebService
import io.legado.app.ui.main.MainActivity import io.legado.app.ui.main.MainActivity
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.utils.* import io.legado.app.utils.*
import splitties.init.appCtx import splitties.init.appCtx
import java.io.File
class OtherConfigFragment : BasePreferenceFragment(), class OtherConfigFragment : BasePreferenceFragment(),
@ -44,10 +36,6 @@ class OtherConfigFragment : BasePreferenceFragment(),
SharedReceiverActivity::class.java.name SharedReceiverActivity::class.java.name
) )
private val webPort get() = getPrefInt(PreferKey.webPort, 1122) private val webPort get() = getPrefInt(PreferKey.webPort, 1122)
private val selectCoverImage = registerForActivityResult(ActivityResultContracts.GetContent()) {
it ?: return@registerForActivityResult
setCoverFromUri(it)
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
putPrefBoolean(PreferKey.processText, isProcessTextEnabled()) putPrefBoolean(PreferKey.processText, isProcessTextEnabled())
@ -56,7 +44,6 @@ class OtherConfigFragment : BasePreferenceFragment(),
upPreferenceSummary(PreferKey.preDownloadNum, AppConfig.preDownloadNum.toString()) upPreferenceSummary(PreferKey.preDownloadNum, AppConfig.preDownloadNum.toString())
upPreferenceSummary(PreferKey.threadCount, AppConfig.threadCount.toString()) upPreferenceSummary(PreferKey.threadCount, AppConfig.threadCount.toString())
upPreferenceSummary(PreferKey.webPort, webPort.toString()) upPreferenceSummary(PreferKey.webPort, webPort.toString())
upPreferenceSummary(PreferKey.defaultCover, getPrefString(PreferKey.defaultCover))
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -98,17 +85,7 @@ class OtherConfigFragment : BasePreferenceFragment(),
putPrefInt(PreferKey.webPort, it) putPrefInt(PreferKey.webPort, it)
} }
PreferKey.cleanCache -> clearCache() PreferKey.cleanCache -> clearCache()
PreferKey.defaultCover -> if (getPrefString(PreferKey.defaultCover).isNullOrEmpty()) {
selectCoverImage.launch("image/*")
} else {
selector(items = arrayListOf("删除图片", "选择图片")) { _, i ->
if (i == 0) {
removePref(PreferKey.defaultCover)
} else {
selectCoverImage.launch("image/*")
}
}
}
} }
return super.onPreferenceTreeClick(preference) return super.onPreferenceTreeClick(preference)
} }
@ -134,9 +111,6 @@ class OtherConfigFragment : BasePreferenceFragment(),
setProcessTextEnable(it.getBoolean(key, true)) setProcessTextEnable(it.getBoolean(key, true))
} }
PreferKey.showDiscovery, PreferKey.showRss -> postEvent(EventBus.NOTIFY_MAIN, true) PreferKey.showDiscovery, PreferKey.showRss -> postEvent(EventBus.NOTIFY_MAIN, true)
PreferKey.defaultCover -> upPreferenceSummary(
key, getPrefString(PreferKey.defaultCover)
)
PreferKey.language -> listView.postDelayed({ PreferKey.language -> listView.postDelayed({
LanguageUtils.setConfiguration(appCtx) LanguageUtils.setConfiguration(appCtx)
val intent = Intent(appCtx, MainActivity::class.java) val intent = Intent(appCtx, MainActivity::class.java)
@ -157,11 +131,6 @@ class OtherConfigFragment : BasePreferenceFragment(),
getString(R.string.pre_download_s, value) getString(R.string.pre_download_s, value)
PreferKey.threadCount -> preference.summary = getString(R.string.threads_num, value) PreferKey.threadCount -> preference.summary = getString(R.string.threads_num, value)
PreferKey.webPort -> preference.summary = getString(R.string.web_port_summary, value) PreferKey.webPort -> preference.summary = getString(R.string.web_port_summary, value)
PreferKey.defaultCover -> preference.summary = if (value.isNullOrBlank()) {
getString(R.string.select_image)
} else {
value
}
else -> if (preference is ListPreference) { else -> if (preference is ListPreference) {
val index = preference.findIndexOfValue(value) val index = preference.findIndexOfValue(value)
// Set the summary to reflect the new value. // Set the summary to reflect the new value.
@ -222,41 +191,4 @@ class OtherConfigFragment : BasePreferenceFragment(),
} }
} }
private fun setCoverFromUri(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(PreferKey.defaultCover, 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()
}
}
} }

@ -9,7 +9,6 @@ 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 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
@ -26,6 +25,7 @@ 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.utils.* import io.legado.app.utils.*
@ -35,17 +35,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 +61,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 +91,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 +134,9 @@ class ThemeConfigFragment : BasePreferenceFragment(),
PreferKey.cNBBackground -> { PreferKey.cNBBackground -> {
upTheme(true) upTheme(true)
} }
PreferKey.defaultCover, PreferKey.defaultCoverDark -> {
upPreferenceSummary(key, getPrefString(key))
}
} }
} }
@ -151,29 +160,52 @@ 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.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)
} }
@ -217,6 +249,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
} }
} }
@ -260,4 +300,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()
}
}
} }

@ -179,7 +179,10 @@ class CoverImageView @JvmOverloads constructor(
@SuppressLint("UseCompatLoadingForDrawables") @SuppressLint("UseCompatLoadingForDrawables")
fun upDefaultCover() { fun upDefaultCover() {
val path = appCtx.getPrefString(PreferKey.defaultCover) val preferKey =
if (AppConfig.isNightTheme) PreferKey.defaultCoverDark
else PreferKey.defaultCover
val path = appCtx.getPrefString(preferKey)
var dw = Drawable.createFromPath(path) var dw = Drawable.createFromPath(path)
if (dw == null) { if (dw == null) {
showBookName = true showBookName = true

@ -0,0 +1,32 @@
package io.legado.app.utils
import android.app.Activity.RESULT_OK
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.activity.result.contract.ActivityResultContract
object ActivityResultContractUtils {
class SelectImage : ActivityResultContract<Int, Pair<Int?, Uri?>?>() {
var requestCode: Int? = null
override fun createIntent(context: Context, input: Int?): Intent {
requestCode = input
return Intent(Intent.ACTION_GET_CONTENT)
.addCategory(Intent.CATEGORY_OPENABLE)
.setType("image/*")
}
override fun parseResult(resultCode: Int, intent: Intent?): Pair<Int?, Uri?>? {
if (resultCode == RESULT_OK) {
return Pair(requestCode, intent?.data)
}
return null
}
}
}

@ -40,20 +40,6 @@
android:defaultValue="true" android:defaultValue="true"
android:key="showRss" android:key="showRss"
android:title="@string/show_rss" android:title="@string/show_rss"
app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.Preference
android:key="defaultCover"
android:title="@string/default_cover"
app:allowDividerAbove="false"
app:allowDividerBelow="false"
app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.SwitchPreference
android:defaultValue="false"
android:key="useDefaultCover"
android:title="@string/use_default_cover"
android:summary="@string/use_default_cover_s"
app:allowDividerAbove="false" app:allowDividerAbove="false"
app:allowDividerBelow="false" app:allowDividerBelow="false"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />

@ -33,6 +33,15 @@
android:title="@string/bar_elevation" android:title="@string/bar_elevation"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.SwitchPreference
android:defaultValue="false"
android:key="useDefaultCover"
android:title="@string/use_default_cover"
android:summary="@string/use_default_cover_s"
app:allowDividerAbove="false"
app:allowDividerBelow="false"
app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.Preference <io.legado.app.ui.widget.prefs.Preference
android:key="themeList" android:key="themeList"
android:summary="@string/theme_list_summary" android:summary="@string/theme_list_summary"
@ -87,6 +96,13 @@
app:cpv_dialogType="preset" app:cpv_dialogType="preset"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.Preference
android:key="defaultCover"
android:title="@string/default_cover"
app:allowDividerAbove="false"
app:allowDividerBelow="false"
app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.Preference <io.legado.app.ui.widget.prefs.Preference
android:key="saveDayTheme" android:key="saveDayTheme"
android:summary="@string/save_day_theme_summary" android:summary="@string/save_day_theme_summary"
@ -141,6 +157,13 @@
app:cpv_dialogType="preset" app:cpv_dialogType="preset"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.Preference
android:key="defaultCoverDark"
android:title="@string/default_cover"
app:allowDividerAbove="false"
app:allowDividerBelow="false"
app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.Preference <io.legado.app.ui.widget.prefs.Preference
android:key="saveNightTheme" android:key="saveNightTheme"
android:summary="@string/save_night_theme_summary" android:summary="@string/save_night_theme_summary"

Loading…
Cancel
Save