From d62c757cc4386293216c9caea7d858ec9f1fba74 Mon Sep 17 00:00:00 2001 From: kunfei Date: Thu, 23 Jun 2022 09:31:29 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ui/book/local/ImportBookActivity.kt | 28 ++--- .../app/ui/book/local/ImportBookAdapter.kt | 4 +- .../app/ui/book/local/ImportBookViewModel.kt | 2 + .../legado/app/ui/book/remote/RemoteBook.kt | 2 +- .../app/ui/book/remote/RemoteBookActivity.kt | 88 +++++++------ .../app/ui/book/remote/RemoteBookAdapter.kt | 118 ++++++++++++++---- .../app/ui/book/remote/RemoteBookViewModel.kt | 32 ++--- .../book/remote/manager/RemoteBookWebDav.kt | 5 +- .../main/res/layout/activity_import_book.xml | 3 +- .../main/res/layout/activity_remote_book.xml | 67 ---------- app/src/main/res/layout/item_remote_book.xml | 108 ---------------- 11 files changed, 181 insertions(+), 276 deletions(-) delete mode 100644 app/src/main/res/layout/activity_remote_book.xml delete mode 100644 app/src/main/res/layout/item_remote_book.xml 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 c3b17df4c..f70e3d17d 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 @@ -41,8 +41,6 @@ class ImportBookActivity : VMBaseActivity() - private var rootDoc: FileDoc? = null - private val subDocs = arrayListOf() private val adapter by lazy { ImportBookAdapter(this, this) } private var scanDocJob: Job? = null @@ -59,6 +57,7 @@ class ImportBookActivity : VMBaseActivity upPath() lastPath.isNullOrEmpty() -> { binding.tvEmptyMsg.visible() selectFolder.launch() @@ -160,9 +160,9 @@ class ImportBookActivity : VMBaseActivity + viewModel.rootDoc?.let { doc -> adapter.clearItems() - val lastDoc = subDocs.lastOrNull() ?: doc + val lastDoc = viewModel.subDocs.lastOrNull() ?: doc binding.refreshProgressBar.isAutoLoading = true scanDocJob?.cancel() scanDocJob = launch(IO) { @@ -261,14 +261,14 @@ class ImportBookActivity : VMBaseActivity(context) { - var selectedUris = hashSetOf() + val selectedUris = hashSetOf() var checkableCount = 0 - private var bookFileNames = arrayListOf() + private val bookFileNames = arrayListOf() override fun getViewBinding(parent: ViewGroup): ItemImportBookBinding { return ItemImportBookBinding.inflate(inflater, parent, false) diff --git a/app/src/main/java/io/legado/app/ui/book/local/ImportBookViewModel.kt b/app/src/main/java/io/legado/app/ui/book/local/ImportBookViewModel.kt index 99d7f6c6d..1c84412d0 100644 --- a/app/src/main/java/io/legado/app/ui/book/local/ImportBookViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/local/ImportBookViewModel.kt @@ -21,6 +21,8 @@ import java.io.File import java.util.* class ImportBookViewModel(application: Application) : BaseViewModel(application) { + var rootDoc: FileDoc? = null + val subDocs = arrayListOf() var sort = context.getPrefInt(PreferKey.localBookImportSort) var dataCallback: DataCallback? = null var dataFlowStart: (() -> Unit)? = null diff --git a/app/src/main/java/io/legado/app/ui/book/remote/RemoteBook.kt b/app/src/main/java/io/legado/app/ui/book/remote/RemoteBook.kt index 1b3a2d003..efe1a686e 100644 --- a/app/src/main/java/io/legado/app/ui/book/remote/RemoteBook.kt +++ b/app/src/main/java/io/legado/app/ui/book/remote/RemoteBook.kt @@ -6,7 +6,7 @@ data class RemoteBook( val size: Long, val contentType: String, val lastModify: Long, - val isOnBookShelf: Boolean + var isOnBookShelf: Boolean ) { val isDir by lazy { diff --git a/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookActivity.kt index 8e4e171ca..58083c627 100644 --- a/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookActivity.kt @@ -1,6 +1,5 @@ package io.legado.app.ui.book.remote -import android.annotation.SuppressLint import android.os.Bundle import android.view.Menu import android.view.MenuItem @@ -9,37 +8,42 @@ import androidx.core.view.isGone import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.R import io.legado.app.base.VMBaseActivity - - -import io.legado.app.databinding.ActivityRemoteBookBinding +import io.legado.app.databinding.ActivityImportBookBinding +import io.legado.app.lib.theme.backgroundColor import io.legado.app.ui.book.remote.manager.RemoteBookWebDav +import io.legado.app.ui.widget.SelectActionBar import io.legado.app.ui.widget.dialog.WaitDialog -import io.legado.app.utils.toastOnUi - import io.legado.app.utils.viewbindingdelegate.viewBinding import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.launch +import java.io.File /** * 展示远程书籍 * @author qianfanguojin * @time 2022/05/12 */ -class RemoteBookActivity : VMBaseActivity(), - RemoteBookAdapter.CallBack { - override val binding by viewBinding(ActivityRemoteBookBinding::inflate) +class RemoteBookActivity : VMBaseActivity(), + RemoteBookAdapter.CallBack, + SelectActionBar.CallBack { + override val binding by viewBinding(ActivityImportBookBinding::inflate) override val viewModel by viewModels() private val adapter by lazy { RemoteBookAdapter(this, this) } private val waitDialog by lazy { WaitDialog(this) } override fun onActivityCreated(savedInstanceState: Bundle?) { + binding.titleBar.setTitle(R.string.remote_book) initView() initData() + initEvent() } private fun initView() { + binding.layTop.setBackgroundColor(backgroundColor) binding.recyclerView.layoutManager = LinearLayoutManager(this) binding.recyclerView.adapter = adapter + binding.selectActionBar.setMainActionText(R.string.add_to_shelf) + binding.selectActionBar.setCallBack(this) } private fun initData() { @@ -51,7 +55,14 @@ class RemoteBookActivity : VMBaseActivity { - viewModel.loadRemoteBookList( - viewModel.dirList.lastOrNull()?.path ?: RemoteBookWebDav.rootBookUrl - ) + upPath() } } return super.onCompatOptionsItemSelected(item) } - override fun finish() { - if (viewModel.dirList.isEmpty()) { - super.finish() - } else { - viewModel.dirList.removeLastOrNull() - val remoteBook = viewModel.dirList.lastOrNull() - viewModel.dataCallback?.clear() - if (remoteBook != null) { - binding.titleBar.title = remoteBook.filename - viewModel.loadRemoteBookList(remoteBook.path) - } else { - binding.titleBar.setTitle(R.string.remote_book) - viewModel.loadRemoteBookList(RemoteBookWebDav.rootBookUrl) - } - } + override fun revertSelection() { + adapter.revertSelection() } - override fun openDir(remoteBook: RemoteBook) { - viewModel.dirList.add(remoteBook) - binding.titleBar.title = remoteBook.filename - viewModel.dataCallback?.clear() - viewModel.loadRemoteBookList(remoteBook.path) + override fun selectAll(selectAll: Boolean) { + adapter.selectAll(selectAll) } - @SuppressLint("NotifyDataSetChanged") - override fun addToBookshelf(remoteBook: RemoteBook) { + override fun onClickSelectBarMainAction() { waitDialog.show() - viewModel.addToBookshelf(remoteBook, success = { - toastOnUi(getString(R.string.download_book_success)) + viewModel.addToBookshelf(adapter.selected) { adapter.notifyDataSetChanged() - }) { waitDialog.dismiss() } } + + private fun upPath() { + var path = "books" + File.separator + viewModel.dirList.forEach { + path = path + it.filename + File.separator + } + binding.tvPath.text = path + viewModel.dataCallback?.clear() + adapter.selected.clear() + viewModel.loadRemoteBookList( + viewModel.dirList.lastOrNull()?.path ?: RemoteBookWebDav.rootBookUrl + ) + } + + override fun openDir(remoteBook: RemoteBook) { + viewModel.dirList.add(remoteBook) + upPath() + } + + override fun upCountView() { + binding.selectActionBar.upCountView(adapter.selected.size, adapter.checkableCount) + } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookAdapter.kt b/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookAdapter.kt index 97602562e..1c977c773 100644 --- a/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookAdapter.kt @@ -1,13 +1,17 @@ package io.legado.app.ui.book.remote +import android.annotation.SuppressLint import android.content.Context import android.view.ViewGroup -import androidx.core.view.isGone -import cn.hutool.core.date.LocalDateTimeUtil +import io.legado.app.R import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.RecyclerAdapter -import io.legado.app.databinding.ItemRemoteBookBinding +import io.legado.app.constant.AppConst +import io.legado.app.databinding.ItemImportBookBinding import io.legado.app.utils.ConvertUtils +import io.legado.app.utils.gone +import io.legado.app.utils.invisible +import io.legado.app.utils.visible /** @@ -15,14 +19,16 @@ import io.legado.app.utils.ConvertUtils * @author qianfanguojin */ class RemoteBookAdapter(context: Context, val callBack: CallBack) : - RecyclerAdapter(context) { + RecyclerAdapter(context) { + var selected = hashSetOf() + var checkableCount = 0 - override fun getViewBinding(parent: ViewGroup): ItemRemoteBookBinding { - return ItemRemoteBookBinding.inflate(inflater, parent, false) + override fun getViewBinding(parent: ViewGroup): ItemImportBookBinding { + return ItemImportBookBinding.inflate(inflater, parent, false) } override fun onCurrentListChanged() { - + upCheckableCount() } /** @@ -30,39 +36,107 @@ class RemoteBookAdapter(context: Context, val callBack: CallBack) : */ override fun convert( holder: ItemViewHolder, - binding: ItemRemoteBookBinding, + binding: ItemImportBookBinding, item: RemoteBook, payloads: MutableList ) { binding.run { - tvName.text = item.filename.substringBeforeLast(".") - tvContentType.text = item.contentType - tvSize.text = ConvertUtils.formatFileSize(item.size) - tvDate.text = - LocalDateTimeUtil.format(LocalDateTimeUtil.of(item.lastModify), "yyyy-MM-dd") - llInfo.isGone = item.isDir - tvContentType.isGone = item.isDir - btnDownload.isGone = item.isDir + if (payloads.isEmpty()) { + if (item.isDir) { + ivIcon.setImageResource(R.drawable.ic_folder) + ivIcon.visible() + cbSelect.invisible() + llBrief.gone() + cbSelect.isChecked = false + } else { + if (item.isOnBookShelf) { + ivIcon.setImageResource(R.drawable.ic_book_has) + ivIcon.visible() + cbSelect.invisible() + } else { + ivIcon.invisible() + cbSelect.visible() + } + llBrief.visible() + tvTag.text = item.contentType + tvSize.text = ConvertUtils.formatFileSize(item.size) + tvDate.text = AppConst.dateFormat.format(item.lastModify) + cbSelect.isChecked = selected.contains(item) + } + tvName.text = item.filename + } else { + cbSelect.isChecked = selected.contains(item) + } } } - override fun registerListener(holder: ItemViewHolder, binding: ItemRemoteBookBinding) { - binding.root.setOnClickListener { + override fun registerListener(holder: ItemViewHolder, binding: ItemImportBookBinding) { + holder.itemView.setOnClickListener { getItem(holder.layoutPosition)?.let { if (it.isDir) { callBack.openDir(it) + } else if (!it.isOnBookShelf) { + if (!selected.contains(it)) { + selected.add(it) + } else { + selected.remove(it) + } + notifyItemChanged(holder.layoutPosition, true) + callBack.upCountView() } } } - binding.btnDownload.setOnClickListener { - getItem(holder.layoutPosition)?.let { - callBack.addToBookshelf(it) + } + + private fun upCheckableCount() { + checkableCount = 0 + getItems().forEach { + if (!it.isDir && !it.isOnBookShelf) { + checkableCount++ + } + } + callBack.upCountView() + } + + @SuppressLint("NotifyDataSetChanged") + fun selectAll(selectAll: Boolean) { + if (selectAll) { + getItems().forEach { + if (!it.isDir && !it.isOnBookShelf) { + selected.add(it) + } } + } else { + selected.clear() } + notifyDataSetChanged() + callBack.upCountView() } + fun revertSelection() { + getItems().forEach { + if (!it.isDir) { + if (selected.contains(it)) { + selected.remove(it) + } else { + selected.add(it) + } + } + } + callBack.upCountView() + } + + fun removeSelection() { + for (i in getItems().lastIndex downTo 0) { + if (getItem(i) in selected) { + removeItem(i) + } + } + } + + interface CallBack { fun openDir(remoteBook: RemoteBook) - fun addToBookshelf(remoteBook: RemoteBook) + fun upCountView() } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookViewModel.kt b/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookViewModel.kt index 3699d79dc..557921318 100644 --- a/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookViewModel.kt @@ -1,8 +1,8 @@ package io.legado.app.ui.book.remote import android.app.Application -import android.net.Uri import io.legado.app.base.BaseViewModel +import io.legado.app.constant.AppLog import io.legado.app.model.localBook.LocalBook import io.legado.app.ui.book.remote.manager.RemoteBookWebDav import io.legado.app.utils.toastOnUi @@ -62,33 +62,23 @@ class RemoteBookViewModel(application: Application): BaseViewModel(application){ } } - fun addToBookshelf(uriList: HashSet, finally: () -> Unit) { + fun addToBookshelf(remoteBooks: HashSet, finally: () -> Unit) { execute { - uriList.forEach { - LocalBook.importFile(Uri.parse(it)) + remoteBooks.forEach { remoteBook -> + val downloadBookPath = RemoteBookWebDav.getRemoteBook(remoteBook) + downloadBookPath?.let { + LocalBook.importFile(it) + remoteBook.isOnBookShelf = true + } } - }.onFinally { - finally.invoke() - } - } - - /** - * 添加书籍到本地书架 - */ - fun addToBookshelf(remoteBook: RemoteBook, success: () -> Unit, finally: () -> Unit) { - execute { - val downloadBookPath = RemoteBookWebDav.getRemoteBook(remoteBook) - downloadBookPath?.let { - LocalBook.importFile(it) - } - }.onSuccess { - success.invoke() }.onError { - context.toastOnUi(it.localizedMessage) + AppLog.put("导入出错\n${it.localizedMessage}", it) + context.toastOnUi("导入出错\n${it.localizedMessage}") }.onFinally { finally.invoke() } } + interface DataCallback { fun setItems(remoteFiles: List) diff --git a/app/src/main/java/io/legado/app/ui/book/remote/manager/RemoteBookWebDav.kt b/app/src/main/java/io/legado/app/ui/book/remote/manager/RemoteBookWebDav.kt index 9c67171c5..c5d6d2052 100644 --- a/app/src/main/java/io/legado/app/ui/book/remote/manager/RemoteBookWebDav.kt +++ b/app/src/main/java/io/legado/app/ui/book/remote/manager/RemoteBookWebDav.kt @@ -108,7 +108,10 @@ object RemoteBookWebDav : RemoteBookManager() { } override suspend fun delete(remoteBookUrl: String): Boolean { - TODO("Not yet implemented") + AppWebDav.authorization?.let { + return WebDav(remoteBookUrl, it).delete() + } + return false } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_import_book.xml b/app/src/main/res/layout/activity_import_book.xml index 7e3ee8997..61e1206c3 100644 --- a/app/src/main/res/layout/activity_import_book.xml +++ b/app/src/main/res/layout/activity_import_book.xml @@ -9,8 +9,7 @@ android:id="@+id/titleBar" android:layout_width="match_parent" android:layout_height="wrap_content" - app:layout_constraintTop_toTopOf="parent" - app:title="@string/book_local" /> + app:layout_constraintTop_toTopOf="parent" /> - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/item_remote_book.xml b/app/src/main/res/layout/item_remote_book.xml deleted file mode 100644 index 3fa520967..000000000 --- a/app/src/main/res/layout/item_remote_book.xml +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file