From 37b287d3415fb4497c561b24160bdded89b9d601 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 29 Aug 2021 12:30:27 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=8A=E4=BC=A0=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E8=BD=AC=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 9 +- .../io/legado/app/data/entities/BaseSource.kt | 4 + .../java/io/legado/app/help/CacheManager.kt | 5 + .../io/legado/app/help/DirectLinkUpload.kt | 44 ++++++++ .../io/legado/app/help/http/OkHttpUtils.kt | 18 ++++ .../app/model/analyzeRule/AnalyzeRule.kt | 5 +- .../legado/app/ui/book/cache/CacheActivity.kt | 5 +- .../app/ui/book/local/ImportBookActivity.kt | 4 +- .../ui/book/read/config/BgTextConfigDialog.kt | 8 +- .../ui/book/read/config/SpeakEngineDialog.kt | 8 +- .../source/edit/BookSourceEditActivity.kt | 6 +- .../book/source/manage/BookSourceActivity.kt | 8 +- .../app/ui/config/BackupConfigFragment.kt | 10 +- .../app/ui/config/DirectLinkUploadConfig.kt | 63 +++++++++++ .../app/ui/document/FilePickerActivity.kt | 12 +-- .../app/ui/document/FilePickerDialog.kt | 4 +- .../{FilePicker.kt => HandleFileContract.kt} | 2 +- .../legado/app/ui/login/RuleUiLoginDialog.kt | 10 +- .../main/bookshelf/BaseBookshelfFragment.kt | 8 +- .../app/ui/replace/ReplaceRuleActivity.kt | 8 +- .../legado/app/ui/rss/read/ReadRssActivity.kt | 4 +- .../ui/rss/source/manage/RssSourceActivity.kt | 8 +- .../app/ui/widget/font/FontSelectDialog.kt | 4 +- .../dialog_direct_link_upload_config.xml | 101 ++++++++++++++++++ app/src/main/res/values-es-rES/strings.xml | 2 + app/src/main/res/values-ja-rJP/strings.xml | 2 + app/src/main/res/values-pt-rBR/strings.xml | 2 + app/src/main/res/values-zh-rHK/strings.xml | 2 + app/src/main/res/values-zh-rTW/strings.xml | 2 + app/src/main/res/values-zh/strings.xml | 2 + app/src/main/res/values/strings.xml | 2 + 31 files changed, 316 insertions(+), 56 deletions(-) create mode 100644 app/src/main/java/io/legado/app/help/DirectLinkUpload.kt create mode 100644 app/src/main/java/io/legado/app/ui/config/DirectLinkUploadConfig.kt rename app/src/main/java/io/legado/app/ui/document/{FilePicker.kt => HandleFileContract.kt} (93%) create mode 100644 app/src/main/res/layout/dialog_direct_link_upload_config.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2dffd3dc1..04f2f5d8d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -295,7 +295,8 @@ + android:hardwareAccelerated="true" + android:theme="@style/AppTheme.Transparent" /> + android:label="legado Web Service" + android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"> diff --git a/app/src/main/java/io/legado/app/data/entities/BaseSource.kt b/app/src/main/java/io/legado/app/data/entities/BaseSource.kt index 01fdec156..59c523d05 100644 --- a/app/src/main/java/io/legado/app/data/entities/BaseSource.kt +++ b/app/src/main/java/io/legado/app/data/entities/BaseSource.kt @@ -107,6 +107,10 @@ interface BaseSource : JsExtensions { CacheManager.put("userInfo_${getStoreUrl()}", data) } + fun removeLoginInfo() { + CacheManager.delete("userInfo_${getStoreUrl()}") + } + /** * 执行JS */ diff --git a/app/src/main/java/io/legado/app/help/CacheManager.kt b/app/src/main/java/io/legado/app/help/CacheManager.kt index 6194a6175..60627ee35 100644 --- a/app/src/main/java/io/legado/app/help/CacheManager.kt +++ b/app/src/main/java/io/legado/app/help/CacheManager.kt @@ -59,4 +59,9 @@ object CacheManager { } return null } + + fun delete(key: String) { + appDb.cacheDao.delete(key) + ACache.get(appCtx).remove(key) + } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/DirectLinkUpload.kt b/app/src/main/java/io/legado/app/help/DirectLinkUpload.kt new file mode 100644 index 000000000..cf5f88ee5 --- /dev/null +++ b/app/src/main/java/io/legado/app/help/DirectLinkUpload.kt @@ -0,0 +1,44 @@ +package io.legado.app.help + +import io.legado.app.help.http.newCallStrResponse +import io.legado.app.help.http.okHttpClient +import io.legado.app.help.http.postMultipart +import io.legado.app.model.analyzeRule.AnalyzeRule +import io.legado.app.model.analyzeRule.RuleData + +object DirectLinkUpload { + + private const val uploadUrlKey = "directLinkUploadUrl" + private const val downloadUrlRuleKey = "directLinkDownloadUrlRule" + + suspend fun upLoad(fileName: String, byteArray: ByteArray): String { + val res = okHttpClient.newCallStrResponse { + url("https://shuyuan.miaogongzi.site/index.html") + postMultipart(mapOf("file" to Triple(fileName, byteArray, null))) + } + val analyzeRule = AnalyzeRule(RuleData()).setContent(res.body, res.url) + return analyzeRule.getString("tag.b@text") + } + + fun getUploadUrl(): String? { + return CacheManager.get(uploadUrlKey) + } + + fun putUploadUrl(url: String) { + CacheManager.put(uploadUrlKey, url) + } + + fun getDownloadUrlRule(): String? { + return CacheManager.get(uploadUrlKey) + } + + fun putDownloadUrlRule(rule: String) { + CacheManager.put(downloadUrlRuleKey, rule) + } + + fun delete() { + CacheManager.delete(uploadUrlKey) + CacheManager.delete(downloadUrlRuleKey) + } + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt b/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt index 2c8206123..e9921fb2e 100644 --- a/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt +++ b/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt @@ -114,6 +114,24 @@ fun Request.Builder.postForm(form: Map, encoded: Boolean = false post(formBody.build()) } +fun Request.Builder.postMultipart(form: Map) { + val multipartBody = MultipartBody.Builder() + form.forEach { + when (it.value) { + is Triple<*, *, *> -> { + val triple = it.value as Triple<*, *, *> + val fileName = triple.first!!.toString() + val file = triple.second as ByteArray + val mediaType = triple.third?.toString()?.toMediaType() + val requestBody = file.toRequestBody(mediaType) + multipartBody.addFormDataPart(it.key, fileName, requestBody) + } + else -> multipartBody.addFormDataPart(it.key, it.value.toString()) + } + } + post(multipartBody.build()) +} + fun Request.Builder.postJson(json: String?) { json?.let { val requestBody = json.toRequestBody("application/json; charset=UTF-8".toMediaType()) diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt index 780160a25..297690f27 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt @@ -25,7 +25,10 @@ import kotlin.collections.HashMap */ @Keep @Suppress("unused", "RegExpRedundantEscape", "MemberVisibilityCanBePrivate") -class AnalyzeRule(val ruleData: RuleDataInterface, private val source: BaseSource) : JsExtensions { +class AnalyzeRule( + val ruleData: RuleDataInterface, + private val source: BaseSource? = null +) : JsExtensions { var book = if (ruleData is BaseBook) ruleData else null diff --git a/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt b/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt index c8c91dca2..8aed7f749 100644 --- a/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt @@ -24,8 +24,8 @@ import io.legado.app.help.BookHelp import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.selector import io.legado.app.service.help.CacheBook -import io.legado.app.ui.document.FilePicker import io.legado.app.ui.document.FilePickerParam +import io.legado.app.ui.document.HandleFileContract import io.legado.app.ui.widget.dialog.TextListDialog import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding @@ -53,7 +53,7 @@ class CacheActivity : VMBaseActivity() private val groupList: ArrayList = arrayListOf() private var groupId: Long = -1 - private val exportDir = registerForActivityResult(FilePicker()) { uri -> + private val exportDir = registerForActivityResult(HandleFileContract()) { uri -> uri ?: return@registerForActivityResult if (uri.isContentScheme()) { ACache.get(this@CacheActivity).put(exportBookPathKey, uri.toString()) @@ -304,6 +304,7 @@ class CacheActivity : VMBaseActivity() } } + @SuppressLint("SetTextI18n") private fun alertExportFileName() { alert(R.string.export_file_name) { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { diff --git a/app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt index bde918fa1..b47405be7 100644 --- a/app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt @@ -21,7 +21,7 @@ import io.legado.app.lib.dialogs.alert import io.legado.app.lib.permission.Permissions import io.legado.app.lib.permission.PermissionsCompat import io.legado.app.lib.theme.backgroundColor -import io.legado.app.ui.document.FilePicker +import io.legado.app.ui.document.HandleFileContract import io.legado.app.ui.widget.SelectActionBar import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding @@ -49,7 +49,7 @@ class ImportBookActivity : VMBaseActivity + private val selectFolder = registerForActivityResult(HandleFileContract()) { uri -> uri ?: return@registerForActivityResult if (uri.isContentScheme()) { AppConfig.importBookPath = uri.toString() diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt index 18db769aa..2e1399f91 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt @@ -24,8 +24,8 @@ import io.legado.app.lib.theme.bottomBackground import io.legado.app.lib.theme.getPrimaryTextColor import io.legado.app.lib.theme.getSecondaryTextColor import io.legado.app.ui.book.read.ReadBookActivity -import io.legado.app.ui.document.FilePicker import io.legado.app.ui.document.FilePickerParam +import io.legado.app.ui.document.HandleFileContract import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding import java.io.File @@ -48,11 +48,11 @@ class BgTextConfigDialog : BaseDialogFragment() { setBgFromUri(uri) } } - private val selectExportDir = registerForActivityResult(FilePicker()) { + private val selectExportDir = registerForActivityResult(HandleFileContract()) { it ?: return@registerForActivityResult exportConfig(it) } - private val selectImportDoc = registerForActivityResult(FilePicker()) { + private val selectImportDoc = registerForActivityResult(HandleFileContract()) { it ?: return@registerForActivityResult if (it.toString() == importFormNet) { importNetConfigAlert() @@ -190,7 +190,7 @@ class BgTextConfigDialog : BaseDialogFragment() { binding.ivImport.setOnClickListener { selectImportDoc.launch( FilePickerParam( - mode = FilePicker.FILE, + mode = HandleFileContract.FILE, title = getString(R.string.import_str), allowExtensions = arrayOf("zip"), otherActions = arrayOf(importFormNet) diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt index 563f6f554..8d7da8423 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt @@ -25,8 +25,8 @@ import io.legado.app.lib.dialogs.alert import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.primaryColor import io.legado.app.service.help.ReadAloud -import io.legado.app.ui.document.FilePicker import io.legado.app.ui.document.FilePickerParam +import io.legado.app.ui.document.HandleFileContract import io.legado.app.ui.widget.dialog.TextDialog import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding @@ -41,12 +41,12 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener lateinit var adapter: Adapter private val viewModel: SpeakEngineViewModel by viewModels() private var engineId = appCtx.getPrefLong(PreferKey.speakEngine) - private val importDocResult = registerForActivityResult(FilePicker()) { + private val importDocResult = registerForActivityResult(HandleFileContract()) { it?.let { viewModel.importLocal(it) } } - private val exportDirResult = registerForActivityResult(FilePicker()) { + private val exportDirResult = registerForActivityResult(HandleFileContract()) { it?.let { viewModel.export(it) } @@ -116,7 +116,7 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener R.id.menu_default -> viewModel.importDefault() R.id.menu_import_local -> importDocResult.launch( FilePickerParam( - mode = FilePicker.FILE, + mode = HandleFileContract.FILE, allowExtensions = arrayOf("txt", "json") ) ) diff --git a/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt b/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt index 65c91a24f..a35911ab6 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt @@ -25,8 +25,8 @@ import io.legado.app.lib.dialogs.selector import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.backgroundColor import io.legado.app.ui.book.source.debug.BookSourceDebugActivity -import io.legado.app.ui.document.FilePicker import io.legado.app.ui.document.FilePickerParam +import io.legado.app.ui.document.HandleFileContract import io.legado.app.ui.login.SourceLoginActivity import io.legado.app.ui.qrcode.QrCodeResult import io.legado.app.ui.widget.KeyboardToolPop @@ -55,7 +55,7 @@ class BookSourceEditActivity : upRecyclerView(source) } } - private val selectDoc = registerForActivityResult(FilePicker()) { uri -> + private val selectDoc = registerForActivityResult(HandleFileContract()) { uri -> uri ?: return@registerForActivityResult if (uri.isContentScheme()) { sendText(uri.toString()) @@ -418,7 +418,7 @@ class BookSourceEditActivity : 2 -> showRegexHelp() 3 -> selectDoc.launch( FilePickerParam( - mode = FilePicker.FILE + mode = HandleFileContract.FILE ) ) } diff --git a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt index a1e341df4..ae0a8c7cb 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt @@ -31,8 +31,8 @@ import io.legado.app.service.help.CheckSource import io.legado.app.ui.association.ImportBookSourceDialog import io.legado.app.ui.book.source.debug.BookSourceDebugActivity import io.legado.app.ui.book.source.edit.BookSourceEditActivity -import io.legado.app.ui.document.FilePicker import io.legado.app.ui.document.FilePickerParam +import io.legado.app.ui.document.HandleFileContract import io.legado.app.ui.qrcode.QrCodeResult import io.legado.app.ui.widget.SelectActionBar import io.legado.app.ui.widget.dialog.TextDialog @@ -66,7 +66,7 @@ class BookSourceActivity : VMBaseActivity + private val importDoc = registerForActivityResult(HandleFileContract()) { uri -> uri ?: return@registerForActivityResult try { uri.readText(this)?.let { @@ -76,7 +76,7 @@ class BookSourceActivity : VMBaseActivity + private val exportDir = registerForActivityResult(HandleFileContract()) { uri -> uri ?: return@registerForActivityResult if (uri.isContentScheme()) { DocumentFile.fromTreeUri(this, uri)?.let { @@ -125,7 +125,7 @@ class BookSourceActivity : VMBaseActivity importDoc.launch( FilePickerParam( - mode = FilePicker.FILE, + mode = HandleFileContract.FILE, allowExtensions = arrayOf("txt", "json") ) ) diff --git a/app/src/main/java/io/legado/app/ui/config/BackupConfigFragment.kt b/app/src/main/java/io/legado/app/ui/config/BackupConfigFragment.kt index 5db3ae74a..ff9963999 100644 --- a/app/src/main/java/io/legado/app/ui/config/BackupConfigFragment.kt +++ b/app/src/main/java/io/legado/app/ui/config/BackupConfigFragment.kt @@ -28,7 +28,7 @@ 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.accentColor -import io.legado.app.ui.document.FilePicker +import io.legado.app.ui.document.HandleFileContract import io.legado.app.ui.widget.dialog.TextDialog import io.legado.app.utils.* import kotlinx.coroutines.Dispatchers.Main @@ -38,7 +38,7 @@ import splitties.init.appCtx class BackupConfigFragment : BasePreferenceFragment(), SharedPreferences.OnSharedPreferenceChangeListener { - private val selectBackupPath = registerForActivityResult(FilePicker()) { uri -> + private val selectBackupPath = registerForActivityResult(HandleFileContract()) { uri -> uri ?: return@registerForActivityResult if (uri.isContentScheme()) { AppConfig.backupPath = uri.toString() @@ -46,7 +46,7 @@ class BackupConfigFragment : BasePreferenceFragment(), AppConfig.backupPath = uri.path } } - private val backupDir = registerForActivityResult(FilePicker()) { uri -> + private val backupDir = registerForActivityResult(HandleFileContract()) { uri -> uri ?: return@registerForActivityResult if (uri.isContentScheme()) { AppConfig.backupPath = uri.toString() @@ -70,7 +70,7 @@ class BackupConfigFragment : BasePreferenceFragment(), } } } - private val restoreDir = registerForActivityResult(FilePicker()) { uri -> + private val restoreDir = registerForActivityResult(HandleFileContract()) { uri -> uri ?: return@registerForActivityResult if (uri.isContentScheme()) { AppConfig.backupPath = uri.toString() @@ -86,7 +86,7 @@ class BackupConfigFragment : BasePreferenceFragment(), } } } - private val restoreOld = registerForActivityResult(FilePicker()) { uri -> + private val restoreOld = registerForActivityResult(HandleFileContract()) { uri -> uri?.let { ImportOldData.importUri(appCtx, uri) } diff --git a/app/src/main/java/io/legado/app/ui/config/DirectLinkUploadConfig.kt b/app/src/main/java/io/legado/app/ui/config/DirectLinkUploadConfig.kt new file mode 100644 index 000000000..a4ff95cab --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/config/DirectLinkUploadConfig.kt @@ -0,0 +1,63 @@ +package io.legado.app.ui.config + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import io.legado.app.R +import io.legado.app.base.BaseDialogFragment +import io.legado.app.databinding.DialogDirectLinkUploadConfigBinding +import io.legado.app.help.DirectLinkUpload +import io.legado.app.utils.toastOnUi +import io.legado.app.utils.viewbindingdelegate.viewBinding +import io.legado.app.utils.windowSize +import splitties.views.onClick + +class DirectLinkUploadConfig : BaseDialogFragment() { + + private val binding by viewBinding(DialogDirectLinkUploadConfigBinding::bind) + + override fun onStart() { + super.onStart() + val dm = requireActivity().windowSize + dialog?.window?.setLayout( + (dm.widthPixels * 0.9).toInt(), + ViewGroup.LayoutParams.WRAP_CONTENT + ) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return inflater.inflate(R.layout.dialog_direct_link_upload_config, container) + } + + override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { + binding.editUploadUrl.setText(DirectLinkUpload.getUploadUrl()) + binding.editDownloadUrlRule.setText(DirectLinkUpload.getDownloadUrlRule()) + binding.tvCancel.onClick { + dismiss() + } + binding.tvFooterLeft.onClick { + DirectLinkUpload.delete() + } + binding.tvOk.onClick { + val uploadUrl = binding.editUploadUrl.text?.toString() + val downloadUrlRule = binding.editDownloadUrlRule.text?.toString() + uploadUrl ?: let { + toastOnUi("上传Url不能为空") + return@onClick + } + downloadUrlRule ?: let { + toastOnUi("下载Url规则不能为空") + return@onClick + } + DirectLinkUpload.putUploadUrl(uploadUrl) + DirectLinkUpload.putDownloadUrlRule(downloadUrlRule) + dismiss() + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/document/FilePickerActivity.kt b/app/src/main/java/io/legado/app/ui/document/FilePickerActivity.kt index 1665a1c50..5e55deaef 100644 --- a/app/src/main/java/io/legado/app/ui/document/FilePickerActivity.kt +++ b/app/src/main/java/io/legado/app/ui/document/FilePickerActivity.kt @@ -46,7 +46,7 @@ class FilePickerActivity : override fun onActivityCreated(savedInstanceState: Bundle?) { val mode = intent.getIntExtra("mode", 0) val allowExtensions = intent.getStringArrayExtra("allowExtensions") - val selectList = if (mode == FilePicker.DIRECTORY) { + val selectList = if (mode == HandleFileContract.DIRECTORY) { arrayListOf(getString(R.string.sys_folder_picker)) } else { arrayListOf(getString(R.string.sys_file_picker)) @@ -58,7 +58,7 @@ class FilePickerActivity : selectList.addAll(it) } val title = intent.getStringExtra("title") ?: let { - if (mode == FilePicker.DIRECTORY) { + if (mode == HandleFileContract.DIRECTORY) { return@let getString(R.string.select_folder) } else { return@let getString(R.string.select_file) @@ -67,23 +67,23 @@ class FilePickerActivity : alert(title) { items(selectList) { _, index -> when (index) { - 0 -> if (mode == FilePicker.DIRECTORY) { + 0 -> if (mode == HandleFileContract.DIRECTORY) { selectDocTree.launch(null) } else { selectDoc.launch(typesOfExtensions(allowExtensions)) } - 1 -> if (mode == FilePicker.DIRECTORY) { + 1 -> if (mode == HandleFileContract.DIRECTORY) { checkPermissions { FilePickerDialog.show( supportFragmentManager, - mode = FilePicker.DIRECTORY + mode = HandleFileContract.DIRECTORY ) } } else { checkPermissions { FilePickerDialog.show( supportFragmentManager, - mode = FilePicker.FILE, + mode = HandleFileContract.FILE, allowExtensions = allowExtensions ) } diff --git a/app/src/main/java/io/legado/app/ui/document/FilePickerDialog.kt b/app/src/main/java/io/legado/app/ui/document/FilePickerDialog.kt index 06964a969..e549295ae 100644 --- a/app/src/main/java/io/legado/app/ui/document/FilePickerDialog.kt +++ b/app/src/main/java/io/legado/app/ui/document/FilePickerDialog.kt @@ -16,8 +16,8 @@ import androidx.recyclerview.widget.RecyclerView import io.legado.app.R import io.legado.app.databinding.DialogFileChooserBinding import io.legado.app.lib.theme.primaryColor -import io.legado.app.ui.document.FilePicker.Companion.DIRECTORY -import io.legado.app.ui.document.FilePicker.Companion.FILE +import io.legado.app.ui.document.HandleFileContract.Companion.DIRECTORY +import io.legado.app.ui.document.HandleFileContract.Companion.FILE import io.legado.app.ui.document.adapter.FileAdapter import io.legado.app.ui.document.adapter.PathAdapter import io.legado.app.ui.widget.recycler.VerticalDivider diff --git a/app/src/main/java/io/legado/app/ui/document/FilePicker.kt b/app/src/main/java/io/legado/app/ui/document/HandleFileContract.kt similarity index 93% rename from app/src/main/java/io/legado/app/ui/document/FilePicker.kt rename to app/src/main/java/io/legado/app/ui/document/HandleFileContract.kt index dfc0d5789..ae42385ca 100644 --- a/app/src/main/java/io/legado/app/ui/document/FilePicker.kt +++ b/app/src/main/java/io/legado/app/ui/document/HandleFileContract.kt @@ -7,7 +7,7 @@ import android.net.Uri import androidx.activity.result.contract.ActivityResultContract @Suppress("unused") -class FilePicker : ActivityResultContract() { +class HandleFileContract : ActivityResultContract() { companion object { const val DIRECTORY = 0 diff --git a/app/src/main/java/io/legado/app/ui/login/RuleUiLoginDialog.kt b/app/src/main/java/io/legado/app/ui/login/RuleUiLoginDialog.kt index 81773df3a..5485ca07f 100644 --- a/app/src/main/java/io/legado/app/ui/login/RuleUiLoginDialog.kt +++ b/app/src/main/java/io/legado/app/ui/login/RuleUiLoginDialog.kt @@ -74,16 +74,22 @@ class RuleUiLoginDialog : BaseDialogFragment() { binding.toolBar.setOnMenuItemClickListener { item -> when (item.itemId) { R.id.menu_ok -> { - val loginData = hashMapOf() + val loginData = hashMapOf() loginUi?.forEachIndexed { index, rowUi -> when (rowUi.type) { "text", "password" -> { val value = binding.root.findViewById(index) .findViewById(R.id.editText).text?.toString() - loginData[rowUi.name] = value + if (!value.isNullOrBlank()) { + loginData[rowUi.name] = value + } } } } + if (loginData.isEmpty()) { + bookSource.removeLoginInfo() + return@setOnMenuItemClickListener true + } bookSource.putLoginInfo(GSON.toJson(loginData)) bookSource.getLoginJs()?.let { try { diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BaseBookshelfFragment.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BaseBookshelfFragment.kt index 679886807..e4c06309d 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BaseBookshelfFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BaseBookshelfFragment.kt @@ -18,8 +18,8 @@ import io.legado.app.ui.book.cache.CacheActivity import io.legado.app.ui.book.group.GroupManageDialog import io.legado.app.ui.book.local.ImportBookActivity import io.legado.app.ui.book.search.SearchActivity -import io.legado.app.ui.document.FilePicker import io.legado.app.ui.document.FilePickerParam +import io.legado.app.ui.document.HandleFileContract import io.legado.app.ui.main.MainViewModel import io.legado.app.utils.* @@ -28,7 +28,7 @@ abstract class BaseBookshelfFragment(layoutId: Int) : VMBaseFragment() override val viewModel by viewModels() - private val importBookshelf = registerForActivityResult(FilePicker()) { + private val importBookshelf = registerForActivityResult(HandleFileContract()) { it?.readText(requireContext())?.let { text -> viewModel.importBookshelf(text, groupId) } @@ -56,7 +56,7 @@ abstract class BaseBookshelfFragment(layoutId: Int) : VMBaseFragment viewModel.exportBookshelf(books) { - activity?.share(it) + } R.id.menu_import_bookshelf -> importBookshelfAlert(groupId) } @@ -136,7 +136,7 @@ abstract class BaseBookshelfFragment(layoutId: Int) : VMBaseFragment + private val importDoc = registerForActivityResult(HandleFileContract()) { uri -> kotlin.runCatching { uri?.readText(this)?.let { ImportReplaceRuleDialog.start(supportFragmentManager, it) @@ -78,7 +78,7 @@ class ReplaceRuleActivity : VMBaseActivity + private val exportDir = registerForActivityResult(HandleFileContract()) { uri -> uri ?: return@registerForActivityResult if (uri.isContentScheme()) { DocumentFile.fromTreeUri(this, uri)?.let { @@ -215,7 +215,7 @@ class ReplaceRuleActivity : VMBaseActivity showImportDialog() R.id.menu_import_local -> importDoc.launch( FilePickerParam( - mode = FilePicker.FILE, + mode = HandleFileContract.FILE, allowExtensions = arrayOf("txt", "json") ) ) diff --git a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt index a8ebdd2a3..59d27a742 100644 --- a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt @@ -22,8 +22,8 @@ import io.legado.app.lib.theme.DrawableUtils import io.legado.app.lib.theme.primaryTextColor import io.legado.app.service.help.Download import io.legado.app.ui.association.OnLineImportActivity -import io.legado.app.ui.document.FilePicker import io.legado.app.ui.document.FilePickerParam +import io.legado.app.ui.document.HandleFileContract import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding import kotlinx.coroutines.launch @@ -42,7 +42,7 @@ class ReadRssActivity : VMBaseActivity private var ttsMenuItem: MenuItem? = null private var customWebViewCallback: WebChromeClient.CustomViewCallback? = null private var webPic: String? = null - private val saveImage = registerForActivityResult(FilePicker()) { + private val saveImage = registerForActivityResult(HandleFileContract()) { it ?: return@registerForActivityResult ACache.get(this).put(imagePathKey, it.toString()) viewModel.saveImage(webPic, it.toString()) diff --git a/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt b/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt index ca49e1ac8..af5a3d7c6 100644 --- a/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt @@ -22,8 +22,8 @@ import io.legado.app.lib.dialogs.alert import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.primaryTextColor import io.legado.app.ui.association.ImportRssSourceDialog -import io.legado.app.ui.document.FilePicker import io.legado.app.ui.document.FilePickerParam +import io.legado.app.ui.document.HandleFileContract import io.legado.app.ui.qrcode.QrCodeResult import io.legado.app.ui.rss.source.edit.RssSourceEditActivity import io.legado.app.ui.widget.SelectActionBar @@ -57,7 +57,7 @@ class RssSourceActivity : VMBaseActivity + private val importDoc = registerForActivityResult(HandleFileContract()) { uri -> kotlin.runCatching { uri?.readText(this)?.let { ImportRssSourceDialog.start(supportFragmentManager, it) @@ -66,7 +66,7 @@ class RssSourceActivity : VMBaseActivity + private val exportDir = registerForActivityResult(HandleFileContract()) { uri -> uri ?: return@registerForActivityResult if (uri.isContentScheme()) { DocumentFile.fromTreeUri(this, uri)?.let { @@ -103,7 +103,7 @@ class RssSourceActivity : VMBaseActivity startActivity() R.id.menu_import_local -> importDoc.launch( FilePickerParam( - mode = FilePicker.FILE, + mode = HandleFileContract.FILE, allowExtensions = arrayOf("txt", "json") ) ) diff --git a/app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt b/app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt index 3b25ba29d..85eaa9dbd 100644 --- a/app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt +++ b/app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt @@ -19,8 +19,8 @@ import io.legado.app.lib.dialogs.alert import io.legado.app.lib.permission.Permissions import io.legado.app.lib.permission.PermissionsCompat import io.legado.app.lib.theme.primaryColor -import io.legado.app.ui.document.FilePicker import io.legado.app.ui.document.FilePickerParam +import io.legado.app.ui.document.HandleFileContract import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding import kotlinx.coroutines.Dispatchers.Main @@ -39,7 +39,7 @@ class FontSelectDialog : BaseDialogFragment(), } private var adapter: FontAdapter? = null private val binding by viewBinding(DialogFontSelectBinding::bind) - private val selectFontDir = registerForActivityResult(FilePicker()) { uri -> + private val selectFontDir = registerForActivityResult(HandleFileContract()) { uri -> uri ?: return@registerForActivityResult if (uri.toString().isContentScheme()) { putPrefString(PreferKey.fontFolder, uri.toString()) diff --git a/app/src/main/res/layout/dialog_direct_link_upload_config.xml b/app/src/main/res/layout/dialog_direct_link_upload_config.xml new file mode 100644 index 000000000..71524f83c --- /dev/null +++ b/app/src/main/res/layout/dialog_direct_link_upload_config.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index 803bfae84..d8601637a 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -864,4 +864,6 @@ Disabled when 0, enable range from 1 to 25\nThe greater the radius, the stronger the effect of blurring 需登录 使用Cronet网络组件 + 上传URL + 下载URL规则 diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index 805f16d6e..8374af50b 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -864,4 +864,6 @@ Disabled when 0, enable range from 1 to 25\nThe greater the radius, the stronger the effect of blurring 需登录 使用Cronet网络组件 + 上传URL + 下载URL规则 diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 57936ae27..cee99d41b 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -864,5 +864,7 @@ Desativado quando 0, Ativado entre 1 e 25\n Quanto maior o raio, mais forte o efeito de desfocagem Login necessário Usando componentes de rede Cronet + 上传URL + 下载URL规则 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index ab94ebc25..7213bdc9e 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -861,5 +861,7 @@ 書源校驗時顯示網絡請求步驟和時間 需登录 使用Cronet网络组件 + 上传URL + 下载URL规则 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 02e01270e..fcdf70fc6 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -862,5 +862,7 @@ 書源校驗時顯示網絡請求步驟和時間 需登录 使用Cronet网络组件 + 上传URL + 下载URL规则 diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 4dc88b7d6..e41040a9a 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -863,5 +863,7 @@ 书源校验时显示网络请求步骤和时间 需登录 使用Cronet网络组件 + 上传URL + 下载URL规则 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index aa38bae1c..5d7370fbb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -864,5 +864,7 @@ Show network status and timestamp during source checking 需登录 使用Cronet网络组件 + 上传URL + 下载URL规则