diff --git a/app/build.gradle b/app/build.gradle index c299deee3..6741567bb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -87,7 +87,7 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" //fireBase - implementation 'com.google.firebase:firebase-core:17.2.0' + implementation 'com.google.firebase:firebase-core:17.2.1' implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1' //androidX @@ -97,8 +97,8 @@ dependencies { implementation 'androidx.preference:preference:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0' - implementation 'androidx.viewpager2:viewpager2:1.0.0-beta05' - implementation 'com.google.android.material:material:1.1.0-beta01' + implementation 'androidx.viewpager2:viewpager2:1.0.0-rc01' + implementation 'com.google.android.material:material:1.2.0-alpha01' implementation 'com.google.android:flexbox:1.1.0' //lifecycle @@ -107,7 +107,7 @@ dependencies { implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version" //room - def room_version = '2.2.0' + def room_version = '2.2.1' implementation "androidx.room:room-runtime:$room_version" kapt "androidx.room:room-compiler:$room_version" diff --git a/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt b/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt index d2b48fa49..85965050c 100644 --- a/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt @@ -29,14 +29,14 @@ interface BookSourceDao { @Query("select distinct enabled from book_sources where bookSourceName like :searchKey or bookSourceGroup like :searchKey or bookSourceUrl like :searchKey") fun searchIsEnable(searchKey: String = ""): List - @Query("update book_sources set enabled = 1 where bookSourceUrl in (:sourceUrls)") - fun enableSection(vararg sourceUrls: String) + @Query("update book_sources set enabled = 1 where bookSourceUrl = :sourceUrl") + fun enableSection(sourceUrl: String) - @Query("update book_sources set enabled = 0 where bookSourceUrl in (:sourceUrls)") - fun disableSection(vararg sourceUrls: String) + @Query("update book_sources set enabled = 0 where bookSourceUrl = :sourceUrl") + fun disableSection(sourceUrl: String) - @Query("delete from book_sources where bookSourceUrl in (:sourceUrls)") - fun delSection(vararg sourceUrls: String) + @Query("delete from book_sources where bookSourceUrl = :sourceUrl") + fun delSection(sourceUrl: String) @Query("select * from book_sources where enabledExplore = 1 order by customOrder asc") fun observeFind(): DataSource.Factory diff --git a/app/src/main/java/io/legado/app/model/webbook/BookChapterList.kt b/app/src/main/java/io/legado/app/model/webbook/BookChapterList.kt index 21e3fd67b..f47bcd8da 100644 --- a/app/src/main/java/io/legado/app/model/webbook/BookChapterList.kt +++ b/app/src/main/java/io/legado/app/model/webbook/BookChapterList.kt @@ -58,7 +58,8 @@ object BookChapterList { tocRule, listRule, book, - bookSource + bookSource, + printLog = false ) nextUrl = if (chapterData.nextUrl.isNotEmpty()) chapterData.nextUrl[0] @@ -88,8 +89,7 @@ object BookChapterList { tocRule, listRule, book, - bookSource, - getNextUrl = false + bookSource ) item.chapterList = nextChapterData.chapterList } diff --git a/app/src/main/java/io/legado/app/model/webbook/BookContent.kt b/app/src/main/java/io/legado/app/model/webbook/BookContent.kt index 014454edc..49ce90783 100644 --- a/app/src/main/java/io/legado/app/model/webbook/BookContent.kt +++ b/app/src/main/java/io/legado/app/model/webbook/BookContent.kt @@ -123,7 +123,7 @@ object BookContent { analyzeRule.getStringList(nextUrlRule, true)?.let { nextUrlList.addAll(it) } - SourceDebug.printLog(bookSource.bookSourceUrl, "└" + nextUrlList.joinToString(",")) + SourceDebug.printLog(bookSource.bookSourceUrl, "└" + nextUrlList.joinToString(","), printLog) } val content = analyzeRule.getString(contentRule.content ?: "")?.htmlFormat() ?: "" return ContentData(content, nextUrlList) diff --git a/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt b/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt index 2e2342348..43dbeca82 100644 --- a/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt @@ -99,14 +99,7 @@ class SearchActivity : VMBaseActivity(R.layout.activity_book_se search_view.clearFocus() query?.let { viewModel.saveSearchKey(query) - viewModel.search(it, { - refresh_progress_bar.isAutoLoading = true - initData() - fb_stop.visible() - }, { - refresh_progress_bar.isAutoLoading = false - fb_stop.invisible() - }) + viewModel.search(it) } return true } @@ -178,7 +171,7 @@ class SearchActivity : VMBaseActivity(R.layout.activity_book_se } private fun scrollToBottom() { - if (!viewModel.isLoading) { + if (!viewModel.isLoading && viewModel.searchKey.isNotEmpty()) { viewModel.search("") } } @@ -227,6 +220,17 @@ class SearchActivity : VMBaseActivity(R.layout.activity_book_se historyData?.observe(this, Observer { historyKeyAdapter.setItems(it) }) } + override fun startSearch() { + refresh_progress_bar.isAutoLoading = true + initData() + fb_stop.visible() + } + + override fun searchFinally() { + refresh_progress_bar.isAutoLoading = false + fb_stop.invisible() + } + override fun showBookInfo(name: String, author: String) { viewModel.getSearchBook(name, author) { searchBook -> searchBook?.let { diff --git a/app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt b/app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt index 3d8d715d9..9700fafb0 100644 --- a/app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt @@ -25,23 +25,22 @@ class SearchViewModel(application: Application) : BaseViewModel(application) { var isLoading = false private var searchBooks = arrayListOf() - fun search( - key: String, - start: (() -> Unit)? = null, - finally: (() -> Unit)? = null - ) { + fun search(key: String) { task?.cancel() - if (key.isEmpty()) { + if (key.isEmpty() && searchKey.isEmpty()) { + return + } else if (key.isEmpty()) { + isLoading = true searchPage++ - } else { + } else if (key.isNotEmpty()) { + isLoading = true + searchPage = 0 searchKey = key searchBooks.clear() } - if (searchKey.isEmpty()) return startTime = System.currentTimeMillis() - start?.invoke() + callBack?.startSearch() task = execute { - isLoading = true val searchGroup = context.getPrefString("searchGroup") ?: "" val bookSourceList = if (searchGroup.isBlank()) { App.db.bookSourceDao().allEnabled @@ -66,7 +65,7 @@ class SearchViewModel(application: Application) : BaseViewModel(application) { } task?.invokeOnCompletion { - finally?.invoke() + callBack?.searchFinally() isLoading = false } } @@ -176,5 +175,7 @@ class SearchViewModel(application: Application) : BaseViewModel(application) { interface CallBack { var adapter: SearchAdapter + fun startSearch() + fun searchFinally() } } diff --git a/app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugAdapter.kt b/app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugAdapter.kt index 2ec4e9518..7fd07fbda 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugAdapter.kt @@ -1,6 +1,7 @@ package io.legado.app.ui.book.source.debug import android.content.Context +import android.view.View import io.legado.app.R import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.SimpleRecyclerAdapter @@ -10,6 +11,18 @@ class BookSourceDebugAdapter(context: Context) : SimpleRecyclerAdapter(context, R.layout.item_log) { override fun convert(holder: ItemViewHolder, item: String, payloads: MutableList) { holder.itemView.apply { + if (text_view.getTag(R.id.tag1) == null) { + val listener = object : View.OnAttachStateChangeListener { + override fun onViewAttachedToWindow(v: View) { + text_view.isCursorVisible = false + text_view.isCursorVisible = true + } + + override fun onViewDetachedFromWindow(v: View) {} + } + text_view.addOnAttachStateChangeListener(listener) + text_view.setTag(R.id.tag1, listener) + } text_view.text = item } } 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 ec1359b63..20661274d 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 @@ -249,8 +249,11 @@ class BookSourceActivity : VMBaseActivity(R.layout.activity } importSource -> if (resultCode == Activity.RESULT_OK) { data?.data?.let { - FileUtils.getPath(this, it)?.let { path -> + val path = FileUtils.getPath(this, it) + if (path != null) { viewModel.importSourceFromFilePath(path) + } else { + toast(R.string.uri_to_path_fail) } } } diff --git a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt index 7a3b5bb91..4c36f0d59 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt @@ -42,19 +42,25 @@ class BookSourceViewModel(application: Application) : BaseViewModel(application) fun enableSelection(ids: LinkedHashSet) { execute { - App.db.bookSourceDao().enableSection(*ids.toTypedArray()) + ids.forEach { + App.db.bookSourceDao().enableSection(it) + } } } fun disableSelection(ids: LinkedHashSet) { execute { - App.db.bookSourceDao().disableSection(*ids.toTypedArray()) + ids.forEach { + App.db.bookSourceDao().disableSection(it) + } } } fun delSelection(ids: LinkedHashSet) { execute { - App.db.bookSourceDao().delSection(*ids.toTypedArray()) + ids.forEach { + App.db.bookSourceDao().delSection(it) + } } } diff --git a/app/src/main/java/io/legado/app/ui/widget/page/curl/CurlRenderer.kt b/app/src/main/java/io/legado/app/ui/widget/page/curl/CurlRenderer.kt index dc0e124d5..d2125b1f3 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/curl/CurlRenderer.kt +++ b/app/src/main/java/io/legado/app/ui/widget/page/curl/CurlRenderer.kt @@ -14,11 +14,7 @@ import javax.microedition.khronos.opengles.GL10 * * @author harism */ -class CurlRenderer -/** - * Basic constructor. - */ - (private val mObserver: Observer) : GLSurfaceView.Renderer { +class CurlRenderer(private val mObserver: Observer) : GLSurfaceView.Renderer { // Background fill color. private var mBackgroundColor: Int = 0 // Curl meshes used for static and dynamic rendering. @@ -71,10 +67,6 @@ class CurlRenderer gl.glClear(GL10.GL_COLOR_BUFFER_BIT) gl.glLoadIdentity() - if (USE_PERSPECTIVE_PROJECTION) { - gl.glTranslatef(0f, 0f, -6f) - } - for (i in mCurlMeshes.indices) { mCurlMeshes[i].onDrawFrame(gl) } @@ -94,14 +86,10 @@ class CurlRenderer gl.glMatrixMode(GL10.GL_PROJECTION) gl.glLoadIdentity() - if (USE_PERSPECTIVE_PROJECTION) { - GLU.gluPerspective(gl, 20f, width.toFloat() / height, .1f, 100f) - } else { - GLU.gluOrtho2D( - gl, mViewRect.left, mViewRect.right, - mViewRect.bottom, mViewRect.top - ) - } + GLU.gluOrtho2D( + gl, mViewRect.left, mViewRect.right, + mViewRect.bottom, mViewRect.top + ) gl.glMatrixMode(GL10.GL_MODELVIEW) gl.glLoadIdentity() @@ -128,29 +116,6 @@ class CurlRenderer mCurlMeshes.remove(mesh) } - /** - * Change background/clear color. - */ - fun setBackgroundColor(color: Int) { - mBackgroundColor = color - } - - /** - * Set margins or padding. Note: margins are proportional. Meaning a value - * of .1f will produce a 10% margin. - */ - @Synchronized - fun setMargins( - left: Float, top: Float, right: Float, - bottom: Float - ) { - mMargins.left = left - mMargins.top = top - mMargins.right = right - mMargins.bottom = bottom - updatePageRects() - } - /** * Sets visible page count to one or two. Should be either SHOW_ONE_PAGE or * SHOW_TWO_PAGES. @@ -246,7 +211,5 @@ class CurlRenderer // Constants for changing view mode. const val SHOW_ONE_PAGE = 1 const val SHOW_TWO_PAGES = 2 - // Set to true for checking quickly how perspective projection looks. - private const val USE_PERSPECTIVE_PROJECTION = false } } diff --git a/app/src/main/java/io/legado/app/ui/widget/page/curl/CurlView.kt b/app/src/main/java/io/legado/app/ui/widget/page/curl/CurlView.kt index a6089c4bc..2b62974ef 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/curl/CurlView.kt +++ b/app/src/main/java/io/legado/app/ui/widget/page/curl/CurlView.kt @@ -410,14 +410,6 @@ class CurlView : GLSurfaceView, View.OnTouchListener, CurlRenderer.Observer { mEnableTouchPressure = enableTouchPressure } - /** - * Set margins (or padding). Note: margins are proportional. Meaning a value - * of .1f will produce a 10% margin. - */ - fun setMargins(left: Float, top: Float, right: Float, bottom: Float) { - mRenderer.setMargins(left, top, right, bottom) - } - /** * Setter for whether left side page is rendered. This is useful mostly for * situations where right (main) page is aligned to left side of screen and diff --git a/app/src/main/java/io/legado/app/ui/widget/page/delegate/SimulationPageDelegate.kt b/app/src/main/java/io/legado/app/ui/widget/page/delegate/SimulationPageDelegate.kt index d7ee69211..e28b63509 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/delegate/SimulationPageDelegate.kt +++ b/app/src/main/java/io/legado/app/ui/widget/page/delegate/SimulationPageDelegate.kt @@ -56,7 +56,6 @@ class SimulationPageDelegate(pageView: PageView) : HorizontalPageDelegate(pageVi private inner class SizeChangedObserver : CurlView.SizeChangedObserver { override fun onSizeChanged(width: Int, height: Int) { pageView.curlView?.setViewMode(CurlView.SHOW_ONE_PAGE) - pageView.curlView?.setMargins(0f, 0f, 0f, 0f) } } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/utils/FileUtils.kt b/app/src/main/java/io/legado/app/utils/FileUtils.kt index 533504279..39148fe76 100644 --- a/app/src/main/java/io/legado/app/utils/FileUtils.kt +++ b/app/src/main/java/io/legado/app/utils/FileUtils.kt @@ -92,7 +92,7 @@ object FileUtils { // ExternalStorageProvider if (isExternalStorageDocument(uri)) { val docId = DocumentsContract.getDocumentId(uri) - val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + val split = docId.split(":") val type = split[0] if ("primary".equals(type, ignoreCase = true)) { @@ -101,7 +101,7 @@ object FileUtils { } else if (isDownloadsDocument(uri)) { val id = DocumentsContract.getDocumentId(uri) - val split = id.split(":").dropLastWhile { it.isEmpty() }.toTypedArray() + val split = id.split(":") val type = split[0] if ("raw".equals(type, ignoreCase = true)) { //处理某些机型(比如Google Pixel )ID是raw:/storage/emulated/0/Download/c20f8664da05ab6b4644913048ea8c83.mp4 @@ -115,14 +115,13 @@ object FileUtils { return getDataColumn(context, contentUri, null, null) } else if (isMediaDocument(uri)) { val docId = DocumentsContract.getDocumentId(uri) - val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() - val type = split[0] + val split = docId.split(":".toRegex()) - var contentUri: Uri? = null - when (type) { - "image" -> contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI - "video" -> contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI - "audio" -> contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + val contentUri: Uri = when (split[0]) { + "image" -> MediaStore.Images.Media.EXTERNAL_CONTENT_URI + "video" -> MediaStore.Video.Media.EXTERNAL_CONTENT_URI + "audio" -> MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + else -> uri } val selection = "_id=?" @@ -137,7 +136,6 @@ object FileUtils { uri.lastPathSegment else getDataColumn(context, uri, null, null) - } else if ("file".equals(uri.scheme, ignoreCase = true)) { return uri.path }// File @@ -145,8 +143,8 @@ object FileUtils { return null } - fun getDataColumn( - context: Context, uri: Uri?, selection: String?, + private fun getDataColumn( + context: Context, uri: Uri, selection: String?, selectionArgs: kotlin.Array? ): String? { @@ -155,7 +153,7 @@ object FileUtils { try { context.contentResolver.query( - uri!!, + uri, projection, selection, selectionArgs, @@ -177,7 +175,7 @@ object FileUtils { * @param uri The Uri to check. * @return Whether the Uri authority is ExternalStorageProvider. */ - fun isExternalStorageDocument(uri: Uri): Boolean { + private fun isExternalStorageDocument(uri: Uri): Boolean { return "com.android.externalstorage.documents" == uri.authority } @@ -185,7 +183,7 @@ object FileUtils { * @param uri The Uri to check. * @return Whether the Uri authority is DownloadsProvider. */ - fun isDownloadsDocument(uri: Uri): Boolean { + private fun isDownloadsDocument(uri: Uri): Boolean { return "com.android.providers.downloads.documents" == uri.authority } @@ -193,7 +191,7 @@ object FileUtils { * @param uri The Uri to check. * @return Whether the Uri authority is MediaProvider. */ - fun isMediaDocument(uri: Uri): Boolean { + private fun isMediaDocument(uri: Uri): Boolean { return "com.android.providers.media.documents" == uri.authority } @@ -201,7 +199,7 @@ object FileUtils { * @param uri The Uri to check. * @return Whether the Uri authority is Google Photos. */ - fun isGooglePhotosUri(uri: Uri): Boolean { + private fun isGooglePhotosUri(uri: Uri): Boolean { return "com.google.android.apps.photos.content" == uri.authority } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b9d9f260a..dc4bb8af1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -540,5 +540,6 @@ 文件选择 文件夹选择 我是有底线的 + Uri转Path失败