Merge branch 'master' into master

pull/276/head
kunfei 4 years ago committed by GitHub
commit 7485224a4e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      app/src/main/assets/updateLog.md
  2. 6
      app/src/main/java/io/legado/app/help/JsExtensions.kt
  3. 7
      app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt
  4. 3
      app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt
  5. 3
      app/src/main/java/io/legado/app/ui/main/MainActivity.kt
  6. 11
      app/src/main/java/io/legado/app/ui/main/MainViewModel.kt
  7. 26
      app/src/main/java/io/legado/app/ui/widget/font/FontAdapter.kt
  8. 87
      app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt
  9. 2
      app/src/main/java/io/legado/app/ui/widget/image/CoverImageView.kt
  10. 2
      app/src/main/java/io/legado/app/utils/DocumentUtils.kt
  11. 10
      app/src/main/java/io/legado/app/utils/StringExtensions.kt
  12. 2
      app/src/main/res/values-zh-rHK/strings.xml
  13. 2
      app/src/main/res/values-zh-rTW/strings.xml
  14. 2
      app/src/main/res/values-zh/strings.xml
  15. 2
      app/src/main/res/values/strings.xml
  16. 7
      app/src/main/res/xml/pref_config_backup.xml

@ -3,6 +3,9 @@
* 请关注公众号[开源阅读]()支持我,同时关注合作公众号[小说拾遗](),阅读公众号小编。
* 新公众号[开源阅读]()已启用,[开源阅读软件]()备用
**2020/07/20**
* 优化文字选择,不再缓存
**2020/07/19**
* 添加自定义默认封面
* 修复封面选择本地图片时书架不显示的bug

@ -52,4 +52,10 @@ interface JsExtensions {
fun timeFormat(time: Long): String {
return dateFormat.format(Date(time))
}
//utf8编码转gbk编码
fun utf8ToGbk(str: String): String {
val utf8 = String(str.toByteArray(charset("UTF-8")))
val unicode = String(utf8.toByteArray(), charset("UTF-8"))
return String(unicode.toByteArray(charset("GBK")))
}
}

@ -27,6 +27,7 @@ import io.legado.app.service.AudioPlayService
import io.legado.app.service.help.AudioPlay
import io.legado.app.ui.book.changesource.ChangeSourceDialog
import io.legado.app.ui.book.chapterlist.ChapterListActivity
import io.legado.app.ui.widget.image.CoverImageView
import io.legado.app.utils.*
import kotlinx.android.synthetic.main.activity_audio_play.*
import org.apache.commons.lang3.time.DateFormatUtils
@ -117,8 +118,8 @@ class AudioPlayActivity :
private fun upCover(path: String?) {
ImageLoader.load(this, path)
.placeholder(R.drawable.image_cover_default)
.error(R.drawable.image_cover_default)
.placeholder(CoverImageView.defaultDrawable)
.error(CoverImageView.defaultDrawable)
.into(iv_cover)
ImageLoader.load(this, path)
.transition(DrawableTransitionOptions.withCrossFade(1500))
@ -128,7 +129,7 @@ class AudioPlayActivity :
}
private fun defaultCover(): RequestBuilder<Drawable> {
return ImageLoader.load(this, R.drawable.image_cover_default)
return ImageLoader.load(this, CoverImageView.defaultDrawable)
.apply(bitmapTransform(BlurTransformation(this, 25)))
}

@ -32,6 +32,7 @@ import io.legado.app.ui.book.info.edit.BookInfoEditActivity
import io.legado.app.ui.book.read.ReadBookActivity
import io.legado.app.ui.book.search.SearchActivity
import io.legado.app.ui.book.source.edit.BookSourceEditActivity
import io.legado.app.ui.widget.image.CoverImageView
import io.legado.app.utils.dp
import io.legado.app.utils.getViewModel
import io.legado.app.utils.gone
@ -141,7 +142,7 @@ class BookInfoActivity :
}
private fun defaultCover(): RequestBuilder<Drawable> {
return ImageLoader.load(this, R.drawable.image_cover_default)
return ImageLoader.load(this, CoverImageView.defaultDrawable)
.apply(bitmapTransform(BlurTransformation(this, 25)))
}

