diff --git a/.gitignore b/.gitignore index d32290ef4..700c700fe 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,3 @@ node_modules/ /app/google /app/gradle.properties package-lock.json -18PlusList.txt diff --git a/app/src/main/assets/18PlusList.txt b/app/src/main/assets/18PlusList.txt new file mode 100644 index 000000000..7776c3b14 --- /dev/null +++ b/app/src/main/assets/18PlusList.txt @@ -0,0 +1,2 @@ +OGN5dS5jb20= +c2cwMC54eXo= \ No newline at end of file diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 1b9ae3c09..533d8bdc1 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -3,6 +3,13 @@ * 请关注公众号[开源阅读]()支持我,同时关注合作公众号[小说拾遗](),阅读公众号小编。 * 新公众号[开源阅读]()已启用,[开源阅读软件]()备用 +**2020/05/18** +* 修复http://alanskycn.gitee.io/书源导入失败问题,被屏蔽UA了 + +**2020/05/17** +* 自动翻页功能完成 +* 替换规则输入时弹出辅助输入条 + **2020/05/10** * 添加识别rss分组中的频道信息,在菜单中可以切换频道 from yangyxd * 源管理添加置底,批量置顶,批量置地 diff --git a/app/src/main/java/io/legado/app/constant/AppConst.kt b/app/src/main/java/io/legado/app/constant/AppConst.kt index cf37e2b10..10ffccd1f 100644 --- a/app/src/main/java/io/legado/app/constant/AppConst.kt +++ b/app/src/main/java/io/legado/app/constant/AppConst.kt @@ -20,7 +20,7 @@ object AppConst { const val UA_NAME = "User-Agent" val userAgent: String by lazy { - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36" + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36" } val SCRIPT_ENGINE: ScriptEngine by lazy { diff --git a/app/src/main/java/io/legado/app/help/SourceHelp.kt b/app/src/main/java/io/legado/app/help/SourceHelp.kt index 4cd1ca831..bdb883b10 100644 --- a/app/src/main/java/io/legado/app/help/SourceHelp.kt +++ b/app/src/main/java/io/legado/app/help/SourceHelp.kt @@ -3,8 +3,9 @@ package io.legado.app.help import android.os.Handler import android.os.Looper import io.legado.app.App -import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.RssSource +import io.legado.app.utils.EncoderUtils +import io.legado.app.utils.NetworkUtils import io.legado.app.utils.splitNotBlank import org.jetbrains.anko.toast @@ -32,17 +33,20 @@ object SourceHelp { } } - fun insertBookSource(vararg bookSources: BookSource) { - App.db.bookSourceDao().insert(*bookSources) - } - private fun is18Plus(url: String?): Boolean { url ?: return false if (AppConfig.isGooglePlay) return false - list18Plus.forEach { - if (url.contains(it)) { - return true + val baseUrl = NetworkUtils.getBaseUrl(url) + baseUrl ?: return false + try { + val host = baseUrl.split("//", ".") + val base64Url = EncoderUtils.base64Encode("${host[host.lastIndex - 1]}.${host.last()}") + list18Plus.forEach { + if (base64Url == it) { + return true + } } + } catch (e: Exception) { } return false } diff --git a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt index 31064e268..dd480fbf5 100644 --- a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt +++ b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt @@ -1,5 +1,6 @@ package io.legado.app.help.http +import io.legado.app.constant.AppConst import io.legado.app.help.http.api.HttpGetApi import io.legado.app.utils.NetworkUtils import kotlinx.coroutines.suspendCancellableCoroutine @@ -43,7 +44,11 @@ object HttpHelper { val response = getApiService(baseUrl, encode) .get(url, mapOf()) .execute() - return response.body() + return if (response.body() != null) { + response.body() + } else { + response.errorBody().toString() + } } return null } @@ -90,6 +95,7 @@ object HttpHelper { return Interceptor { chain -> val request = chain.request() .newBuilder() + .addHeader(AppConst.UA_NAME, AppConst.userAgent) .addHeader("Keep-Alive", "300") .addHeader("Connection", "Keep-Alive") .addHeader("Cache-Control", "no-cache") diff --git a/app/src/main/java/io/legado/app/help/storage/OldRule.kt b/app/src/main/java/io/legado/app/help/storage/OldRule.kt index f5919eb2c..b69b35526 100644 --- a/app/src/main/java/io/legado/app/help/storage/OldRule.kt +++ b/app/src/main/java/io/legado/app/help/storage/OldRule.kt @@ -20,7 +20,7 @@ object OldRule { } catch (e: Exception) { null } - runCatching { + try { if (sourceAny?.ruleToc == null) { source.apply { val jsonItem = jsonPath.parse(json.trim()) @@ -125,6 +125,8 @@ object OldRule { GSON.fromJsonObject(GSON.toJson(sourceAny.ruleContent)) } } + } catch (e: Exception) { + e.printStackTrace() } return source } diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt index e8835130a..0c25c6086 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt @@ -85,7 +85,9 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo private val mHandler = Handler() private val keepScreenRunnable: Runnable = Runnable { Help.keepScreenOn(window, false) } - + private val autoPageRunnable: Runnable = Runnable { autoPagePlus() } + override var autoPageProgress = 0 + override var isAutoPage = false private var screenTimeOut: Long = 0 private var timeBatteryReceiver: TimeBatteryReceiver? = null override val pageFactory: TextPageFactory get() = page_view.pageFactory @@ -344,6 +346,10 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo toast(R.string.read_aloud_pause) return true } + if (isAutoPage) { + autoPageStop() + return true + } } } } @@ -558,7 +564,31 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo * 自动翻页 */ override fun autoPage() { + if (isAutoPage) { + autoPageStop() + } else { + isAutoPage = true + autoPagePlus() + } + read_menu.setAutoPage(isAutoPage) + } + + private fun autoPageStop() { + isAutoPage = false + mHandler.removeCallbacks(autoPageRunnable) + page_view.upContent() + } + private fun autoPagePlus() { + mHandler.removeCallbacks(autoPageRunnable) + autoPageProgress++ + if (autoPageProgress >= 460) { + autoPageProgress = 0 + page_view.fillPage(PageDelegate.Direction.NEXT) + } else { + page_view.invalidate() + } + mHandler.postDelayed(autoPageRunnable, 100) } /** diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadMenu.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadMenu.kt index 254d037ad..317af6aab 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadMenu.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadMenu.kt @@ -140,7 +140,11 @@ class ReadMenu : FrameLayout { }) //自动翻页 - fabAutoPage.onClick { callBack?.autoPage() } + fabAutoPage.onClick { + runMenuOut { + callBack?.autoPage() + } + } //替换 fabReplaceRule.onClick { callBack?.openReplaceRule() } diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt index 3a996bfe9..ff93f113a 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt @@ -3,14 +3,19 @@ package io.legado.app.ui.book.read.page import android.annotation.SuppressLint import android.content.Context import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.Rect import android.util.AttributeSet import android.view.MotionEvent import android.widget.FrameLayout import io.legado.app.help.ReadBookConfig +import io.legado.app.lib.theme.accentColor import io.legado.app.service.help.ReadBook import io.legado.app.ui.book.read.page.delegate.* import io.legado.app.ui.book.read.page.entities.TextChapter import io.legado.app.utils.activity +import io.legado.app.utils.screenshot +import kotlinx.android.synthetic.main.activity_book_read.view.* class PageView(context: Context, attrs: AttributeSet) : FrameLayout(context, attrs), @@ -23,6 +28,12 @@ class PageView(context: Context, attrs: AttributeSet) : var prevPage: ContentView = ContentView(context) var curPage: ContentView = ContentView(context) var nextPage: ContentView = ContentView(context) + private val autoPageRect by lazy { Rect() } + private val autoPagePint by lazy { + Paint().apply { + color = context.accentColor + } + } init { addView(nextPage) @@ -44,8 +55,21 @@ class PageView(context: Context, attrs: AttributeSet) : override fun dispatchDraw(canvas: Canvas) { super.dispatchDraw(canvas) - pageDelegate?.onDraw(canvas) + if (callBack.isAutoPage) { + nextPage.screenshot()?.let { + val bottom = page_view.height * callBack.autoPageProgress / 460 + autoPageRect.set(0, 0, page_view.width, bottom) + canvas.drawBitmap(it, autoPageRect, autoPageRect, null) + canvas.drawRect( + 0f, + bottom.toFloat() - 1, + page_view.width.toFloat(), + bottom.toFloat(), + autoPagePint + ) + } + } } override fun computeScroll() { @@ -146,18 +170,18 @@ class PageView(context: Context, attrs: AttributeSet) : override val currentChapter: TextChapter? get() { - return if (callBack.isInitFinish) ReadBook.textChapter(0) else null - } + return if (callBack.isInitFinish) ReadBook.textChapter(0) else null + } override val nextChapter: TextChapter? get() { - return if (callBack.isInitFinish) ReadBook.textChapter(1) else null - } + return if (callBack.isInitFinish) ReadBook.textChapter(1) else null + } override val prevChapter: TextChapter? get() { - return if (callBack.isInitFinish) ReadBook.textChapter(-1) else null - } + return if (callBack.isInitFinish) ReadBook.textChapter(-1) else null + } override fun hasNextChapter(): Boolean { return ReadBook.durChapterIndex < ReadBook.chapterSize - 1 @@ -169,6 +193,8 @@ class PageView(context: Context, attrs: AttributeSet) : interface CallBack { val isInitFinish: Boolean + val isAutoPage: Boolean + val autoPageProgress: Int fun clickCenter() fun screenOffTimerStart() fun showTextActionMenu() diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/delegate/HorizontalPageDelegate.kt b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/HorizontalPageDelegate.kt index f8f9bec74..774f522be 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/delegate/HorizontalPageDelegate.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/HorizontalPageDelegate.kt @@ -104,7 +104,7 @@ abstract class HorizontalPageDelegate(pageView: PageView) : PageDelegate(pageVie } override fun nextPageByAnim() { - super.nextPageByAnim() + abort() if (!hasNext()) return setDirection(Direction.NEXT) setTouchPoint(viewWidth.toFloat(), 0f) @@ -112,7 +112,7 @@ abstract class HorizontalPageDelegate(pageView: PageView) : PageDelegate(pageVie } override fun prevPageByAnim() { - super.prevPageByAnim() + abort() if (!hasPrev()) return setDirection(Direction.PREV) setTouchPoint(0f, 0f) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/delegate/PageDelegate.kt b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/PageDelegate.kt index cd455b641..2f3bf9728 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/delegate/PageDelegate.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/PageDelegate.kt @@ -170,13 +170,9 @@ abstract class PageDelegate(protected val pageView: PageView) : open fun onScroll() {}//移动contentView, slidePage - open fun nextPageByAnim() { - abort() - } + abstract fun nextPageByAnim() - open fun prevPageByAnim() { - abort() - } + abstract fun prevPageByAnim() open fun keyTurnPage(direction: Direction) { if (isRunning) return diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/delegate/ScrollPageDelegate.kt b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/ScrollPageDelegate.kt index 3fa333cbf..b00578ec2 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/delegate/ScrollPageDelegate.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/ScrollPageDelegate.kt @@ -79,12 +79,12 @@ class ScrollPageDelegate(pageView: PageView) : PageDelegate(pageView) { } override fun nextPageByAnim() { - super.nextPageByAnim() + abort() startScroll(0, 0, 0, -ChapterProvider.visibleHeight) } override fun prevPageByAnim() { - super.prevPageByAnim() + abort() startScroll(0, 0, 0, ChapterProvider.visibleHeight) } } \ No newline at end of file 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 5077a71cf..c6dc63c8e 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 @@ -233,6 +233,7 @@ class BookSourceViewModel(application: Application) : BaseViewModel(application) else -> "格式不对" } }.onError { + it.printStackTrace() finally(it.localizedMessage ?: "") }.onSuccess { finally(it) @@ -240,7 +241,11 @@ class BookSourceViewModel(application: Application) : BaseViewModel(application) } private fun importSourceUrl(url: String): Int { - HttpHelper.simpleGet(url, "UTF-8")?.let { body -> + HttpHelper.simpleGet(url, "UTF-8").let { body -> + if (body == null) { + toast("访问网站失败") + return 0 + } val bookSources = mutableListOf() val items: List> = jsonPath.parse(body).read("$") for (item in items) { @@ -252,6 +257,5 @@ class BookSourceViewModel(application: Application) : BaseViewModel(application) App.db.bookSourceDao().insert(*bookSources.toTypedArray()) return bookSources.size } - return 0 } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/replacerule/edit/ReplaceEditDialog.kt b/app/src/main/java/io/legado/app/ui/replacerule/edit/ReplaceEditDialog.kt index 73c64a0e1..0027f3209 100644 --- a/app/src/main/java/io/legado/app/ui/replacerule/edit/ReplaceEditDialog.kt +++ b/app/src/main/java/io/legado/app/ui/replacerule/edit/ReplaceEditDialog.kt @@ -1,26 +1,32 @@ package io.legado.app.ui.replacerule.edit import android.os.Bundle -import android.util.DisplayMetrics import android.view.LayoutInflater import android.view.MenuItem import android.view.View import android.view.ViewGroup +import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.view.ViewGroup.LayoutParams.WRAP_CONTENT +import android.widget.EditText +import android.widget.PopupWindow import androidx.appcompat.widget.Toolbar import androidx.fragment.app.DialogFragment import androidx.fragment.app.FragmentManager import androidx.lifecycle.Observer import io.legado.app.R +import io.legado.app.constant.AppConst import io.legado.app.constant.Theme import io.legado.app.data.entities.ReplaceRule +import io.legado.app.ui.widget.KeyboardToolPop import io.legado.app.utils.applyTint import io.legado.app.utils.getViewModel import io.legado.app.utils.toast import kotlinx.android.synthetic.main.dialog_replace_edit.* +import org.jetbrains.anko.sdk27.listeners.onFocusChange class ReplaceEditDialog : DialogFragment(), - Toolbar.OnMenuItemClickListener { + Toolbar.OnMenuItemClickListener, + KeyboardToolPop.CallBack { companion object { @@ -41,12 +47,11 @@ class ReplaceEditDialog : DialogFragment(), } private lateinit var viewModel: ReplaceEditViewModel + private lateinit var mSoftKeyboardTool: PopupWindow override fun onStart() { super.onStart() - val dm = DisplayMetrics() - activity?.windowManager?.defaultDisplay?.getMetrics(dm) - dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), WRAP_CONTENT) + dialog?.window?.setLayout(MATCH_PARENT, WRAP_CONTENT) } override fun onCreateView( @@ -60,6 +65,7 @@ class ReplaceEditDialog : DialogFragment(), override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + mSoftKeyboardTool = KeyboardToolPop(requireContext(), AppConst.keyboardToolChars, this) tool_bar.inflateMenu(R.menu.replace_edit) tool_bar.menu.applyTint(requireContext(), Theme.getTheme()) tool_bar.setOnMenuItemClickListener(this) @@ -69,12 +75,20 @@ class ReplaceEditDialog : DialogFragment(), arguments?.let { viewModel.initData(it) } + et_replace_rule.onFocusChange { v, hasFocus -> + if (hasFocus) { + mSoftKeyboardTool.width = v.width + mSoftKeyboardTool.showAsDropDown(v) + } else { + mSoftKeyboardTool.dismiss() + } + } } override fun onMenuItemClick(item: MenuItem?): Boolean { when (item?.itemId) { R.id.menu_save -> { - val rule = getReplaceRule(); + val rule = getReplaceRule() if (!rule.isValid()){ toast(R.string.replace_rule_invalid) } @@ -111,6 +125,30 @@ class ReplaceEditDialog : DialogFragment(), val callBack get() = activity as? CallBack + private fun insertText(text: String) { + if (text.isBlank()) return + val view = dialog?.window?.decorView?.findFocus() + if (view is EditText) { + val start = view.selectionStart + val end = view.selectionEnd + val edit = view.editableText//获取EditText的文字 + if (start < 0 || start >= edit.length) { + edit.append(text) + } else { + edit.replace(start, end, text)//光标所在位置插入文字 + } + } + } + + override fun sendText(text: String) { + if (text == AppConst.keyboardToolChars[0]) { + val view = dialog?.window?.decorView?.findFocus() + view?.clearFocus() + } else { + insertText(text) + } + } + interface CallBack { fun onReplaceRuleSave() } diff --git a/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt b/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt index 10f9a718b..5abddf2e0 100644 --- a/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt @@ -17,7 +17,6 @@ import io.legado.app.ui.rss.source.edit.RssSourceEditActivity import io.legado.app.utils.* import kotlinx.android.synthetic.main.activity_rss_artivles.* import org.jetbrains.anko.startActivityForResult -import java.util.* class RssSortActivity : VMBaseActivity(R.layout.activity_rss_artivles) { @@ -44,10 +43,13 @@ class RssSortActivity : VMBaseActivity(R.layout.activity_rss_a return super.onCompatCreateOptionsMenu(menu) } +<<<<<<< HEAD override fun onPrepareOptionsMenu(menu: Menu?): Boolean { return super.onPrepareOptionsMenu(menu) } +======= +>>>>>>> 6c28abcdcd7b57f40de92223ec9e6241805e2b7c override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.menu_edit_source -> viewModel.rssSource?.sourceUrl?.let { @@ -58,9 +60,12 @@ class RssSortActivity : VMBaseActivity(R.layout.activity_rss_a viewModel.clearArticles() } } +<<<<<<< HEAD R.id.menu_switch_layout -> { switchLayout() } +======= +>>>>>>> 6c28abcdcd7b57f40de92223ec9e6241805e2b7c } return super.onCompatOptionsItemSelected(item) }