pull/1415/head
gedoor 3 years ago
parent 4ad07aefc3
commit 39bc7e29d0
  1. 38
      app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt
  2. 17
      app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt
  3. 21
      app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt
  4. 33
      app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt
  5. 13
      app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt
  6. 42
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt
  7. 7
      app/src/main/java/io/legado/app/ui/browser/WebViewActivity.kt
  8. 71
      app/src/main/java/io/legado/app/ui/config/BackupConfigFragment.kt
  9. 27
      app/src/main/java/io/legado/app/ui/document/HandleFileContract.kt
  10. 10
      app/src/main/java/io/legado/app/ui/main/bookshelf/BaseBookshelfFragment.kt
  11. 33
      app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt
  12. 7
      app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt
  13. 33
      app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt
  14. 37
      app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt

@ -46,19 +46,19 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
private val adapter by lazy { CacheAdapter(this, this) }
private var booksFlowJob: Job? = null
private var menu: Menu? = null
private var exportPosition = -1
private val groupList: ArrayList<BookGroup> = arrayListOf()
private var groupId: Long = -1
private val exportDir = registerForActivityResult(HandleFileContract()) { uri ->
uri ?: return@registerForActivityResult
if (uri.isContentScheme()) {
ACache.get(this@CacheActivity).put(exportBookPathKey, uri.toString())
startExport(uri.toString())
} else {
uri.path?.let { path ->
ACache.get(this@CacheActivity).put(exportBookPathKey, path)
startExport(path)
private val exportDir = registerForActivityResult(HandleFileContract()) { result ->
result.uri?.let { uri ->
if (uri.isContentScheme()) {
ACache.get(this@CacheActivity).put(exportBookPathKey, uri.toString())
startExport(uri.toString(), result.requestCode)
} else {
uri.path?.let { path ->
ACache.get(this@CacheActivity).put(exportBookPathKey, path)
startExport(path, result.requestCode)
}
}
}
}
@ -128,8 +128,7 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
R.id.menu_export_no_chapter_name -> AppConfig.exportNoChapterName = !item.isChecked
R.id.menu_export_web_dav -> AppConfig.exportToWebDav = !item.isChecked
R.id.menu_export_folder -> {
exportPosition = -1
selectExportFolder()
selectExportFolder(-1)
}
R.id.menu_export_file_name -> alertExportFileName()
R.id.menu_export_type -> showExportTypeConfig()
@ -236,26 +235,24 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
}
override fun export(position: Int) {
exportPosition = position
val path = ACache.get(this@CacheActivity).getAsString(exportBookPathKey)
if (path.isNullOrEmpty()) {
selectExportFolder()
selectExportFolder(position)
} else {
startExport(path)
startExport(path, position)
}
}
private fun exportAll() {
exportPosition = -10
val path = ACache.get(this@CacheActivity).getAsString(exportBookPathKey)
if (path.isNullOrEmpty()) {
selectExportFolder()
selectExportFolder(-10)
} else {
startExport(path)
startExport(path, -10)
}
}
private fun selectExportFolder() {
private fun selectExportFolder(exportPosition: Int) {
val default = arrayListOf<SelectItem<Int>>()
val path = ACache.get(this@CacheActivity).getAsString(exportBookPathKey)
if (!path.isNullOrEmpty()) {
@ -263,10 +260,11 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
}
exportDir.launch {
otherActions = default
requestCode = exportPosition
}
}
private fun startExport(path: String) {
private fun startExport(path: String, exportPosition: Int) {
if (exportPosition == -10) {
if (adapter.getItems().isNotEmpty()) {
adapter.getItems().forEach { book ->

@ -49,15 +49,16 @@ class ImportBookActivity : VMBaseActivity<ActivityImportBookBinding, ImportBookV
private val adapter by lazy { ImportBookAdapter(this, this) }
private var sdPath = FileUtils.getSdCardPath()
private var path = sdPath
private val selectFolder = registerForActivityResult(HandleFileContract()) { uri ->
uri ?: return@registerForActivityResult
if (uri.isContentScheme()) {
AppConfig.importBookPath = uri.toString()
initRootDoc()
} else {
uri.path?.let { path ->
AppConfig.importBookPath = path
private val selectFolder = registerForActivityResult(HandleFileContract()) {
it.uri?.let { uri ->
if (uri.isContentScheme()) {
AppConfig.importBookPath = uri.toString()
initRootDoc()
} else {
uri.path?.let { path ->
AppConfig.importBookPath = path
initRootDoc()
}
}
}
}

@ -5,7 +5,10 @@ import android.content.DialogInterface
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.view.*
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import androidx.documentfile.provider.DocumentFile
import com.jaredrummler.android.colorpicker.ColorPickerDialog
import io.legado.app.R
@ -50,15 +53,17 @@ class BgTextConfigDialog : BaseDialogFragment(R.layout.dialog_read_bg_text) {
}
}
private val selectExportDir = registerForActivityResult(HandleFileContract()) {
it ?: return@registerForActivityResult
exportConfig(it)
it.uri?.let { uri ->
exportConfig(uri)
}
}
private val selectImportDoc = registerForActivityResult(HandleFileContract()) {
it ?: return@registerForActivityResult
if (it.toString() == importFormNet) {
importNetConfigAlert()
} else {
importConfig(it)
it.uri?.let { uri ->
if (uri.toString() == importFormNet) {
importNetConfigAlert()
} else {
importConfig(uri)
}
}
}

@ -39,25 +39,26 @@ class SpeakEngineDialog : BaseDialogFragment(R.layout.dialog_recycler_view),
private val adapter by lazy { Adapter(requireContext()) }
private var ttsEngine: String? = AppConfig.ttsEngine
private val importDocResult = registerForActivityResult(HandleFileContract()) {
it?.let {
viewModel.importLocal(it)
it.uri?.let { uri ->
viewModel.importLocal(uri)
}
}
private val exportDirResult = registerForActivityResult(HandleFileContract()) { uri ->
uri ?: return@registerForActivityResult
alert(R.string.export_success) {
if (uri.toString().isAbsUrl()) {
DirectLinkUpload.getSummary()?.let { summary ->
setMessage(summary)
private val exportDirResult = registerForActivityResult(HandleFileContract()) {
it.uri?.let { uri ->
alert(R.string.export_success) {
if (uri.toString().isAbsUrl()) {
DirectLinkUpload.getSummary()?.let { summary ->
setMessage(summary)
}
}
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.hint = getString(R.string.path)
editView.setText(uri.toString())
}
customView { alertBinding.root }
okButton {
requireContext().sendToClip(uri.toString())
}
}
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.hint = getString(R.string.path)
editView.setText(uri.toString())
}
customView { alertBinding.root }
okButton {
requireContext().sendToClip(uri.toString())
}
}
}

@ -54,12 +54,13 @@ class BookSourceEditActivity :
upRecyclerView(source)
}
}
private val selectDoc = registerForActivityResult(HandleFileContract()) { uri ->
uri ?: return@registerForActivityResult
if (uri.isContentScheme()) {
sendText(uri.toString())
} else {
sendText(uri.path.toString())
private val selectDoc = registerForActivityResult(HandleFileContract()) {
it.uri?.let { uri ->
if (uri.isContentScheme()) {
sendText(uri.toString())
} else {
sendText(uri.path.toString())
}
}
}

@ -64,29 +64,31 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
it ?: return@registerForActivityResult
showDialogFragment(ImportBookSourceDialog(it))
}
private val importDoc = registerForActivityResult(HandleFileContract()) { uri ->
uri ?: return@registerForActivityResult
try {
showDialogFragment(ImportBookSourceDialog(uri.readText(this)))
} catch (e: Exception) {
toastOnUi("readTextError:${e.localizedMessage}")
private val importDoc = registerForActivityResult(HandleFileContract()) {
it.uri?.let { uri ->
try {
showDialogFragment(ImportBookSourceDialog(uri.readText(this)))
} catch (e: Exception) {
toastOnUi("readTextError:${e.localizedMessage}")
}
}
}
private val exportDir = registerForActivityResult(HandleFileContract()) { uri ->
uri ?: return@registerForActivityResult
alert(R.string.export_success) {
if (uri.toString().isAbsUrl()) {
DirectLinkUpload.getSummary()?.let { summary ->
setMessage(summary)
private val exportDir = registerForActivityResult(HandleFileContract()) {
it.uri?.let { uri ->
alert(R.string.export_success) {
if (uri.toString().isAbsUrl()) {
DirectLinkUpload.getSummary()?.let { summary ->
setMessage(summary)
}
}
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.hint = getString(R.string.path)
editView.setText(uri.toString())
}
customView { alertBinding.root }
okButton {
sendToClip(uri.toString())
}
}
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.hint = getString(R.string.path)
editView.setText(uri.toString())
}
customView { alertBinding.root }
okButton {
sendToClip(uri.toString())
}
}
}

@ -33,9 +33,10 @@ class WebViewActivity : VMBaseActivity<ActivityWebViewBinding, WebViewModel>() {
private var customWebViewCallback: WebChromeClient.CustomViewCallback? = null
private var webPic: String? = null
private val saveImage = registerForActivityResult(HandleFileContract()) {
it ?: return@registerForActivityResult
ACache.get(this).put(imagePathKey, it.toString())
viewModel.saveImage(webPic, it.toString())
it.uri?.let { uri ->
ACache.get(this).put(imagePathKey, uri.toString())
viewModel.saveImage(webPic, uri.toString())
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {

@ -38,56 +38,59 @@ import splitties.init.appCtx
class BackupConfigFragment : BasePreferenceFragment(),
SharedPreferences.OnSharedPreferenceChangeListener {
private val selectBackupPath = registerForActivityResult(HandleFileContract()) { uri ->
uri ?: return@registerForActivityResult
if (uri.isContentScheme()) {
AppConfig.backupPath = uri.toString()
} else {
AppConfig.backupPath = uri.path
private val selectBackupPath = registerForActivityResult(HandleFileContract()) {
it.uri?.let { uri ->
if (uri.isContentScheme()) {
AppConfig.backupPath = uri.toString()
} else {
AppConfig.backupPath = uri.path
}
}
}
private val backupDir = registerForActivityResult(HandleFileContract()) { uri ->
uri ?: return@registerForActivityResult
if (uri.isContentScheme()) {
AppConfig.backupPath = uri.toString()
Coroutine.async {
Backup.backup(appCtx, uri.toString())
}.onSuccess {
appCtx.toastOnUi(R.string.backup_success)
}.onError {
appCtx.toastOnUi(R.string.backup_fail)
}
} else {
uri.path?.let { path ->
AppConfig.backupPath = path
private val backupDir = registerForActivityResult(HandleFileContract()) {
it.uri?.let { uri ->
if (uri.isContentScheme()) {
AppConfig.backupPath = uri.toString()
Coroutine.async {
Backup.backup(appCtx, path)
Backup.backup(appCtx, uri.toString())
}.onSuccess {
appCtx.toastOnUi(R.string.backup_success)
}.onError {
appCtx.toastOnUi(R.string.backup_fail)
}
} else {
uri.path?.let { path ->
AppConfig.backupPath = path
Coroutine.async {
Backup.backup(appCtx, path)
}.onSuccess {
appCtx.toastOnUi(R.string.backup_success)
}.onError {
appCtx.toastOnUi(R.string.backup_fail)
}
}
}
}
}
private val restoreDir = registerForActivityResult(HandleFileContract()) { uri ->
uri ?: return@registerForActivityResult
if (uri.isContentScheme()) {
AppConfig.backupPath = uri.toString()
Coroutine.async {
Restore.restore(appCtx, uri.toString())
}
} else {
uri.path?.let { path ->
AppConfig.backupPath = path
private val restoreDir = registerForActivityResult(HandleFileContract()) {
it.uri?.let { uri ->
if (uri.isContentScheme()) {
AppConfig.backupPath = uri.toString()
Coroutine.async {
Restore.restore(appCtx, path)
Restore.restore(appCtx, uri.toString())
}
} else {
uri.path?.let { path ->
AppConfig.backupPath = path
Coroutine.async {
Restore.restore(appCtx, path)
}
}
}
}
}
private val restoreOld = registerForActivityResult(HandleFileContract()) { uri ->
uri?.let {
private val restoreOld = registerForActivityResult(HandleFileContract()) {
it.uri?.let { uri ->
ImportOldData.importUri(appCtx, uri)
}
}

@ -11,13 +11,9 @@ import io.legado.app.utils.putJson
@Suppress("unused")
class HandleFileContract :
ActivityResultContract<HandleFileContract.HandleFileParam.() -> Unit, Uri?>() {
ActivityResultContract<HandleFileContract.HandleFileParam.() -> Unit, HandleFileContract.Result>() {
companion object {
const val DIR = 0
const val FILE = 1
const val EXPORT = 3
}
private var requestCode: Int = 0
override fun createIntent(context: Context, input: (HandleFileParam.() -> Unit)?): Intent {
val intent = Intent(context, HandleFileActivity::class.java)
@ -26,6 +22,7 @@ class HandleFileContract :
handleFileParam.apply(input)
}
handleFileParam.let {
requestCode = it.requestCode
intent.putExtra("mode", it.mode)
intent.putExtra("title", it.title)
intent.putExtra("allowExtensions", it.allowExtensions)
@ -39,11 +36,17 @@ class HandleFileContract :
return intent
}
override fun parseResult(resultCode: Int, intent: Intent?): Uri? {
override fun parseResult(resultCode: Int, intent: Intent?): Result {
if (resultCode == RESULT_OK) {
return intent?.data
return Result(intent?.data, requestCode)
}
return null
return Result(null, requestCode)
}
companion object {
const val DIR = 0
const val FILE = 1
const val EXPORT = 3
}
@Suppress("ArrayInDataClass")
@ -53,6 +56,12 @@ class HandleFileContract :
var allowExtensions: Array<String> = arrayOf(),
var otherActions: ArrayList<SelectItem<Int>>? = null,
var fileData: Triple<String, ByteArray, String>? = null,
var requestCode: Int = 0
)
data class Result(
val uri: Uri?,
val requestCode: Int
)
}

@ -31,12 +31,16 @@ abstract class BaseBookshelfFragment(layoutId: Int) : VMBaseFragment<BookshelfVi
override val viewModel by viewModels<BookshelfViewModel>()
private val importBookshelf = registerForActivityResult(HandleFileContract()) {
it?.readText(requireContext())?.let { text ->
viewModel.importBookshelf(text, groupId)
kotlin.runCatching {
it.uri?.readText(requireContext())?.let { text ->
viewModel.importBookshelf(text, groupId)
}
}.onFailure {
toastOnUi(it.localizedMessage ?: "ERROR")
}
}
private val exportResult = registerForActivityResult(HandleFileContract()) {
it?.let { uri ->
it.uri?.let { uri ->
alert(R.string.export_success) {
if (uri.toString().isAbsUrl()) {
DirectLinkUpload.getSummary()?.let { summary ->

@ -71,9 +71,9 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
setResult(RESULT_OK)
}
}
private val importDoc = registerForActivityResult(HandleFileContract()) { uri ->
private val importDoc = registerForActivityResult(HandleFileContract()) {
kotlin.runCatching {
uri?.readText(this)?.let {
it.uri?.readText(this)?.let {
showDialogFragment(
ImportReplaceRuleDialog(it)
)
@ -82,21 +82,22 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
toastOnUi("readTextError:${it.localizedMessage}")
}
}
private val exportResult = registerForActivityResult(HandleFileContract()) { uri ->
uri ?: return@registerForActivityResult
alert(R.string.export_success) {
if (uri.toString().isAbsUrl()) {
DirectLinkUpload.getSummary()?.let { summary ->
setMessage(summary)
private val exportResult = registerForActivityResult(HandleFileContract()) {
it.uri?.let { uri ->
alert(R.string.export_success) {
if (uri.toString().isAbsUrl()) {
DirectLinkUpload.getSummary()?.let { summary ->
setMessage(summary)
}
}
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.hint = getString(R.string.path)
editView.setText(uri.toString())
}
customView { alertBinding.root }
okButton {
sendToClip(uri.toString())
}
}
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.hint = getString(R.string.path)
editView.setText(uri.toString())
}
customView { alertBinding.root }
okButton {
sendToClip(uri.toString())
}
}
}

@ -42,9 +42,10 @@ class ReadRssActivity : VMBaseActivity<ActivityRssReadBinding, ReadRssViewModel>
private var customWebViewCallback: WebChromeClient.CustomViewCallback? = null
private var webPic: String? = null
private val saveImage = registerForActivityResult(HandleFileContract()) {
it ?: return@registerForActivityResult
ACache.get(this).put(imagePathKey, it.toString())
viewModel.saveImage(webPic, it.toString())
it.uri?.let { uri ->
ACache.get(this).put(imagePathKey, uri.toString())
viewModel.saveImage(webPic, uri.toString())
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {

@ -57,9 +57,9 @@ class RssSourceActivity : VMBaseActivity<ActivityRssSourceBinding, RssSourceView
ImportRssSourceDialog(it)
)
}
private val importDoc = registerForActivityResult(HandleFileContract()) { uri ->
private val importDoc = registerForActivityResult(HandleFileContract()) {
kotlin.runCatching {
uri?.readText(this)?.let {
it.uri?.readText(this)?.let {
showDialogFragment(
ImportRssSourceDialog(it)
)
@ -68,21 +68,22 @@ class RssSourceActivity : VMBaseActivity<ActivityRssSourceBinding, RssSourceView
toastOnUi("readTextError:${it.localizedMessage}")
}
}
private val exportResult = registerForActivityResult(HandleFileContract()) { uri ->
uri ?: return@registerForActivityResult
alert(R.string.export_success) {
if (uri.toString().isAbsUrl()) {
DirectLinkUpload.getSummary()?.let { summary ->
setMessage(summary)
private val exportResult = registerForActivityResult(HandleFileContract()) {
it.uri?.let { uri ->
alert(R.string.export_success) {
if (uri.toString().isAbsUrl()) {
DirectLinkUpload.getSummary()?.let { summary ->
setMessage(summary)
}
}
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.hint = getString(R.string.path)
editView.setText(uri.toString())
}
customView { alertBinding.root }
okButton {
sendToClip(uri.toString())
}
}
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.hint = getString(R.string.path)
editView.setText(uri.toString())
}
customView { alertBinding.root }
okButton {
sendToClip(uri.toString())
}
}
}

@ -40,27 +40,28 @@ class FontSelectDialog : BaseDialogFragment(R.layout.dialog_font_select),
val curFontPath = callBack?.curFontPath ?: ""
FontAdapter(requireContext(), curFontPath, this)
}
private val selectFontDir = registerForActivityResult(HandleFileContract()) { uri ->
uri ?: return@registerForActivityResult
if (uri.toString().isContentScheme()) {
putPrefString(PreferKey.fontFolder, uri.toString())
val doc = DocumentFile.fromTreeUri(requireContext(), uri)
if (doc != null) {
context?.contentResolver?.takePersistableUriPermission(
uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION
)
loadFontFiles(doc)
private val selectFontDir = registerForActivityResult(HandleFileContract()) {
it.uri?.let { uri ->
if (uri.toString().isContentScheme()) {
putPrefString(PreferKey.fontFolder, uri.toString())
val doc = DocumentFile.fromTreeUri(requireContext(), uri)
if (doc != null) {
context?.contentResolver?.takePersistableUriPermission(
uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION
)
loadFontFiles(doc)
} else {
RealPathUtil.getPath(requireContext(), uri)?.let {
loadFontFilesByPermission(it)
}
}
} else {
RealPathUtil.getPath(requireContext(), uri)?.let {
loadFontFilesByPermission(it)
uri.path?.let { path ->
putPrefString(PreferKey.fontFolder, path)
loadFontFilesByPermission(path)
}
}
} else {
uri.path?.let { path ->
putPrefString(PreferKey.fontFolder, path)
loadFontFilesByPermission(path)
}
}
}

Loading…
Cancel
Save