优化
This commit is contained in:
@@ -20,12 +20,17 @@ import io.legado.app.lib.dialogs.alert
|
|||||||
import io.legado.app.lib.theme.primaryTextColor
|
import io.legado.app.lib.theme.primaryTextColor
|
||||||
import io.legado.app.ui.book.read.ReadBookActivity
|
import io.legado.app.ui.book.read.ReadBookActivity
|
||||||
import io.legado.app.ui.book.search.SearchActivity
|
import io.legado.app.ui.book.search.SearchActivity
|
||||||
import io.legado.app.utils.*
|
import io.legado.app.utils.applyTint
|
||||||
|
import io.legado.app.utils.cnCompare
|
||||||
|
import io.legado.app.utils.getInt
|
||||||
|
import io.legado.app.utils.putInt
|
||||||
|
import io.legado.app.utils.startActivity
|
||||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
class ReadRecordActivity : BaseActivity<ActivityReadRecordBinding>() {
|
class ReadRecordActivity : BaseActivity<ActivityReadRecordBinding>() {
|
||||||
|
|
||||||
@@ -149,7 +154,7 @@ class ReadRecordActivity : BaseActivity<ActivityReadRecordBinding>() {
|
|||||||
inner class RecordAdapter(context: Context) :
|
inner class RecordAdapter(context: Context) :
|
||||||
RecyclerAdapter<ReadRecordShow, ItemReadRecordBinding>(context) {
|
RecyclerAdapter<ReadRecordShow, ItemReadRecordBinding>(context) {
|
||||||
|
|
||||||
private val dateFormat = SimpleDateFormat("yyyy-MM-dd")
|
private val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
|
||||||
|
|
||||||
override fun getViewBinding(parent: ViewGroup): ItemReadRecordBinding {
|
override fun getViewBinding(parent: ViewGroup): ItemReadRecordBinding {
|
||||||
return ItemReadRecordBinding.inflate(inflater, parent, false)
|
return ItemReadRecordBinding.inflate(inflater, parent, false)
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package io.legado.app.ui.book.bookmark
|
package io.legado.app.ui.book.bookmark
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.documentfile.provider.DocumentFile
|
import androidx.documentfile.provider.DocumentFile
|
||||||
import io.legado.app.base.BaseViewModel
|
import io.legado.app.base.BaseViewModel
|
||||||
|
import io.legado.app.constant.AppLog
|
||||||
import io.legado.app.data.appDb
|
import io.legado.app.data.appDb
|
||||||
import io.legado.app.utils.*
|
import io.legado.app.utils.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -16,25 +16,32 @@ class AllBookmarkViewModel(application: Application) : BaseViewModel(application
|
|||||||
|
|
||||||
|
|
||||||
@Suppress("BlockingMethodInNonBlockingContext")
|
@Suppress("BlockingMethodInNonBlockingContext")
|
||||||
@SuppressLint("SimpleDateFormat")
|
|
||||||
fun saveToFile(treeUri: Uri) {
|
fun saveToFile(treeUri: Uri) {
|
||||||
execute {
|
execute {
|
||||||
val dateFormat = SimpleDateFormat("yyMMddHHmmss")
|
val dateFormat = SimpleDateFormat("yyMMddHHmmss", Locale.getDefault())
|
||||||
|
val bookmark = appDb.bookmarkDao.all
|
||||||
if (treeUri.isContentScheme()) {
|
if (treeUri.isContentScheme()) {
|
||||||
val doc = DocumentFile.fromTreeUri(context, treeUri)
|
val doc = DocumentFile.fromTreeUri(context, treeUri)
|
||||||
?.createFile("", "bookmark-${dateFormat.format(Date())}")
|
?.createFile("", "bookmark-${dateFormat.format(Date())}")
|
||||||
doc?.let {
|
doc?.let {
|
||||||
context.contentResolver.openOutputStream(doc.uri)!!.use {
|
context.contentResolver.openOutputStream(doc.uri)!!.use {
|
||||||
GSON.writeToOutputStream(it, appDb.bookmarkDao.all)
|
GSON.writeToOutputStream(it, bookmark)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val path = treeUri.path!!
|
val path = treeUri.path!!
|
||||||
val file = FileUtils.createFileIfNotExist(File(path), "bookmark-${dateFormat.format(Date())}")
|
val file = FileUtils.createFileIfNotExist(
|
||||||
|
File(path),
|
||||||
|
"bookmark-${dateFormat.format(Date())}"
|
||||||
|
)
|
||||||
FileOutputStream(file).use {
|
FileOutputStream(file).use {
|
||||||
GSON.writeToOutputStream(it, appDb.bookmarkDao.all)
|
GSON.writeToOutputStream(it, bookmark)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}.onError {
|
||||||
|
AppLog.put("导出失败\n${it.localizedMessage}", it, true)
|
||||||
|
}.onSuccess {
|
||||||
|
context.toastOnUi("导出成功")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import io.legado.app.lib.theme.primaryTextColor
|
|||||||
import io.legado.app.model.ReadBook
|
import io.legado.app.model.ReadBook
|
||||||
import io.legado.app.ui.about.AppLogDialog
|
import io.legado.app.ui.about.AppLogDialog
|
||||||
import io.legado.app.ui.book.toc.rule.TxtTocRuleDialog
|
import io.legado.app.ui.book.toc.rule.TxtTocRuleDialog
|
||||||
|
import io.legado.app.ui.file.HandleFileContract
|
||||||
import io.legado.app.ui.widget.dialog.WaitDialog
|
import io.legado.app.ui.widget.dialog.WaitDialog
|
||||||
import io.legado.app.utils.*
|
import io.legado.app.utils.*
|
||||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||||
@@ -41,6 +42,11 @@ class TocActivity : VMBaseActivity<ActivityChapterListBinding, TocViewModel>(),
|
|||||||
private var menu: Menu? = null
|
private var menu: Menu? = null
|
||||||
private var searchView: SearchView? = null
|
private var searchView: SearchView? = null
|
||||||
private val waitDialog by lazy { WaitDialog(this) }
|
private val waitDialog by lazy { WaitDialog(this) }
|
||||||
|
private val exportDir = registerForActivityResult(HandleFileContract()) {
|
||||||
|
it.uri?.let { uri ->
|
||||||
|
viewModel.saveBookmark(uri)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
tabLayout = binding.titleBar.findViewById(R.id.tab_layout)
|
tabLayout = binding.titleBar.findViewById(R.id.tab_layout)
|
||||||
@@ -71,9 +77,6 @@ class TocActivity : VMBaseActivity<ActivityChapterListBinding, TocViewModel>(),
|
|||||||
override fun onCompatCreateOptionsMenu(menu: Menu): Boolean {
|
override fun onCompatCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
menuInflater.inflate(R.menu.book_toc, menu)
|
menuInflater.inflate(R.menu.book_toc, menu)
|
||||||
this.menu = menu
|
this.menu = menu
|
||||||
viewModel.bookData.value?.let {
|
|
||||||
menu.setGroupVisible(R.id.menu_group_text, it.isLocalTxt)
|
|
||||||
}
|
|
||||||
val search = menu.findItem(R.id.menu_search)
|
val search = menu.findItem(R.id.menu_search)
|
||||||
searchView = (search.actionView as SearchView).apply {
|
searchView = (search.actionView as SearchView).apply {
|
||||||
applyTint(primaryTextColor)
|
applyTint(primaryTextColor)
|
||||||
@@ -110,6 +113,15 @@ class TocActivity : VMBaseActivity<ActivityChapterListBinding, TocViewModel>(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onMenuOpened(featureId: Int, menu: Menu): Boolean {
|
override fun onMenuOpened(featureId: Int, menu: Menu): Boolean {
|
||||||
|
if (tabLayout.selectedTabPosition == 1) {
|
||||||
|
menu.setGroupVisible(R.id.menu_group_bookmark, true)
|
||||||
|
menu.setGroupVisible(R.id.menu_group_toc, false)
|
||||||
|
menu.setGroupVisible(R.id.menu_group_text, false)
|
||||||
|
} else {
|
||||||
|
menu.setGroupVisible(R.id.menu_group_bookmark, false)
|
||||||
|
menu.setGroupVisible(R.id.menu_group_toc, true)
|
||||||
|
menu.setGroupVisible(R.id.menu_group_text, viewModel.bookData.value?.isLocalTxt == true)
|
||||||
|
}
|
||||||
menu.findItem(R.id.menu_use_replace)?.isChecked =
|
menu.findItem(R.id.menu_use_replace)?.isChecked =
|
||||||
AppConfig.tocUiUseReplace
|
AppConfig.tocUiUseReplace
|
||||||
menu.findItem(R.id.menu_split_long_chapter)?.isChecked =
|
menu.findItem(R.id.menu_split_long_chapter)?.isChecked =
|
||||||
@@ -122,6 +134,7 @@ class TocActivity : VMBaseActivity<ActivityChapterListBinding, TocViewModel>(),
|
|||||||
R.id.menu_toc_regex -> showDialogFragment(
|
R.id.menu_toc_regex -> showDialogFragment(
|
||||||
TxtTocRuleDialog(viewModel.bookData.value?.tocUrl)
|
TxtTocRuleDialog(viewModel.bookData.value?.tocUrl)
|
||||||
)
|
)
|
||||||
|
|
||||||
R.id.menu_split_long_chapter -> {
|
R.id.menu_split_long_chapter -> {
|
||||||
viewModel.bookData.value?.let { book ->
|
viewModel.bookData.value?.let { book ->
|
||||||
item.isChecked = !item.isChecked
|
item.isChecked = !item.isChecked
|
||||||
@@ -129,6 +142,7 @@ class TocActivity : VMBaseActivity<ActivityChapterListBinding, TocViewModel>(),
|
|||||||
upBookAndToc(book)
|
upBookAndToc(book)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.menu_reverse_toc -> viewModel.reverseToc {
|
R.id.menu_reverse_toc -> viewModel.reverseToc {
|
||||||
viewModel.chapterListCallBack?.upChapterList(searchView?.query?.toString())
|
viewModel.chapterListCallBack?.upChapterList(searchView?.query?.toString())
|
||||||
setResult(RESULT_OK, Intent().apply {
|
setResult(RESULT_OK, Intent().apply {
|
||||||
@@ -136,11 +150,15 @@ class TocActivity : VMBaseActivity<ActivityChapterListBinding, TocViewModel>(),
|
|||||||
putExtra("chapterPos", 0)
|
putExtra("chapterPos", 0)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.menu_use_replace -> {
|
R.id.menu_use_replace -> {
|
||||||
AppConfig.tocUiUseReplace = !item.isChecked
|
AppConfig.tocUiUseReplace = !item.isChecked
|
||||||
viewModel.chapterListCallBack?.clearDisplayTitle()
|
viewModel.chapterListCallBack?.clearDisplayTitle()
|
||||||
viewModel.chapterListCallBack?.upChapterList(searchView?.query?.toString())
|
viewModel.chapterListCallBack?.upChapterList(searchView?.query?.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
R.id.menu_export -> exportDir.launch()
|
||||||
|
|
||||||
R.id.menu_log -> showDialogFragment<AppLogDialog>()
|
R.id.menu_log -> showDialogFragment<AppLogDialog>()
|
||||||
}
|
}
|
||||||
return super.onCompatOptionsItemSelected(item)
|
return super.onCompatOptionsItemSelected(item)
|
||||||
|
|||||||
@@ -2,11 +2,26 @@ package io.legado.app.ui.book.toc
|
|||||||
|
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import android.net.Uri
|
||||||
|
import androidx.documentfile.provider.DocumentFile
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import io.legado.app.R
|
||||||
import io.legado.app.base.BaseViewModel
|
import io.legado.app.base.BaseViewModel
|
||||||
|
import io.legado.app.constant.AppLog
|
||||||
import io.legado.app.data.appDb
|
import io.legado.app.data.appDb
|
||||||
import io.legado.app.data.entities.Book
|
import io.legado.app.data.entities.Book
|
||||||
|
import io.legado.app.exception.NoStackTraceException
|
||||||
import io.legado.app.model.localBook.LocalBook
|
import io.legado.app.model.localBook.LocalBook
|
||||||
|
import io.legado.app.utils.FileUtils
|
||||||
|
import io.legado.app.utils.GSON
|
||||||
|
import io.legado.app.utils.isContentScheme
|
||||||
|
import io.legado.app.utils.toastOnUi
|
||||||
|
import io.legado.app.utils.writeToOutputStream
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileOutputStream
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Date
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
class TocViewModel(application: Application) : BaseViewModel(application) {
|
class TocViewModel(application: Application) : BaseViewModel(application) {
|
||||||
var bookUrl: String = ""
|
var bookUrl: String = ""
|
||||||
@@ -63,6 +78,41 @@ class TocViewModel(application: Application) : BaseViewModel(application) {
|
|||||||
bookMarkCallBack?.upBookmark(newText)
|
bookMarkCallBack?.upBookmark(newText)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("BlockingMethodInNonBlockingContext")
|
||||||
|
fun saveBookmark(treeUri: Uri) {
|
||||||
|
execute {
|
||||||
|
val book = bookData.value
|
||||||
|
?: throw NoStackTraceException(context.getString(R.string.no_book))
|
||||||
|
val dateFormat = SimpleDateFormat("yyMMddHHmmss", Locale.getDefault())
|
||||||
|
val bookmark = appDb.bookmarkDao.getByBook(book.name, book.author)
|
||||||
|
if (treeUri.isContentScheme()) {
|
||||||
|
val doc = DocumentFile.fromTreeUri(context, treeUri)
|
||||||
|
?.createFile("", "bookmark-${dateFormat.format(Date())}")
|
||||||
|
doc?.let {
|
||||||
|
context.contentResolver.openOutputStream(doc.uri)!!.use {
|
||||||
|
GSON.writeToOutputStream(it, bookmark)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val path = treeUri.path!!
|
||||||
|
val file = FileUtils.createFileIfNotExist(
|
||||||
|
File(path), "bookmark-${
|
||||||
|
dateFormat.format(
|
||||||
|
Date()
|
||||||
|
)
|
||||||
|
}"
|
||||||
|
)
|
||||||
|
FileOutputStream(file).use {
|
||||||
|
GSON.writeToOutputStream(it, bookmark)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.onError {
|
||||||
|
AppLog.put("导出失败\n${it.localizedMessage}", it, true)
|
||||||
|
}.onSuccess {
|
||||||
|
context.toastOnUi("导出成功")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
interface ChapterListCallBack {
|
interface ChapterListCallBack {
|
||||||
fun upChapterList(searchKey: String?)
|
fun upChapterList(searchKey: String?)
|
||||||
|
|
||||||
|
|||||||
@@ -50,8 +50,7 @@ object StringUtils {
|
|||||||
* 将日期转换成昨天、今天、明天
|
* 将日期转换成昨天、今天、明天
|
||||||
*/
|
*/
|
||||||
fun dateConvert(source: String, pattern: String): String {
|
fun dateConvert(source: String, pattern: String): String {
|
||||||
@SuppressLint("SimpleDateFormat")
|
val format = SimpleDateFormat(pattern, Locale.getDefault())
|
||||||
val format = SimpleDateFormat(pattern)
|
|
||||||
val calendar = Calendar.getInstance()
|
val calendar = Calendar.getInstance()
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
val date = format.parse(source) ?: return ""
|
val date = format.parse(source) ?: return ""
|
||||||
|
|||||||
@@ -21,22 +21,39 @@
|
|||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/menu_split_long_chapter"
|
android:id="@+id/menu_split_long_chapter"
|
||||||
android:title="@string/split_long_chapter"
|
|
||||||
android:checkable="true"
|
android:checkable="true"
|
||||||
|
android:title="@string/split_long_chapter"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
|
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<item
|
<group
|
||||||
android:id="@+id/menu_reverse_toc"
|
android:id="@+id/menu_group_toc"
|
||||||
android:title="@string/reverse_toc"
|
android:visible="true">
|
||||||
app:showAsAction="never" />
|
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/menu_use_replace"
|
android:id="@+id/menu_reverse_toc"
|
||||||
android:checkable="true"
|
android:title="@string/reverse_toc"
|
||||||
android:title="@string/use_replace"
|
app:showAsAction="never" />
|
||||||
app:showAsAction="never" />
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_use_replace"
|
||||||
|
android:checkable="true"
|
||||||
|
android:title="@string/use_replace"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
|
||||||
|
</group>
|
||||||
|
|
||||||
|
<group
|
||||||
|
android:id="@+id/menu_group_bookmark"
|
||||||
|
android:visible="false">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_export_bookmark"
|
||||||
|
android:title="@string/export"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
|
||||||
|
</group>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/menu_log"
|
android:id="@+id/menu_log"
|
||||||
|
|||||||
Reference in New Issue
Block a user