@ -64,6 +64,9 @@ class MainActivity : VMBaseActivity<MainViewModel>(R.layout.activity_main),
viewModel.upChapterList()
}, 1000)
}
view_pager_main.postDelayed({
viewModel.postLoad()
}, 3000)
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {

@ -10,6 +10,7 @@ import io.legado.app.data.entities.RssSource
import io.legado.app.help.http.HttpHelper
import io.legado.app.help.storage.Restore
import io.legado.app.model.WebBook
import io.legado.app.utils.FileUtils
import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonObject
import io.legado.app.utils.postEvent
@ -77,4 +78,14 @@ class MainViewModel(application: Application) : BaseViewModel(application) {
}
}
}
fun postLoad() {
execute {
FileUtils.getDirFile(context.cacheDir, "Fonts").let {
if (it.exists()) {
it.delete()
}
}
}
}
}

@ -2,9 +2,12 @@ package io.legado.app.ui.widget.font
import android.content.Context
import android.graphics.Typeface
import android.os.Build
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.utils.DocItem
import io.legado.app.utils.RealPathUtil
import io.legado.app.utils.invisible
import io.legado.app.utils.visible
import kotlinx.android.synthetic.main.item_font.view.*
@ -13,15 +16,28 @@ import org.jetbrains.anko.toast
import java.io.File
class FontAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<File>(context, R.layout.item_font) {
SimpleRecyclerAdapter<DocItem>(context, R.layout.item_font) {
override fun convert(holder: ItemViewHolder, item: File, payloads: MutableList<Any>) {
override fun convert(holder: ItemViewHolder, item: DocItem, payloads: MutableList<Any>) {
with(holder.itemView) {
try {
val typeface = Typeface.createFromFile(item)
val typeface: Typeface? = if (item.isContentPath) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.contentResolver
.openFileDescriptor(item.uri, "r")
?.fileDescriptor?.let {
Typeface.Builder(it).build()
}
} else {
Typeface.createFromFile(RealPathUtil.getPath(context, item.uri))
}
} else {
Typeface.createFromFile(item.uri.toString())
}
tv_font.typeface = typeface
} catch (e: Exception) {
context.toast("读取${item.name}字体失败")
e.printStackTrace()
context.toast("Read ${item.name} Error: ${e.localizedMessage}")
}
tv_font.text = item.name
this.onClick { callBack.onClick(item) }
@ -42,7 +58,7 @@ class FontAdapter(context: Context, val callBack: CallBack) :
}
interface CallBack {
fun onClick(file: File)
fun onClick(docItem: DocItem)
val curFilePath: String
}
}

@ -26,11 +26,11 @@ import io.legado.app.ui.filechooser.FileChooserDialog
import io.legado.app.ui.filechooser.FilePicker
import io.legado.app.utils.*
import kotlinx.android.synthetic.main.dialog_font_select.*
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.util.*
class FontSelectDialog : BaseDialogFragment(),
FileChooserDialog.CallBack,
@ -40,9 +40,6 @@ class FontSelectDialog : BaseDialogFragment(),
private val fontFolder by lazy {
FileUtils.createFolderIfNotExist(App.INSTANCE.filesDir, "Fonts")
}
private val fontCacheFolder by lazy {
FileUtils.createFolderIfNotExist(App.INSTANCE.cacheDir, "Fonts")
}
private var adapter: FontAdapter? = null
override fun onStart() {
@ -90,7 +87,9 @@ class FontSelectDialog : BaseDialogFragment(),
R.id.menu_default -> {
val requireContext = requireContext()
requireContext.alert(titleResource = R.string.system_typeface) {
items(requireContext.resources.getStringArray(R.array.system_typefaces).toList()) { _, i ->
items(
requireContext.resources.getStringArray(R.array.system_typefaces).toList()
) { _, i ->
AppConfig.systemTypefaces = i
onDefaultFontChange()
dismiss()
@ -117,40 +116,16 @@ class FontSelectDialog : BaseDialogFragment(),
@SuppressLint("DefaultLocale")
private fun getFontFiles(doc: DocumentFile) {
execute {
val fontItems = arrayListOf<DocItem>()
val docItems = DocumentUtils.listFiles(App.INSTANCE, doc.uri)
fontCacheFolder.listFiles()?.forEach { fontFile ->
var contain = false
for (item in docItems) {
if (fontFile.name == item.name) {
contain = true
break
}
}
if (!contain) {
fontFile.delete()
}
}
docItems.forEach { item ->
if (item.name.toLowerCase().matches(".*\\.[ot]tf".toRegex())) {
val fontFile = FileUtils.getFile(fontCacheFolder, item.name)
if (!fontFile.exists()) {
DocumentUtils.readBytes(App.INSTANCE, item.uri)?.let { byteArray ->
fontFile.writeBytes(byteArray)
}
}
}
}
try {
fontCacheFolder.listFiles { pathName ->
pathName.name.toLowerCase().matches(".*\\.[ot]tf".toRegex())
}?.let {
withContext(Main) {
adapter?.setItems(it.toList())
}
fontItems.add(item)
}
} catch (e: Exception) {
toast(e.localizedMessage ?: "")
}
fontItems
}.onSuccess {
adapter?.setItems(it)
}.onError {
toast("getFontFiles:${it.localizedMessage}")
}
@ -163,12 +138,22 @@ class FontSelectDialog : BaseDialogFragment(),
.rationale(R.string.tip_perm_request_storage)
.onGranted {
try {
val fontItems = arrayListOf<DocItem>()
val file = File(path)
file.listFiles { pathName ->
pathName.name.toLowerCase().matches(".*\\.[ot]tf".toRegex())
}?.let {
adapter?.setItems(it.toList())
}?.forEach {
fontItems.add(
DocItem(
it.name,
it.extension,
it.length(),
Date(it.lastModified()),
Uri.parse(it.absolutePath)
)
)
}
adapter?.setItems(fontItems)
} catch (e: Exception) {
toast(e.localizedMessage ?: "")
}
@ -176,16 +161,32 @@ class FontSelectDialog : BaseDialogFragment(),
.request()
}
override fun onClick(file: File) {
launch(IO) {
file.copyTo(FileUtils.createFileIfNotExist(fontFolder, file.name), true)
.absolutePath.let { path ->
if (curFilePath != path) {
withContext(Main) {
callBack?.selectFile(path)
override fun onClick(docItem: DocItem) {
execute {
fontFolder.listFiles()?.forEach {
it.delete()
}
if (docItem.isContentPath) {
val file = FileUtils.createFileIfNotExist(fontFolder, docItem.name)
@Suppress("BlockingMethodInNonBlockingContext")
requireActivity().contentResolver.openInputStream(docItem.uri)?.use { input ->
file.outputStream().use { output ->
input.copyTo(output)
}
}
callBack?.selectFile(file.path)
} else {
val file = File(docItem.uri.toString())
file.copyTo(FileUtils.createFileIfNotExist(fontFolder, file.name), true)
.absolutePath.let { path ->
if (curFilePath != path) {
withContext(Main) {
callBack?.selectFile(path)
}
}
}
}
}.onSuccess {
dialog?.dismiss()
}
}

@ -165,7 +165,7 @@ class CoverImageView : androidx.appcompat.widget.AppCompatImageView {
companion object {
private var showBookName = false
private lateinit var defaultDrawable: Drawable
lateinit var defaultDrawable: Drawable
init {
upDefaultCover()

@ -138,6 +138,8 @@ data class DocItem(
val isDir: Boolean by lazy {
DocumentsContract.Document.MIME_TYPE_DIR == attr
}
val isContentPath get() = uri.toString().isContentPath()
}
@Throws(Exception::class)

@ -1,7 +1,8 @@
package io.legado.app.utils
val removeHtmlRegex =
"</?(?:html|head|div|a|p|b|br|hr|h\\d|article|dd|dl|span|link|title)[^>]*>".toRegex()
val removeHtmlRegex = "</?(?:div|p|br|hr|h\\d|article|dd|dl)[^>]*>".toRegex()
val imgRegex = "<img[^>]*>".toRegex()
val notImgHtmlRegex = "^\\s*|</?(?!img)\\w+[^>]*>".toRegex()
fun String?.safeTrim() = if (this.isNullOrBlank()) null else this.trim()
@ -37,7 +38,10 @@ fun String?.isJsonArray(): Boolean =
fun String?.htmlFormat(): String {
this ?: return ""
return this.replace(removeHtmlRegex, "\n")
return this
.replace(imgRegex, "\n$0\n")
.replace(removeHtmlRegex, "\n")
.replace(notImgHtmlRegex, "")
.replace("\\s*\\n+\\s*".toRegex(), "\n  ")
.replace("^[\\n\\s]+".toRegex(), "  ")
.replace("[\\n\\s]+$".toRegex(), "")

@ -721,4 +721,6 @@
<string name="contributors_summary">gedoor,Invinciblelee等,详情请在github中查看</string>
<string name="clear_cache_summary">清除已下载书籍和字体缓存</string>
<string name="default_cover">默认封面</string>
<string name="restore_ignore">恢复忽略列表</string>
<string name="restore_ignore_summary">恢复时忽略一些内容不恢复,方便不同手机配置不同</string>
</resources>

@ -721,5 +721,7 @@
<string name="contributors_summary">gedoor,Invinciblelee等,详情请在github中查看</string>
<string name="clear_cache_summary">清除已下载书籍和字体缓存</string>
<string name="default_cover">默认封面</string>
<string name="restore_ignore">恢复忽略列表</string>
<string name="restore_ignore_summary">恢复时忽略一些内容不恢复,方便不同手机配置不同</string>
</resources>

@ -721,4 +721,6 @@
<string name="contributors_summary">gedoor,Invinciblelee等,详情请在github中查看</string>
<string name="clear_cache_summary">清除已下载书籍和字体缓存</string>
<string name="default_cover">默认封面</string>
<string name="restore_ignore">恢复忽略列表</string>
<string name="restore_ignore_summary">恢复时忽略一些内容不恢复,方便不同手机配置不同</string>
</resources>

@ -722,5 +722,7 @@
<string name="contributors_summary">gedoor,Invinciblelee etc. Checking in github for details</string>
<string name="clear_cache_summary">Clear the cache of the downloaded books and fonts</string>
<string name="default_cover">Default cover</string>
<string name="restore_ignore">恢复忽略列表</string>
<string name="restore_ignore_summary">恢复时忽略一些内容不恢复,方便不同手机配置不同</string>
</resources>

@ -39,6 +39,7 @@
</io.legado.app.ui.widget.prefs.PreferenceCategory>
<io.legado.app.ui.widget.prefs.PreferenceCategory
android:title="@string/backup_restore"
app:allowDividerBelow="false"
app:iconSpaceReserved="false"
app:layout="@layout/view_preference_category">
@ -61,6 +62,12 @@
android:summary="@string/restore_summary"
app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.Preference
android:key="restoreIgnore"
android:title="@string/restore_ignore"
android:summary="@string/restore_ignore_summary"
app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.Preference
android:key="import_old"
android:title="@string/menu_import_old_version"

Loading…
Cancel
Save