From 6ed9cdc3ffb0a91cc9047bb34633c1b1f402d60a Mon Sep 17 00:00:00 2001 From: Administrator Date: Sun, 15 Dec 2019 09:38:30 +0800 Subject: [PATCH 01/96] =?UTF-8?q?=E5=A2=9E=E5=8A=A0BookInfo=E9=AB=98?= =?UTF-8?q?=E6=96=AF=E6=A8=A1=E7=B3=8A=E8=83=8C=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 3 +++ app/src/main/AndroidManifest.xml | 3 ++- .../io/legado/app/ui/book/info/BookInfoActivity.kt | 11 +++++++++++ app/src/main/res/layout/activity_book_info.xml | 7 +++++++ app/src/main/res/values/styles.xml | 6 ++++++ 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index c2bc779e2..8bd44a700 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -159,6 +159,9 @@ dependencies { //MarkDown implementation 'ru.noties.markwon:core:3.0.2' + + //高斯模糊 + implementation 'jp.wasabeef:glide-transformations:4.1.0' } apply plugin: 'com.google.gms.google-services' \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6d456ff25..d3eff6243 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -78,7 +78,8 @@ - + diff --git a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt index cf89e975c..9ed5ffb6d 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt @@ -6,6 +6,9 @@ import android.os.Bundle import android.view.Menu import android.view.MenuItem import androidx.lifecycle.Observer +import com.bumptech.glide.Glide +import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions +import com.bumptech.glide.request.RequestOptions.bitmapTransform import io.legado.app.R import io.legado.app.base.VMBaseActivity import io.legado.app.constant.BookType @@ -23,6 +26,7 @@ import io.legado.app.ui.chapterlist.ChapterListActivity import io.legado.app.utils.getViewModel import io.legado.app.utils.gone import io.legado.app.utils.visible +import jp.wasabeef.glide.transformations.BlurTransformation import kotlinx.android.synthetic.main.activity_book_info.* import kotlinx.android.synthetic.main.view_title_bar.* import org.jetbrains.anko.sdk27.listeners.onClick @@ -40,6 +44,7 @@ class BookInfoActivity : VMBaseActivity(R.layout.activity_boo override fun onActivityCreated(savedInstanceState: Bundle?) { setSupportActionBar(toolbar) + title_bar.getBackground().setAlpha(0) viewModel.bookData.observe(this, Observer { showBook(it) }) viewModel.isLoadingData.observe(this, Observer { upLoading(it) }) viewModel.chapterListData.observe(this, Observer { showChapter(it) }) @@ -103,6 +108,12 @@ class BookInfoActivity : VMBaseActivity(R.layout.activity_boo .error(R.drawable.image_cover_default) .centerCrop() .into(iv_cover) + Glide.with(this).load(it) + .transition(DrawableTransitionOptions.withCrossFade(1500)) + .error(R.drawable.image_cover_default) + .centerCrop() + .apply(bitmapTransform(BlurTransformation(125, 6))) + .into(bg_book) //模糊、渐变、缩小效果 } val kinds = book.getKindList() if (kinds.isEmpty()) { diff --git a/app/src/main/res/layout/activity_book_info.xml b/app/src/main/res/layout/activity_book_info.xml index 6fa8db584..fdad506fb 100644 --- a/app/src/main/res/layout/activity_book_info.xml +++ b/app/src/main/res/layout/activity_book_info.xml @@ -6,6 +6,13 @@ android:layout_height="match_parent" android:orientation="vertical"> + + true + + + From 216398e98cd70893dc9ca8fb817f4e60d8c45025 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 15 Dec 2019 21:50:56 +0800 Subject: [PATCH 12/96] up --- .../io/legado/app/ui/about/DonateActivity.kt | 2 -- .../io/legado/app/ui/audio/AudioPlayActivity.kt | 2 -- .../legado/app/ui/book/info/BookInfoActivity.kt | 2 -- .../legado/app/ui/book/read/ReadBookActivity.kt | 2 -- .../ui/book/source/manage/BookSourceActivity.kt | 2 -- .../app/ui/chapterlist/ChapterListActivity.kt | 2 -- .../io/legado/app/ui/config/ConfigActivity.kt | 2 -- .../ui/rss/source/manage/RssSourceActivity.kt | 2 -- .../java/io/legado/app/ui/widget/TitleBar.kt | 17 ----------------- 9 files changed, 33 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/about/DonateActivity.kt b/app/src/main/java/io/legado/app/ui/about/DonateActivity.kt index b5f6c7a8d..32c8d0172 100644 --- a/app/src/main/java/io/legado/app/ui/about/DonateActivity.kt +++ b/app/src/main/java/io/legado/app/ui/about/DonateActivity.kt @@ -13,7 +13,6 @@ import io.legado.app.base.BaseActivity import io.legado.app.lib.theme.ATH import io.legado.app.utils.ACache import kotlinx.android.synthetic.main.activity_donate.* -import kotlinx.android.synthetic.main.view_title_bar.* import org.jetbrains.anko.toast import java.net.URLEncoder @@ -25,7 +24,6 @@ import java.net.URLEncoder class DonateActivity : BaseActivity(R.layout.activity_donate) { override fun onActivityCreated(savedInstanceState: Bundle?) { - setSupportActionBar(toolbar) ATH.applyEdgeEffectColor(scroll_view) vw_zfb_tz.setOnClickListener { aliDonate(this) } cv_wx_gzh.setOnClickListener { diff --git a/app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt b/app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt index 8e389bb37..47d15704e 100644 --- a/app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt +++ b/app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt @@ -26,7 +26,6 @@ import io.legado.app.ui.changesource.ChangeSourceDialog import io.legado.app.ui.chapterlist.ChapterListActivity import io.legado.app.utils.* import kotlinx.android.synthetic.main.activity_audio_play.* -import kotlinx.android.synthetic.main.view_title_bar.* import org.apache.commons.lang3.time.DateFormatUtils import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onLongClick @@ -43,7 +42,6 @@ class AudioPlayActivity : VMBaseActivity(R.layout.activity_a private var adjustProgress = false override fun onActivityCreated(savedInstanceState: Bundle?) { - setSupportActionBar(toolbar) AudioPlay.titleData.observe(this, Observer { title_bar.title = it }) AudioPlay.coverData.observe(this, Observer { upCover(it) }) viewModel.initData(intent) diff --git a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt index ec3b3060a..81af03c04 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt @@ -30,7 +30,6 @@ import io.legado.app.utils.getViewModel import io.legado.app.utils.gone import io.legado.app.utils.visible import kotlinx.android.synthetic.main.activity_book_info.* -import kotlinx.android.synthetic.main.view_title_bar.* import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.startActivity import org.jetbrains.anko.toast @@ -46,7 +45,6 @@ class BookInfoActivity : get() = getViewModel(BookInfoViewModel::class.java) override fun onActivityCreated(savedInstanceState: Bundle?) { - setSupportActionBar(toolbar) title_bar.background.alpha = 0 viewModel.bookData.observe(this, Observer { showBook(it) }) viewModel.isLoadingData.observe(this, Observer { upLoading(it) }) 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 11c9dc5cf..7b9daf6d2 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 @@ -40,7 +40,6 @@ import io.legado.app.utils.* import kotlinx.android.synthetic.main.activity_book_read.* import kotlinx.android.synthetic.main.view_book_page.* import kotlinx.android.synthetic.main.view_read_menu.* -import kotlinx.android.synthetic.main.view_title_bar.* import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.launch @@ -66,7 +65,6 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo override fun onActivityCreated(savedInstanceState: Bundle?) { Help.upLayoutInDisplayCutoutMode(window) - setSupportActionBar(toolbar) initView() ReadBook.callBack = this ReadBook.titleDate.observe(this, Observer { title_bar.title = it }) 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 4623579b7..d2cc149e1 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 @@ -36,7 +36,6 @@ import io.legado.app.utils.* import kotlinx.android.synthetic.main.activity_book_source.* import kotlinx.android.synthetic.main.dialog_edit_text.view.* import kotlinx.android.synthetic.main.view_search.* -import kotlinx.android.synthetic.main.view_title_bar.* import org.jetbrains.anko.startActivity import org.jetbrains.anko.startActivityForResult import org.jetbrains.anko.startService @@ -57,7 +56,6 @@ class BookSourceActivity : VMBaseActivity(R.layout.activity private var groupMenu: SubMenu? = null override fun onActivityCreated(savedInstanceState: Bundle?) { - setSupportActionBar(toolbar) initUriScheme() initRecyclerView() initSearchView() diff --git a/app/src/main/java/io/legado/app/ui/chapterlist/ChapterListActivity.kt b/app/src/main/java/io/legado/app/ui/chapterlist/ChapterListActivity.kt index e1175bc6a..86db52459 100644 --- a/app/src/main/java/io/legado/app/ui/chapterlist/ChapterListActivity.kt +++ b/app/src/main/java/io/legado/app/ui/chapterlist/ChapterListActivity.kt @@ -17,7 +17,6 @@ import io.legado.app.utils.gone import io.legado.app.utils.visible import kotlinx.android.synthetic.main.activity_chapter_list.* import kotlinx.android.synthetic.main.view_tab_layout.* -import kotlinx.android.synthetic.main.view_title_bar.* class ChapterListActivity : VMBaseActivity(R.layout.activity_chapter_list) { override val viewModel: ChapterListViewModel @@ -26,7 +25,6 @@ class ChapterListActivity : VMBaseActivity(R.layout.activi private var searchView: SearchView? = null override fun onActivityCreated(savedInstanceState: Bundle?) { - setSupportActionBar(toolbar) tab_layout.setSelectedTabIndicatorColor(accentColor) viewModel.bookUrl = intent.getStringExtra("bookUrl") viewModel.loadBook { diff --git a/app/src/main/java/io/legado/app/ui/config/ConfigActivity.kt b/app/src/main/java/io/legado/app/ui/config/ConfigActivity.kt index a926a8ae2..838b5c31d 100644 --- a/app/src/main/java/io/legado/app/ui/config/ConfigActivity.kt +++ b/app/src/main/java/io/legado/app/ui/config/ConfigActivity.kt @@ -5,7 +5,6 @@ import io.legado.app.R import io.legado.app.base.VMBaseActivity import io.legado.app.utils.getViewModel import kotlinx.android.synthetic.main.activity_config.* -import kotlinx.android.synthetic.main.view_title_bar.* class ConfigActivity : VMBaseActivity(R.layout.activity_config) { override val viewModel: ConfigViewModel @@ -15,7 +14,6 @@ class ConfigActivity : VMBaseActivity(R.layout.activity_config) intent.getIntExtra("configType", -1).let { if (it != -1) viewModel.configType = it } - this.setSupportActionBar(toolbar) when (viewModel.configType) { ConfigViewModel.TYPE_CONFIG -> { 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 08f03ac8f..a75134288 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 @@ -35,7 +35,6 @@ import io.legado.app.utils.* import kotlinx.android.synthetic.main.activity_rss_source.* import kotlinx.android.synthetic.main.dialog_edit_text.view.* import kotlinx.android.synthetic.main.view_search.* -import kotlinx.android.synthetic.main.view_title_bar.* import org.jetbrains.anko.startActivity import org.jetbrains.anko.startActivityForResult @@ -55,7 +54,6 @@ class RssSourceActivity : VMBaseActivity(R.layout.activity_r private var groupMenu: SubMenu? = null override fun onActivityCreated(savedInstanceState: Bundle?) { - setSupportActionBar(toolbar) initRecyclerView() initSearchView() initLiveDataGroup() diff --git a/app/src/main/java/io/legado/app/ui/widget/TitleBar.kt b/app/src/main/java/io/legado/app/ui/widget/TitleBar.kt index d516601d9..7001c3999 100644 --- a/app/src/main/java/io/legado/app/ui/widget/TitleBar.kt +++ b/app/src/main/java/io/legado/app/ui/widget/TitleBar.kt @@ -2,7 +2,6 @@ package io.legado.app.ui.widget import android.content.Context import android.content.res.ColorStateList -import android.graphics.Color import android.graphics.PorterDuff import android.graphics.drawable.Drawable import android.util.AttributeSet @@ -14,9 +13,7 @@ import androidx.appcompat.widget.Toolbar import androidx.core.graphics.drawable.DrawableCompat import com.google.android.material.appbar.AppBarLayout import io.legado.app.R -import io.legado.app.lib.theme.DrawableUtils import io.legado.app.lib.theme.primaryColor -import io.legado.app.lib.theme.primaryTextColor import io.legado.app.utils.activity import io.legado.app.utils.getNavigationBarHeight import io.legado.app.utils.getStatusBarHeight @@ -190,20 +187,6 @@ class TitleBar(context: Context, attrs: AttributeSet?) : AppBarLayout(context, a it.supportActionBar?.setDisplayHomeAsUpEnabled(displayHomeAsUp) } } - - val primaryTextColor = if (isInEditMode) Color.BLACK else context.primaryTextColor - DrawableUtils.setTint(toolbar.overflowIcon, primaryTextColor) - toolbar.setTitleTextColor(primaryTextColor) - - if (navigationIconTint != null) { - wrapDrawableTint(toolbar.navigationIcon, navigationIconTint, navigationIconTintMode) - } else { - wrapDrawableTint( - toolbar.navigationIcon, - ColorStateList.valueOf(primaryTextColor), - navigationIconTintMode - ) - } } private fun wrapDrawableTint(drawable: Drawable?, tintList: ColorStateList?, tintMode: Int) { From 2c24d4c9f4c4a18d7a0b94ccfaec6453eca4c1a5 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 15 Dec 2019 21:55:35 +0800 Subject: [PATCH 13/96] up --- .../java/io/legado/app/ui/widget/TitleBar.kt | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/widget/TitleBar.kt b/app/src/main/java/io/legado/app/ui/widget/TitleBar.kt index 7001c3999..ab931f3ab 100644 --- a/app/src/main/java/io/legado/app/ui/widget/TitleBar.kt +++ b/app/src/main/java/io/legado/app/ui/widget/TitleBar.kt @@ -2,15 +2,12 @@ package io.legado.app.ui.widget import android.content.Context import android.content.res.ColorStateList -import android.graphics.PorterDuff -import android.graphics.drawable.Drawable import android.util.AttributeSet import android.view.Menu import android.view.View import androidx.annotation.ColorInt import androidx.annotation.StyleRes import androidx.appcompat.widget.Toolbar -import androidx.core.graphics.drawable.DrawableCompat import com.google.android.material.appbar.AppBarLayout import io.legado.app.R import io.legado.app.lib.theme.primaryColor @@ -189,34 +186,4 @@ class TitleBar(context: Context, attrs: AttributeSet?) : AppBarLayout(context, a } } - private fun wrapDrawableTint(drawable: Drawable?, tintList: ColorStateList?, tintMode: Int) { - if (drawable == null || tintList == null) return - val wrappedDrawable = DrawableCompat.wrap(drawable.mutate()) - DrawableCompat.setTintList(wrappedDrawable, tintList) - DrawableCompat.setTintMode(wrappedDrawable, intToMode(tintMode)) - } - - private fun intToMode(`val`: Int): PorterDuff.Mode { - when (`val`) { - 0 -> return PorterDuff.Mode.CLEAR - 1 -> return PorterDuff.Mode.SRC - 2 -> return PorterDuff.Mode.DST - 3 -> return PorterDuff.Mode.SRC_OVER - 4 -> return PorterDuff.Mode.DST_OVER - 5 -> return PorterDuff.Mode.SRC_IN - 6 -> return PorterDuff.Mode.DST_IN - 7 -> return PorterDuff.Mode.SRC_OUT - 8 -> return PorterDuff.Mode.DST_OUT - 9 -> return PorterDuff.Mode.SRC_ATOP - 10 -> return PorterDuff.Mode.DST_ATOP - 11 -> return PorterDuff.Mode.XOR - 16 -> return PorterDuff.Mode.DARKEN - 17 -> return PorterDuff.Mode.LIGHTEN - 13 -> return PorterDuff.Mode.MULTIPLY - 14 -> return PorterDuff.Mode.SCREEN - 12 -> return PorterDuff.Mode.ADD - 15 -> return PorterDuff.Mode.OVERLAY - else -> return PorterDuff.Mode.CLEAR - } - } } \ No newline at end of file From 0de6928a8fdfd1e9ff171dd2f9688c0b1a1c3efd Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 15 Dec 2019 22:06:40 +0800 Subject: [PATCH 14/96] up --- app/src/main/AndroidManifest.xml | 3 +-- app/src/main/java/io/legado/app/base/BaseActivity.kt | 12 +++++++++--- .../main/java/io/legado/app/base/VMBaseActivity.kt | 4 ++-- .../io/legado/app/ui/book/info/BookInfoActivity.kt | 2 +- app/src/main/res/values/styles.xml | 7 +------ 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d3eff6243..6d456ff25 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -78,8 +78,7 @@ - + diff --git a/app/src/main/java/io/legado/app/base/BaseActivity.kt b/app/src/main/java/io/legado/app/base/BaseActivity.kt index 3c645407a..cff1863e7 100644 --- a/app/src/main/java/io/legado/app/base/BaseActivity.kt +++ b/app/src/main/java/io/legado/app/base/BaseActivity.kt @@ -22,7 +22,7 @@ import kotlinx.coroutines.cancel abstract class BaseActivity( private val layoutID: Int, private val fullScreen: Boolean = true, - private val initTheme: Boolean = true + private val theme: Theme = Theme.Auto ) : AppCompatActivity(), CoroutineScope by MainScope() { @@ -76,8 +76,10 @@ abstract class BaseActivity( private fun initTheme() { ATH.applyBackgroundTint(window.decorView) - if (initTheme) { - if (ColorUtils.isColorLight(primaryColor)) { + when (theme) { + Theme.Dark -> setTheme(R.style.AppTheme_Dark) + Theme.Light -> setTheme(R.style.AppTheme_Light) + else -> if (ColorUtils.isColorLight(primaryColor)) { setTheme(R.style.AppTheme_Light) } else { setTheme(R.style.AppTheme_Dark) @@ -105,4 +107,8 @@ abstract class BaseActivity( currentFocus?.hideSoftInput() super.finish() } + + enum class Theme { + Dark, Light, Auto + } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/base/VMBaseActivity.kt b/app/src/main/java/io/legado/app/base/VMBaseActivity.kt index e52067060..65d8e123d 100644 --- a/app/src/main/java/io/legado/app/base/VMBaseActivity.kt +++ b/app/src/main/java/io/legado/app/base/VMBaseActivity.kt @@ -5,8 +5,8 @@ import androidx.lifecycle.ViewModel abstract class VMBaseActivity( layoutID: Int, fullScreen: Boolean = true, - initTheme: Boolean = true -) : BaseActivity(layoutID, fullScreen, initTheme) { + theme: Theme = Theme.Auto +) : BaseActivity(layoutID, fullScreen, theme) { protected abstract val viewModel: VM diff --git a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt index 81af03c04..a7f1aad4a 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt @@ -36,7 +36,7 @@ import org.jetbrains.anko.toast class BookInfoActivity : - VMBaseActivity(R.layout.activity_book_info, initTheme = false), + VMBaseActivity(R.layout.activity_book_info, theme = Theme.Dark), GroupSelectDialog.CallBack, ChapterListAdapter.CallBack, ChangeSourceDialog.CallBack { diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 61054e519..ec0b50735 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -23,12 +23,6 @@ true - - - $content", - "text/html", - "utf-8", - url - ) + webView.loadDataWithBaseURL(url, content, "text/html", "utf-8", url) } else { - webView.loadData( - "$content", - "text/html", - "utf-8" - ) + webView.loadData(content, "text/html", "utf-8") } } }) From 4fdc262089f159704b96515a799532fc1d175fb4 Mon Sep 17 00:00:00 2001 From: kunfei Date: Wed, 18 Dec 2019 12:31:07 +0800 Subject: [PATCH 28/96] up --- .../io/legado/app/ui/rss/read/ReadRssActivity.kt | 5 +++-- .../io/legado/app/ui/rss/read/ReadRssViewModel.kt | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) 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 4417d8fba..f20be3f87 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 @@ -59,10 +59,11 @@ class ReadRssActivity : VMBaseActivity(R.layout.activity_rss_r viewModel.rssArticle?.let { upJavaScriptEnable() val url = NetworkUtils.getAbsoluteURL(it.origin, it.link) + val html = viewModel.clHtml(content) if (viewModel.rssSource?.loadWithBaseUrl == true) { - webView.loadDataWithBaseURL(url, content, "text/html", "utf-8", url) + webView.loadDataWithBaseURL(url, html, "text/html", "utf-8", url) } else { - webView.loadData(content, "text/html", "utf-8") + webView.loadData(html, "text/html", "utf-8") } } }) diff --git a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt index 52c090072..8c6f56279 100644 --- a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt @@ -77,6 +77,19 @@ class ReadRssViewModel(application: Application) : BaseViewModel(application) { } } + fun clHtml(content: String): String { + return """ + + + + + + + $content + + """ + } + interface CallBack { fun upStarMenu() } From 593e66f145d7c32145a6c8f9bac2df6dd5a42dbf Mon Sep 17 00:00:00 2001 From: kunfei Date: Wed, 18 Dec 2019 20:38:33 +0800 Subject: [PATCH 29/96] up --- .../app/ui/book/read/ReadBookActivity.kt | 29 ++++++- .../res/layout/dialog_download_choice.xml | 78 +++++++++++++++++++ 2 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 app/src/main/res/layout/dialog_download_choice.xml 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 7b9daf6d2..23bec9842 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 @@ -1,5 +1,6 @@ package io.legado.app.ui.book.read +import android.annotation.SuppressLint import android.app.Activity import android.content.Intent import android.net.Uri @@ -8,6 +9,7 @@ import android.text.SpannableStringBuilder import android.view.KeyEvent import android.view.Menu import android.view.MenuItem +import android.view.View import androidx.core.view.isVisible import androidx.lifecycle.Observer import com.jaredrummler.android.colorpicker.ColorPickerDialogListener @@ -18,11 +20,10 @@ import io.legado.app.constant.Status import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter import io.legado.app.help.ReadBookConfig -import io.legado.app.lib.dialogs.alert -import io.legado.app.lib.dialogs.noButton -import io.legado.app.lib.dialogs.okButton +import io.legado.app.lib.dialogs.* import io.legado.app.receiver.TimeElectricityReceiver import io.legado.app.service.BaseReadAloudService +import io.legado.app.service.help.Download import io.legado.app.service.help.ReadAloud import io.legado.app.service.help.ReadBook import io.legado.app.ui.book.read.config.* @@ -38,6 +39,7 @@ import io.legado.app.ui.widget.page.PageView import io.legado.app.ui.widget.page.delegate.PageDelegate import io.legado.app.utils.* import kotlinx.android.synthetic.main.activity_book_read.* +import kotlinx.android.synthetic.main.dialog_download_choice.view.* import kotlinx.android.synthetic.main.view_book_page.* import kotlinx.android.synthetic.main.view_read_menu.* import kotlinx.coroutines.Dispatchers.IO @@ -131,6 +133,7 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo /** * 菜单 */ + @SuppressLint("InflateParams") override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.menu_change_source -> { @@ -146,6 +149,26 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo viewModel.refreshContent(it) } } + R.id.menu_download -> ReadBook.book?.let { book -> + alert(titleResource = R.string.download_offline) { + var view: View? = null + customView { + layoutInflater.inflate(R.layout.dialog_download_choice, null).apply { + view = this + edit_start.setText(book.durChapterIndex.toString()) + edit_end.setText(book.totalChapterNum.toString()) + } + } + yesButton { + view?.apply { + val start = edit_start?.text?.toString()?.toInt() ?: 0 + val end = edit_end?.text?.toString()?.toInt() ?: book.totalChapterNum + Download.start(this@ReadBookActivity, book.bookUrl, start, end) + } + } + noButton() + }.show().applyTint() + } } return super.onCompatOptionsItemSelected(item) } diff --git a/app/src/main/res/layout/dialog_download_choice.xml b/app/src/main/res/layout/dialog_download_choice.xml new file mode 100644 index 000000000..9eabee75b --- /dev/null +++ b/app/src/main/res/layout/dialog_download_choice.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + From 86fdd1b2dc8d3b4ef7eafa2e8705791c53924085 Mon Sep 17 00:00:00 2001 From: kunfei Date: Wed, 18 Dec 2019 21:31:12 +0800 Subject: [PATCH 30/96] up --- .../legado/app/ui/widget/page/ChapterProvider.kt | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/widget/page/ChapterProvider.kt b/app/src/main/java/io/legado/app/ui/widget/page/ChapterProvider.kt index 80c21103a..25b68e6c3 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/ChapterProvider.kt +++ b/app/src/main/java/io/legado/app/ui/widget/page/ChapterProvider.kt @@ -4,6 +4,8 @@ import android.text.Spannable import android.text.SpannableStringBuilder import android.text.style.ForegroundColorSpan import android.text.style.RelativeSizeSpan +import androidx.core.text.HtmlCompat +import androidx.core.text.HtmlCompat.FROM_HTML_MODE_COMPACT import io.legado.app.App import io.legado.app.data.entities.BookChapter import io.legado.app.lib.theme.accentColor @@ -17,7 +19,9 @@ object ChapterProvider { fun getTextChapter( bookChapter: BookChapter, - content: String, chapterSize: Int + content: String, + chapterSize: Int, + isHtml: Boolean = false ): TextChapter { textView?.let { val textPages = arrayListOf() @@ -26,7 +30,15 @@ object ChapterProvider { var surplusText = content var pageIndex = 0 while (surplusText.isNotEmpty()) { - val spannableStringBuilder = SpannableStringBuilder(surplusText) + val spannableStringBuilder = + if (isHtml) { + HtmlCompat.fromHtml( + surplusText, + FROM_HTML_MODE_COMPACT + ) as SpannableStringBuilder + } else { + SpannableStringBuilder(surplusText) + } if (pageIndex == 0) { val end = surplusText.indexOf("\n") if (end > 0) { From 18a524266bf7ec234512d6e4a1dd92a20a039aa2 Mon Sep 17 00:00:00 2001 From: Administrator Date: Wed, 18 Dec 2019 22:45:36 +0800 Subject: [PATCH 31/96] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ui/book/search/SearchActivity.kt | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) 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 72008b68a..0ffefda51 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 @@ -3,6 +3,8 @@ package io.legado.app.ui.book.search import android.os.Bundle import android.view.Menu import android.view.MenuItem +import android.view.View.GONE +import android.view.View.VISIBLE import androidx.appcompat.widget.SearchView import androidx.lifecycle.LiveData import androidx.lifecycle.Observer @@ -28,6 +30,7 @@ import kotlinx.coroutines.withContext import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.startActivity + class SearchActivity : VMBaseActivity(R.layout.activity_book_search), SearchViewModel.CallBack, BookAdapter.CallBack, @@ -110,10 +113,10 @@ class SearchActivity : VMBaseActivity(R.layout.activity_book_se } }) search_view.setOnQueryTextFocusChangeListener { _, hasFocus -> - if (hasFocus) { - ll_history.visible() + if (!hasFocus && search_view.query.toString().trim().isEmpty()) { + finish() } else { - ll_history.invisible() + openOrCloseHistory(hasFocus) } } } @@ -175,6 +178,15 @@ class SearchActivity : VMBaseActivity(R.layout.activity_book_se } } + private fun openOrCloseHistory(open: Boolean) { + if (open) { + upHistory("") + ll_history.visibility = VISIBLE + } else { + ll_history.visibility = GONE + } + } + private fun upGroupMenu() { val selectedGroup = getPrefString("searchGroup") ?: "" menu?.removeGroup(R.id.source_group) @@ -216,7 +228,13 @@ class SearchActivity : VMBaseActivity(R.layout.activity_book_se } else { App.db.searchKeywordDao().liveDataSearch(key) } - historyData?.observe(this, Observer { historyKeyAdapter.setItems(it) }) + historyData?.observe(this, Observer { historyKeyAdapter.setItems(it) + if (it.isEmpty()) { + tv_clear_history.invisible() + } else { + tv_clear_history.visible() + } + }) } override fun startSearch() { @@ -254,4 +272,4 @@ class SearchActivity : VMBaseActivity(R.layout.activity_book_se } } } -} +} \ No newline at end of file From ce275cc483e5ba9e5c96e41c4b4e8b22c6adf09c Mon Sep 17 00:00:00 2001 From: kunfei Date: Thu, 19 Dec 2019 21:43:21 +0800 Subject: [PATCH 32/96] up --- .../java/io/legado/app/ui/book/read/ReadBookActivity.kt | 6 ++++++ 1 file changed, 6 insertions(+) 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 23bec9842..f7fd36db6 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 @@ -169,6 +169,12 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo noButton() }.show().applyTint() } + R.id.menu_add_bookmark -> { + + } + R.id.menu_copy_text -> { + + } } return super.onCompatOptionsItemSelected(item) } From 11a58cc54a4c67a939640c5113fe73bf60bdf73b Mon Sep 17 00:00:00 2001 From: kunfei Date: Fri, 20 Dec 2019 10:53:53 +0800 Subject: [PATCH 33/96] up --- .../java/io/legado/app/ui/main/MainActivity.kt | 11 +++-------- .../io/legado/app/ui/rss/read/ReadRssActivity.kt | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/main/MainActivity.kt b/app/src/main/java/io/legado/app/ui/main/MainActivity.kt index 1b5966efb..a059e380d 100644 --- a/app/src/main/java/io/legado/app/ui/main/MainActivity.kt +++ b/app/src/main/java/io/legado/app/ui/main/MainActivity.kt @@ -13,7 +13,6 @@ import io.legado.app.BuildConfig import io.legado.app.R import io.legado.app.base.VMBaseActivity import io.legado.app.constant.Bus -import io.legado.app.help.ActivityHelp import io.legado.app.help.storage.Backup import io.legado.app.lib.theme.ATH import io.legado.app.service.BaseReadAloudService @@ -113,14 +112,10 @@ class MainActivity : VMBaseActivity(R.layout.activity_main), } override fun finish() { - if (ActivityHelp.size() > 1) { - moveTaskToBack(true) - } else { - if (!BuildConfig.DEBUG) { - Backup.autoBackup() - } - super.finish() + if (!BuildConfig.DEBUG) { + Backup.autoBackup() } + super.finish() } override fun onDestroy() { 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 f20be3f87..5eb701ebc 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 @@ -2,6 +2,7 @@ package io.legado.app.ui.rss.read import android.annotation.SuppressLint import android.os.Bundle +import android.view.KeyEvent import android.view.Menu import android.view.MenuItem import android.webkit.WebSettings @@ -90,4 +91,18 @@ class ReadRssActivity : VMBaseActivity(R.layout.activity_rss_r } DrawableUtils.setTint(starMenuItem?.icon, primaryTextColor) } + + override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean { + event?.let { + when (keyCode) { + KeyEvent.KEYCODE_BACK -> if (event.isTracking && !event.isCanceled && webView.canGoBack()) { + if (webView.copyBackForwardList().size > 1) { + webView.goBack() + return true + } + } + } + } + return super.onKeyUp(keyCode, event) + } } \ No newline at end of file From 0d060a5ec87b260d94464e5924c133d5ea2dff5a Mon Sep 17 00:00:00 2001 From: kunfei Date: Fri, 20 Dec 2019 11:30:00 +0800 Subject: [PATCH 34/96] up --- .../java/io/legado/app/ui/rss/read/ReadRssActivity.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) 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 5eb701ebc..9fc29878b 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 @@ -92,6 +92,16 @@ class ReadRssActivity : VMBaseActivity(R.layout.activity_rss_r DrawableUtils.setTint(starMenuItem?.icon, primaryTextColor) } + override fun onKeyLongPress(keyCode: Int, event: KeyEvent?): Boolean { + when (keyCode) { + KeyEvent.KEYCODE_BACK -> { + finish() + return true + } + } + return super.onKeyLongPress(keyCode, event) + } + override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean { event?.let { when (keyCode) { From ad6f9c4f27ab38b9ad0075e63bb9f0e2fed40429 Mon Sep 17 00:00:00 2001 From: kunfei Date: Fri, 20 Dec 2019 13:59:08 +0800 Subject: [PATCH 35/96] up --- .../java/io/legado/app/help/storage/OldRule.kt | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) 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 1c180838c..c4c9a0818 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 @@ -5,11 +5,7 @@ import io.legado.app.constant.BookType import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.rule.* import io.legado.app.help.storage.Restore.jsonPath -import io.legado.app.utils.GSON -import io.legado.app.utils.fromJsonObject -import io.legado.app.utils.readInt -import io.legado.app.utils.readString -import io.legado.app.utils.readBool +import io.legado.app.utils.* import java.util.regex.Pattern object OldRule { @@ -129,7 +125,10 @@ object OldRule { newRule = newRule.replace("|", "||") } } - if (newRule.contains("&") && !newRule.contains("&&")) { + if (newRule.contains("&") + && !newRule.contains("&&") + && !newRule.contains("http") + ) { newRule = newRule.replace("&", "&&") } } @@ -145,10 +144,9 @@ object OldRule { return toNewUrl(oldUrls) val urls = oldUrls.split("(&&|\n)+".toRegex()) - val newUrls = urls.map { - toNewUrl(it)?.replace("\n\\s*".toRegex(),"") + return urls.map { + toNewUrl(it)?.replace("\n\\s*".toRegex(), "") }.joinToString("\n") - return newUrls } private fun toNewUrl(oldUrl: String?): String? { From f3478cb0f4ae0670da9d7adacbc5295a540c6fe1 Mon Sep 17 00:00:00 2001 From: kunfei Date: Fri, 20 Dec 2019 14:18:01 +0800 Subject: [PATCH 36/96] up --- app/src/main/java/io/legado/app/help/storage/OldRule.kt | 1 + 1 file changed, 1 insertion(+) 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 c4c9a0818..0c9baa659 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 @@ -128,6 +128,7 @@ object OldRule { if (newRule.contains("&") && !newRule.contains("&&") && !newRule.contains("http") + && !newRule.startsWith("/") ) { newRule = newRule.replace("&", "&&") } From 72001bee30398e2e677fa7fa8eaf85ae690fc19f Mon Sep 17 00:00:00 2001 From: kunfei Date: Fri, 20 Dec 2019 16:06:00 +0800 Subject: [PATCH 37/96] up --- app/src/main/assets/updateLog.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 721545ff0..21a7c6e0d 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -4,6 +4,12 @@ * 先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】,提示存储权限,选择允许即可导入成功。 * 注意:由于安卓10更改了权限策略,还需要给「允许安装其他应用」的权限才能导入源。MIUI11也需要此权限。 +**2019/12/20** +* 阅读界面的下载菜单可以用了 +* rss阅读bug修复,webView内可以用返回建返回上一链接 +* 优化搜索界面逻辑 +* 导入旧书源时url里的&不再转为&& + **2019/12/16** * 添加几个主题选择 * 音频播放添加header支持 From 9ec48a75dace952b229267528cc1021ea23df245 Mon Sep 17 00:00:00 2001 From: kunfei Date: Fri, 20 Dec 2019 16:24:44 +0800 Subject: [PATCH 38/96] up --- app/src/main/res/layout/item_bookshelf_grid.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/layout/item_bookshelf_grid.xml b/app/src/main/res/layout/item_bookshelf_grid.xml index 0160a1896..4ed7e8158 100644 --- a/app/src/main/res/layout/item_bookshelf_grid.xml +++ b/app/src/main/res/layout/item_bookshelf_grid.xml @@ -12,7 +12,7 @@ Date: Fri, 20 Dec 2019 16:26:26 +0800 Subject: [PATCH 39/96] up --- app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt index 485b3d02b..f5568d4bb 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt @@ -111,6 +111,7 @@ class BookInfoActivity : tv_intro.text = book.getDisplayIntro() book.getDisplayCover()?.let { ImageLoader.load(this, it) + .dontAnimate() .error(R.drawable.image_cover_default) .centerCrop() .into(iv_cover) From 424dbf9238dceb9dc4ffdde0a8c73331b977d59f Mon Sep 17 00:00:00 2001 From: kunfei Date: Fri, 20 Dec 2019 16:34:52 +0800 Subject: [PATCH 40/96] up --- .../main/java/io/legado/app/ui/book/info/BookInfoActivity.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt index f5568d4bb..c55c1812c 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt @@ -111,8 +111,6 @@ class BookInfoActivity : tv_intro.text = book.getDisplayIntro() book.getDisplayCover()?.let { ImageLoader.load(this, it) - .dontAnimate() - .error(R.drawable.image_cover_default) .centerCrop() .into(iv_cover) ImageLoader.load(this, it) From 946613102eab14b9ab52e0e8aabf1845b6ce05a9 Mon Sep 17 00:00:00 2001 From: kunfei Date: Fri, 20 Dec 2019 16:35:36 +0800 Subject: [PATCH 41/96] up --- app/src/main/assets/updateLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 21a7c6e0d..169510a32 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -9,6 +9,7 @@ * rss阅读bug修复,webView内可以用返回建返回上一链接 * 优化搜索界面逻辑 * 导入旧书源时url里的&不再转为&& +* 修复书架封面显示不全的bug **2019/12/16** * 添加几个主题选择 From 62e99caf75d03f4752ce310add6555dd50ca778a Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 21 Dec 2019 10:51:39 +0800 Subject: [PATCH 42/96] up --- .../main/java/io/legado/app/ui/book/search/SearchActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 0ffefda51..2cf9cae3d 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 @@ -180,7 +180,7 @@ class SearchActivity : VMBaseActivity(R.layout.activity_book_se private fun openOrCloseHistory(open: Boolean) { if (open) { - upHistory("") + upHistory(search_view.query.toString()) ll_history.visibility = VISIBLE } else { ll_history.visibility = GONE From f8d6aafac11c45d2d5c7ed870aea74a67372254a Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 21 Dec 2019 11:02:28 +0800 Subject: [PATCH 43/96] up --- app/src/main/java/io/legado/app/ui/widget/page/DataSource.kt | 2 -- .../main/java/io/legado/app/ui/widget/page/PageFactory.kt | 2 -- app/src/main/java/io/legado/app/ui/widget/page/PageView.kt | 4 ---- .../java/io/legado/app/ui/widget/page/TextPageFactory.kt | 5 ----- 4 files changed, 13 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/widget/page/DataSource.kt b/app/src/main/java/io/legado/app/ui/widget/page/DataSource.kt index e10a48d8a..d7efe18a5 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/DataSource.kt +++ b/app/src/main/java/io/legado/app/ui/widget/page/DataSource.kt @@ -9,8 +9,6 @@ interface DataSource { fun getChapterPosition(): Int - fun getChapter(position: Int): TextChapter? - fun getCurrentChapter(): TextChapter? fun getNextChapter(): TextChapter? diff --git a/app/src/main/java/io/legado/app/ui/widget/page/PageFactory.kt b/app/src/main/java/io/legado/app/ui/widget/page/PageFactory.kt index f9b9ca4cb..72eaa5eda 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/PageFactory.kt +++ b/app/src/main/java/io/legado/app/ui/widget/page/PageFactory.kt @@ -2,8 +2,6 @@ package io.legado.app.ui.widget.page abstract class PageFactory(protected val dataSource: DataSource) { - abstract fun pageAt(index: Int): DATA? - abstract fun moveToFirst() abstract fun moveToLast() diff --git a/app/src/main/java/io/legado/app/ui/widget/page/PageView.kt b/app/src/main/java/io/legado/app/ui/widget/page/PageView.kt index ec4693ffb..759ee2c46 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/PageView.kt +++ b/app/src/main/java/io/legado/app/ui/widget/page/PageView.kt @@ -190,10 +190,6 @@ class PageView(context: Context, attrs: AttributeSet) : return ReadBook.durChapterIndex } - override fun getChapter(position: Int): TextChapter? { - return ReadBook.textChapter(position) - } - override fun getCurrentChapter(): TextChapter? { return ReadBook.textChapter(0) } diff --git a/app/src/main/java/io/legado/app/ui/widget/page/TextPageFactory.kt b/app/src/main/java/io/legado/app/ui/widget/page/TextPageFactory.kt index d25acb1ef..d5aaa68d7 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/TextPageFactory.kt +++ b/app/src/main/java/io/legado/app/ui/widget/page/TextPageFactory.kt @@ -21,11 +21,6 @@ class TextPageFactory(dataSource: DataSource) : PageFactory(dataSource } } - override fun pageAt(index: Int): TextPage { - return dataSource.getCurrentChapter()?.page(index) - ?: TextPage(index = index, title = "index:$index") - } - override fun moveToFirst() { dataSource.setPageIndex(0) } From 8990bba2dbbd13e9bc8fc0ed75f663d64c7472d0 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 21 Dec 2019 11:13:12 +0800 Subject: [PATCH 44/96] up --- .../java/io/legado/app/ui/book/read/ReadBookActivity.kt | 3 +++ .../java/io/legado/app/ui/book/read/ReadBookViewModel.kt | 4 ++++ app/src/main/java/io/legado/app/ui/widget/page/PageView.kt | 7 ++++--- 3 files changed, 11 insertions(+), 3 deletions(-) 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 f7fd36db6..c166d4b96 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 @@ -60,6 +60,9 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo override val viewModel: ReadBookViewModel get() = getViewModel(ReadBookViewModel::class.java) + override val isInitFinish: Boolean + get() = viewModel.isInitFinish + private val requestCodeChapterList = 568 private val requestCodeEditSource = 111 private val requestCodeReplace = 31242 diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt index 66d0a0b71..c45095a7e 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt @@ -19,6 +19,8 @@ import kotlinx.coroutines.withContext class ReadBookViewModel(application: Application) : BaseViewModel(application) { + var isInitFinish = false + fun initData(intent: Intent) { execute { ReadBook.inBookshelf = intent.getBooleanExtra("inBookshelf", true) @@ -37,6 +39,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { private fun initBook(book: Book) { if (ReadBook.book?.bookUrl != book.bookUrl) { ReadBook.resetData(book) + isInitFinish = true val count = App.db.bookChapterDao().getChapterCount(book.bookUrl) if (count == 0) { if (book.tocUrl.isEmpty()) { @@ -55,6 +58,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { ReadBook.saveRead() } } else { + isInitFinish = true ReadBook.titleDate.postValue(book.name) if (ReadBook.chapterSize == 0) { if (book.tocUrl.isEmpty()) { diff --git a/app/src/main/java/io/legado/app/ui/widget/page/PageView.kt b/app/src/main/java/io/legado/app/ui/widget/page/PageView.kt index 759ee2c46..4dc4193f8 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/PageView.kt +++ b/app/src/main/java/io/legado/app/ui/widget/page/PageView.kt @@ -191,15 +191,15 @@ class PageView(context: Context, attrs: AttributeSet) : } override fun getCurrentChapter(): TextChapter? { - return ReadBook.textChapter(0) + return if (callBack?.isInitFinish == true) ReadBook.textChapter(0) else null } override fun getNextChapter(): TextChapter? { - return ReadBook.textChapter(1) + return if (callBack?.isInitFinish == true) ReadBook.textChapter(1) else null } override fun getPreviousChapter(): TextChapter? { - return ReadBook.textChapter(-1) + return if (callBack?.isInitFinish == true) ReadBook.textChapter(-1) else null } override fun hasNextChapter(): Boolean { @@ -244,5 +244,6 @@ class PageView(context: Context, attrs: AttributeSet) : */ fun clickCenter() + val isInitFinish: Boolean } } From 68729e78a2eea892ee6777b9834ba2e3ae355ea5 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 22 Dec 2019 09:12:22 +0800 Subject: [PATCH 45/96] up --- app/src/main/AndroidManifest.xml | 1 + .../legado/app/ui/download/DownloadActivity.kt | 16 ++++++++++++++++ app/src/main/res/layout/activity_download.xml | 7 +++++++ 3 files changed, 24 insertions(+) create mode 100644 app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt create mode 100644 app/src/main/res/layout/activity_download.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6d456ff25..bc92ac136 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -102,6 +102,7 @@ + diff --git a/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt b/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt new file mode 100644 index 000000000..72356b869 --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt @@ -0,0 +1,16 @@ +package io.legado.app.ui.download + +import android.os.Bundle +import io.legado.app.R +import io.legado.app.base.BaseActivity + + +class DownloadActivity : BaseActivity(R.layout.activity_download) { + + + override fun onActivityCreated(savedInstanceState: Bundle?) { + + } + + +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_download.xml b/app/src/main/res/layout/activity_download.xml new file mode 100644 index 000000000..d829e291c --- /dev/null +++ b/app/src/main/res/layout/activity_download.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file From 18c1ebc11e91b21548f65933e66a56887b01c229 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 22 Dec 2019 09:16:33 +0800 Subject: [PATCH 46/96] up --- app/src/main/java/io/legado/app/service/DownloadService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/service/DownloadService.kt b/app/src/main/java/io/legado/app/service/DownloadService.kt index 6948259a3..d665d6b8f 100644 --- a/app/src/main/java/io/legado/app/service/DownloadService.kt +++ b/app/src/main/java/io/legado/app/service/DownloadService.kt @@ -39,9 +39,9 @@ class DownloadService : BaseService() { } override fun onDestroy() { - super.onDestroy() tasks.clear() searchPool.close() + super.onDestroy() } private fun download(bookUrl: String?, start: Int, end: Int) { From 2ecadf195f518841c683a08ab8118e780b01da49 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 22 Dec 2019 09:20:12 +0800 Subject: [PATCH 47/96] up --- app/src/main/java/io/legado/app/ui/about/DonateActivity.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/about/DonateActivity.kt b/app/src/main/java/io/legado/app/ui/about/DonateActivity.kt index 32c8d0172..107be8809 100644 --- a/app/src/main/java/io/legado/app/ui/about/DonateActivity.kt +++ b/app/src/main/java/io/legado/app/ui/about/DonateActivity.kt @@ -76,8 +76,8 @@ class DonateActivity : BaseActivity(R.layout.activity_donate) { private fun aliDonate(context: Context) { try { val qrCode = URLEncoder.encode("tsx06677nwdk3javroq4ef0", "utf-8") - val aliPayQr = "alipayqr://platformapi/startapp?" + - "saId=10000007&qrcode=https://qr.alipay.com/$qrCode" + val aliPayQr = + "alipayqr://platformapi/startapp?saId=10000007&qrcode=https://qr.alipay.com/$qrCode" val intent = Intent(Intent.ACTION_VIEW, Uri.parse(aliPayQr)) context.startActivity(intent) } catch (e: Exception) { From 6f9a208326091c99b184d84fe609f8a9feb38a9b Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 22 Dec 2019 15:09:36 +0800 Subject: [PATCH 48/96] up --- app/src/main/AndroidManifest.xml | 1 + .../legado/app/ui/widget/page/ContentSelectActionCallback.kt | 3 ++- .../main/java/io/legado/app/ui/widget/page/ContentTextView.kt | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index bc92ac136..8572589cd 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,6 +4,7 @@ package="io.legado.app"> + diff --git a/app/src/main/java/io/legado/app/ui/widget/page/ContentSelectActionCallback.kt b/app/src/main/java/io/legado/app/ui/widget/page/ContentSelectActionCallback.kt index e8e8af8d4..76a4b669a 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/ContentSelectActionCallback.kt +++ b/app/src/main/java/io/legado/app/ui/widget/page/ContentSelectActionCallback.kt @@ -3,12 +3,13 @@ package io.legado.app.ui.widget.page import android.view.ActionMode import android.view.Menu import android.view.MenuItem +import android.widget.TextView import io.legado.app.R import io.legado.app.constant.Bus import io.legado.app.utils.postEvent -class ContentSelectActionCallback(private val textView: ContentTextView) : ActionMode.Callback { +class ContentSelectActionCallback(private val textView: TextView) : ActionMode.Callback { override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean { when (item?.itemId) { diff --git a/app/src/main/java/io/legado/app/ui/widget/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/widget/page/ContentTextView.kt index 383425a7a..3a73c3227 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/widget/page/ContentTextView.kt @@ -241,4 +241,5 @@ class ContentTextView : AppCompatTextView { } } } + } From bf3e57b87d36517bae5a0c498d88ab5a8c8b4fef Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 22 Dec 2019 15:11:33 +0800 Subject: [PATCH 49/96] up --- app/src/main/AndroidManifest.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8572589cd..bc92ac136 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,7 +4,6 @@ package="io.legado.app"> - From 898d3b6559c7b9cbf9534c937a01fc88a9ba01dc Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 22 Dec 2019 15:25:12 +0800 Subject: [PATCH 50/96] up --- .../io/legado/app/ui/audio/AudioPlayActivity.kt | 5 ++++- app/src/main/res/layout/activity_audio_play.xml | 14 ++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt b/app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt index 2b27a1600..a348b6e1e 100644 --- a/app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt +++ b/app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt @@ -16,6 +16,7 @@ import io.legado.app.R import io.legado.app.base.VMBaseActivity import io.legado.app.constant.Bus import io.legado.app.constant.Status +import io.legado.app.constant.Theme import io.legado.app.data.entities.Book import io.legado.app.help.BlurTransformation import io.legado.app.help.ImageLoader @@ -34,7 +35,8 @@ import org.jetbrains.anko.sdk27.listeners.onLongClick import org.jetbrains.anko.startActivityForResult -class AudioPlayActivity : VMBaseActivity(R.layout.activity_audio_play), +class AudioPlayActivity : + VMBaseActivity(R.layout.activity_audio_play, theme = Theme.Dark), ChangeSourceDialog.CallBack { override val viewModel: AudioPlayViewModel @@ -44,6 +46,7 @@ class AudioPlayActivity : VMBaseActivity(R.layout.activity_a private var adjustProgress = false override fun onActivityCreated(savedInstanceState: Bundle?) { + title_bar.background.alpha = 0 AudioPlay.titleData.observe(this, Observer { title_bar.title = it }) AudioPlay.coverData.observe(this, Observer { upCover(it) }) viewModel.initData(intent) diff --git a/app/src/main/res/layout/activity_audio_play.xml b/app/src/main/res/layout/activity_audio_play.xml index cbae32334..71a7edfe8 100644 --- a/app/src/main/res/layout/activity_audio_play.xml +++ b/app/src/main/res/layout/activity_audio_play.xml @@ -15,20 +15,18 @@ android:scaleType="centerCrop" tools:ignore="ContentDescription" /> + + - - Date: Sun, 22 Dec 2019 15:27:42 +0800 Subject: [PATCH 51/96] up --- app/src/main/assets/updateLog.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 169510a32..87ba8e640 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -4,6 +4,9 @@ * 先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】,提示存储权限,选择允许即可导入成功。 * 注意:由于安卓10更改了权限策略,还需要给「允许安装其他应用」的权限才能导入源。MIUI11也需要此权限。 +**2019/12/22** +* 更新音频播放界面 + **2019/12/20** * 阅读界面的下载菜单可以用了 * rss阅读bug修复,webView内可以用返回建返回上一链接 From d41042af5caf759228414c79e78b2b93fdd50d19 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 22 Dec 2019 15:51:34 +0800 Subject: [PATCH 52/96] up --- .../io/legado/app/ui/book/read/ReadBookViewModel.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt index c45095a7e..8ee7b8e47 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt @@ -40,18 +40,17 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { if (ReadBook.book?.bookUrl != book.bookUrl) { ReadBook.resetData(book) isInitFinish = true - val count = App.db.bookChapterDao().getChapterCount(book.bookUrl) - if (count == 0) { + ReadBook.chapterSize = App.db.bookChapterDao().getChapterCount(book.bookUrl) + if (ReadBook.chapterSize == 0) { if (book.tocUrl.isEmpty()) { loadBookInfo(book) } else { loadChapterList(book) } } else { - if (ReadBook.durChapterIndex > count - 1) { - ReadBook.durChapterIndex = count - 1 + if (ReadBook.durChapterIndex > ReadBook.chapterSize - 1) { + ReadBook.durChapterIndex = ReadBook.chapterSize - 1 } - ReadBook.chapterSize = count ReadBook.loadContent() } if (ReadBook.inBookshelf) { @@ -60,6 +59,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { } else { isInitFinish = true ReadBook.titleDate.postValue(book.name) + ReadBook.chapterSize = App.db.bookChapterDao().getChapterCount(book.bookUrl) if (ReadBook.chapterSize == 0) { if (book.tocUrl.isEmpty()) { loadBookInfo(book) From 62a74363b4422787d28c43dd2bf90ac9ebbdc857 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 22 Dec 2019 21:19:33 +0800 Subject: [PATCH 53/96] up --- app/src/main/res/layout/activity_download.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/src/main/res/layout/activity_download.xml b/app/src/main/res/layout/activity_download.xml index d829e291c..2f7ebd6f2 100644 --- a/app/src/main/res/layout/activity_download.xml +++ b/app/src/main/res/layout/activity_download.xml @@ -1,7 +1,19 @@ + + + + \ No newline at end of file From a1a6ce78501f902f4183d8248eccdabbaff0aab4 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 22 Dec 2019 21:24:25 +0800 Subject: [PATCH 54/96] up --- .../legado/app/ui/download/DownloadAdapter.kt | 18 ++++++++++++++++++ app/src/main/res/layout/item_download.xml | 7 +++++++ 2 files changed, 25 insertions(+) create mode 100644 app/src/main/java/io/legado/app/ui/download/DownloadAdapter.kt create mode 100644 app/src/main/res/layout/item_download.xml diff --git a/app/src/main/java/io/legado/app/ui/download/DownloadAdapter.kt b/app/src/main/java/io/legado/app/ui/download/DownloadAdapter.kt new file mode 100644 index 000000000..8407633ff --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/download/DownloadAdapter.kt @@ -0,0 +1,18 @@ +package io.legado.app.ui.download + +import android.content.Context +import io.legado.app.R +import io.legado.app.base.adapter.ItemViewHolder +import io.legado.app.base.adapter.SimpleRecyclerAdapter +import io.legado.app.data.entities.Book + + +class DownloadAdapter(context: Context) : + SimpleRecyclerAdapter(context, R.layout.item_download) { + + + override fun convert(holder: ItemViewHolder, item: Book, payloads: MutableList) { + + } + +} \ No newline at end of file diff --git a/app/src/main/res/layout/item_download.xml b/app/src/main/res/layout/item_download.xml new file mode 100644 index 000000000..d829e291c --- /dev/null +++ b/app/src/main/res/layout/item_download.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file From 4d2d4e5f4248de6e20ac8b8924ee9e351c78b60f Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 22 Dec 2019 21:30:53 +0800 Subject: [PATCH 55/96] up --- .../java/io/legado/app/ui/download/DownloadActivity.kt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt b/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt index 72356b869..3f551da51 100644 --- a/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt +++ b/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt @@ -1,16 +1,24 @@ package io.legado.app.ui.download import android.os.Bundle +import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.R import io.legado.app.base.BaseActivity +import kotlinx.android.synthetic.main.activity_download.* class DownloadActivity : BaseActivity(R.layout.activity_download) { + lateinit var adapter: DownloadAdapter override fun onActivityCreated(savedInstanceState: Bundle?) { - + initRecyclerView() } + private fun initRecyclerView() { + recycler_view.layoutManager = LinearLayoutManager(this) + adapter = DownloadAdapter(this) + recycler_view.adapter = adapter + } } \ No newline at end of file From f22aa549d9a94c47f14f2901241c1455352abfc2 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 22 Dec 2019 21:37:16 +0800 Subject: [PATCH 56/96] up --- .../io/legado/app/ui/download/DownloadActivity.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt b/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt index 3f551da51..18e6ce0c4 100644 --- a/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt +++ b/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt @@ -1,18 +1,23 @@ package io.legado.app.ui.download import android.os.Bundle +import androidx.lifecycle.LiveData +import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.R import io.legado.app.base.BaseActivity +import io.legado.app.data.entities.Book import kotlinx.android.synthetic.main.activity_download.* class DownloadActivity : BaseActivity(R.layout.activity_download) { lateinit var adapter: DownloadAdapter + private var bookshelfLiveData: LiveData>? = null override fun onActivityCreated(savedInstanceState: Bundle?) { initRecyclerView() + initLiveData() } private fun initRecyclerView() { @@ -21,4 +26,10 @@ class DownloadActivity : BaseActivity(R.layout.activity_download) { recycler_view.adapter = adapter } + private fun initLiveData() { + bookshelfLiveData?.removeObservers(this) + bookshelfLiveData?.observe(this, Observer { + + }) + } } \ No newline at end of file From c323c0959fd3b0dd6c32bf71cc0548385a7de1a5 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 22 Dec 2019 21:44:53 +0800 Subject: [PATCH 57/96] up --- app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt b/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt index 18e6ce0c4..2ae90c8a5 100644 --- a/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt +++ b/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt @@ -29,7 +29,7 @@ class DownloadActivity : BaseActivity(R.layout.activity_download) { private fun initLiveData() { bookshelfLiveData?.removeObservers(this) bookshelfLiveData?.observe(this, Observer { - + adapter.setItems(it) }) } } \ No newline at end of file From c10b2b7dee5945e705b5e70733a407d685e47bdd Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 22 Dec 2019 21:48:12 +0800 Subject: [PATCH 58/96] up --- app/src/main/java/io/legado/app/help/ActivityHelp.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/ActivityHelp.kt b/app/src/main/java/io/legado/app/help/ActivityHelp.kt index fa15510f7..ca7c20f5f 100644 --- a/app/src/main/java/io/legado/app/help/ActivityHelp.kt +++ b/app/src/main/java/io/legado/app/help/ActivityHelp.kt @@ -1,7 +1,6 @@ package io.legado.app.help import android.app.Activity -import io.legado.app.utils.LogUtils import java.lang.ref.WeakReference import java.util.* @@ -13,7 +12,6 @@ object ActivityHelp { private val activities: MutableList> = arrayListOf() fun size(): Int { - LogUtils.d("xxxx", activities.size.toString()) return activities.size } From c59477c5165c8bed0069db77f78e90f9208bb118 Mon Sep 17 00:00:00 2001 From: kunfei Date: Mon, 23 Dec 2019 19:27:16 +0800 Subject: [PATCH 59/96] up --- app/src/main/java/io/legado/app/App.kt | 2 +- .../main/java/io/legado/app/constant/PreferKey.kt | 1 + .../io/legado/app/service/BaseReadAloudService.kt | 2 +- .../main/java/io/legado/app/service/help/ReadBook.kt | 4 ++-- .../io/legado/app/ui/book/read/ReadBookActivity.kt | 6 +++--- .../app/ui/book/read/config/ReadStyleDialog.kt | 5 +++-- .../ui/{widget => book/read}/page/ChapterProvider.kt | 2 +- .../read}/page/ContentSelectActionCallback.kt | 2 +- .../ui/{widget => book/read}/page/ContentTextView.kt | 2 +- .../app/ui/{widget => book/read}/page/ContentView.kt | 2 +- .../app/ui/{widget => book/read}/page/DataSource.kt | 2 +- .../app/ui/{widget => book/read}/page/PageFactory.kt | 2 +- .../app/ui/{widget => book/read}/page/PageView.kt | 12 +++++++----- .../app/ui/{widget => book/read}/page/TextChapter.kt | 2 +- .../app/ui/{widget => book/read}/page/TextPage.kt | 2 +- .../ui/{widget => book/read}/page/TextPageFactory.kt | 2 +- .../ui/{widget => book/read}/page/curl/CurlMesh.java | 2 +- .../ui/{widget => book/read}/page/curl/CurlPage.kt | 2 +- .../{widget => book/read}/page/curl/CurlRenderer.kt | 2 +- .../ui/{widget => book/read}/page/curl/CurlView.kt | 2 +- .../read}/page/delegate/CoverPageDelegate.kt | 4 ++-- .../read}/page/delegate/EventExtensions.kt | 2 +- .../read}/page/delegate/HorizontalPageDelegate.kt | 4 ++-- .../read}/page/delegate/NoAnimPageDelegate.kt | 4 ++-- .../read}/page/delegate/PageDelegate.kt | 6 +++--- .../read}/page/delegate/ScrollPageDelegate.kt | 4 ++-- .../read}/page/delegate/SimulationPageDelegate.kt | 8 ++++---- .../read}/page/delegate/SlidePageDelegate.kt | 4 ++-- app/src/main/res/layout/activity_book_read.xml | 4 ++-- app/src/main/res/layout/view_book_page.xml | 2 +- 30 files changed, 52 insertions(+), 48 deletions(-) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/ChapterProvider.kt (98%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/ContentSelectActionCallback.kt (96%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/ContentTextView.kt (99%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/ContentView.kt (99%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/DataSource.kt (89%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/PageFactory.kt (90%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/PageView.kt (95%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/TextChapter.kt (98%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/TextPage.kt (96%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/TextPageFactory.kt (98%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/curl/CurlMesh.java (99%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/curl/CurlPage.kt (99%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/curl/CurlRenderer.kt (99%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/curl/CurlView.kt (99%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/delegate/CoverPageDelegate.kt (96%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/delegate/EventExtensions.kt (86%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/delegate/HorizontalPageDelegate.kt (94%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/delegate/NoAnimPageDelegate.kt (78%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/delegate/PageDelegate.kt (98%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/delegate/ScrollPageDelegate.kt (97%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/delegate/SimulationPageDelegate.kt (94%) rename app/src/main/java/io/legado/app/ui/{widget => book/read}/page/delegate/SlidePageDelegate.kt (94%) diff --git a/app/src/main/java/io/legado/app/App.kt b/app/src/main/java/io/legado/app/App.kt index 1b757bde7..ee3e4f5f6 100644 --- a/app/src/main/java/io/legado/app/App.kt +++ b/app/src/main/java/io/legado/app/App.kt @@ -18,7 +18,7 @@ import io.legado.app.help.ActivityHelp import io.legado.app.help.CrashHandler import io.legado.app.help.ReadBookConfig import io.legado.app.lib.theme.ThemeStore -import io.legado.app.ui.widget.page.ChapterProvider +import io.legado.app.ui.book.read.page.ChapterProvider import io.legado.app.utils.getCompatColor import io.legado.app.utils.getPrefInt import io.legado.app.utils.isNightTheme diff --git a/app/src/main/java/io/legado/app/constant/PreferKey.kt b/app/src/main/java/io/legado/app/constant/PreferKey.kt index d4f54bb5d..4217e376d 100644 --- a/app/src/main/java/io/legado/app/constant/PreferKey.kt +++ b/app/src/main/java/io/legado/app/constant/PreferKey.kt @@ -14,4 +14,5 @@ object PreferKey { const val processText = "process_text" const val cleanCache = "cleanCache" const val lastGroup = "lastGroup" + const val pageAnim = "pageAnim" } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/service/BaseReadAloudService.kt b/app/src/main/java/io/legado/app/service/BaseReadAloudService.kt index 7f3cbb34e..c657f621e 100644 --- a/app/src/main/java/io/legado/app/service/BaseReadAloudService.kt +++ b/app/src/main/java/io/legado/app/service/BaseReadAloudService.kt @@ -26,7 +26,7 @@ import io.legado.app.help.MediaHelp import io.legado.app.receiver.MediaButtonReceiver import io.legado.app.service.help.ReadBook import io.legado.app.ui.book.read.ReadBookActivity -import io.legado.app.ui.widget.page.TextChapter +import io.legado.app.ui.book.read.page.TextChapter import io.legado.app.utils.getPrefBoolean import io.legado.app.utils.postEvent diff --git a/app/src/main/java/io/legado/app/service/help/ReadBook.kt b/app/src/main/java/io/legado/app/service/help/ReadBook.kt index 7603c0ab3..451883b55 100644 --- a/app/src/main/java/io/legado/app/service/help/ReadBook.kt +++ b/app/src/main/java/io/legado/app/service/help/ReadBook.kt @@ -11,8 +11,8 @@ import io.legado.app.help.IntentDataHelp import io.legado.app.help.coroutine.Coroutine import io.legado.app.model.WebBook import io.legado.app.service.BaseReadAloudService -import io.legado.app.ui.widget.page.ChapterProvider -import io.legado.app.ui.widget.page.TextChapter +import io.legado.app.ui.book.read.page.ChapterProvider +import io.legado.app.ui.book.read.page.TextChapter import kotlinx.coroutines.* import kotlinx.coroutines.Dispatchers.Main 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 c166d4b96..fdc95233d 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 @@ -29,14 +29,14 @@ import io.legado.app.service.help.ReadBook import io.legado.app.ui.book.read.config.* import io.legado.app.ui.book.read.config.BgTextConfigDialog.Companion.BG_COLOR import io.legado.app.ui.book.read.config.BgTextConfigDialog.Companion.TEXT_COLOR +import io.legado.app.ui.book.read.page.ChapterProvider +import io.legado.app.ui.book.read.page.PageView +import io.legado.app.ui.book.read.page.delegate.PageDelegate import io.legado.app.ui.book.source.edit.BookSourceEditActivity import io.legado.app.ui.changesource.ChangeSourceDialog import io.legado.app.ui.chapterlist.ChapterListActivity import io.legado.app.ui.replacerule.ReplaceRuleActivity import io.legado.app.ui.replacerule.edit.ReplaceEditDialog -import io.legado.app.ui.widget.page.ChapterProvider -import io.legado.app.ui.widget.page.PageView -import io.legado.app.ui.widget.page.delegate.PageDelegate import io.legado.app.utils.* import kotlinx.android.synthetic.main.activity_book_read.* import kotlinx.android.synthetic.main.dialog_download_choice.view.* diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt index a816677f0..ea050dac8 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt @@ -11,6 +11,7 @@ import androidx.core.view.get import androidx.fragment.app.DialogFragment import io.legado.app.R import io.legado.app.constant.Bus +import io.legado.app.constant.PreferKey import io.legado.app.help.ImageLoader import io.legado.app.help.ReadBookConfig import io.legado.app.lib.dialogs.selector @@ -66,7 +67,7 @@ class ReadStyleDialog : DialogFragment() { } private fun initData() { - requireContext().getPrefInt("pageAnim").let { + requireContext().getPrefInt(PreferKey.pageAnim).let { if (it >= 0 && it < rg_page_anim.childCount) { rg_page_anim.check(rg_page_anim[it].id) } @@ -179,7 +180,7 @@ class ReadStyleDialog : DialogFragment() { rg_page_anim.onCheckedChange { _, checkedId -> for (i in 0 until rg_page_anim.childCount) { if (checkedId == rg_page_anim[i].id) { - requireContext().putPrefInt("pageAnim", i) + requireContext().putPrefInt(PreferKey.pageAnim, i) val activity = activity if (activity is ReadBookActivity) { activity.page_view.upPageAnim(i) diff --git a/app/src/main/java/io/legado/app/ui/widget/page/ChapterProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ChapterProvider.kt similarity index 98% rename from app/src/main/java/io/legado/app/ui/widget/page/ChapterProvider.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/ChapterProvider.kt index 25b68e6c3..63cc6748d 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/ChapterProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ChapterProvider.kt @@ -1,4 +1,4 @@ -package io.legado.app.ui.widget.page +package io.legado.app.ui.book.read.page import android.text.Spannable import android.text.SpannableStringBuilder diff --git a/app/src/main/java/io/legado/app/ui/widget/page/ContentSelectActionCallback.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentSelectActionCallback.kt similarity index 96% rename from app/src/main/java/io/legado/app/ui/widget/page/ContentSelectActionCallback.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/ContentSelectActionCallback.kt index 76a4b669a..cfce5f27b 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/ContentSelectActionCallback.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentSelectActionCallback.kt @@ -1,4 +1,4 @@ -package io.legado.app.ui.widget.page +package io.legado.app.ui.book.read.page import android.view.ActionMode import android.view.Menu diff --git a/app/src/main/java/io/legado/app/ui/widget/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt similarity index 99% rename from app/src/main/java/io/legado/app/ui/widget/page/ContentTextView.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index 3a73c3227..190e31ac9 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -1,4 +1,4 @@ -package io.legado.app.ui.widget.page +package io.legado.app.ui.book.read.page import android.annotation.SuppressLint import android.content.Context diff --git a/app/src/main/java/io/legado/app/ui/widget/page/ContentView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentView.kt similarity index 99% rename from app/src/main/java/io/legado/app/ui/widget/page/ContentView.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/ContentView.kt index 4f371949d..08c819899 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/ContentView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentView.kt @@ -1,4 +1,4 @@ -package io.legado.app.ui.widget.page +package io.legado.app.ui.book.read.page import android.annotation.SuppressLint import android.content.Context diff --git a/app/src/main/java/io/legado/app/ui/widget/page/DataSource.kt b/app/src/main/java/io/legado/app/ui/book/read/page/DataSource.kt similarity index 89% rename from app/src/main/java/io/legado/app/ui/widget/page/DataSource.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/DataSource.kt index d7efe18a5..7c93e52c2 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/DataSource.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/DataSource.kt @@ -1,4 +1,4 @@ -package io.legado.app.ui.widget.page +package io.legado.app.ui.book.read.page interface DataSource { val isScrollDelegate: Boolean diff --git a/app/src/main/java/io/legado/app/ui/widget/page/PageFactory.kt b/app/src/main/java/io/legado/app/ui/book/read/page/PageFactory.kt similarity index 90% rename from app/src/main/java/io/legado/app/ui/widget/page/PageFactory.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/PageFactory.kt index 72eaa5eda..6f39f2992 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/PageFactory.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/PageFactory.kt @@ -1,4 +1,4 @@ -package io.legado.app.ui.widget.page +package io.legado.app.ui.book.read.page abstract class PageFactory(protected val dataSource: DataSource) { diff --git a/app/src/main/java/io/legado/app/ui/widget/page/PageView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt similarity index 95% rename from app/src/main/java/io/legado/app/ui/widget/page/PageView.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt index 4dc4193f8..9d17e0f18 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/PageView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt @@ -1,4 +1,4 @@ -package io.legado.app.ui.widget.page +package io.legado.app.ui.book.read.page import android.annotation.SuppressLint import android.content.Context @@ -6,11 +6,13 @@ import android.graphics.Canvas import android.util.AttributeSet import android.view.MotionEvent import android.widget.FrameLayout +import io.legado.app.constant.PreferKey import io.legado.app.help.ReadBookConfig import io.legado.app.service.help.ReadBook -import io.legado.app.ui.widget.page.curl.CurlView -import io.legado.app.ui.widget.page.delegate.* +import io.legado.app.ui.book.read.page.curl.CurlView +import io.legado.app.ui.book.read.page.delegate.* import io.legado.app.utils.activity +import io.legado.app.utils.getPrefInt class PageView(context: Context, attrs: AttributeSet) : FrameLayout(context, attrs), @@ -37,7 +39,7 @@ class PageView(context: Context, attrs: AttributeSet) : upBg() setWillNotDraw(false) pageFactory = TextPageFactory(this) - upPageAnim() + upPageAnim(context.getPrefInt(PreferKey.pageAnim)) curPage?.callBack = this } @@ -88,7 +90,7 @@ class PageView(context: Context, attrs: AttributeSet) : } } - fun upPageAnim(pageAnim: Int = 0) { + fun upPageAnim(pageAnim: Int) { if (curlView != null) { removeView(curlView) curlView = null diff --git a/app/src/main/java/io/legado/app/ui/widget/page/TextChapter.kt b/app/src/main/java/io/legado/app/ui/book/read/page/TextChapter.kt similarity index 98% rename from app/src/main/java/io/legado/app/ui/widget/page/TextChapter.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/TextChapter.kt index d9c57c4ce..a4dacac60 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/TextChapter.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/TextChapter.kt @@ -1,4 +1,4 @@ -package io.legado.app.ui.widget.page +package io.legado.app.ui.book.read.page import android.text.SpannableStringBuilder import kotlin.math.min diff --git a/app/src/main/java/io/legado/app/ui/widget/page/TextPage.kt b/app/src/main/java/io/legado/app/ui/book/read/page/TextPage.kt similarity index 96% rename from app/src/main/java/io/legado/app/ui/widget/page/TextPage.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/TextPage.kt index 44f47d098..4950bf68a 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/TextPage.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/TextPage.kt @@ -1,4 +1,4 @@ -package io.legado.app.ui.widget.page +package io.legado.app.ui.book.read.page import android.text.Spannable import android.text.SpannableStringBuilder diff --git a/app/src/main/java/io/legado/app/ui/widget/page/TextPageFactory.kt b/app/src/main/java/io/legado/app/ui/book/read/page/TextPageFactory.kt similarity index 98% rename from app/src/main/java/io/legado/app/ui/widget/page/TextPageFactory.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/TextPageFactory.kt index d5aaa68d7..8423d04ab 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/TextPageFactory.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/TextPageFactory.kt @@ -1,4 +1,4 @@ -package io.legado.app.ui.widget.page +package io.legado.app.ui.book.read.page import io.legado.app.service.help.ReadBook diff --git a/app/src/main/java/io/legado/app/ui/widget/page/curl/CurlMesh.java b/app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlMesh.java similarity index 99% rename from app/src/main/java/io/legado/app/ui/widget/page/curl/CurlMesh.java rename to app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlMesh.java index f0e5a3fff..65ddbc363 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/curl/CurlMesh.java +++ b/app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlMesh.java @@ -1,4 +1,4 @@ -package io.legado.app.ui.widget.page.curl; +package io.legado.app.ui.book.read.page.curl; import android.graphics.Bitmap; import android.graphics.Color; diff --git a/app/src/main/java/io/legado/app/ui/widget/page/curl/CurlPage.kt b/app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlPage.kt similarity index 99% rename from app/src/main/java/io/legado/app/ui/widget/page/curl/CurlPage.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlPage.kt index 5f6ad5bb1..88f2fb16c 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/curl/CurlPage.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlPage.kt @@ -1,4 +1,4 @@ -package io.legado.app.ui.widget.page.curl +package io.legado.app.ui.book.read.page.curl import android.graphics.Bitmap import android.graphics.Canvas 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/book/read/page/curl/CurlRenderer.kt similarity index 99% rename from app/src/main/java/io/legado/app/ui/widget/page/curl/CurlRenderer.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlRenderer.kt index aeec2472b..6d44ee1ee 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/curl/CurlRenderer.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlRenderer.kt @@ -1,4 +1,4 @@ -package io.legado.app.ui.widget.page.curl +package io.legado.app.ui.book.read.page.curl import android.graphics.Color import android.graphics.PointF 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/book/read/page/curl/CurlView.kt similarity index 99% rename from app/src/main/java/io/legado/app/ui/widget/page/curl/CurlView.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlView.kt index 1124d71d0..ecd5d410d 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/curl/CurlView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlView.kt @@ -1,4 +1,4 @@ -package io.legado.app.ui.widget.page.curl +package io.legado.app.ui.book.read.page.curl import android.content.Context import android.graphics.PixelFormat diff --git a/app/src/main/java/io/legado/app/ui/widget/page/delegate/CoverPageDelegate.kt b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/CoverPageDelegate.kt similarity index 96% rename from app/src/main/java/io/legado/app/ui/widget/page/delegate/CoverPageDelegate.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/delegate/CoverPageDelegate.kt index 10ac07abd..c30affba3 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/delegate/CoverPageDelegate.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/CoverPageDelegate.kt @@ -1,9 +1,9 @@ -package io.legado.app.ui.widget.page.delegate +package io.legado.app.ui.book.read.page.delegate import android.graphics.Canvas import android.graphics.Matrix import android.graphics.drawable.GradientDrawable -import io.legado.app.ui.widget.page.PageView +import io.legado.app.ui.book.read.page.PageView class CoverPageDelegate(pageView: PageView) : HorizontalPageDelegate(pageView) { diff --git a/app/src/main/java/io/legado/app/ui/widget/page/delegate/EventExtensions.kt b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/EventExtensions.kt similarity index 86% rename from app/src/main/java/io/legado/app/ui/widget/page/delegate/EventExtensions.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/delegate/EventExtensions.kt index 99916e27a..05d6b28a3 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/delegate/EventExtensions.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/EventExtensions.kt @@ -1,4 +1,4 @@ -package io.legado.app.ui.widget.page.delegate +package io.legado.app.ui.book.read.page.delegate import android.view.MotionEvent diff --git a/app/src/main/java/io/legado/app/ui/widget/page/delegate/HorizontalPageDelegate.kt b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/HorizontalPageDelegate.kt similarity index 94% rename from app/src/main/java/io/legado/app/ui/widget/page/delegate/HorizontalPageDelegate.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/delegate/HorizontalPageDelegate.kt index 1f2b3fa42..ef43b929e 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/delegate/HorizontalPageDelegate.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/HorizontalPageDelegate.kt @@ -1,7 +1,7 @@ -package io.legado.app.ui.widget.page.delegate +package io.legado.app.ui.book.read.page.delegate import android.view.MotionEvent -import io.legado.app.ui.widget.page.PageView +import io.legado.app.ui.book.read.page.PageView import io.legado.app.utils.screenshot import kotlin.math.abs diff --git a/app/src/main/java/io/legado/app/ui/widget/page/delegate/NoAnimPageDelegate.kt b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/NoAnimPageDelegate.kt similarity index 78% rename from app/src/main/java/io/legado/app/ui/widget/page/delegate/NoAnimPageDelegate.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/delegate/NoAnimPageDelegate.kt index 7008455b8..8837698d0 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/delegate/NoAnimPageDelegate.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/NoAnimPageDelegate.kt @@ -1,7 +1,7 @@ -package io.legado.app.ui.widget.page.delegate +package io.legado.app.ui.book.read.page.delegate import android.graphics.Canvas -import io.legado.app.ui.widget.page.PageView +import io.legado.app.ui.book.read.page.PageView class NoAnimPageDelegate(pageView: PageView) : HorizontalPageDelegate(pageView) { override fun onScrollStart() { diff --git a/app/src/main/java/io/legado/app/ui/widget/page/delegate/PageDelegate.kt b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/PageDelegate.kt similarity index 98% rename from app/src/main/java/io/legado/app/ui/widget/page/delegate/PageDelegate.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/delegate/PageDelegate.kt index 0c6585df8..c9e0ca546 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/delegate/PageDelegate.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/PageDelegate.kt @@ -1,4 +1,4 @@ -package io.legado.app.ui.widget.page.delegate +package io.legado.app.ui.book.read.page.delegate import android.graphics.Bitmap import android.graphics.Canvas @@ -9,8 +9,8 @@ import android.widget.Scroller import androidx.annotation.CallSuper import androidx.interpolator.view.animation.FastOutLinearInInterpolator import com.google.android.material.snackbar.Snackbar -import io.legado.app.ui.widget.page.ContentView -import io.legado.app.ui.widget.page.PageView +import io.legado.app.ui.book.read.page.ContentView +import io.legado.app.ui.book.read.page.PageView import io.legado.app.utils.screenshot import io.legado.app.utils.snackbar import kotlin.math.abs diff --git a/app/src/main/java/io/legado/app/ui/widget/page/delegate/ScrollPageDelegate.kt b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/ScrollPageDelegate.kt similarity index 97% rename from app/src/main/java/io/legado/app/ui/widget/page/delegate/ScrollPageDelegate.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/delegate/ScrollPageDelegate.kt index 4e333bd1c..bf8a51a02 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/delegate/ScrollPageDelegate.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/ScrollPageDelegate.kt @@ -1,9 +1,9 @@ -package io.legado.app.ui.widget.page.delegate +package io.legado.app.ui.book.read.page.delegate import android.graphics.Canvas import android.graphics.Matrix import android.view.MotionEvent -import io.legado.app.ui.widget.page.PageView +import io.legado.app.ui.book.read.page.PageView import io.legado.app.utils.screenshot import kotlin.math.abs 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/book/read/page/delegate/SimulationPageDelegate.kt similarity index 94% rename from app/src/main/java/io/legado/app/ui/widget/page/delegate/SimulationPageDelegate.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/delegate/SimulationPageDelegate.kt index a83d548a2..eb58e616c 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/delegate/SimulationPageDelegate.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/SimulationPageDelegate.kt @@ -1,10 +1,10 @@ -package io.legado.app.ui.widget.page.delegate +package io.legado.app.ui.book.read.page.delegate import android.graphics.Canvas import android.view.MotionEvent -import io.legado.app.ui.widget.page.PageView -import io.legado.app.ui.widget.page.curl.CurlPage -import io.legado.app.ui.widget.page.curl.CurlView +import io.legado.app.ui.book.read.page.PageView +import io.legado.app.ui.book.read.page.curl.CurlPage +import io.legado.app.ui.book.read.page.curl.CurlView import io.legado.app.utils.screenshot import kotlin.math.abs diff --git a/app/src/main/java/io/legado/app/ui/widget/page/delegate/SlidePageDelegate.kt b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/SlidePageDelegate.kt similarity index 94% rename from app/src/main/java/io/legado/app/ui/widget/page/delegate/SlidePageDelegate.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/delegate/SlidePageDelegate.kt index 2615976e6..24c0781d7 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/delegate/SlidePageDelegate.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/SlidePageDelegate.kt @@ -1,8 +1,8 @@ -package io.legado.app.ui.widget.page.delegate +package io.legado.app.ui.book.read.page.delegate import android.graphics.Canvas import android.graphics.Matrix -import io.legado.app.ui.widget.page.PageView +import io.legado.app.ui.book.read.page.PageView class SlidePageDelegate(pageView: PageView) : HorizontalPageDelegate(pageView) { diff --git a/app/src/main/res/layout/activity_book_read.xml b/app/src/main/res/layout/activity_book_read.xml index 1d86c11d0..245e4ac49 100644 --- a/app/src/main/res/layout/activity_book_read.xml +++ b/app/src/main/res/layout/activity_book_read.xml @@ -4,13 +4,13 @@ android:layout_height="match_parent" android:orientation="vertical"> - - diff --git a/app/src/main/res/layout/view_book_page.xml b/app/src/main/res/layout/view_book_page.xml index d6ad84daf..410efe662 100644 --- a/app/src/main/res/layout/view_book_page.xml +++ b/app/src/main/res/layout/view_book_page.xml @@ -27,7 +27,7 @@ - Date: Mon, 23 Dec 2019 20:25:27 +0800 Subject: [PATCH 60/96] up --- app/src/main/assets/updateLog.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 87ba8e640..12171a213 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -4,6 +4,9 @@ * 先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】,提示存储权限,选择允许即可导入成功。 * 注意:由于安卓10更改了权限策略,还需要给「允许安装其他应用」的权限才能导入源。MIUI11也需要此权限。 +**2019/12/23** +* 修复每次打开翻页模式恢复默认的bug + **2019/12/22** * 更新音频播放界面 From 6506a887b9270af8b79938d9836b8c0acdd1dfa6 Mon Sep 17 00:00:00 2001 From: kunfei Date: Mon, 23 Dec 2019 20:32:40 +0800 Subject: [PATCH 61/96] up --- .../main/java/io/legado/app/ui/book/read/page/ContentView.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentView.kt index 08c819899..41d4b937f 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentView.kt @@ -133,7 +133,9 @@ class ContentView : FrameLayout { fun scrollTo(pos: Int?) { if (pos != null) { content_text_view.post { - content_text_view.scrollTo(0, content_text_view.layout.getLineTop(pos)) + if (content_text_view.layout.lineCount >= pos) { + content_text_view.scrollTo(0, content_text_view.layout.getLineTop(pos)) + } } } } From 8b0d369a944930a879bb1c204499560b0aec2730 Mon Sep 17 00:00:00 2001 From: kunfei Date: Mon, 23 Dec 2019 21:41:40 +0800 Subject: [PATCH 62/96] up --- .../io/legado/app/service/AudioPlayService.kt | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/io/legado/app/service/AudioPlayService.kt b/app/src/main/java/io/legado/app/service/AudioPlayService.kt index 2cedf7542..cf7815d03 100644 --- a/app/src/main/java/io/legado/app/service/AudioPlayService.kt +++ b/app/src/main/java/io/legado/app/service/AudioPlayService.kt @@ -157,6 +157,7 @@ class AudioPlayService : BaseService(), } private fun adjustProgress(position: Int) { + if (isM3U8()) return if (mediaPlayer.isPlaying) { mediaPlayer.seekTo(position) } else { @@ -177,21 +178,25 @@ class AudioPlayService : BaseService(), } } + private fun isM3U8(): Boolean { + return url.endsWith("m3u8") + } + /** * 加载完成 */ override fun onPrepared(mp: MediaPlayer?) { if (pause) return - mp?.let { - mp.start() - mp.seekTo(position) - postEvent(Bus.AUDIO_SIZE, mp.duration) - bookChapter?.let { - it.end = mp.duration.toLong() - } - handler.removeCallbacks(mpRunnable) - handler.post(mpRunnable) + mediaPlayer.start() + if (!isM3U8()) { + mediaPlayer.seekTo(position) + } + postEvent(Bus.AUDIO_SIZE, mediaPlayer.duration) + bookChapter?.let { + it.end = mediaPlayer.duration.toLong() } + handler.removeCallbacks(mpRunnable) + handler.post(mpRunnable) } /** From a4af037e50a7006797359ba1c249601355e28863 Mon Sep 17 00:00:00 2001 From: kunfei Date: Mon, 23 Dec 2019 21:56:06 +0800 Subject: [PATCH 63/96] up --- .../io/legado/app/service/AudioPlayService.kt | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/io/legado/app/service/AudioPlayService.kt b/app/src/main/java/io/legado/app/service/AudioPlayService.kt index cf7815d03..0a3c24e35 100644 --- a/app/src/main/java/io/legado/app/service/AudioPlayService.kt +++ b/app/src/main/java/io/legado/app/service/AudioPlayService.kt @@ -157,7 +157,6 @@ class AudioPlayService : BaseService(), } private fun adjustProgress(position: Int) { - if (isM3U8()) return if (mediaPlayer.isPlaying) { mediaPlayer.seekTo(position) } else { @@ -178,19 +177,13 @@ class AudioPlayService : BaseService(), } } - private fun isM3U8(): Boolean { - return url.endsWith("m3u8") - } - /** * 加载完成 */ override fun onPrepared(mp: MediaPlayer?) { if (pause) return mediaPlayer.start() - if (!isM3U8()) { - mediaPlayer.seekTo(position) - } + mediaPlayer.seekTo(position) postEvent(Bus.AUDIO_SIZE, mediaPlayer.duration) bookChapter?.let { it.end = mediaPlayer.duration.toLong() @@ -203,10 +196,10 @@ class AudioPlayService : BaseService(), * 播放出错 */ override fun onError(mp: MediaPlayer?, what: Int, extra: Int): Boolean { - AudioPlay.status = Status.STOP - postEvent(Bus.AUDIO_STATE, Status.STOP) - launch { - toast("error: $what $extra $url") + if (!mediaPlayer.isPlaying) { + AudioPlay.status = Status.STOP + postEvent(Bus.AUDIO_STATE, Status.STOP) + launch { toast("error: $what $extra $url") } } return true } From dcbe9531073a2c0d5cdd0d062bc7d69d562b24b5 Mon Sep 17 00:00:00 2001 From: kunfei Date: Mon, 23 Dec 2019 22:04:09 +0800 Subject: [PATCH 64/96] up --- .../io/legado/app/service/AudioPlayService.kt | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/io/legado/app/service/AudioPlayService.kt b/app/src/main/java/io/legado/app/service/AudioPlayService.kt index 0a3c24e35..6855b8b84 100644 --- a/app/src/main/java/io/legado/app/service/AudioPlayService.kt +++ b/app/src/main/java/io/legado/app/service/AudioPlayService.kt @@ -134,14 +134,18 @@ class AudioPlayService : BaseService(), } private fun pause(pause: Boolean) { - AudioPlayService.pause = pause - handler.removeCallbacks(mpRunnable) - position = mediaPlayer.currentPosition - mediaPlayer.pause() - upMediaSessionPlaybackState(PlaybackStateCompat.STATE_PAUSED) - AudioPlay.status = Status.PAUSE - postEvent(Bus.AUDIO_STATE, Status.PAUSE) - upNotification() + if (url.contains(".m3u8", false)) { + stopSelf() + } else { + AudioPlayService.pause = pause + handler.removeCallbacks(mpRunnable) + position = mediaPlayer.currentPosition + mediaPlayer.pause() + upMediaSessionPlaybackState(PlaybackStateCompat.STATE_PAUSED) + AudioPlay.status = Status.PAUSE + postEvent(Bus.AUDIO_STATE, Status.PAUSE) + upNotification() + } } private fun resume() { From 1944ace9541b2080932a901c961b9e26005400ac Mon Sep 17 00:00:00 2001 From: kunfei Date: Mon, 23 Dec 2019 22:07:10 +0800 Subject: [PATCH 65/96] up --- app/src/main/assets/updateLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 12171a213..586a8f614 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -6,6 +6,7 @@ **2019/12/23** * 修复每次打开翻页模式恢复默认的bug +* 修复m3u8报错问题 **2019/12/22** * 更新音频播放界面 From d9e2f979ae2d39c2ad76305299a6a1a1cfc2c6c2 Mon Sep 17 00:00:00 2001 From: kunfei Date: Tue, 24 Dec 2019 08:43:31 +0800 Subject: [PATCH 66/96] up --- app/src/main/java/io/legado/app/constant/Bus.kt | 1 + .../java/io/legado/app/service/WebService.kt | 3 +++ .../java/io/legado/app/ui/main/my/MyFragment.kt | 17 +++++++++++++---- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/io/legado/app/constant/Bus.kt b/app/src/main/java/io/legado/app/constant/Bus.kt index 395d51ec4..b14c9f538 100644 --- a/app/src/main/java/io/legado/app/constant/Bus.kt +++ b/app/src/main/java/io/legado/app/constant/Bus.kt @@ -18,4 +18,5 @@ object Bus { const val AUDIO_SIZE = "audioSize" const val AUDIO_SPEED = "audioSpeed" const val SHOW_RSS = "showRss" + const val WEB_SERVICE_STOP = "webServiceStop" } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/service/WebService.kt b/app/src/main/java/io/legado/app/service/WebService.kt index b32e6d6bc..25f2b6822 100644 --- a/app/src/main/java/io/legado/app/service/WebService.kt +++ b/app/src/main/java/io/legado/app/service/WebService.kt @@ -8,9 +8,11 @@ import io.legado.app.R import io.legado.app.base.BaseService import io.legado.app.constant.Action import io.legado.app.constant.AppConst +import io.legado.app.constant.Bus import io.legado.app.help.IntentHelp import io.legado.app.utils.NetworkUtils import io.legado.app.utils.getPrefInt +import io.legado.app.utils.postEvent import io.legado.app.web.HttpServer import io.legado.app.web.WebSocketServer import kotlinx.coroutines.launch @@ -54,6 +56,7 @@ class WebService : BaseService() { if (webSocketServer?.isAlive == true) { webSocketServer?.stop() } + postEvent(Bus.WEB_SERVICE_STOP, true) } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { diff --git a/app/src/main/java/io/legado/app/ui/main/my/MyFragment.kt b/app/src/main/java/io/legado/app/ui/main/my/MyFragment.kt index b84538aa1..e19d68ec5 100644 --- a/app/src/main/java/io/legado/app/ui/main/my/MyFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/my/MyFragment.kt @@ -7,9 +7,11 @@ import android.view.MenuItem import android.view.View import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat +import androidx.preference.SwitchPreference import io.legado.app.App import io.legado.app.R import io.legado.app.base.BaseFragment +import io.legado.app.constant.Bus import io.legado.app.help.BookHelp import io.legado.app.help.permission.Permissions import io.legado.app.help.permission.PermissionsCompat @@ -23,10 +25,7 @@ import io.legado.app.ui.book.source.manage.BookSourceActivity import io.legado.app.ui.config.ConfigActivity import io.legado.app.ui.config.ConfigViewModel import io.legado.app.ui.replacerule.ReplaceRuleActivity -import io.legado.app.utils.LogUtils -import io.legado.app.utils.getPrefBoolean -import io.legado.app.utils.startActivity -import io.legado.app.utils.toast +import io.legado.app.utils.* import kotlinx.android.synthetic.main.view_title_bar.* import org.jetbrains.anko.startActivity @@ -64,7 +63,17 @@ class MyFragment : BaseFragment(R.layout.fragment_my_config) { SharedPreferences.OnSharedPreferenceChangeListener { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + if (WebService.isRun) { + putPrefBoolean("webService", true) + } else { + putPrefBoolean("webService", false) + } addPreferencesFromResource(R.xml.pref_main) + observeEvent(Bus.WEB_SERVICE_STOP) { + findPreference("webService")?.let { + it.isChecked = false + } + } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { From a2235ca21d4dd827551c567be3165159134aa34e Mon Sep 17 00:00:00 2001 From: kunfei Date: Wed, 25 Dec 2019 08:06:57 +0800 Subject: [PATCH 67/96] up --- .../java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt | 2 +- .../main/java/io/legado/app/service/AudioPlayService.kt | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index bf8aded6d..b5343cf7f 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -117,7 +117,7 @@ class AnalyzeUrl( page?.let { val matcher = pagePattern.matcher(ruleUrl) while (matcher.find()) { - val pages = matcher.group(1).split(",") + val pages = matcher.group(1)!!.split(",") ruleUrl = if (page <= pages.size) { ruleUrl.replace(matcher.group(), pages[page - 1].trim { it <= ' ' }) } else { diff --git a/app/src/main/java/io/legado/app/service/AudioPlayService.kt b/app/src/main/java/io/legado/app/service/AudioPlayService.kt index 6855b8b84..ef2638c29 100644 --- a/app/src/main/java/io/legado/app/service/AudioPlayService.kt +++ b/app/src/main/java/io/legado/app/service/AudioPlayService.kt @@ -26,6 +26,7 @@ import io.legado.app.data.entities.BookChapter import io.legado.app.help.BookHelp import io.legado.app.help.IntentHelp import io.legado.app.help.MediaHelp +import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.receiver.MediaButtonReceiver import io.legado.app.service.help.AudioPlay import io.legado.app.ui.audio.AudioPlayActivity @@ -121,8 +122,10 @@ class AudioPlayService : BaseService(), AudioPlay.status = Status.PLAY postEvent(Bus.AUDIO_STATE, Status.PLAY) mediaPlayer.reset() - val uri = Uri.parse(url) - mediaPlayer.setDataSource(this, uri, AudioPlay.headers()) + val analyzeUrl = + AnalyzeUrl(url, headerMapF = AudioPlay.headers(), useWebView = true) + val uri = Uri.parse(analyzeUrl.url) + mediaPlayer.setDataSource(this, uri, analyzeUrl.headerMap) mediaPlayer.prepareAsync() } catch (e: Exception) { launch { From 3339c0540cd3522c3b91c6d0eb3a8de5c5424340 Mon Sep 17 00:00:00 2001 From: kunfei Date: Thu, 26 Dec 2019 15:06:21 +0800 Subject: [PATCH 68/96] up --- app/src/main/res/layout/item_download.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/src/main/res/layout/item_download.xml b/app/src/main/res/layout/item_download.xml index d829e291c..5ee60eeea 100644 --- a/app/src/main/res/layout/item_download.xml +++ b/app/src/main/res/layout/item_download.xml @@ -4,4 +4,19 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + + + + + + \ No newline at end of file From 4d3c757f13debb56e9a3d6a8e080da7ca9ee0a19 Mon Sep 17 00:00:00 2001 From: kunfei Date: Fri, 27 Dec 2019 09:39:26 +0800 Subject: [PATCH 69/96] up --- .../main/java/io/legado/app/data/dao/BookDao.kt | 3 +++ app/src/main/java/io/legado/app/help/BookHelp.kt | 15 +++++++++++++-- .../io/legado/app/ui/download/DownloadActivity.kt | 2 ++ .../io/legado/app/ui/download/DownloadAdapter.kt | 7 +++++-- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/io/legado/app/data/dao/BookDao.kt b/app/src/main/java/io/legado/app/data/dao/BookDao.kt index 42e76ddd6..d7fa8e1cf 100644 --- a/app/src/main/java/io/legado/app/data/dao/BookDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/BookDao.kt @@ -17,6 +17,9 @@ interface BookDao { @Query("SELECT * FROM books WHERE origin = '${BookType.local}' order by durChapterTime desc") fun observeLocal(): LiveData> + @Query("SELECT * FROM books WHERE origin <> '${BookType.local}' order by durChapterTime desc") + fun observeWeb(): LiveData> + @Query("SELECT * FROM books WHERE `group` = :group") fun observeByGroup(group: Int): LiveData> diff --git a/app/src/main/java/io/legado/app/help/BookHelp.kt b/app/src/main/java/io/legado/app/help/BookHelp.kt index e6f17134a..5070a74dc 100644 --- a/app/src/main/java/io/legado/app/help/BookHelp.kt +++ b/app/src/main/java/io/legado/app/help/BookHelp.kt @@ -35,8 +35,15 @@ object BookHelp { FileHelp.getFolder(getBookCachePath()) } + @Synchronized fun saveContent(book: Book, bookChapter: BookChapter, content: String) { if (content.isEmpty()) return + FileHelp.getFolder(getBookFolder(book)).listFiles()?.forEach { + if (it.name.startsWith(String.format("%05d", bookChapter.index))) { + it.delete() + return@forEach + } + } val filePath = getChapterPath(book, bookChapter) val file = FileHelp.getFile(filePath) file.writeText(content) @@ -74,11 +81,15 @@ object BookHelp { } } - private fun getChapterPath(book: Book, bookChapter: BookChapter): String { + private fun getBookFolder(book: Book): String { val bookFolder = formatFolderName(book.name + book.bookUrl) + return "${getBookCachePath()}${File.separator}$bookFolder" + } + + private fun getChapterPath(book: Book, bookChapter: BookChapter): String { val chapterFile = String.format("%05d-%s", bookChapter.index, MD5Utils.md5Encode(bookChapter.title)) - return "${getBookCachePath()}${File.separator}$bookFolder${File.separator}$chapterFile.nb" + return "${getBookFolder(book)}${File.separator}$chapterFile.nb" } private fun formatFolderName(folderName: String): String { diff --git a/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt b/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt index 2ae90c8a5..633d38ca9 100644 --- a/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt +++ b/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt @@ -4,6 +4,7 @@ import android.os.Bundle import androidx.lifecycle.LiveData import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager +import io.legado.app.App import io.legado.app.R import io.legado.app.base.BaseActivity import io.legado.app.data.entities.Book @@ -28,6 +29,7 @@ class DownloadActivity : BaseActivity(R.layout.activity_download) { private fun initLiveData() { bookshelfLiveData?.removeObservers(this) + bookshelfLiveData = App.db.bookDao().observeWeb() bookshelfLiveData?.observe(this, Observer { adapter.setItems(it) }) diff --git a/app/src/main/java/io/legado/app/ui/download/DownloadAdapter.kt b/app/src/main/java/io/legado/app/ui/download/DownloadAdapter.kt index 8407633ff..c6825041f 100644 --- a/app/src/main/java/io/legado/app/ui/download/DownloadAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/download/DownloadAdapter.kt @@ -5,14 +5,17 @@ import io.legado.app.R import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.data.entities.Book +import kotlinx.android.synthetic.main.item_download.view.* class DownloadAdapter(context: Context) : SimpleRecyclerAdapter(context, R.layout.item_download) { - override fun convert(holder: ItemViewHolder, item: Book, payloads: MutableList) { - + with(holder.itemView) { + tv_name.text = item.name + tv_author.text = item.author + } } } \ No newline at end of file From 4126bf8f168bc691a463d5b07e9207e2491949b0 Mon Sep 17 00:00:00 2001 From: kunfei Date: Fri, 27 Dec 2019 11:03:25 +0800 Subject: [PATCH 70/96] up --- .../io/legado/app/ui/download/DownloadActivity.kt | 14 ++++++++++++++ app/src/main/res/menu/download.xml | 4 ++++ 2 files changed, 18 insertions(+) create mode 100644 app/src/main/res/menu/download.xml diff --git a/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt b/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt index 633d38ca9..ccf7facb0 100644 --- a/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt +++ b/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt @@ -1,6 +1,8 @@ package io.legado.app.ui.download import android.os.Bundle +import android.view.Menu +import android.view.MenuItem import androidx.lifecycle.LiveData import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager @@ -21,6 +23,18 @@ class DownloadActivity : BaseActivity(R.layout.activity_download) { initLiveData() } + override fun onCompatCreateOptionsMenu(menu: Menu): Boolean { + menuInflater.inflate(R.menu.download, menu) + return super.onCompatCreateOptionsMenu(menu) + } + + override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { + + } + return super.onCompatOptionsItemSelected(item) + } + private fun initRecyclerView() { recycler_view.layoutManager = LinearLayoutManager(this) adapter = DownloadAdapter(this) diff --git a/app/src/main/res/menu/download.xml b/app/src/main/res/menu/download.xml new file mode 100644 index 000000000..e73b6af79 --- /dev/null +++ b/app/src/main/res/menu/download.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From bea0a08fa0e78a961fe93d4fca84e218fb7dc82a Mon Sep 17 00:00:00 2001 From: kunfei Date: Fri, 27 Dec 2019 11:22:18 +0800 Subject: [PATCH 71/96] up --- .../main/java/io/legado/app/ui/download/DownloadActivity.kt | 2 ++ .../io/legado/app/ui/main/bookshelf/BookshelfFragment.kt | 3 ++- app/src/main/res/menu/download.xml | 6 +++++- app/src/main/res/menu/main_bookshelf.xml | 4 ++-- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt b/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt index ccf7facb0..30632f26c 100644 --- a/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt +++ b/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt @@ -30,7 +30,9 @@ class DownloadActivity : BaseActivity(R.layout.activity_download) { override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { + R.id.menu_download_start -> { + } } return super.onCompatOptionsItemSelected(item) } diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt index 4b8d578ec..15a494694 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt @@ -19,6 +19,7 @@ import io.legado.app.lib.dialogs.selector import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.accentColor import io.legado.app.ui.book.search.SearchActivity +import io.legado.app.ui.download.DownloadActivity import io.legado.app.utils.getPrefBoolean import io.legado.app.utils.getViewModel import io.legado.app.utils.putPrefInt @@ -62,7 +63,7 @@ class BookshelfFragment : VMBaseFragment(R.layout.fragment_b } R.id.menu_arrange_bookshelf -> { } - R.id.menu_download_all -> viewModel.downloadAll() + R.id.menu_download -> startActivity() } } diff --git a/app/src/main/res/menu/download.xml b/app/src/main/res/menu/download.xml index e73b6af79..7762fc4e7 100644 --- a/app/src/main/res/menu/download.xml +++ b/app/src/main/res/menu/download.xml @@ -1,4 +1,8 @@ - + + + \ No newline at end of file diff --git a/app/src/main/res/menu/main_bookshelf.xml b/app/src/main/res/menu/main_bookshelf.xml index 45b586ca8..1c63a7629 100644 --- a/app/src/main/res/menu/main_bookshelf.xml +++ b/app/src/main/res/menu/main_bookshelf.xml @@ -21,9 +21,9 @@ app:showAsAction="never" /> Date: Fri, 27 Dec 2019 15:11:29 +0800 Subject: [PATCH 72/96] up --- app/src/main/res/layout/item_download.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/layout/item_download.xml b/app/src/main/res/layout/item_download.xml index 5ee60eeea..f23794e94 100644 --- a/app/src/main/res/layout/item_download.xml +++ b/app/src/main/res/layout/item_download.xml @@ -2,7 +2,8 @@ + android:layout_height="wrap_content" + android:padding="16dp"> Date: Fri, 27 Dec 2019 15:12:08 +0800 Subject: [PATCH 73/96] up --- app/src/main/res/menu/download.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/menu/download.xml b/app/src/main/res/menu/download.xml index 7762fc4e7..50dfdbeaa 100644 --- a/app/src/main/res/menu/download.xml +++ b/app/src/main/res/menu/download.xml @@ -1,8 +1,10 @@ - + + android:title="@string/action_download" + app:showAsAction="ifRoom" /> \ No newline at end of file From 2a9a8df1c0ab50243461fcea7225bead09fa29e0 Mon Sep 17 00:00:00 2001 From: kunfei Date: Fri, 27 Dec 2019 15:12:50 +0800 Subject: [PATCH 74/96] up --- app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6231a701f..7dc6b33fd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -45,7 +45,7 @@ 阅读·搜索 书架还空着,先去添加吧! 搜索 - 下载任务 + 下载 列表视图 网格视图三列 网格视图四列 From 1466e9dee83de6c4e2cc59a825445243f522545b Mon Sep 17 00:00:00 2001 From: kunfei Date: Fri, 27 Dec 2019 21:14:46 +0800 Subject: [PATCH 75/96] up --- .../io/legado/app/ui/download/DownloadActivity.kt | 14 ++++++++++++-- .../app/ui/main/bookshelf/BookshelfViewModel.kt | 8 -------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt b/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt index 30632f26c..850aac866 100644 --- a/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt +++ b/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt @@ -10,7 +10,10 @@ import io.legado.app.App import io.legado.app.R import io.legado.app.base.BaseActivity import io.legado.app.data.entities.Book +import io.legado.app.service.help.Download import kotlinx.android.synthetic.main.activity_download.* +import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.launch class DownloadActivity : BaseActivity(R.layout.activity_download) { @@ -30,8 +33,15 @@ class DownloadActivity : BaseActivity(R.layout.activity_download) { override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { - R.id.menu_download_start -> { - + R.id.menu_download_start -> launch(IO) { + App.db.bookDao().webBooks.forEach { book -> + Download.start( + this@DownloadActivity, + book.bookUrl, + book.durChapterIndex, + book.totalChapterNum + ) + } } } return super.onCompatOptionsItemSelected(item) diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt index 7f116694e..83d3c41a5 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt @@ -4,7 +4,6 @@ import android.app.Application import io.legado.app.App import io.legado.app.base.BaseViewModel import io.legado.app.data.entities.BookGroup -import io.legado.app.service.help.Download class BookshelfViewModel(application: Application) : BaseViewModel(application) { @@ -33,11 +32,4 @@ class BookshelfViewModel(application: Application) : BaseViewModel(application) } } - fun downloadAll() { - execute { - App.db.bookDao().webBooks.forEach { book -> - Download.start(context, book.bookUrl, book.durChapterIndex, book.totalChapterNum) - } - } - } } From 1de48788fe1d6cc70562f7d2cdc5d8ed9fb1a447 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 28 Dec 2019 10:49:07 +0800 Subject: [PATCH 76/96] up --- .../main/java/io/legado/app/help/BookHelp.kt | 4 ++++ .../legado/app/ui/download/DownloadAdapter.kt | 19 +++++++++++++++++-- .../app/ui/main/explore/ExploreAdapter.kt | 2 -- app/src/main/res/layout/item_find_book.xml | 6 ++---- app/src/main/res/values/strings.xml | 1 + 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/BookHelp.kt b/app/src/main/java/io/legado/app/help/BookHelp.kt index 5070a74dc..1ea320505 100644 --- a/app/src/main/java/io/legado/app/help/BookHelp.kt +++ b/app/src/main/java/io/legado/app/help/BookHelp.kt @@ -49,6 +49,10 @@ object BookHelp { file.writeText(content) } + fun getChapterCount(book: Book): Int { + return FileHelp.getFolder(getBookFolder(book)).list()?.size ?: 0 + } + fun hasContent(book: Book, bookChapter: BookChapter): Boolean { val filePath = getChapterPath(book, bookChapter) runCatching { diff --git a/app/src/main/java/io/legado/app/ui/download/DownloadAdapter.kt b/app/src/main/java/io/legado/app/ui/download/DownloadAdapter.kt index c6825041f..25b1b5b35 100644 --- a/app/src/main/java/io/legado/app/ui/download/DownloadAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/download/DownloadAdapter.kt @@ -1,10 +1,12 @@ package io.legado.app.ui.download 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 import io.legado.app.data.entities.Book +import io.legado.app.help.BookHelp import kotlinx.android.synthetic.main.item_download.view.* @@ -13,9 +15,22 @@ class DownloadAdapter(context: Context) : override fun convert(holder: ItemViewHolder, item: Book, payloads: MutableList) { with(holder.itemView) { - tv_name.text = item.name - tv_author.text = item.author + if (payloads.isEmpty()) { + tv_name.text = item.name + tv_author.text = item.author + upDownloadCount(this, item) + } else { + upDownloadCount(this, item) + } } } + private fun upDownloadCount(view: View, book: Book) { + view.tv_download.text = context.getString( + R.string.download_count, + BookHelp.getChapterCount(book), + book.totalChapterNum + ) + } + } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt b/app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt index c0d19851f..144fa4e19 100644 --- a/app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt @@ -9,7 +9,6 @@ import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.data.entities.BookSource import io.legado.app.help.coroutine.Coroutine -import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.accentColor import io.legado.app.utils.ACache import io.legado.app.utils.gone @@ -29,7 +28,6 @@ class ExploreAdapter(context: Context, private val scope: CoroutineScope, val ca override fun convert(holder: ItemViewHolder, item: BookSource, payloads: MutableList) { with(holder.itemView) { if (payloads.isEmpty()) { - ATH.applyBackgroundTint(ll_title) tv_name.text = item.bookSourceName ll_title.onClick { val oldEx = exIndex diff --git a/app/src/main/res/layout/item_find_book.xml b/app/src/main/res/layout/item_find_book.xml index 266e69e8d..8a95ed1e2 100644 --- a/app/src/main/res/layout/item_find_book.xml +++ b/app/src/main/res/layout/item_find_book.xml @@ -18,11 +18,9 @@ android:paddingTop="6dp" android:paddingBottom="6dp" android:layout_margin="4dp" - android:background="@color/background" - android:elevation="3dp" + android:background="@color/btn_bg_press" android:orientation="horizontal" - android:gravity="center_vertical" - tools:ignore="UseCompoundDrawables"> + android:gravity="center_vertical"> 开始下载 取消下载 暂无任务 + 已下载 %d/%d 导入选择书籍 更新和搜索线程数,如感觉卡顿请减小线程数,量力而行 切换图标 From abbc64f356340cb70965002e6ed3a55f6e977626 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 28 Dec 2019 10:51:57 +0800 Subject: [PATCH 77/96] up --- app/src/main/java/io/legado/app/service/DownloadService.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/service/DownloadService.kt b/app/src/main/java/io/legado/app/service/DownloadService.kt index d665d6b8f..8f5a6c606 100644 --- a/app/src/main/java/io/legado/app/service/DownloadService.kt +++ b/app/src/main/java/io/legado/app/service/DownloadService.kt @@ -32,7 +32,7 @@ class DownloadService : BaseService() { intent.getIntExtra("start", 0), intent.getIntExtra("end", 0) ) - Action.stop -> stopSelf() + Action.stop -> stopDownload() } } return super.onStartCommand(intent, flags, startId) @@ -75,6 +75,11 @@ class DownloadService : BaseService() { } } + private fun stopDownload() { + tasks.clear() + stopSelf() + } + /** * 更新通知 */ From e568c14b04918c4b5120ba08630323fe7680b85a Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 28 Dec 2019 10:56:32 +0800 Subject: [PATCH 78/96] up --- app/src/main/java/io/legado/app/data/dao/BookDao.kt | 4 ++-- .../main/java/io/legado/app/ui/download/DownloadActivity.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/io/legado/app/data/dao/BookDao.kt b/app/src/main/java/io/legado/app/data/dao/BookDao.kt index d7fa8e1cf..68de17a66 100644 --- a/app/src/main/java/io/legado/app/data/dao/BookDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/BookDao.kt @@ -17,8 +17,8 @@ interface BookDao { @Query("SELECT * FROM books WHERE origin = '${BookType.local}' order by durChapterTime desc") fun observeLocal(): LiveData> - @Query("SELECT * FROM books WHERE origin <> '${BookType.local}' order by durChapterTime desc") - fun observeWeb(): LiveData> + @Query("SELECT * FROM books WHERE origin <> '${BookType.local}' and type = 0 order by durChapterTime desc") + fun observeDownload(): LiveData> @Query("SELECT * FROM books WHERE `group` = :group") fun observeByGroup(group: Int): LiveData> diff --git a/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt b/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt index 850aac866..0ca90a472 100644 --- a/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt +++ b/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt @@ -55,7 +55,7 @@ class DownloadActivity : BaseActivity(R.layout.activity_download) { private fun initLiveData() { bookshelfLiveData?.removeObservers(this) - bookshelfLiveData = App.db.bookDao().observeWeb() + bookshelfLiveData = App.db.bookDao().observeDownload() bookshelfLiveData?.observe(this, Observer { adapter.setItems(it) }) From dfbb47b56e4d69e7b54b39c1d2f09dbe66536538 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 28 Dec 2019 11:14:30 +0800 Subject: [PATCH 79/96] up --- app/src/main/java/io/legado/app/constant/Bus.kt | 1 + .../java/io/legado/app/service/DownloadService.kt | 13 +++++++++++++ .../io/legado/app/ui/download/DownloadActivity.kt | 8 ++++++++ 3 files changed, 22 insertions(+) diff --git a/app/src/main/java/io/legado/app/constant/Bus.kt b/app/src/main/java/io/legado/app/constant/Bus.kt index b14c9f538..7795773e6 100644 --- a/app/src/main/java/io/legado/app/constant/Bus.kt +++ b/app/src/main/java/io/legado/app/constant/Bus.kt @@ -19,4 +19,5 @@ object Bus { const val AUDIO_SPEED = "audioSpeed" const val SHOW_RSS = "showRss" const val WEB_SERVICE_STOP = "webServiceStop" + const val UP_DOWNLOAD = "upDownload" } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/service/DownloadService.kt b/app/src/main/java/io/legado/app/service/DownloadService.kt index 8f5a6c606..a1042b4d6 100644 --- a/app/src/main/java/io/legado/app/service/DownloadService.kt +++ b/app/src/main/java/io/legado/app/service/DownloadService.kt @@ -1,16 +1,19 @@ package io.legado.app.service import android.content.Intent +import android.os.Handler import androidx.core.app.NotificationCompat import io.legado.app.App import io.legado.app.R import io.legado.app.base.BaseService import io.legado.app.constant.Action import io.legado.app.constant.AppConst +import io.legado.app.constant.Bus import io.legado.app.help.BookHelp import io.legado.app.help.IntentHelp import io.legado.app.help.coroutine.Coroutine import io.legado.app.model.WebBook +import io.legado.app.utils.postEvent import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.asCoroutineDispatcher import java.util.concurrent.Executors @@ -18,10 +21,13 @@ import java.util.concurrent.Executors class DownloadService : BaseService() { private var searchPool = Executors.newFixedThreadPool(16).asCoroutineDispatcher() private var tasks: ArrayList> = arrayListOf() + private val handler = Handler() + private var runnable: Runnable = Runnable { upDownload() } override fun onCreate() { super.onCreate() updateNotification("正在启动下载") + handler.postDelayed(runnable, 1000) } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { @@ -41,6 +47,7 @@ class DownloadService : BaseService() { override fun onDestroy() { tasks.clear() searchPool.close() + handler.removeCallbacks(runnable) super.onDestroy() } @@ -80,6 +87,12 @@ class DownloadService : BaseService() { stopSelf() } + private fun upDownload() { + postEvent(Bus.UP_DOWNLOAD, true) + handler.removeCallbacks(runnable) + handler.postDelayed(runnable, 1000) + } + /** * 更新通知 */ diff --git a/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt b/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt index 0ca90a472..9789bc273 100644 --- a/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt +++ b/app/src/main/java/io/legado/app/ui/download/DownloadActivity.kt @@ -9,8 +9,10 @@ import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.App import io.legado.app.R import io.legado.app.base.BaseActivity +import io.legado.app.constant.Bus import io.legado.app.data.entities.Book import io.legado.app.service.help.Download +import io.legado.app.utils.observeEvent import kotlinx.android.synthetic.main.activity_download.* import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.launch @@ -60,4 +62,10 @@ class DownloadActivity : BaseActivity(R.layout.activity_download) { adapter.setItems(it) }) } + + override fun observeLiveBus() { + observeEvent(Bus.UP_DOWNLOAD) { + adapter.notifyItemRangeChanged(0, adapter.itemCount, true) + } + } } \ No newline at end of file From ea0f25f7352cd7d2b4cf1fb0bd7683831bd4ef60 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 28 Dec 2019 11:18:24 +0800 Subject: [PATCH 80/96] up --- app/src/main/assets/updateLog.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 586a8f614..c79ed4f59 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -4,6 +4,9 @@ * 先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】,提示存储权限,选择允许即可导入成功。 * 注意:由于安卓10更改了权限策略,还需要给「允许安装其他应用」的权限才能导入源。MIUI11也需要此权限。 +**2019/12/28** +* 添加下载界面 + **2019/12/23** * 修复每次打开翻页模式恢复默认的bug * 修复m3u8报错问题 From 7628ed1e5e1c0d090b8d818b47b4e9df85486576 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 28 Dec 2019 11:23:00 +0800 Subject: [PATCH 81/96] up --- app/src/main/java/io/legado/app/constant/PreferKey.kt | 1 + .../io/legado/app/ui/book/read/config/ReadStyleDialog.kt | 6 +++--- .../java/io/legado/app/ui/book/read/page/ContentView.kt | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/io/legado/app/constant/PreferKey.kt b/app/src/main/java/io/legado/app/constant/PreferKey.kt index 4217e376d..c777fdb9a 100644 --- a/app/src/main/java/io/legado/app/constant/PreferKey.kt +++ b/app/src/main/java/io/legado/app/constant/PreferKey.kt @@ -15,4 +15,5 @@ object PreferKey { const val cleanCache = "cleanCache" const val lastGroup = "lastGroup" const val pageAnim = "pageAnim" + const val readBookFont = "readBookFont" } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt index ea050dac8..098edad43 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt @@ -87,13 +87,13 @@ class ReadStyleDialog : DialogFragment() { } tv_text_font.onClick { FontSelectDialog(requireContext()).apply { - curPath = requireContext().getPrefString("readBookFont") + curPath = requireContext().getPrefString(PreferKey.readBookFont) defaultFont = { - requireContext().putPrefString("readBookFont", "") + requireContext().putPrefString(PreferKey.readBookFont, "") postEvent(Bus.UP_CONFIG, true) } selectFile = { - requireContext().putPrefString("readBookFont", it) + requireContext().putPrefString(PreferKey.readBookFont, it) postEvent(Bus.UP_CONFIG, true) } }.show() diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentView.kt index 41d4b937f..903cc3abc 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentView.kt @@ -81,7 +81,7 @@ class ContentView : FrameLayout { tv_bottom_right.setTextColor(it) } } - context.getPrefString("readBookFont")?.let { + context.getPrefString(PreferKey.readBookFont)?.let { if (it.isNotEmpty()) { content_text_view.typeface = Typeface.createFromFile(it) } else { From 3b4d0adee962866a9fee5a82a15ef93cc0999fda Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 28 Dec 2019 16:43:57 +0800 Subject: [PATCH 82/96] up --- .../io/legado/app/data/dao/BookGroupDao.kt | 3 +++ .../java/io/legado/app/help/storage/Backup.kt | 18 ++++++++++++++---- .../java/io/legado/app/help/storage/Restore.kt | 14 ++++++++++---- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/io/legado/app/data/dao/BookGroupDao.kt b/app/src/main/java/io/legado/app/data/dao/BookGroupDao.kt index 0078eb26b..c48bd6e6b 100644 --- a/app/src/main/java/io/legado/app/data/dao/BookGroupDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/BookGroupDao.kt @@ -16,6 +16,9 @@ interface BookGroupDao { @get:Query("SELECT MAX(groupId) FROM book_groups") val maxId: Int + @Query("SELECT * FROM book_groups ORDER BY `order`") + fun all(): List + @Insert(onConflict = OnConflictStrategy.REPLACE) fun insert(vararg bookGroup: BookGroup) diff --git a/app/src/main/java/io/legado/app/help/storage/Backup.kt b/app/src/main/java/io/legado/app/help/storage/Backup.kt index 7062d1951..529deb629 100644 --- a/app/src/main/java/io/legado/app/help/storage/Backup.kt +++ b/app/src/main/java/io/legado/app/help/storage/Backup.kt @@ -27,8 +27,9 @@ object Backup { legadoPath + File.separator + "Export" } - private fun pbackup(path :String = legadoPath){ + private fun pBackup(path: String = legadoPath) { backupBookshelf(path) + backupBookGroup(path) backupBookSource(path) backupRssSource(path) backupReplaceRule(path) @@ -39,7 +40,7 @@ object Backup { fun backup() { doAsync { - pbackup() + pBackup() uiThread { App.INSTANCE.toast(R.string.backup_success) } @@ -48,7 +49,7 @@ object Backup { fun autoBackup() { doAsync { - pbackup() + pBackup() } } @@ -56,13 +57,22 @@ object Backup { App.db.bookDao().allBooks.let { if (it.isNotEmpty()) { val json = GSON.toJson(it) - val file = FileHelp.getFile(path + File.separator + "bookshelf.json") file.writeText(json) } } } + private fun backupBookGroup(path: String) { + App.db.bookGroupDao().all().let { + if (it.isNotEmpty()) { + val json = GSON.toJson(it) + val file = FileHelp.getFile(path + File.separator + "bookGroup.json") + file.writeText(json) + } + } + } + private fun backupBookSource(path: String) { App.db.bookSourceDao().all.let { if (it.isNotEmpty()) { diff --git a/app/src/main/java/io/legado/app/help/storage/Restore.kt b/app/src/main/java/io/legado/app/help/storage/Restore.kt index 53b040f28..b2e34783e 100644 --- a/app/src/main/java/io/legado/app/help/storage/Restore.kt +++ b/app/src/main/java/io/legado/app/help/storage/Restore.kt @@ -9,10 +9,7 @@ import com.jayway.jsonpath.ParseContext import io.legado.app.App import io.legado.app.R import io.legado.app.constant.AppConst -import io.legado.app.data.entities.Book -import io.legado.app.data.entities.BookSource -import io.legado.app.data.entities.ReplaceRule -import io.legado.app.data.entities.RssSource +import io.legado.app.data.entities.* import io.legado.app.help.FileHelp import io.legado.app.help.ReadBookConfig import io.legado.app.utils.* @@ -47,6 +44,15 @@ object Restore { } catch (e: Exception) { e.printStackTrace() } + try { + val file = FileHelp.getFile(path + File.separator + "bookGroup.json") + val json = file.readText() + GSON.fromJsonArray(json)?.let { + App.db.bookGroupDao().insert(*it.toTypedArray()) + } + } catch (e: Exception) { + e.printStackTrace() + } try { val file = FileHelp.getFile(path + File.separator + "bookSource.json") val json = file.readText() From 4c9cd3bf0bb4539fd48e03cfcad4a55c6919c8d9 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 28 Dec 2019 16:45:04 +0800 Subject: [PATCH 83/96] up --- app/src/main/assets/updateLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index c79ed4f59..17989e384 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -6,6 +6,7 @@ **2019/12/28** * 添加下载界面 +* 添加分组备份 **2019/12/23** * 修复每次打开翻页模式恢复默认的bug From eea8dae17cbb2c3ed4a3a02dae09e5b0c8dbe247 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 28 Dec 2019 20:10:01 +0800 Subject: [PATCH 84/96] up --- .../io/legado/app/service/DownloadService.kt | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/io/legado/app/service/DownloadService.kt b/app/src/main/java/io/legado/app/service/DownloadService.kt index a1042b4d6..7383f691b 100644 --- a/app/src/main/java/io/legado/app/service/DownloadService.kt +++ b/app/src/main/java/io/legado/app/service/DownloadService.kt @@ -23,6 +23,18 @@ class DownloadService : BaseService() { private var tasks: ArrayList> = arrayListOf() private val handler = Handler() private var runnable: Runnable = Runnable { upDownload() } + private val notificationBuilder by lazy { + val builder = NotificationCompat.Builder(this, AppConst.channelIdDownload) + .setSmallIcon(R.drawable.ic_download) + .setOngoing(true) + .setContentTitle(getString(R.string.download_offline)) + builder.addAction( + R.drawable.ic_stop_black_24dp, + getString(R.string.cancel), + IntentHelp.servicePendingIntent(this, Action.stop) + ) + builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + } override fun onCreate() { super.onCreate() @@ -97,17 +109,8 @@ class DownloadService : BaseService() { * 更新通知 */ private fun updateNotification(content: String) { - val builder = NotificationCompat.Builder(this, AppConst.channelIdDownload) - .setSmallIcon(R.drawable.ic_download) - .setOngoing(true) - .setContentTitle(getString(R.string.download_offline)) - .setContentText(content) - builder.addAction( - R.drawable.ic_stop_black_24dp, - getString(R.string.cancel), - IntentHelp.servicePendingIntent(this, Action.stop) - ) - builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + val builder = notificationBuilder + builder.setContentText(content) val notification = builder.build() startForeground(AppConst.notificationIdDownload, notification) } From fc12579eb0358771c562ce1d520ddd034d846f60 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 28 Dec 2019 20:12:32 +0800 Subject: [PATCH 85/96] up --- app/src/main/java/io/legado/app/service/DownloadService.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/io/legado/app/service/DownloadService.kt b/app/src/main/java/io/legado/app/service/DownloadService.kt index 7383f691b..798fcdfb8 100644 --- a/app/src/main/java/io/legado/app/service/DownloadService.kt +++ b/app/src/main/java/io/legado/app/service/DownloadService.kt @@ -23,6 +23,7 @@ class DownloadService : BaseService() { private var tasks: ArrayList> = arrayListOf() private val handler = Handler() private var runnable: Runnable = Runnable { upDownload() } + private var notificationContent = "正在启动下载" private val notificationBuilder by lazy { val builder = NotificationCompat.Builder(this, AppConst.channelIdDownload) .setSmallIcon(R.drawable.ic_download) @@ -38,7 +39,7 @@ class DownloadService : BaseService() { override fun onCreate() { super.onCreate() - updateNotification("正在启动下载") + updateNotification(notificationContent) handler.postDelayed(runnable, 1000) } @@ -74,7 +75,7 @@ class DownloadService : BaseService() { if (!BookHelp.hasContent(book, chapter)) { webBook.getContent(book, chapter, scope = this, context = searchPool) .onStart { - updateNotification(chapter.title) + notificationContent = chapter.title } .onSuccess(IO) { content -> content?.let { @@ -100,6 +101,7 @@ class DownloadService : BaseService() { } private fun upDownload() { + updateNotification(notificationContent) postEvent(Bus.UP_DOWNLOAD, true) handler.removeCallbacks(runnable) handler.postDelayed(runnable, 1000) From 4aafb528e23b975b05a0a25832d081bf34e3e6ea Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 28 Dec 2019 21:06:12 +0800 Subject: [PATCH 86/96] up --- .../io/legado/app/ui/rss/read/ReadRssActivity.kt | 16 ++++++++++++++++ app/src/main/res/menu/rss_read.xml | 6 ++++++ 2 files changed, 22 insertions(+) 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 9fc29878b..037364296 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 @@ -1,6 +1,7 @@ package io.legado.app.ui.rss.read import android.annotation.SuppressLint +import android.content.Intent import android.os.Bundle import android.view.KeyEvent import android.view.Menu @@ -15,6 +16,7 @@ import io.legado.app.lib.theme.primaryTextColor import io.legado.app.utils.NetworkUtils import io.legado.app.utils.getViewModel import kotlinx.android.synthetic.main.activity_rss_read.* +import org.jetbrains.anko.toast class ReadRssActivity : VMBaseActivity(R.layout.activity_rss_read), ReadRssViewModel.CallBack { @@ -42,6 +44,9 @@ class ReadRssActivity : VMBaseActivity(R.layout.activity_rss_r override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.menu_rss_star -> viewModel.star() + R.id.menu_share_it -> viewModel.rssArticle?.let { + shareText("链接分享", it.link) + } } return super.onCompatOptionsItemSelected(item) } @@ -115,4 +120,15 @@ class ReadRssActivity : VMBaseActivity(R.layout.activity_rss_r } return super.onKeyUp(keyCode, event) } + + private fun shareText(title: String, text: String) { + try { + val textIntent = Intent(Intent.ACTION_SEND) + textIntent.type = "text/plain" + textIntent.putExtra(Intent.EXTRA_TEXT, text) + startActivity(Intent.createChooser(textIntent, title)) + } catch (e: Exception) { + toast(R.string.can_not_share) + } + } } \ No newline at end of file diff --git a/app/src/main/res/menu/rss_read.xml b/app/src/main/res/menu/rss_read.xml index 29f3087ba..15463f64d 100644 --- a/app/src/main/res/menu/rss_read.xml +++ b/app/src/main/res/menu/rss_read.xml @@ -8,4 +8,10 @@ android:icon="@drawable/ic_star_border" app:showAsAction="always" /> + + \ No newline at end of file From 807123a23063a7e2436dfa617fd646808300f2be Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 28 Dec 2019 21:30:12 +0800 Subject: [PATCH 87/96] up --- app/src/main/res/drawable/bg_shadow_bottom.png | Bin 3127 -> 0 bytes app/src/main/res/drawable/bg_shadow_bottom.xml | 8 ++++++++ .../main/res/drawable/bg_shadow_bottom_night.png | Bin 418 -> 0 bytes .../main/res/drawable/bg_shadow_bottom_night.xml | 8 ++++++++ app/src/main/res/drawable/bg_shadow_top.png | Bin 340 -> 0 bytes app/src/main/res/drawable/bg_shadow_top.xml | 8 ++++++++ .../main/res/drawable/bg_shadow_top_night.png | Bin 424 -> 0 bytes .../main/res/drawable/bg_shadow_top_night.xml | 8 ++++++++ 8 files changed, 32 insertions(+) delete mode 100644 app/src/main/res/drawable/bg_shadow_bottom.png create mode 100644 app/src/main/res/drawable/bg_shadow_bottom.xml delete mode 100644 app/src/main/res/drawable/bg_shadow_bottom_night.png create mode 100644 app/src/main/res/drawable/bg_shadow_bottom_night.xml delete mode 100644 app/src/main/res/drawable/bg_shadow_top.png create mode 100644 app/src/main/res/drawable/bg_shadow_top.xml delete mode 100644 app/src/main/res/drawable/bg_shadow_top_night.png create mode 100644 app/src/main/res/drawable/bg_shadow_top_night.xml diff --git a/app/src/main/res/drawable/bg_shadow_bottom.png b/app/src/main/res/drawable/bg_shadow_bottom.png deleted file mode 100644 index ac0124b670691689ed19d44fb1498230f91cbf68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3127 zcmV-749N3|P)KLZ*U+5Lu!Sk^o_Z5E4Meg@_7P6crJiNL9pw)e1;Xm069{HJUZAPk55R%$-RIA z6-eL&AQ0xu!e<4=008gy@A0LT~suv4>S3ILP<0Bm`DLLvaF4FK%)Nj?Pt*r}7;7Xa9z9H|HZjR63e zC`Tj$K)V27Re@400>HumpsYY5E(E}?0f1SyGDiY{y#)Yvj#!WnKwtoXnL;eg03bL5 z07D)V%>y7z1E4U{zu>7~aD})?0RX_umCct+(lZpemCzb@^6=o|A>zVpu|i=NDG+7} zl4`aK{0#b-!z=TL9Wt0BGO&T{GJWpjryhdijfaIQ&2!o}p04JRKYg3k&Tf zVxhe-O!X z{f;To;xw^bEES6JSc$k$B2CA6xl)ltA<32E66t?3@gJ7`36pmX0IY^jz)rRYwaaY4 ze(nJRiw;=Qb^t(r^DT@T3y}a2XEZW-_W%Hszxj_qD**t_m!#tW0KDiJT&R>6OvVTR z07RgHDzHHZ48atvzz&?j9lXF70$~P3Knx_nJP<+#`N z#-MZ2bTkiLfR>_b(HgWKJ%F~Nr_oF3b#wrIijHG|(J>BYjM-sajE6;FiC7vY#};Gd zST$CUHDeuEH+B^pz@B062qXfFfD`NpUW5?BY=V%GM_5c)L#QR}BeW8_2v-S%gfYS= zB9o|3v?Y2H`NVi)In3rTB8+ej^> zQ=~r95NVuDChL%G$=>7$vVg20myx%S50Foi`^m%Pw-h?Xh~i8Mq9jtJloCocWk2Nv zrJpiFnV_ms&8eQ$2&#xWpIS+6pmtC%Q-`S&GF4Q#^mhymh7E(qNMa}%YZ-ePrx>>xFPTiH1=E+A$W$=bG8>s^ zm=Bn5Rah$aDtr}@$`X}2l~$F0mFKEdRdZE8)p@E5RI61Ft6o-prbbn>P~)iy)E2AN zsU20jsWz_8Qg>31P|s0cqrPALg8E|(vWA65poU1JRAaZs8I2(p#xiB`SVGovRs-uS zYnV-9TeA7=Om+qP8+I>yOjAR1s%ETak!GFdam@h^# z)@rS0t$wXH+Irf)+G6c;?H29p+V6F6oj{!|o%K3xI`?%6x;DB|x`n#ibhIR?(H}Q3Gzd138Ei2)WAMz7W9Vy`X}HnwgyEn!VS)>mv$8&{hQn>w4zwy3R}t;BYlZQm5)6pty=DfLrs+A-|>>;~;Q z_F?uV_HFjh9n2gO9o9Q^JA86v({H5aB!kjoO6 zc9$1ZZKsN-Zl8L~mE{`ly3)1N^`o1+o7}D0ZPeY&J;i;i`%NyJ8_8Y6J?}yE@b_5a zam?eLr<8@mESk|3$_SkmS{wQ>%qC18))9_|&j{ZT zes8AvOzF(F2#DZEY>2oYX&IRp`F#{ADl)1r>QS^)ba8a|EY_^#S^HO&t^Rgqwv=MZThqqEWH8 zxJo>d=ABlR_Bh=;eM9Tw|Ih34~oTE|= zX_mAr*D$vzw@+p(E0Yc6dFE}(8oqt`+R{gE3x4zjX+Sb3_cYE^= zgB=w+-tUy`ytONMS8KgRef4hA?t0j zufM;t32jm~jUGrkaOInTZ`zyfns>EuS}G30LFK_G-==(f<51|K&cocp&EJ`SxAh3? zNO>#LI=^+SEu(FqJ)ynt=!~PC9bO$rzPJB=?=j6w@a-(u02P7 zaQ)#(uUl{HW%tYNS3ItC^iAtK(eKlL`f9+{bJzISE?u8_z3;~C8@FyI-5j_jy7l;W z_U#vU3hqqYU3!mrul&B+{ptt$59)uk{;_4iZQ%G|z+lhASr6|H35TBkl>gI*;nGLU zN7W-nBaM%pA0HbH8olyl&XeJ%vZoWz%6?Y=dFykl=imL}`%BMQ{Mhgd`HRoLu6e2R za__6DuR6yg#~-}Tc|Gx_{H@O0eebyMy5GmWADJlpK>kqk(fVV@r_fLLKIeS?{4e)} z^ZO;zpECde03c&XQcVB=dL;k=fP(-4`Tqa_faw4Lbua(`>RI+y?e7jKeZ#YO-C z0c1%;K~#9!?AWnt!!Q_yQ3WDshAdvX1w7>yvUu(LKT?NUAc9ch$Q>k~;qVivI}|={ zop8QAPQahwj{t%IL4Y7Y5FiK;1PB5I0WZb9f{3m=z-YIttUnCB+as7L z2n1sxpd5)HAd5o~kP!q30_s6rT(_fZAt3W_;e_>J=tXNZfw_?Y<~Rg_Km>s}1OYGO5CozS1eC)F=iB2N=Vfx;Uhke! zSP00X2ytE}7(rT%{B!c=ng{}6 + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_shadow_bottom_night.png b/app/src/main/res/drawable/bg_shadow_bottom_night.png deleted file mode 100644 index c3036b0364870453a94ee0d1a7683baa968ff2d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 418 zcmeAS@N?(olHy`uVBq!ia0vp^M}XLlgAGWQtluI6q!^2X+?^QKos)S9a~60+7BevL9R^{>^*yigW;dax8Dr*Mr|L}5_k*}1VCs)c}J((1V_BC&fy!=xl%)ZcZ38L03sg2&?ZIYko+nOkKuXsGt@#a9W&u)` z2vpVwR8|NwZ8FfbIY1?k)&P|}2P)YCQj!W(vJRvKWYTP)k~<(J>wrqW1C>;Olq3U{ z%mXU<2r^|lP{|&UlC?l3?}18wfRv;ImF%1K;eM~%{kb9RvTOPF`2fR}!PC{xWt~$( F699})m_h&m diff --git a/app/src/main/res/drawable/bg_shadow_bottom_night.xml b/app/src/main/res/drawable/bg_shadow_bottom_night.xml new file mode 100644 index 000000000..de0d552f3 --- /dev/null +++ b/app/src/main/res/drawable/bg_shadow_bottom_night.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_shadow_top.png b/app/src/main/res/drawable/bg_shadow_top.png deleted file mode 100644 index cb8fee03db41e424234fce1f138671c15d338c3d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 340 zcmeAS@N?(olHy`uVBq!ia0vp^M}XLlg&9b;HLg?#QbGYfA+8+iZY**Ztctck5`t!a zDt86SvXun+1&cEZvGQ`(?r9eRioEu8aSVw#{Pxnt%)<@>t{2;_3^EfW?=(o>IbgKv zfc4+)lcqLF$b711HrgeB`k$;^PmbC)O`RsKMK9M*7FrfRx5%}b_jmF!&+rXxZ#&oc zCq%l4rKtq9tmNs)xbgH_*R?f{vMiN5FY@{cCI-0P*(kepQMt%PkwX_me(>Zvl`!-2 z-U(ovTO@PedWz8eg)F^FZU&+U-)bbq&Qx@r;2~(~mZaGqre!zopr0Bb^kD*ylh diff --git a/app/src/main/res/drawable/bg_shadow_top.xml b/app/src/main/res/drawable/bg_shadow_top.xml new file mode 100644 index 000000000..067790cc9 --- /dev/null +++ b/app/src/main/res/drawable/bg_shadow_top.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_shadow_top_night.png b/app/src/main/res/drawable/bg_shadow_top_night.png deleted file mode 100644 index 7984c35dbd2cdb35c16cf7942de030ed4e225565..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 424 zcmeAS@N?(olHy`uVBq!ia0vp^M}XLlgAGWQtluI6q!^2X+?^QKos)S9a~60+7BevL9R^{>lk;;^Bllfrk9fQG{C_uv)`~2aO-8k* zOuKLEZ#dQRBZsA^?Z& zY!)NMJgG*Xj_Ym;!jEuF4af=70@2Ctw%C zHruCTGf2Zm!4oYOxhyrOgxc2ll=nJ>Et~A-pqOyt)DwQE4W5d7{_#q0_c3_FQ+S6X zCG}I0e9jslpsiL}Kw}TPDWrGo2f4)&X!f5>77-@4>+1|soZgr-sj=_?k*14W!cqZ) zB|PT@Hw1D>1a<5=&$0%n>a`FL7h|(_I736c&T0Oe4XlDe@&eO=q08Xu>gTe~DWM4f Du2h!N diff --git a/app/src/main/res/drawable/bg_shadow_top_night.xml b/app/src/main/res/drawable/bg_shadow_top_night.xml new file mode 100644 index 000000000..3e776dbad --- /dev/null +++ b/app/src/main/res/drawable/bg_shadow_top_night.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file From 148ebfc585df2b503f182602e11d31f01fe2ed1c Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 28 Dec 2019 21:37:13 +0800 Subject: [PATCH 88/96] up --- app/src/main/res/drawable/bg_shadow_bottom.xml | 2 +- app/src/main/res/drawable/bg_shadow_bottom_night.xml | 2 +- app/src/main/res/drawable/bg_shadow_top.xml | 2 +- app/src/main/res/drawable/bg_shadow_top_night.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/drawable/bg_shadow_bottom.xml b/app/src/main/res/drawable/bg_shadow_bottom.xml index 88abc41aa..68063fd27 100644 --- a/app/src/main/res/drawable/bg_shadow_bottom.xml +++ b/app/src/main/res/drawable/bg_shadow_bottom.xml @@ -2,7 +2,7 @@ \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_shadow_bottom_night.xml b/app/src/main/res/drawable/bg_shadow_bottom_night.xml index de0d552f3..85d10b753 100644 --- a/app/src/main/res/drawable/bg_shadow_bottom_night.xml +++ b/app/src/main/res/drawable/bg_shadow_bottom_night.xml @@ -2,7 +2,7 @@ \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_shadow_top.xml b/app/src/main/res/drawable/bg_shadow_top.xml index 067790cc9..98f1df214 100644 --- a/app/src/main/res/drawable/bg_shadow_top.xml +++ b/app/src/main/res/drawable/bg_shadow_top.xml @@ -2,7 +2,7 @@ \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_shadow_top_night.xml b/app/src/main/res/drawable/bg_shadow_top_night.xml index 3e776dbad..2ef90a767 100644 --- a/app/src/main/res/drawable/bg_shadow_top_night.xml +++ b/app/src/main/res/drawable/bg_shadow_top_night.xml @@ -2,7 +2,7 @@ \ No newline at end of file From 1776012f77531aefdb8f8435aad3ee8e167636f3 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 28 Dec 2019 21:58:20 +0800 Subject: [PATCH 89/96] up --- app/build.gradle | 6 +++--- .../java/io/legado/app/model/analyzeRule/AnalyzeRule.kt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d99118fc5..7469f6cf2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -98,7 +98,7 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0' implementation 'androidx.viewpager2:viewpager2:1.0.0' - implementation 'com.google.android.material:material:1.2.0-alpha02' + implementation 'com.google.android.material:material:1.2.0-alpha03' implementation 'com.google.android:flexbox:1.1.0' //lifecycle @@ -107,12 +107,12 @@ dependencies { implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version" //room - def room_version = '2.2.2' + def room_version = '2.2.3' implementation "androidx.room:room-runtime:$room_version" kapt "androidx.room:room-compiler:$room_version" //paging - implementation 'androidx.paging:paging-runtime:2.1.0' + implementation 'androidx.paging:paging-runtime:2.1.1' //anko def anko_version = '0.10.8' 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 c2ed7c8da..419164917 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 @@ -614,7 +614,7 @@ class AnalyzeRule(var book: BaseBook? = null) : JsExtensions { val pattern = Pattern.compile("(第)(.+?)(章)") val matcher = pattern.matcher(s) return if (matcher.find()) { - matcher.group(1) + StringUtils.stringToInt(matcher.group(2)) + matcher.group(3) + matcher.group(1)!! + StringUtils.stringToInt(matcher.group(2)) + matcher.group(3) } else { s } From 24974cfa176231abbd1c7382fd5f5833d577e43f Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 28 Dec 2019 22:10:08 +0800 Subject: [PATCH 90/96] up --- app/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/app/build.gradle b/app/build.gradle index 7469f6cf2..18d4ac8ed 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -37,6 +37,7 @@ android { versionName version testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" project.ext.set("archivesBaseName", name + "_" + version) + multiDexEnabled true } buildTypes { release { From b49a5d7de92bc20edb4a0c0737d1631bdfbddd10 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 28 Dec 2019 22:17:03 +0800 Subject: [PATCH 91/96] up --- .../main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 419164917..3aa920237 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 @@ -320,7 +320,7 @@ class AnalyzeRule(var book: BaseBook? = null) : JsExtensions { val pattern = Pattern.compile(rule.replaceRegex) val matcher = pattern.matcher(vResult) if (matcher.find()) { - matcher.group(0).replaceFirst(rule.replaceRegex.toRegex(), rule.replacement) + matcher.group(0)!!.replaceFirst(rule.replaceRegex.toRegex(), rule.replacement) } else { "" } From 52c8996af64fc360d7506903444b97f33064b79e Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 29 Dec 2019 19:32:28 +0800 Subject: [PATCH 92/96] up --- .../java/io/legado/app/ui/chapterlist/ChapterListFragment.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/io/legado/app/ui/chapterlist/ChapterListFragment.kt b/app/src/main/java/io/legado/app/ui/chapterlist/ChapterListFragment.kt index 8a1990b88..c8860f021 100644 --- a/app/src/main/java/io/legado/app/ui/chapterlist/ChapterListFragment.kt +++ b/app/src/main/java/io/legado/app/ui/chapterlist/ChapterListFragment.kt @@ -13,6 +13,7 @@ import io.legado.app.R import io.legado.app.base.VMBaseFragment import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter +import io.legado.app.lib.theme.backgroundColor import io.legado.app.utils.getViewModelOfActivity import kotlinx.android.synthetic.main.fragment_chapter_list.* import org.jetbrains.anko.sdk27.listeners.onClick @@ -58,6 +59,7 @@ class ChapterListFragment : VMBaseFragment(R.layout.fragme } private fun initView() { + ll_chapter_base_info.setBackgroundColor(backgroundColor) iv_chapter_top.onClick { recycler_view.scrollToPosition(0) } iv_chapter_bottom.onClick { if (adapter.itemCount > 0) { From 4568b39af13f7fd54e08608787abb1aa6d3c8dab Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 29 Dec 2019 19:40:08 +0800 Subject: [PATCH 93/96] up --- .../java/io/legado/app/model/analyzeRule/AnalyzeByRegex.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByRegex.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByRegex.kt index 28e022fb5..5475df744 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByRegex.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByRegex.kt @@ -16,7 +16,7 @@ object AnalyzeByRegex { // 新建容器 val info = arrayListOf() for (groupIndex in 0..resM.groupCount()) { - info.add(resM.group(groupIndex)) + info.add(resM.group(groupIndex)!!) } info } else { @@ -43,7 +43,7 @@ object AnalyzeByRegex { // 新建容器 val info = arrayListOf() for (groupIndex in 0..resM.groupCount()) { - info.add(resM.group(groupIndex)) + info.add(resM.group(groupIndex)!!) } books.add(info) } while (resM.find()) From 6f20ed67e764bf725a85baaae00f17530997e4fb Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 29 Dec 2019 19:41:34 +0800 Subject: [PATCH 94/96] up --- app/src/main/java/io/legado/app/model/rss/RssParser.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/io/legado/app/model/rss/RssParser.kt b/app/src/main/java/io/legado/app/model/rss/RssParser.kt index 7606bd43e..816a3858f 100644 --- a/app/src/main/java/io/legado/app/model/rss/RssParser.kt +++ b/app/src/main/java/io/legado/app/model/rss/RssParser.kt @@ -122,9 +122,9 @@ object RssParser { if (matcherImg.find()) { val imgTag = matcherImg.group(1) val patternLink = "src\\s*=\\s*\"(.+?)\"".toPattern() - val matcherLink = patternLink.matcher(imgTag) + val matcherLink = patternLink.matcher(imgTag!!) if (matcherLink.find()) { - url = matcherLink.group(1).trim() + url = matcherLink.group(1)!!.trim() } } return url From 41258272b742a333a8f4e307775c396e6fe2e7f6 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 29 Dec 2019 19:52:50 +0800 Subject: [PATCH 95/96] up --- app/src/main/res/drawable/side_nav_bar.xml | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 app/src/main/res/drawable/side_nav_bar.xml diff --git a/app/src/main/res/drawable/side_nav_bar.xml b/app/src/main/res/drawable/side_nav_bar.xml deleted file mode 100644 index 6d81870b0..000000000 --- a/app/src/main/res/drawable/side_nav_bar.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - \ No newline at end of file From 81ac4d23d268914cf3e42fda1960c9b7cd0326b5 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 29 Dec 2019 22:20:39 +0800 Subject: [PATCH 96/96] up --- .../legado/app/ui/book/read/page/PageView.kt | 6 - .../app/ui/book/read/page/curl/CurlMesh.java | 954 ------------------ .../app/ui/book/read/page/curl/CurlPage.kt | 191 ---- .../ui/book/read/page/curl/CurlRenderer.kt | 221 ---- .../app/ui/book/read/page/curl/CurlView.kt | 769 -------------- .../book/read/page/delegate/PageDelegate.kt | 4 +- .../page/delegate/SimulationPageDelegate.kt | 570 +++++++++-- 7 files changed, 487 insertions(+), 2228 deletions(-) delete mode 100644 app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlMesh.java delete mode 100644 app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlPage.kt delete mode 100644 app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlRenderer.kt delete mode 100644 app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlView.kt 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 9d17e0f18..84dafcaa6 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 @@ -9,7 +9,6 @@ import android.widget.FrameLayout import io.legado.app.constant.PreferKey import io.legado.app.help.ReadBookConfig import io.legado.app.service.help.ReadBook -import io.legado.app.ui.book.read.page.curl.CurlView import io.legado.app.ui.book.read.page.delegate.* import io.legado.app.utils.activity import io.legado.app.utils.getPrefInt @@ -26,7 +25,6 @@ class PageView(context: Context, attrs: AttributeSet) : var prevPage: ContentView? = null var curPage: ContentView? = null var nextPage: ContentView? = null - var curlView: CurlView? = null init { callBack = activity as? CallBack @@ -91,10 +89,6 @@ class PageView(context: Context, attrs: AttributeSet) : } fun upPageAnim(pageAnim: Int) { - if (curlView != null) { - removeView(curlView) - curlView = null - } pageDelegate = null pageDelegate = when (pageAnim) { 0 -> CoverPageDelegate(this) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlMesh.java b/app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlMesh.java deleted file mode 100644 index 65ddbc363..000000000 --- a/app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlMesh.java +++ /dev/null @@ -1,954 +0,0 @@ -package io.legado.app.ui.book.read.page.curl; - -import android.graphics.Bitmap; -import android.graphics.Color; -import android.graphics.PointF; -import android.graphics.RectF; -import android.opengl.GLUtils; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; - -import javax.microedition.khronos.opengles.GL10; - -/** - * Class implementing actual curl/page rendering. - * - * @author harism - */ -public class CurlMesh { - - // Flag for rendering some lines used for developing. Shows - // curl position and one for the direction from the - // position given. Comes handy once playing around with different - // ways for following pointer. - private static final boolean DRAW_CURL_POSITION = false; - // Flag for drawing polygon outlines. Using this flag crashes on emulator - // due to reason unknown to me. Leaving it here anyway as seeing polygon - // outlines gives good insight how original rectangle is divided. - private static final boolean DRAW_POLYGON_OUTLINES = false; - // Flag for enabling shadow rendering. - private static final boolean DRAW_SHADOW = true; - // Flag for texture rendering. While this is likely something you - // don't want to do it's been used for development purposes as texture - // rendering is rather slow on emulator. - private static final boolean DRAW_TEXTURE = true; - - // Colors for shadow. Inner one is the color drawn next to surface where - // shadowed area starts and outer one is color shadow ends to. - private static final float[] SHADOW_INNER_COLOR = {0f, 0f, 0f, .5f}; - private static final float[] SHADOW_OUTER_COLOR = {0f, 0f, 0f, .0f}; - - // Let's avoid using 'new' as much as possible. Meaning we introduce arrays - // once here and reuse them on runtime. Doesn't really have very much effect - // but avoids some garbage collections from happening. - private Array mArrDropShadowVertices; - private Array mArrIntersections; - private Array mArrOutputVertices; - private Array mArrRotatedVertices; - private Array mArrScanLines; - private Array mArrSelfShadowVertices; - private Array mArrTempShadowVertices; - private Array mArrTempVertices; - - // Buffers for feeding rasterizer. - private FloatBuffer mBufColors; - private FloatBuffer mBufCurlPositionLines; - private FloatBuffer mBufShadowColors; - private FloatBuffer mBufShadowVertices; - private FloatBuffer mBufTexCoords; - private FloatBuffer mBufVertices; - - private int mCurlPositionLinesCount; - private int mDropShadowCount; - - // Boolean for 'flipping' texture sideways. - private boolean mFlipTexture = false; - // Maximum number of split lines used for creating a curl. - private int mMaxCurlSplits; - - // Bounding rectangle for this mesh. mRectagle[0] = top-left corner, - // mRectangle[1] = bottom-left, mRectangle[2] = top-right and mRectangle[3] - // bottom-right. - private final Vertex[] mRectangle = new Vertex[4]; - private int mSelfShadowCount; - - private boolean mTextureBack = false; - // Texture ids and other variables. - private int[] mTextureIds = null; - private final CurlPage mTexturePage = new CurlPage(); - private final RectF mTextureRectBack = new RectF(); - private final RectF mTextureRectFront = new RectF(); - - private int mVerticesCountBack; - private int mVerticesCountFront; - - /** - * Constructor for mesh object. - * - * @param maxCurlSplits Maximum number curl can be divided into. The bigger the value - * the smoother curl will be. With the cost of having more - * polygons for drawing. - */ - public CurlMesh(int maxCurlSplits) { - // There really is no use for 0 splits. - mMaxCurlSplits = maxCurlSplits < 1 ? 1 : maxCurlSplits; - - mArrScanLines = new Array<>(maxCurlSplits + 2); - mArrOutputVertices = new Array<>(7); - mArrRotatedVertices = new Array<>(4); - mArrIntersections = new Array<>(2); - mArrTempVertices = new Array<>(7 + 4); - for (int i = 0; i < 7 + 4; ++i) { - mArrTempVertices.add(new Vertex()); - } - - if (DRAW_SHADOW) { - mArrSelfShadowVertices = new Array<>( - (mMaxCurlSplits + 2) * 2); - mArrDropShadowVertices = new Array<>( - (mMaxCurlSplits + 2) * 2); - mArrTempShadowVertices = new Array<>( - (mMaxCurlSplits + 2) * 2); - for (int i = 0; i < (mMaxCurlSplits + 2) * 2; ++i) { - mArrTempShadowVertices.add(new ShadowVertex()); - } - } - - // Rectangle consists of 4 vertices. Index 0 = top-left, index 1 = - // bottom-left, index 2 = top-right and index 3 = bottom-right. - for (int i = 0; i < 4; ++i) { - mRectangle[i] = new Vertex(); - } - // Set up shadow penumbra direction to each vertex. We do fake 'self - // shadow' calculations based on this information. - mRectangle[0].mPenumbraX = mRectangle[1].mPenumbraX = mRectangle[1].mPenumbraY = mRectangle[3].mPenumbraY = -1; - mRectangle[0].mPenumbraY = mRectangle[2].mPenumbraX = mRectangle[2].mPenumbraY = mRectangle[3].mPenumbraX = 1; - - if (DRAW_CURL_POSITION) { - mCurlPositionLinesCount = 3; - ByteBuffer hvbb = ByteBuffer - .allocateDirect(mCurlPositionLinesCount * 2 * 2 * 4); - hvbb.order(ByteOrder.nativeOrder()); - mBufCurlPositionLines = hvbb.asFloatBuffer(); - mBufCurlPositionLines.position(0); - } - - // There are 4 vertices from bounding rect, max 2 from adding split line - // to two corners and curl consists of max mMaxCurlSplits lines each - // outputting 2 vertices. - int maxVerticesCount = 4 + 2 + (2 * mMaxCurlSplits); - ByteBuffer vbb = ByteBuffer.allocateDirect(maxVerticesCount * 3 * 4); - vbb.order(ByteOrder.nativeOrder()); - mBufVertices = vbb.asFloatBuffer(); - mBufVertices.position(0); - - if (DRAW_TEXTURE) { - ByteBuffer tbb = ByteBuffer - .allocateDirect(maxVerticesCount * 2 * 4); - tbb.order(ByteOrder.nativeOrder()); - mBufTexCoords = tbb.asFloatBuffer(); - mBufTexCoords.position(0); - } - - ByteBuffer cbb = ByteBuffer.allocateDirect(maxVerticesCount * 4 * 4); - cbb.order(ByteOrder.nativeOrder()); - mBufColors = cbb.asFloatBuffer(); - mBufColors.position(0); - - if (DRAW_SHADOW) { - int maxShadowVerticesCount = (mMaxCurlSplits + 2) * 2 * 2; - ByteBuffer scbb = ByteBuffer - .allocateDirect(maxShadowVerticesCount * 4 * 4); - scbb.order(ByteOrder.nativeOrder()); - mBufShadowColors = scbb.asFloatBuffer(); - mBufShadowColors.position(0); - - ByteBuffer sibb = ByteBuffer - .allocateDirect(maxShadowVerticesCount * 3 * 4); - sibb.order(ByteOrder.nativeOrder()); - mBufShadowVertices = sibb.asFloatBuffer(); - mBufShadowVertices.position(0); - - mDropShadowCount = mSelfShadowCount = 0; - } - } - - /** - * Adds vertex to buffers. - */ - private void addVertex(Vertex vertex) { - mBufVertices.put((float) vertex.mPosX); - mBufVertices.put((float) vertex.mPosY); - mBufVertices.put((float) vertex.mPosZ); - mBufColors.put(vertex.mColorFactor * Color.red(vertex.mColor) / 255f); - mBufColors.put(vertex.mColorFactor * Color.green(vertex.mColor) / 255f); - mBufColors.put(vertex.mColorFactor * Color.blue(vertex.mColor) / 255f); - mBufColors.put(Color.alpha(vertex.mColor) / 255f); - if (DRAW_TEXTURE) { - mBufTexCoords.put((float) vertex.mTexX); - mBufTexCoords.put((float) vertex.mTexY); - } - } - - /** - * Sets curl for this mesh. - * - * @param curlPos Position for curl 'center'. Can be any point on line collinear - * to curl. - * @param curlDir Curl direction, should be normalized. - * @param radius Radius of curl. - */ - public synchronized void curl(PointF curlPos, PointF curlDir, double radius) { - - // First add some 'helper' lines used for development. - if (DRAW_CURL_POSITION) { - mBufCurlPositionLines.position(0); - - mBufCurlPositionLines.put(curlPos.x); - mBufCurlPositionLines.put(curlPos.y - 1.0f); - mBufCurlPositionLines.put(curlPos.x); - mBufCurlPositionLines.put(curlPos.y + 1.0f); - mBufCurlPositionLines.put(curlPos.x - 1.0f); - mBufCurlPositionLines.put(curlPos.y); - mBufCurlPositionLines.put(curlPos.x + 1.0f); - mBufCurlPositionLines.put(curlPos.y); - - mBufCurlPositionLines.put(curlPos.x); - mBufCurlPositionLines.put(curlPos.y); - mBufCurlPositionLines.put(curlPos.x + curlDir.x * 2); - mBufCurlPositionLines.put(curlPos.y + curlDir.y * 2); - - mBufCurlPositionLines.position(0); - } - - // Actual 'curl' implementation starts here. - mBufVertices.position(0); - mBufColors.position(0); - if (DRAW_TEXTURE) { - mBufTexCoords.position(0); - } - - // Calculate curl angle from direction. - double curlAngle = Math.acos(curlDir.x); - curlAngle = curlDir.y > 0 ? -curlAngle : curlAngle; - - // Initiate rotated rectangle which's is translated to curlPos and - // rotated so that curl direction heads to right (1,0). Vertices are - // ordered in ascending order based on x -coordinate at the same time. - // And using y -coordinate in very rare case in which two vertices have - // same x -coordinate. - mArrTempVertices.addAll(mArrRotatedVertices); - mArrRotatedVertices.clear(); - for (int i = 0; i < 4; ++i) { - Vertex v = mArrTempVertices.remove(0); - v.set(mRectangle[i]); - v.translate(-curlPos.x, -curlPos.y); - v.rotateZ(-curlAngle); - int j = 0; - for (; j < mArrRotatedVertices.size(); ++j) { - Vertex v2 = mArrRotatedVertices.get(j); - if (v.mPosX > v2.mPosX) { - break; - } - if (v.mPosX == v2.mPosX && v.mPosY > v2.mPosY) { - break; - } - } - mArrRotatedVertices.add(j, v); - } - - // Rotated rectangle lines/vertex indices. We need to find bounding - // lines for rotated rectangle. After sorting vertices according to - // their x -coordinate we don't have to worry about vertices at indices - // 0 and 1. But due to inaccuracy it's possible vertex 3 is not the - // opposing corner from vertex 0. So we are calculating distance from - // vertex 0 to vertices 2 and 3 - and altering line indices if needed. - // Also vertices/lines are given in an order first one has x -coordinate - // at least the latter one. This property is used in getIntersections to - // see if there is an intersection. - int[][] lines = {{0, 1}, {0, 2}, {1, 3}, {2, 3}}; - { - // TODO: There really has to be more 'easier' way of doing this - - // not including extensive use of sqrt. - Vertex v0 = mArrRotatedVertices.get(0); - Vertex v2 = mArrRotatedVertices.get(2); - Vertex v3 = mArrRotatedVertices.get(3); - double dist2 = Math.sqrt((v0.mPosX - v2.mPosX) - * (v0.mPosX - v2.mPosX) + (v0.mPosY - v2.mPosY) - * (v0.mPosY - v2.mPosY)); - double dist3 = Math.sqrt((v0.mPosX - v3.mPosX) - * (v0.mPosX - v3.mPosX) + (v0.mPosY - v3.mPosY) - * (v0.mPosY - v3.mPosY)); - if (dist2 > dist3) { - lines[1][1] = 3; - lines[2][1] = 2; - } - } - - mVerticesCountFront = mVerticesCountBack = 0; - - if (DRAW_SHADOW) { - mArrTempShadowVertices.addAll(mArrDropShadowVertices); - mArrTempShadowVertices.addAll(mArrSelfShadowVertices); - mArrDropShadowVertices.clear(); - mArrSelfShadowVertices.clear(); - } - - // Length of 'curl' curve. - double curlLength = Math.PI * radius; - // Calculate scan lines. - // TODO: Revisit this code one day. There is room for optimization here. - mArrScanLines.clear(); - if (mMaxCurlSplits > 0) { - mArrScanLines.add((double) 0); - } - for (int i = 1; i < mMaxCurlSplits; ++i) { - mArrScanLines.add((-curlLength * i) / (mMaxCurlSplits - 1)); - } - // As mRotatedVertices is ordered regarding x -coordinate, adding - // this scan line produces scan area picking up vertices which are - // rotated completely. One could say 'until infinity'. - mArrScanLines.add(mArrRotatedVertices.get(3).mPosX - 1); - - // Start from right most vertex. Pretty much the same as first scan area - // is starting from 'infinity'. - double scanXmax = mArrRotatedVertices.get(0).mPosX + 1; - - for (int i = 0; i < mArrScanLines.size(); ++i) { - // Once we have scanXmin and scanXmax we have a scan area to start - // working with. - double scanXmin = mArrScanLines.get(i); - // First iterate 'original' rectangle vertices within scan area. - for (int j = 0; j < mArrRotatedVertices.size(); ++j) { - Vertex v = mArrRotatedVertices.get(j); - // Test if vertex lies within this scan area. - // TODO: Frankly speaking, can't remember why equality check was - // added to both ends. Guessing it was somehow related to case - // where radius=0f, which, given current implementation, could - // be handled much more effectively anyway. - if (v.mPosX >= scanXmin && v.mPosX <= scanXmax) { - // Pop out a vertex from temp vertices. - Vertex n = mArrTempVertices.remove(0); - n.set(v); - // This is done solely for triangulation reasons. Given a - // rotated rectangle it has max 2 vertices having - // intersection. - Array intersections = getIntersections( - mArrRotatedVertices, lines, n.mPosX); - // In a sense one could say we're adding vertices always in - // two, positioned at the ends of intersecting line. And for - // triangulation to work properly they are added based on y - // -coordinate. And this if-else is doing it for us. - if (intersections.size() == 1 - && intersections.get(0).mPosY > v.mPosY) { - // In case intersecting vertex is higher add it first. - mArrOutputVertices.addAll(intersections); - mArrOutputVertices.add(n); - } else if (intersections.size() <= 1) { - // Otherwise add original vertex first. - mArrOutputVertices.add(n); - mArrOutputVertices.addAll(intersections); - } else { - // There should never be more than 1 intersecting - // vertex. But if it happens as a fallback simply skip - // everything. - mArrTempVertices.add(n); - mArrTempVertices.addAll(intersections); - } - } - } - - // Search for scan line intersections. - Array intersections = getIntersections(mArrRotatedVertices, - lines, scanXmin); - - // We expect to get 0 or 2 vertices. In rare cases there's only one - // but in general given a scan line intersecting rectangle there - // should be 2 intersecting vertices. - if (intersections.size() == 2) { - // There were two intersections, add them based on y - // -coordinate, higher first, lower last. - Vertex v1 = intersections.get(0); - Vertex v2 = intersections.get(1); - if (v1.mPosY < v2.mPosY) { - mArrOutputVertices.add(v2); - mArrOutputVertices.add(v1); - } else { - mArrOutputVertices.addAll(intersections); - } - } else if (intersections.size() != 0) { - // This happens in a case in which there is a original vertex - // exactly at scan line or something went very much wrong if - // there are 3+ vertices. What ever the reason just return the - // vertices to temp vertices for later use. In former case it - // was handled already earlier once iterating through - // mRotatedVertices, in latter case it's better to avoid doing - // anything with them. - mArrTempVertices.addAll(intersections); - } - - // Add vertices found during this iteration to vertex etc buffers. - while (mArrOutputVertices.size() > 0) { - Vertex v = mArrOutputVertices.remove(0); - mArrTempVertices.add(v); - - // Local texture front-facing flag. - boolean textureFront; - - // Untouched vertices. - if (i == 0) { - textureFront = true; - mVerticesCountFront++; - } - // 'Completely' rotated vertices. - else if (i == mArrScanLines.size() - 1 || curlLength == 0) { - v.mPosX = -(curlLength + v.mPosX); - v.mPosZ = 2 * radius; - v.mPenumbraX = -v.mPenumbraX; - - textureFront = false; - mVerticesCountBack++; - } - // Vertex lies within 'curl'. - else { - // Even though it's not obvious from the if-else clause, - // here v.mPosX is between [-curlLength, 0]. And we can do - // calculations around a half cylinder. - double rotY = Math.PI * (v.mPosX / curlLength); - v.mPosX = radius * Math.sin(rotY); - v.mPosZ = radius - (radius * Math.cos(rotY)); - v.mPenumbraX *= Math.cos(rotY); - // Map color multiplier to [.1f, 1f] range. - v.mColorFactor = (float) (.1f + .9f * Math.sqrt(Math - .sin(rotY) + 1)); - - if (v.mPosZ >= radius) { - textureFront = false; - mVerticesCountBack++; - } else { - textureFront = true; - mVerticesCountFront++; - } - } - - // We use local textureFront for flipping backside texture - // locally. Plus additionally if mesh is in flip texture mode, - // we'll make the procedure "backwards". Also, until this point, - // texture coordinates are within [0, 1] range so we'll adjust - // them to final texture coordinates too. - if (textureFront != mFlipTexture) { - v.mTexX *= mTextureRectFront.right; - v.mTexY *= mTextureRectFront.bottom; - v.mColor = mTexturePage.getColor(CurlPage.SIDE_FRONT); - } else { - v.mTexX *= mTextureRectBack.right; - v.mTexY *= mTextureRectBack.bottom; - v.mColor = mTexturePage.getColor(CurlPage.SIDE_BACK); - } - - // Move vertex back to 'world' coordinates. - v.rotateZ(curlAngle); - v.translate(curlPos.x, curlPos.y); - addVertex(v); - - // Drop shadow is cast 'behind' the curl. - if (DRAW_SHADOW && v.mPosZ > 0 && v.mPosZ <= radius) { - ShadowVertex sv = mArrTempShadowVertices.remove(0); - sv.mPosX = v.mPosX; - sv.mPosY = v.mPosY; - sv.mPosZ = v.mPosZ; - sv.mPenumbraX = (v.mPosZ / 2) * -curlDir.x; - sv.mPenumbraY = (v.mPosZ / 2) * -curlDir.y; - sv.mPenumbraColor = v.mPosZ / radius; - int idx = (mArrDropShadowVertices.size() + 1) / 2; - mArrDropShadowVertices.add(idx, sv); - } - // Self shadow is cast partly over mesh. - if (DRAW_SHADOW && v.mPosZ > radius) { - ShadowVertex sv = mArrTempShadowVertices.remove(0); - sv.mPosX = v.mPosX; - sv.mPosY = v.mPosY; - sv.mPosZ = v.mPosZ; - sv.mPenumbraX = ((v.mPosZ - radius) / 3) * v.mPenumbraX; - sv.mPenumbraY = ((v.mPosZ - radius) / 3) * v.mPenumbraY; - sv.mPenumbraColor = (v.mPosZ - radius) / (2 * radius); - int idx = (mArrSelfShadowVertices.size() + 1) / 2; - mArrSelfShadowVertices.add(idx, sv); - } - } - - // Switch scanXmin as scanXmax for next iteration. - scanXmax = scanXmin; - } - - mBufVertices.position(0); - mBufColors.position(0); - if (DRAW_TEXTURE) { - mBufTexCoords.position(0); - } - - // Add shadow Vertices. - if (DRAW_SHADOW) { - mBufShadowColors.position(0); - mBufShadowVertices.position(0); - mDropShadowCount = 0; - - for (int i = 0; i < mArrDropShadowVertices.size(); ++i) { - ShadowVertex sv = mArrDropShadowVertices.get(i); - mBufShadowVertices.put((float) sv.mPosX); - mBufShadowVertices.put((float) sv.mPosY); - mBufShadowVertices.put((float) sv.mPosZ); - mBufShadowVertices.put((float) (sv.mPosX + sv.mPenumbraX)); - mBufShadowVertices.put((float) (sv.mPosY + sv.mPenumbraY)); - mBufShadowVertices.put((float) sv.mPosZ); - for (int j = 0; j < 4; ++j) { - double color = SHADOW_OUTER_COLOR[j] - + (SHADOW_INNER_COLOR[j] - SHADOW_OUTER_COLOR[j]) - * sv.mPenumbraColor; - mBufShadowColors.put((float) color); - } - mBufShadowColors.put(SHADOW_OUTER_COLOR); - mDropShadowCount += 2; - } - mSelfShadowCount = 0; - for (int i = 0; i < mArrSelfShadowVertices.size(); ++i) { - ShadowVertex sv = mArrSelfShadowVertices.get(i); - mBufShadowVertices.put((float) sv.mPosX); - mBufShadowVertices.put((float) sv.mPosY); - mBufShadowVertices.put((float) sv.mPosZ); - mBufShadowVertices.put((float) (sv.mPosX + sv.mPenumbraX)); - mBufShadowVertices.put((float) (sv.mPosY + sv.mPenumbraY)); - mBufShadowVertices.put((float) sv.mPosZ); - for (int j = 0; j < 4; ++j) { - double color = SHADOW_OUTER_COLOR[j] - + (SHADOW_INNER_COLOR[j] - SHADOW_OUTER_COLOR[j]) - * sv.mPenumbraColor; - mBufShadowColors.put((float) color); - } - mBufShadowColors.put(SHADOW_OUTER_COLOR); - mSelfShadowCount += 2; - } - mBufShadowColors.position(0); - mBufShadowVertices.position(0); - } - } - - /** - * Calculates intersections for given scan line. - */ - private Array getIntersections(Array vertices, - int[][] lineIndices, double scanX) { - mArrIntersections.clear(); - // Iterate through rectangle lines each re-presented as a pair of - // vertices. - for (int[] lineIndex : lineIndices) { - Vertex v1 = vertices.get(lineIndex[0]); - Vertex v2 = vertices.get(lineIndex[1]); - // Here we expect that v1.mPosX >= v2.mPosX and wont do intersection - // test the opposite way. - if (v1.mPosX > scanX && v2.mPosX < scanX) { - // There is an intersection, calculate coefficient telling 'how - // far' scanX is from v2. - double c = (scanX - v2.mPosX) / (v1.mPosX - v2.mPosX); - Vertex n = mArrTempVertices.remove(0); - n.set(v2); - n.mPosX = scanX; - n.mPosY += (v1.mPosY - v2.mPosY) * c; - if (DRAW_TEXTURE) { - n.mTexX += (v1.mTexX - v2.mTexX) * c; - n.mTexY += (v1.mTexY - v2.mTexY) * c; - } - if (DRAW_SHADOW) { - n.mPenumbraX += (v1.mPenumbraX - v2.mPenumbraX) * c; - n.mPenumbraY += (v1.mPenumbraY - v2.mPenumbraY) * c; - } - mArrIntersections.add(n); - } - } - return mArrIntersections; - } - - /** - * Getter for textures page for this mesh. - */ - public synchronized CurlPage getTexturePage() { - return mTexturePage; - } - - /** - * Renders our page curl mesh. - */ - public synchronized void onDrawFrame(GL10 gl) { - // First allocate texture if there is not one yet. - if (DRAW_TEXTURE && mTextureIds == null) { - // Generate texture. - mTextureIds = new int[2]; - gl.glGenTextures(2, mTextureIds, 0); - for (int textureId : mTextureIds) { - // Set texture attributes. - gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); - gl.glTexParameterf(GL10.GL_TEXTURE_2D, - GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); - gl.glTexParameterf(GL10.GL_TEXTURE_2D, - GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST); - gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, - GL10.GL_CLAMP_TO_EDGE); - gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, - GL10.GL_CLAMP_TO_EDGE); - } - } - - if (DRAW_TEXTURE && mTexturePage.getTexturesChanged()) { - gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureIds[0]); - Bitmap texture = mTexturePage.getTexture(mTextureRectFront, - CurlPage.SIDE_FRONT); - GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, texture, 0); - texture.recycle(); - - mTextureBack = mTexturePage.hasBackTexture(); - if (mTextureBack) { - gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureIds[1]); - texture = mTexturePage.getTexture(mTextureRectBack, - CurlPage.SIDE_BACK); - GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, texture, 0); - texture.recycle(); - } else { - mTextureRectBack.set(mTextureRectFront); - } - - mTexturePage.recycle(); - reset(); - } - - // Some 'global' settings. - gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); - - // TODO: Drop shadow drawing is done temporarily here to hide some - // problems with its calculation. - if (DRAW_SHADOW) { - gl.glDisable(GL10.GL_TEXTURE_2D); - gl.glEnable(GL10.GL_BLEND); - gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); - gl.glEnableClientState(GL10.GL_COLOR_ARRAY); - gl.glColorPointer(4, GL10.GL_FLOAT, 0, mBufShadowColors); - gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mBufShadowVertices); - gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, mDropShadowCount); - gl.glDisableClientState(GL10.GL_COLOR_ARRAY); - gl.glDisable(GL10.GL_BLEND); - } - - if (DRAW_TEXTURE) { - gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); - gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mBufTexCoords); - } - gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mBufVertices); - // Enable color array. - gl.glEnableClientState(GL10.GL_COLOR_ARRAY); - gl.glColorPointer(4, GL10.GL_FLOAT, 0, mBufColors); - - // Draw front facing blank vertices. - gl.glDisable(GL10.GL_TEXTURE_2D); - gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, mVerticesCountFront); - - // Draw front facing texture. - if (DRAW_TEXTURE) { - gl.glEnable(GL10.GL_BLEND); - gl.glEnable(GL10.GL_TEXTURE_2D); - - if (!mFlipTexture || !mTextureBack) { - gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureIds[0]); - } else { - gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureIds[1]); - } - - gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); - gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, mVerticesCountFront); - - gl.glDisable(GL10.GL_BLEND); - gl.glDisable(GL10.GL_TEXTURE_2D); - } - - int backStartIdx = Math.max(0, mVerticesCountFront - 2); - int backCount = mVerticesCountFront + mVerticesCountBack - backStartIdx; - - // Draw back facing blank vertices. - gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, backStartIdx, backCount); - - // Draw back facing texture. - if (DRAW_TEXTURE) { - gl.glEnable(GL10.GL_BLEND); - gl.glEnable(GL10.GL_TEXTURE_2D); - - if (mFlipTexture || !mTextureBack) { - gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureIds[0]); - } else { - gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureIds[1]); - } - - gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); - gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, backStartIdx, backCount); - - gl.glDisable(GL10.GL_BLEND); - gl.glDisable(GL10.GL_TEXTURE_2D); - } - - // Disable textures and color array. - gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); - gl.glDisableClientState(GL10.GL_COLOR_ARRAY); - - if (DRAW_POLYGON_OUTLINES) { - gl.glEnable(GL10.GL_BLEND); - gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); - gl.glLineWidth(1.0f); - gl.glColor4f(0.5f, 0.5f, 1.0f, 1.0f); - gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mBufVertices); - gl.glDrawArrays(GL10.GL_LINE_STRIP, 0, mVerticesCountFront); - gl.glDisable(GL10.GL_BLEND); - } - - if (DRAW_CURL_POSITION) { - gl.glEnable(GL10.GL_BLEND); - gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); - gl.glLineWidth(1.0f); - gl.glColor4f(1.0f, 0.5f, 0.5f, 1.0f); - gl.glVertexPointer(2, GL10.GL_FLOAT, 0, mBufCurlPositionLines); - gl.glDrawArrays(GL10.GL_LINES, 0, mCurlPositionLinesCount * 2); - gl.glDisable(GL10.GL_BLEND); - } - - if (DRAW_SHADOW) { - gl.glEnable(GL10.GL_BLEND); - gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); - gl.glEnableClientState(GL10.GL_COLOR_ARRAY); - gl.glColorPointer(4, GL10.GL_FLOAT, 0, mBufShadowColors); - gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mBufShadowVertices); - gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, mDropShadowCount, - mSelfShadowCount); - gl.glDisableClientState(GL10.GL_COLOR_ARRAY); - gl.glDisable(GL10.GL_BLEND); - } - - gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); - } - - /** - * Resets mesh to 'initial' state. Meaning this mesh will draw a plain - * textured rectangle after call to this method. - */ - public synchronized void reset() { - mBufVertices.position(0); - mBufColors.position(0); - if (DRAW_TEXTURE) { - mBufTexCoords.position(0); - } - for (int i = 0; i < 4; ++i) { - Vertex tmp = mArrTempVertices.get(0); - tmp.set(mRectangle[i]); - - if (mFlipTexture) { - tmp.mTexX *= mTextureRectBack.right; - tmp.mTexY *= mTextureRectBack.bottom; - tmp.mColor = mTexturePage.getColor(CurlPage.SIDE_BACK); - } else { - tmp.mTexX *= mTextureRectFront.right; - tmp.mTexY *= mTextureRectFront.bottom; - tmp.mColor = mTexturePage.getColor(CurlPage.SIDE_FRONT); - } - - addVertex(tmp); - } - mVerticesCountFront = 4; - mVerticesCountBack = 0; - mBufVertices.position(0); - mBufColors.position(0); - if (DRAW_TEXTURE) { - mBufTexCoords.position(0); - } - - mDropShadowCount = mSelfShadowCount = 0; - } - - /** - * Resets allocated texture id forcing creation of new one. After calling - * this method you most likely want to set bitmap too as it's lost. This - * method should be called only once e.g GL context is re-created as this - * method does not release previous texture id, only makes sure new one is - * requested on next render. - */ - public synchronized void resetTexture() { - mTextureIds = null; - } - - /** - * If true, flips texture sideways. - */ - public synchronized void setFlipTexture(boolean flipTexture) { - mFlipTexture = flipTexture; - if (flipTexture) { - setTexCoords(1f, 0f, 0f, 1f); - } else { - setTexCoords(0f, 0f, 1f, 1f); - } - } - - /** - * Update mesh bounds. - */ - public void setRect(RectF r) { - mRectangle[0].mPosX = r.left; - mRectangle[0].mPosY = r.top; - mRectangle[1].mPosX = r.left; - mRectangle[1].mPosY = r.bottom; - mRectangle[2].mPosX = r.right; - mRectangle[2].mPosY = r.top; - mRectangle[3].mPosX = r.right; - mRectangle[3].mPosY = r.bottom; - } - - /** - * Sets texture coordinates to mRectangle vertices. - */ - private synchronized void setTexCoords(float left, float top, float right, - float bottom) { - mRectangle[0].mTexX = left; - mRectangle[0].mTexY = top; - mRectangle[1].mTexX = left; - mRectangle[1].mTexY = bottom; - mRectangle[2].mTexX = right; - mRectangle[2].mTexY = top; - mRectangle[3].mTexX = right; - mRectangle[3].mTexY = bottom; - } - - /** - * Simple fixed size array implementation. - */ - private class Array { - private Object[] mArray; - private int mCapacity; - private int mSize; - - Array(int capacity) { - mCapacity = capacity; - mArray = new Object[capacity]; - } - - public void add(int index, T item) { - if (index < 0 || index > mSize || mSize >= mCapacity) { - throw new IndexOutOfBoundsException(); - } - System.arraycopy(mArray, index, mArray, index + 1, mSize - index); - mArray[index] = item; - ++mSize; - } - - public void add(T item) { - if (mSize >= mCapacity) { - throw new IndexOutOfBoundsException(); - } - mArray[mSize++] = item; - } - - public void addAll(Array array) { - if (mSize + array.size() > mCapacity) { - throw new IndexOutOfBoundsException(); - } - for (int i = 0; i < array.size(); ++i) { - mArray[mSize++] = array.get(i); - } - } - - public void clear() { - mSize = 0; - } - - @SuppressWarnings("unchecked") - public T get(int index) { - if (index < 0 || index >= mSize) { - throw new IndexOutOfBoundsException(); - } - return (T) mArray[index]; - } - - @SuppressWarnings("unchecked") - public T remove(int index) { - if (index < 0 || index >= mSize) { - throw new IndexOutOfBoundsException(); - } - T item = (T) mArray[index]; - if (mSize - 1 - index >= 0) - System.arraycopy(mArray, index + 1, mArray, index, mSize - 1 - index); - --mSize; - return item; - } - - public int size() { - return mSize; - } - - } - - /** - * Holder for shadow vertex information. - */ - private class ShadowVertex { - double mPenumbraColor; - double mPenumbraX; - double mPenumbraY; - double mPosX; - double mPosY; - double mPosZ; - } - - /** - * Holder for vertex information. - */ - private class Vertex { - int mColor; - float mColorFactor; - double mPenumbraX; - double mPenumbraY; - double mPosX; - double mPosY; - double mPosZ; - double mTexX; - double mTexY; - - Vertex() { - mPosX = mPosY = mPosZ = mTexX = mTexY = 0; - mColorFactor = 1.0f; - } - - void rotateZ(double theta) { - double cos = Math.cos(theta); - double sin = Math.sin(theta); - double x = mPosX * cos + mPosY * sin; - double y = mPosX * -sin + mPosY * cos; - mPosX = x; - mPosY = y; - double px = mPenumbraX * cos + mPenumbraY * sin; - double py = mPenumbraX * -sin + mPenumbraY * cos; - mPenumbraX = px; - mPenumbraY = py; - } - - public void set(Vertex vertex) { - mPosX = vertex.mPosX; - mPosY = vertex.mPosY; - mPosZ = vertex.mPosZ; - mTexX = vertex.mTexX; - mTexY = vertex.mTexY; - mPenumbraX = vertex.mPenumbraX; - mPenumbraY = vertex.mPenumbraY; - mColor = vertex.mColor; - mColorFactor = vertex.mColorFactor; - } - - public void translate(double dx, double dy) { - mPosX += dx; - mPosY += dy; - } - } -} diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlPage.kt b/app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlPage.kt deleted file mode 100644 index 88f2fb16c..000000000 --- a/app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlPage.kt +++ /dev/null @@ -1,191 +0,0 @@ -package io.legado.app.ui.book.read.page.curl - -import android.graphics.Bitmap -import android.graphics.Canvas -import android.graphics.Color -import android.graphics.RectF - -/** - * Storage class for page textures, blend colors and possibly some other values - * in the future. - * - * @author harism - */ -class CurlPage { - - private var mColorBack: Int = 0 - private var mColorFront: Int = 0 - private var mTextureBack: Bitmap? = null - private var mTextureFront: Bitmap? = null - /** - * Returns true if textures have changed. - */ - var texturesChanged: Boolean = false - private set - - /** - * Default constructor. - */ - init { - reset() - } - - /** - * Getter for color. - */ - fun getColor(side: Int): Int { - return when (side) { - SIDE_FRONT -> mColorFront - else -> mColorBack - } - } - - /** - * Calculates the next highest power of two for a given integer. - */ - private fun getNextHighestPO2(n: Int): Int { - var n1 = n - n1 -= 1 - n1 = n1 or (n1 shr 1) - n1 = n1 or (n1 shr 2) - n1 = n1 or (n1 shr 4) - n1 = n1 or (n1 shr 8) - n1 = n1 or (n1 shr 16) - n1 = n1 or (n1 shr 32) - return n1 + 1 - } - - /** - * Generates nearest power of two sized Bitmap for give Bitmap. Returns this - * new Bitmap using default return statement + original texture coordinates - * are stored into RectF. - */ - private fun getTexture(bitmap: Bitmap, textureRect: RectF): Bitmap { - // Bitmap original size. - val w = bitmap.width - val h = bitmap.height - // Bitmap size expanded to next power of two. This is done due to - // the requirement on many devices, texture width and height should - // be power of two. - val newW = getNextHighestPO2(w) - val newH = getNextHighestPO2(h) - - // TODO: Is there another way to create a bigger Bitmap and copy - // original Bitmap to it more efficiently? Immutable bitmap anyone? - val bitmapTex = Bitmap.createBitmap(newW, newH, bitmap.config) - val c = Canvas(bitmapTex) - c.drawBitmap(bitmap, 0f, 0f, null) - - // Calculate final texture coordinates. - val texX = w.toFloat() / newW - val texY = h.toFloat() / newH - textureRect.set(0f, 0f, texX, texY) - - return bitmapTex - } - - /** - * Getter for textures. Creates Bitmap sized to nearest power of two, copies - * original Bitmap into it and returns it. RectF given as parameter is - * filled with actual texture coordinates in this new upscaled texture - * Bitmap. - */ - fun getTexture(textureRect: RectF, side: Int): Bitmap { - return when (side) { - SIDE_FRONT -> getTexture(mTextureFront!!, textureRect) - else -> getTexture(mTextureBack!!, textureRect) - } - } - - /** - * Returns true if back siding texture exists and it differs from front - * facing one. - */ - fun hasBackTexture(): Boolean { - return mTextureFront != mTextureBack - } - - /** - * Recycles and frees underlying Bitmaps. - */ - fun recycle() { - if (mTextureFront != null) { - mTextureFront!!.recycle() - } - mTextureFront = Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565) - mTextureFront!!.eraseColor(mColorFront) - if (mTextureBack != null) { - mTextureBack!!.recycle() - } - mTextureBack = Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565) - mTextureBack!!.eraseColor(mColorBack) - texturesChanged = false - } - - /** - * Resets this CurlPage into its initial state. - */ - fun reset() { - mColorBack = Color.WHITE - mColorFront = Color.WHITE - recycle() - } - - /** - * Setter blend color. - */ - fun setColor(color: Int, side: Int) { - when (side) { - SIDE_FRONT -> mColorFront = color - SIDE_BACK -> mColorBack = color - else -> { - mColorBack = color - mColorFront = mColorBack - } - } - } - - /** - * Setter for textures. - */ - fun setTexture(texture: Bitmap?, side: Int) { - var texture1 = texture - if (texture1 == null) { - texture1 = Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565) - if (side == SIDE_BACK) { - texture1!!.eraseColor(mColorBack) - } else { - texture1!!.eraseColor(mColorFront) - } - } - when (side) { - SIDE_FRONT -> { - if (mTextureFront != null) - mTextureFront!!.recycle() - mTextureFront = texture1 - } - SIDE_BACK -> { - if (mTextureBack != null) - mTextureBack!!.recycle() - mTextureBack = texture1 - } - SIDE_BOTH -> { - if (mTextureFront != null) - mTextureFront!!.recycle() - if (mTextureBack != null) - mTextureBack!!.recycle() - mTextureBack = texture1 - mTextureFront = mTextureBack - } - } - texturesChanged = true - } - - companion object { - - const val SIDE_BACK = 2 - const val SIDE_BOTH = 3 - const val SIDE_FRONT = 1 - } - -} diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlRenderer.kt b/app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlRenderer.kt deleted file mode 100644 index 6d44ee1ee..000000000 --- a/app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlRenderer.kt +++ /dev/null @@ -1,221 +0,0 @@ -package io.legado.app.ui.book.read.page.curl - -import android.graphics.Color -import android.graphics.PointF -import android.graphics.RectF -import android.opengl.GLSurfaceView -import android.opengl.GLU -import java.util.* -import javax.microedition.khronos.egl.EGLConfig -import javax.microedition.khronos.opengles.GL10 - -/** - * Actual renderer class. - * - * @author harism - */ -class CurlRenderer(private val mObserver: Observer) : GLSurfaceView.Renderer { - // Background fill color. - private var mBackgroundColor: Int = 0 - // Curl meshes used for static and dynamic rendering. - private val mCurlMeshes: Vector = Vector() - private val mMargins = RectF() - // Page rectangles. - private val mPageRectLeft: RectF = RectF() - private val mPageRectRight: RectF = RectF() - // View mode. - private var mViewMode = SHOW_ONE_PAGE - // Screen size. - private var mViewportWidth: Int = 0 - private var mViewportHeight: Int = 0 - // Rect for render area. - private val mViewRect = RectF() - - /** - * Adds CurlMesh to this renderer. - */ - @Synchronized - fun addCurlMesh(mesh: CurlMesh) { - removeCurlMesh(mesh) - mCurlMeshes.add(mesh) - } - - /** - * Returns rect reserved for left or right page. Value page should be - * PAGE_LEFT or PAGE_RIGHT. - */ - fun getPageRect(page: Int): RectF? { - if (page == PAGE_LEFT) { - return mPageRectLeft - } else if (page == PAGE_RIGHT) { - return mPageRectRight - } - return null - } - - @Synchronized - override fun onDrawFrame(gl: GL10) { - - mObserver.onDrawFrame() - - gl.glClearColor( - Color.red(mBackgroundColor) / 255f, - Color.green(mBackgroundColor) / 255f, - Color.blue(mBackgroundColor) / 255f, - Color.alpha(mBackgroundColor) / 255f - ) - gl.glClear(GL10.GL_COLOR_BUFFER_BIT) - gl.glLoadIdentity() - - if (!mObserver.canDraw) { - return - } - - for (i in mCurlMeshes.indices) { - mCurlMeshes[i].onDrawFrame(gl) - } - } - - override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) { - gl.glViewport(0, 0, width, height) - mViewportWidth = width - mViewportHeight = height - - val ratio = width.toFloat() / height - mViewRect.top = 1.0f - mViewRect.bottom = -1.0f - mViewRect.left = -ratio - mViewRect.right = ratio - updatePageRect() - - gl.glMatrixMode(GL10.GL_PROJECTION) - gl.glLoadIdentity() - GLU.gluOrtho2D( - gl, mViewRect.left, mViewRect.right, - mViewRect.bottom, mViewRect.top - ) - - gl.glMatrixMode(GL10.GL_MODELVIEW) - gl.glLoadIdentity() - } - - override fun onSurfaceCreated(gl: GL10, config: EGLConfig) { - gl.glClearColor(0f, 0f, 0f, 1f) - gl.glShadeModel(GL10.GL_SMOOTH) - gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST) - gl.glHint(GL10.GL_LINE_SMOOTH_HINT, GL10.GL_NICEST) - gl.glHint(GL10.GL_POLYGON_SMOOTH_HINT, GL10.GL_NICEST) - gl.glEnable(GL10.GL_LINE_SMOOTH) - gl.glDisable(GL10.GL_DEPTH_TEST) - gl.glDisable(GL10.GL_CULL_FACE) - - mObserver.onSurfaceCreated() - } - - /** - * Removes CurlMesh from this renderer. - */ - @Synchronized - fun removeCurlMesh(mesh: CurlMesh) { - mCurlMeshes.remove(mesh) - } - - /** - * Sets visible page count to one or two. Should be either SHOW_ONE_PAGE or - * SHOW_TWO_PAGES. - */ - @Synchronized - fun setViewMode(viewMode: Int) { - if (viewMode == SHOW_ONE_PAGE) { - mViewMode = viewMode - updatePageRect() - } else if (viewMode == SHOW_TWO_PAGES) { - mViewMode = viewMode - updatePageRect() - } - } - - /** - * Translates screen coordinates into view coordinates. - */ - fun translate(pt: PointF) { - pt.x = mViewRect.left + mViewRect.width() * pt.x / mViewportWidth - pt.y = mViewRect.top - -mViewRect.height() * pt.y / mViewportHeight - } - - /** - * Recalculates page rectangles. - */ - private fun updatePageRect() { - if (mViewRect.width() == 0f || mViewRect.height() == 0f) { - return - } else if (mViewMode == SHOW_ONE_PAGE) { - mPageRectRight.set(mViewRect) - mPageRectRight.left += mViewRect.width() * mMargins.left - mPageRectRight.right -= mViewRect.width() * mMargins.right - mPageRectRight.top += mViewRect.height() * mMargins.top - mPageRectRight.bottom -= mViewRect.height() * mMargins.bottom - - mPageRectLeft.set(mPageRectRight) - mPageRectLeft.offset(-mPageRectRight.width(), 0f) - - val bitmapW = (mPageRectRight.width() * mViewportWidth / mViewRect - .width()).toInt() - val bitmapH = (mPageRectRight.height() * mViewportHeight / mViewRect - .height()).toInt() - mObserver.onPageSizeChanged(bitmapW, bitmapH) - } else if (mViewMode == SHOW_TWO_PAGES) { - mPageRectRight.set(mViewRect) - mPageRectRight.left += mViewRect.width() * mMargins.left - mPageRectRight.right -= mViewRect.width() * mMargins.right - mPageRectRight.top += mViewRect.height() * mMargins.top - mPageRectRight.bottom -= mViewRect.height() * mMargins.bottom - - mPageRectLeft.set(mPageRectRight) - mPageRectLeft.right = (mPageRectLeft.right + mPageRectLeft.left) / 2 - mPageRectRight.left = mPageRectLeft.right - - val bitmapW = (mPageRectRight.width() * mViewportWidth / mViewRect - .width()).toInt() - val bitmapH = (mPageRectRight.height() * mViewportHeight / mViewRect - .height()).toInt() - mObserver.onPageSizeChanged(bitmapW, bitmapH) - } - } - - /** - * Observer for waiting render engine/state updates. - */ - interface Observer { - /** - * Called from onDrawFrame called before rendering is started. This is - * intended to be used for animation purposes. - */ - fun onDrawFrame() - - /** - * Called once page size is changed. Width and height tell the page size - * in pixels making it possible to update textures accordingly. - */ - fun onPageSizeChanged(width: Int, height: Int) - - /** - * Called from onSurfaceCreated to enable texture re-initialization etc - * what needs to be done when this happens. - */ - fun onSurfaceCreated() - - var canDraw: Boolean - } - - companion object { - - // Constant for requesting left page rect. - const val PAGE_LEFT = 1 - // Constant for requesting right page rect. - const val PAGE_RIGHT = 2 - // Constants for changing view mode. - const val SHOW_ONE_PAGE = 1 - const val SHOW_TWO_PAGES = 2 - } -} diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlView.kt deleted file mode 100644 index ecd5d410d..000000000 --- a/app/src/main/java/io/legado/app/ui/book/read/page/curl/CurlView.kt +++ /dev/null @@ -1,769 +0,0 @@ -package io.legado.app.ui.book.read.page.curl - -import android.content.Context -import android.graphics.PixelFormat -import android.graphics.PointF -import android.opengl.GLSurfaceView -import android.util.AttributeSet -import android.view.MotionEvent -import android.view.View -import kotlin.math.max -import kotlin.math.min -import kotlin.math.sin -import kotlin.math.sqrt - -/** - * OpenGL ES View. - * - * @author harism - */ -class CurlView : GLSurfaceView, View.OnTouchListener, CurlRenderer.Observer { - var callBack: CallBack? = null - private var mAllowLastPageCurl = true - - private var mAnimate = false - private val mAnimationDurationTime: Long = 300 - private val mAnimationSource = PointF() - private var mAnimationStartTime: Long = 0 - private val mAnimationTarget = PointF() - private var mAnimationTargetEvent: Int = 0 - - private val mCurlDir = PointF() - - private val mCurlPos = PointF() - private var mCurlState = CURL_NONE - // Current bitmap index. This is always showed as front of right page. - private var mCurrentIndex = 0 - - // Start position for dragging. - private val mDragStartPos = PointF() - - private var mEnableTouchPressure = false - // Bitmap size. These are updated from renderer once it's initialized. - private var mPageBitmapHeight = -1 - - private var mPageBitmapWidth = -1 - // Page meshes. Left and right meshes are 'static' while curl is used to - // show page flipping. - private var mPageCurl: CurlMesh - private var mPageLeft: CurlMesh - private var mPageRight: CurlMesh - - private val mPointerPos = PointerPosition() - - private var mRenderer: CurlRenderer = CurlRenderer(this) - private var mRenderLeftPage = true - private var mSizeChangedObserver: SizeChangedObserver? = null - - // One page is the default. - private var mViewMode = SHOW_ONE_PAGE - - var mPageProvider: PageProvider? = null - set(value) { - field = value - mCurrentIndex = 0 - updatePages() - requestRender() - } - - /** - * Get current page index. Page indices are zero based values presenting - * page being shown on right side of the book. - */ - /** - * Set current page index. Page indices are zero based values presenting - * page being shown on right side of the book. E.g if you set value to 4; - * right side front facing bitmap will be with index 4, back facing 5 and - * for left side page index 3 is front facing, and index 2 back facing (once - * page is on left side it's flipped over). - * - * - * Current index is rounded to closest value divisible with 2. - */ - var currentIndex: Int - get() = mCurrentIndex - set(index) { - mCurrentIndex = if (mPageProvider == null || index < 0) { - 0 - } else { - if (mAllowLastPageCurl) { - min(index, mPageProvider!!.pageCount) - } else { - min(index, mPageProvider!!.pageCount - 1) - } - } - updatePages() - requestRender() - } - - /** - * Default constructor. - */ - constructor(ctx: Context) : super(ctx) - - /** - * Default constructor. - */ - constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs) - - /** - * Default constructor. - */ - constructor(ctx: Context, attrs: AttributeSet, defStyle: Int) : this(ctx, attrs) - - /** - * Initialize method. - */ - init { - setEGLConfigChooser(8, 8, 8, 8, 16, 0) - holder.setFormat(PixelFormat.TRANSLUCENT) - setZOrderOnTop(true) - - setRenderer(mRenderer) - renderMode = RENDERMODE_WHEN_DIRTY - setOnTouchListener(this) - - // Even though left and right pages are static we have to allocate room - // for curl on them too as we are switching meshes. Another way would be - // to swap texture ids only. - mPageLeft = CurlMesh(10) - mPageRight = CurlMesh(10) - mPageCurl = CurlMesh(10) - mPageLeft.setFlipTexture(true) - mPageRight.setFlipTexture(false) - } - - override var canDraw: Boolean = false - - override fun onDrawFrame() { - // We are not animating. - if (!mAnimate) { - return - } - - val currentTime = System.currentTimeMillis() - // If animation is done. - if (currentTime >= mAnimationStartTime + mAnimationDurationTime) { - if (mAnimationTargetEvent == SET_CURL_TO_RIGHT) { - // Switch curled page to right. - val right = mPageCurl - val curl = mPageRight - right.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT)!!) - right.setFlipTexture(false) - right.reset() - mRenderer.removeCurlMesh(curl) - mPageCurl = curl - mPageRight = right - // If we were curling left page update current index. - if (mCurlState == CURL_LEFT) { - --mCurrentIndex - callBack?.pageChange(-1) - } - canDraw = false - } else if (mAnimationTargetEvent == SET_CURL_TO_LEFT) { - // Switch curled page to left. - val left = mPageCurl - val curl = mPageLeft - left.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_LEFT)!!) - left.setFlipTexture(true) - left.reset() - mRenderer.removeCurlMesh(curl) - if (!mRenderLeftPage) { - mRenderer.removeCurlMesh(left) - } - mPageCurl = curl - mPageLeft = left - // If we were curling right page update current index. - if (mCurlState == CURL_RIGHT) { - ++mCurrentIndex - callBack?.pageChange(1) - } - canDraw = false - } - mCurlState = CURL_NONE - mAnimate = false - requestRender() - } else { - mPointerPos.mPos.set(mAnimationSource) - var t = 1f - (currentTime - mAnimationStartTime).toFloat() / mAnimationDurationTime - t = 1f - t * t * t * (3 - 2 * t) - mPointerPos.mPos.x += (mAnimationTarget.x - mAnimationSource.x) * t - mPointerPos.mPos.y += (mAnimationTarget.y - mAnimationSource.y) * t - updateCurlPos(mPointerPos) - } - } - - - override fun onPageSizeChanged(width: Int, height: Int) { - mPageBitmapWidth = width - mPageBitmapHeight = height - updatePages() - requestRender() - } - - public override fun onSizeChanged(w: Int, h: Int, ow: Int, oh: Int) { - super.onSizeChanged(w, h, ow, oh) - requestRender() - if (mSizeChangedObserver != null) { - mSizeChangedObserver!!.onSizeChanged(w, h) - } - } - - override fun onSurfaceCreated() { - // In case surface is recreated, let page meshes drop allocated texture - // ids and ask for new ones. There's no need to set textures here as - // onPageSizeChanged should be called later on. - mPageLeft.resetTexture() - mPageRight.resetTexture() - mPageCurl.resetTexture() - } - - override fun onTouch(view: View, me: MotionEvent): Boolean { - // No dragging during animation at the moment. - if (mAnimate || mPageProvider == null) { - return false - } - - // We need page rects quite extensively so get them for later use. - val rightRect = mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT) - val leftRect = mRenderer.getPageRect(CurlRenderer.PAGE_LEFT) - - // Store pointer position. - mPointerPos.mPos.set(me.x, me.y) - mRenderer.translate(mPointerPos.mPos) - if (mEnableTouchPressure) { - mPointerPos.mPressure = me.pressure - } else { - mPointerPos.mPressure = 0.8f - } - - when (me.action) { - MotionEvent.ACTION_DOWN -> { - run { - - // Once we receive pointer down event its position is mapped to - // right or left edge of page and that'll be the position from where - // user is holding the paper to make curl happen. - mDragStartPos.set(mPointerPos.mPos) - - // First we make sure it's not over or below page. Pages are - // supposed to be same height so it really doesn't matter do we use - // left or right one. - if (mDragStartPos.y > rightRect!!.top) { - mDragStartPos.y = rightRect.top - } else if (mDragStartPos.y < rightRect.bottom) { - mDragStartPos.y = rightRect.bottom - } - - // Then we have to make decisions for the user whether curl is going - // to happen from left or right, and on which page. - if (mViewMode == SHOW_TWO_PAGES) { - // If we have an open book and pointer is on the left from right - // page we'll mark drag position to left edge of left page. - // Additionally checking mCurrentIndex is higher than zero tells - // us there is a visible page at all. - if (mDragStartPos.x < rightRect.left && mCurrentIndex > 0) { - mDragStartPos.x = leftRect!!.left - startCurl(CURL_LEFT) - } else if (mDragStartPos.x >= rightRect.left && mCurrentIndex < mPageProvider!!.pageCount) { - mDragStartPos.x = rightRect.right - if (!mAllowLastPageCurl && mCurrentIndex >= mPageProvider!!.pageCount - 1) { - return false - } - startCurl(CURL_RIGHT) - }// Otherwise check pointer is on right page's side. - } else if (mViewMode == SHOW_ONE_PAGE) { - val halfX = (rightRect.right + rightRect.left) / 2 - if (mDragStartPos.x < halfX && mCurrentIndex > 0) { - mDragStartPos.x = rightRect.left - startCurl(CURL_LEFT) - } else if (mDragStartPos.x >= halfX && mCurrentIndex < mPageProvider!!.pageCount) { - mDragStartPos.x = rightRect.right - if (!mAllowLastPageCurl && mCurrentIndex >= mPageProvider!!.pageCount - 1) { - return false - } - startCurl(CURL_RIGHT) - } - } - // If we have are in curl state, let this case clause flow through - // to next one. We have pointer position and drag position defined - // and this will create first render request given these points. - if (mCurlState == CURL_NONE) { - return false - } - } - updateCurlPos(mPointerPos) - } - MotionEvent.ACTION_MOVE -> { - updateCurlPos(mPointerPos) - } - MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> { - if (mCurlState == CURL_LEFT || mCurlState == CURL_RIGHT) { - // Animation source is the point from where animation starts. - // Also it's handled in a way we actually simulate touch events - // meaning the output is exactly the same as if user drags the - // page to other side. While not producing the best looking - // result (which is easier done by altering curl position and/or - // direction directly), this is done in a hope it made code a - // bit more readable and easier to maintain. - mAnimationSource.set(mPointerPos.mPos) - mAnimationStartTime = System.currentTimeMillis() - - // Given the explanation, here we decide whether to simulate - // drag to left or right end. - if (mViewMode == SHOW_ONE_PAGE && mPointerPos.mPos.x > (rightRect!!.left + rightRect.right) / 2 || mViewMode == SHOW_TWO_PAGES && mPointerPos.mPos.x > rightRect!!.left) { - // On right side target is always right page's right border. - mAnimationTarget.set(mDragStartPos) - mAnimationTarget.x = mRenderer - .getPageRect(CurlRenderer.PAGE_RIGHT)!!.right - mAnimationTargetEvent = SET_CURL_TO_RIGHT - } else { - // On left side target depends on visible pages. - mAnimationTarget.set(mDragStartPos) - if (mCurlState == CURL_RIGHT || mViewMode == SHOW_TWO_PAGES) { - mAnimationTarget.x = leftRect!!.left - } else { - mAnimationTarget.x = rightRect!!.left - } - mAnimationTargetEvent = SET_CURL_TO_LEFT - } - mAnimate = true - requestRender() - } - } - } - - return true - } - - /** - * Allow the last page to curl. - */ - fun setAllowLastPageCurl(allowLastPageCurl: Boolean) { - mAllowLastPageCurl = allowLastPageCurl - } - - /** - * Sets mPageCurl curl position. - */ - private fun setCurlPos(curlPos: PointF, curlDir: PointF, radius: Double) { - - // First reposition curl so that page doesn't 'rip off' from book. - if (mCurlState == CURL_RIGHT || mCurlState == CURL_LEFT && mViewMode == SHOW_ONE_PAGE) { - val pageRect = mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT) - if (curlPos.x >= pageRect!!.right) { - mPageCurl.reset() - requestRender() - return - } - if (curlPos.x < pageRect.left) { - curlPos.x = pageRect.left - } - if (curlDir.y != 0f) { - val diffX = curlPos.x - pageRect.left - val leftY = curlPos.y + diffX * curlDir.x / curlDir.y - if (curlDir.y < 0 && leftY < pageRect.top) { - curlDir.x = curlPos.y - pageRect.top - curlDir.y = pageRect.left - curlPos.x - } else if (curlDir.y > 0 && leftY > pageRect.bottom) { - curlDir.x = pageRect.bottom - curlPos.y - curlDir.y = curlPos.x - pageRect.left - } - } - } else if (mCurlState == CURL_LEFT) { - val pageRect = mRenderer.getPageRect(CurlRenderer.PAGE_LEFT) - if (curlPos.x <= pageRect!!.left) { - mPageCurl.reset() - requestRender() - return - } - if (curlPos.x > pageRect.right) { - curlPos.x = pageRect.right - } - if (curlDir.y != 0f) { - val diffX = curlPos.x - pageRect.right - val rightY = curlPos.y + diffX * curlDir.x / curlDir.y - if (curlDir.y < 0 && rightY < pageRect.top) { - curlDir.x = pageRect.top - curlPos.y - curlDir.y = curlPos.x - pageRect.right - } else if (curlDir.y > 0 && rightY > pageRect.bottom) { - curlDir.x = curlPos.y - pageRect.bottom - curlDir.y = pageRect.right - curlPos.x - } - } - } - - // Finally normalize direction vector and do rendering. - val dist = sqrt((curlDir.x * curlDir.x + curlDir.y * curlDir.y).toDouble()) - if (dist != 0.0) { - curlDir.x /= dist.toFloat() - curlDir.y /= dist.toFloat() - mPageCurl.curl(curlPos, curlDir, radius) - } else { - mPageCurl.reset() - } - - requestRender() - } - - /** - * If set to true, touch event pressure information is used to adjust curl - * radius. The more you press, the flatter the curl becomes. This is - * somewhat experimental and results may vary significantly between devices. - * On emulator pressure information seems to be flat 1.0f which is maximum - * value and therefore not very much of use. - */ - fun setEnableTouchPressure(enableTouchPressure: Boolean) { - mEnableTouchPressure = enableTouchPressure - } - - /** - * 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 - * left page is not visible anyway. - */ - fun setRenderLeftPage(renderLeftPage: Boolean) { - mRenderLeftPage = renderLeftPage - } - - /** - * Sets SizeChangedObserver for this View. Call back method is called from - * this View's onSizeChanged method. - */ - fun setSizeChangedObserver(observer: SizeChangedObserver) { - mSizeChangedObserver = observer - } - - /** - * Sets view mode. Value can be either SHOW_ONE_PAGE or SHOW_TWO_PAGES. In - * former case right page is made size of display, and in latter case two - * pages are laid on visible area. - */ - fun setViewMode(viewMode: Int) { - when (viewMode) { - SHOW_ONE_PAGE -> { - mViewMode = viewMode - mPageLeft.setFlipTexture(true) - mRenderer.setViewMode(CurlRenderer.SHOW_ONE_PAGE) - } - SHOW_TWO_PAGES -> { - mViewMode = viewMode - mPageLeft.setFlipTexture(false) - mRenderer.setViewMode(CurlRenderer.SHOW_TWO_PAGES) - } - } - } - - /** - * Switches meshes and loads new bitmaps if available. Updated to support 2 - * pages in landscape - */ - private fun startCurl(page: Int) { - when (page) { - - // Once right side page is curled, first right page is assigned into - // curled page. And if there are more bitmaps available new bitmap is - // loaded into right side mesh. - CURL_RIGHT -> { - // Remove meshes from renderer. - mRenderer.removeCurlMesh(mPageLeft) - mRenderer.removeCurlMesh(mPageRight) - mRenderer.removeCurlMesh(mPageCurl) - - // We are curling right page. - val curl = mPageRight - mPageRight = mPageCurl - mPageCurl = curl - - if (mCurrentIndex > 0) { - mPageLeft.setFlipTexture(true) - mPageLeft.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_LEFT)!!) - mPageLeft.reset() - if (mRenderLeftPage) { - mRenderer.addCurlMesh(mPageLeft) - } - } - if (mCurrentIndex < mPageProvider!!.pageCount - 1) { - updatePage(mPageRight.texturePage, mCurrentIndex + 1) - mPageRight.setRect( - mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT)!! - ) - mPageRight.setFlipTexture(false) - mPageRight.reset() - mRenderer.addCurlMesh(mPageRight) - } - - // Add curled page to renderer. - mPageCurl.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT)!!) - mPageCurl.setFlipTexture(false) - mPageCurl.reset() - mRenderer.addCurlMesh(mPageCurl) - - mCurlState = CURL_RIGHT - } - - // On left side curl, left page is assigned to curled page. And if - // there are more bitmaps available before currentIndex, new bitmap - // is loaded into left page. - CURL_LEFT -> { - // Remove meshes from renderer. - mRenderer.removeCurlMesh(mPageLeft) - mRenderer.removeCurlMesh(mPageRight) - mRenderer.removeCurlMesh(mPageCurl) - - // We are curling left page. - val curl = mPageLeft - mPageLeft = mPageCurl - mPageCurl = curl - - if (mCurrentIndex > 1) { - updatePage(mPageLeft.texturePage, mCurrentIndex - 2) - mPageLeft.setFlipTexture(true) - mPageLeft - .setRect(mRenderer.getPageRect(CurlRenderer.PAGE_LEFT)!!) - mPageLeft.reset() - if (mRenderLeftPage) { - mRenderer.addCurlMesh(mPageLeft) - } - } - - // If there is something to show on right page add it to renderer. - if (mCurrentIndex < mPageProvider!!.pageCount) { - mPageRight.setFlipTexture(false) - mPageRight.setRect( - mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT)!! - ) - mPageRight.reset() - mRenderer.addCurlMesh(mPageRight) - } - - // How dragging previous page happens depends on view mode. - if (mViewMode == SHOW_ONE_PAGE || mCurlState == CURL_LEFT && mViewMode == SHOW_TWO_PAGES) { - mPageCurl.setRect( - mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT)!! - ) - mPageCurl.setFlipTexture(false) - } else { - mPageCurl.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_LEFT)!!) - mPageCurl.setFlipTexture(true) - } - mPageCurl.reset() - mRenderer.addCurlMesh(mPageCurl) - - mCurlState = CURL_LEFT - } - } - } - - /** - * Updates curl position. - */ - private fun updateCurlPos(pointerPos: PointerPosition) { - - // Default curl radius. - var radius = (mRenderer.getPageRect(CURL_RIGHT)!!.width() / 3).toDouble() - // TODO: This is not an optimal solution. Based on feedback received so - // far; pressure is not very accurate, it may be better not to map - // coefficient to range [0f, 1f] but something like [.2f, 1f] instead. - // Leaving it as is until get my hands on a real device. On emulator - // this doesn't work anyway. - radius *= max(1f - pointerPos.mPressure, 0f).toDouble() - // NOTE: Here we set pointerPos to mCurlPos. It might be a bit confusing - // later to see e.g "mCurlPos.x - mDragStartPos.x" used. But it's - // actually pointerPos we are doing calculations against. Why? Simply to - // optimize code a bit with the cost of making it unreadable. Otherwise - // we had to this in both of the next if-else branches. - mCurlPos.set(pointerPos.mPos) - - // If curl happens on right page, or on left page on two page mode, - // we'll calculate curl position from pointerPos. - if (mCurlState == CURL_RIGHT || mCurlState == CURL_LEFT && mViewMode == SHOW_TWO_PAGES) { - - mCurlDir.x = mCurlPos.x - mDragStartPos.x - mCurlDir.y = mCurlPos.y - mDragStartPos.y - val dist = - sqrt((mCurlDir.x * mCurlDir.x + mCurlDir.y * mCurlDir.y).toDouble()).toFloat() - - // Adjust curl radius so that if page is dragged far enough on - // opposite side, radius gets closer to zero. - val pageWidth = mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT)!! - .width() - var curlLen = radius * Math.PI - if (dist > pageWidth * 2 - curlLen) { - curlLen = max(pageWidth * 2 - dist, 0f).toDouble() - radius = curlLen / Math.PI - } - - // Actual curl position calculation. - if (dist >= curlLen) { - val translate = (dist - curlLen) / 2 - if (mViewMode == SHOW_TWO_PAGES) { - mCurlPos.x -= (mCurlDir.x * translate / dist).toFloat() - } else { - val pageLeftX = mRenderer - .getPageRect(CurlRenderer.PAGE_RIGHT)!!.left - radius = max( - min((mCurlPos.x - pageLeftX).toDouble(), radius), - 0.0 - ) - } - mCurlPos.y -= (mCurlDir.y * translate / dist).toFloat() - } else { - val angle = Math.PI * sqrt(dist / curlLen) - val translate = radius * sin(angle) - mCurlPos.x += (mCurlDir.x * translate / dist).toFloat() - mCurlPos.y += (mCurlDir.y * translate / dist).toFloat() - } - } else if (mCurlState == CURL_LEFT) { - - // Adjust radius regarding how close to page edge we are. - val pageLeftX = mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT)!!.left - radius = max(min((mCurlPos.x - pageLeftX).toDouble(), radius), 0.0) - - val pageRightX = mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT)!!.right - mCurlPos.x -= min((pageRightX - mCurlPos.x).toDouble(), radius).toFloat() - mCurlDir.x = mCurlPos.x + mDragStartPos.x - mCurlDir.y = mCurlPos.y - mDragStartPos.y - }// Otherwise we'll let curl follow pointer position. - - setCurlPos(mCurlPos, mCurlDir, radius) - } - - /** - * Updates given CurlPage via PageProvider for page located at index. - */ - private fun updatePage(page: CurlPage, index: Int) { - // First reset page to initial state. - page.reset() - // Ask page provider to fill it up with bitmaps and colors. - mPageProvider!!.updatePage( - page, mPageBitmapWidth, mPageBitmapHeight, - index - ) - } - - /** - * Updates bitmaps for page meshes. - */ - fun updatePages() { - if (mPageProvider == null || mPageBitmapWidth <= 0 - || mPageBitmapHeight <= 0 - ) { - return - } - - // Remove meshes from renderer. - mRenderer.removeCurlMesh(mPageLeft) - mRenderer.removeCurlMesh(mPageRight) - mRenderer.removeCurlMesh(mPageCurl) - - var leftIdx = mCurrentIndex - 1 - var rightIdx = mCurrentIndex - var curlIdx = -1 - if (mCurlState == CURL_LEFT) { - curlIdx = leftIdx - --leftIdx - } else if (mCurlState == CURL_RIGHT) { - curlIdx = rightIdx - ++rightIdx - } - - if (rightIdx >= 0 && rightIdx < mPageProvider!!.pageCount) { - updatePage(mPageRight.texturePage, rightIdx) - mPageRight.setFlipTexture(false) - mPageRight.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT)!!) - mPageRight.reset() - mRenderer.addCurlMesh(mPageRight) - } - if (leftIdx >= 0 && leftIdx < mPageProvider!!.pageCount) { - updatePage(mPageLeft.texturePage, leftIdx) - mPageLeft.setFlipTexture(true) - mPageLeft.setRect(mRenderer.getPageRect(CurlRenderer.PAGE_LEFT)!!) - mPageLeft.reset() - if (mRenderLeftPage) { - mRenderer.addCurlMesh(mPageLeft) - } - } - if (curlIdx >= 0 && curlIdx < mPageProvider!!.pageCount) { - updatePage(mPageCurl.texturePage, curlIdx) - - if (mCurlState == CURL_RIGHT) { - mPageCurl.setFlipTexture(true) - mPageCurl.setRect( - mRenderer.getPageRect(CurlRenderer.PAGE_RIGHT)!! - ) - } else { - mPageCurl.setFlipTexture(false) - mPageCurl - .setRect(mRenderer.getPageRect(CurlRenderer.PAGE_LEFT)!!) - } - - mPageCurl.reset() - mRenderer.addCurlMesh(mPageCurl) - } - } - - /** - * Provider for feeding 'book' with bitmaps which are used for rendering - * pages. - */ - interface PageProvider { - - /** - * Return number of pages available. - */ - val pageCount: Int - - /** - * Called once new bitmaps/textures are needed. Width and height are in - * pixels telling the size it will be drawn on screen and following them - * ensures that aspect ratio remains. But it's possible to return bitmap - * of any size though. You should use provided CurlPage for storing page - * information for requested page number.

- *

- * Index is a number between 0 and getBitmapCount() - 1. - */ - fun updatePage(page: CurlPage, width: Int, height: Int, index: Int) - } - - /** - * Simple holder for pointer position. - */ - private inner class PointerPosition { - internal var mPos = PointF() - internal var mPressure: Float = 0.toFloat() - } - - /** - * Observer interface for handling CurlView size changes. - */ - interface SizeChangedObserver { - - /** - * Called once CurlView size changes. - */ - fun onSizeChanged(width: Int, height: Int) - } - - interface CallBack { - fun pageChange(change: Int) - } - - companion object { - - // Curl state. We are flipping none, left or right page. - private const val CURL_LEFT = 1 - private const val CURL_NONE = 0 - private const val CURL_RIGHT = 2 - - // Constants for mAnimationTargetEvent. - private const val SET_CURL_TO_LEFT = 1 - private const val SET_CURL_TO_RIGHT = 2 - - // Shows one page at the center of view. - const val SHOW_ONE_PAGE = 1 - // Shows two pages side by side. - const val SHOW_TWO_PAGES = 2 - } - -} 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 c9e0ca546..3f78253b6 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 @@ -69,7 +69,7 @@ abstract class PageDelegate(protected val pageView: PageView) { var isRunning = false var isStarted = false - protected fun setStartPoint(x: Float, y: Float, invalidate: Boolean = true) { + open fun setStartPoint(x: Float, y: Float, invalidate: Boolean = true) { startX = x startY = y @@ -78,7 +78,7 @@ abstract class PageDelegate(protected val pageView: PageView) { } } - protected fun setTouchPoint(x: Float, y: Float, invalidate: Boolean = true) { + open fun setTouchPoint(x: Float, y: Float, invalidate: Boolean = true) { touchX = x touchY = y diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/delegate/SimulationPageDelegate.kt b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/SimulationPageDelegate.kt index eb58e616c..0f2c62475 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/delegate/SimulationPageDelegate.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/SimulationPageDelegate.kt @@ -1,126 +1,526 @@ package io.legado.app.ui.book.read.page.delegate -import android.graphics.Canvas -import android.view.MotionEvent +import android.graphics.* +import android.graphics.drawable.GradientDrawable +import android.os.Build import io.legado.app.ui.book.read.page.PageView -import io.legado.app.ui.book.read.page.curl.CurlPage -import io.legado.app.ui.book.read.page.curl.CurlView -import io.legado.app.utils.screenshot -import kotlin.math.abs +import kotlin.math.* -class SimulationPageDelegate(pageView: PageView) : HorizontalPageDelegate(pageView), - CurlView.CallBack { +class SimulationPageDelegate(pageView: PageView) : HorizontalPageDelegate(pageView) { - var curlView: CurlView? = null + private var mCornerX = 1 // 拖拽点对应的页脚 + + private var mCornerY = 1 + private val mPath0: Path = Path() + private val mPath1: Path = Path() + // 贝塞尔曲线起始点 + private val mBezierStart1 = PointF() + // 贝塞尔曲线控制点 + private val mBezierControl1 = PointF() + // 贝塞尔曲线顶点 + private val mBezierVertex1 = PointF() + // 贝塞尔曲线结束点 + private var mBezierEnd1 = PointF() + + // 另一条贝塞尔曲线 + private val mBezierStart2 = PointF() + + private val mBezierControl2 = PointF() + private val mBezierVertex2 = PointF() + private var mBezierEnd2 = PointF() + + private var mMiddleX = 0f + private var mMiddleY = 0f + private var mDegrees = 0f + private var mTouchToCornerDis = 0f + private var mColorMatrixFilter: ColorMatrixColorFilter? = null + private val mMatrix: Matrix = Matrix() + private val mMatrixArray = floatArrayOf(0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 1.0f) + + // 是否属于右上左下 + private var mIsRT_LB = false + private var mMaxLength = 0f + // 背面颜色组 + private var mBackShadowColors: IntArray? = null + // 前面颜色组 + private var mFrontShadowColors: IntArray? = null + // 有阴影的GradientDrawable + private var mBackShadowDrawableLR: GradientDrawable? = null + private var mBackShadowDrawableRL: GradientDrawable? = null + private var mFolderShadowDrawableLR: GradientDrawable? = null + private var mFolderShadowDrawableRL: GradientDrawable? = null + + private var mFrontShadowDrawableHBT: GradientDrawable? = null + private var mFrontShadowDrawableHTB: GradientDrawable? = null + private var mFrontShadowDrawableVLR: GradientDrawable? = null + private var mFrontShadowDrawableVRL: GradientDrawable? = null + + private val mPaint: Paint = Paint() init { - pageView.curlView ?: let { - curlView = CurlView(pageView.context) - pageView.curlView = curlView - pageView.addView(curlView) - curlView?.mPageProvider = PageProvider() - curlView?.setSizeChangedObserver(SizeChangedObserver()) - curlView?.callBack = this - } + mMaxLength = hypot(pageView.width.toDouble(), pageView.height.toDouble()).toFloat() + mPaint.style = Paint.Style.FILL + //设置颜色数组 + createDrawable() + val cm = ColorMatrix() + val array = floatArrayOf( + 1f, 0f, 0f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, + 0f, 0f, 1f, 0f, 0f, 0f, 0f, 0f, 1f, 0f + ) + cm.set(array) + mColorMatrixFilter = ColorMatrixColorFilter(cm) } - override fun onTouch(event: MotionEvent): Boolean { - when (event.action) { - MotionEvent.ACTION_DOWN -> { - curlView?.currentIndex = 1 - } + override fun setStartPoint(x: Float, y: Float, invalidate: Boolean) { + super.setStartPoint(x, y, invalidate) + calcCornerXY(x, y) + } + + override fun setTouchPoint(x: Float, y: Float, invalidate: Boolean) { + super.setTouchPoint(x, y, invalidate) + //触摸y中间位置吧y变成屏幕高度 + //触摸y中间位置吧y变成屏幕高度 + if (startY > pageView.height / 3.0 + && startY < pageView.height * 2 / 3.0 + || direction == Direction.PREV + ) { + touchY = pageView.height.toFloat() + } + + if (startY > pageView.height / 3.0 + && startY < pageView.height / 2.0 + && direction == Direction.NEXT + ) { + touchY = 1f } - curlView?.dispatchTouchEvent(event) - return super.onTouch(event) } override fun onScrollStart() { - } + val distanceX: Float + when (direction) { + Direction.NEXT -> distanceX = + if (isCancel) { + var dis = viewWidth - startX + touchX + if (dis > viewWidth) { + dis = viewWidth.toFloat() + } + viewWidth - dis + } else { + -(touchX + (viewWidth - startX)) + } + else -> distanceX = + if (isCancel) { + -(touchX - startX) + } else { + viewWidth - (touchX - startX) + } + } - override fun onDraw(canvas: Canvas) { + startScroll(touchX.toInt(), 0, distanceX.toInt(), 0) } override fun onScrollStop() { + curPage?.x = 0.toFloat() + if (!isCancel) { + pageView.fillPage(direction) + } } - override fun onScroll( - e1: MotionEvent, - e2: MotionEvent, - distanceX: Float, - distanceY: Float - ): Boolean { - if (!isMoved) { - val event = e1.toAction(MotionEvent.ACTION_UP) - curPage?.dispatchTouchEvent(event) - event.recycle() - if (abs(distanceX) > abs(distanceY)) { - if (distanceX < 0) { - //如果上一页不存在 - if (!hasPrev()) { - noNext = true - return true - } - //上一页截图 - bitmap = prevPage?.screenshot() - } else { - //如果不存在表示没有下一页了 - if (!hasNext()) { - noNext = true - return true - } - //下一页截图 - bitmap = nextPage?.screenshot() - } - isMoved = true + override fun onDraw(canvas: Canvas) { + bitmap?.let { + if (direction === Direction.NEXT) { + calcPoints() + drawCurrentPageArea(canvas, it, mPath0!!) //绘制翻页时的正面页 +// drawNextPageAreaAndShadow(canvas, it) + drawCurrentPageShadow(canvas) + drawCurrentBackArea(canvas, it) + } else { + calcPoints() + drawCurrentPageArea(canvas, it, mPath0!!) +// drawNextPageAreaAndShadow(canvas, it) + drawCurrentPageShadow(canvas) + drawCurrentBackArea(canvas, it) } } - if (isMoved) { - curlView?.canDraw = true - isCancel = if (pageView.isScrollDelegate) { - if (direction == Direction.NEXT) distanceY < 0 else distanceY > 0 + } + + /** + * 创建阴影的GradientDrawable + */ + private fun createDrawable() { + val color = intArrayOf(0x333333, -0x4fcccccd) + mFolderShadowDrawableRL = GradientDrawable( + GradientDrawable.Orientation.RIGHT_LEFT, color + ).apply { gradientType = GradientDrawable.LINEAR_GRADIENT } + mFolderShadowDrawableLR = GradientDrawable( + GradientDrawable.Orientation.LEFT_RIGHT, color + ).apply { gradientType = GradientDrawable.LINEAR_GRADIENT } + mBackShadowColors = intArrayOf(-0xeeeeef, 0x111111) + mBackShadowDrawableRL = GradientDrawable( + GradientDrawable.Orientation.RIGHT_LEFT, mBackShadowColors + ).apply { gradientType = GradientDrawable.LINEAR_GRADIENT } + mBackShadowDrawableLR = GradientDrawable( + GradientDrawable.Orientation.LEFT_RIGHT, mBackShadowColors + ).apply { gradientType = GradientDrawable.LINEAR_GRADIENT } + mFrontShadowColors = intArrayOf(-0x7feeeeef, 0x111111) + mFrontShadowDrawableVLR = GradientDrawable( + GradientDrawable.Orientation.LEFT_RIGHT, mFrontShadowColors + ).apply { gradientType = GradientDrawable.LINEAR_GRADIENT } + mFrontShadowDrawableVRL = GradientDrawable( + GradientDrawable.Orientation.RIGHT_LEFT, mFrontShadowColors + ).apply { gradientType = GradientDrawable.LINEAR_GRADIENT } + mFrontShadowDrawableHTB = GradientDrawable( + GradientDrawable.Orientation.TOP_BOTTOM, mFrontShadowColors + ).apply { gradientType = GradientDrawable.LINEAR_GRADIENT } + mFrontShadowDrawableHBT = GradientDrawable( + GradientDrawable.Orientation.BOTTOM_TOP, mFrontShadowColors + ).apply { gradientType = GradientDrawable.LINEAR_GRADIENT } + } + + /** + * 绘制翻起页背面 + */ + private fun drawCurrentBackArea( + canvas: Canvas, + bitmap: Bitmap + ) { + val i = (mBezierStart1.x + mBezierControl1.x).toInt() / 2 + val f1 = abs(i - mBezierControl1.x) + val i1 = (mBezierStart2.y + mBezierControl2.y).toInt() / 2 + val f2 = abs(i1 - mBezierControl2.y) + val f3 = min(f1, f2) + mPath1.reset() + mPath1.moveTo(mBezierVertex2.x, mBezierVertex2.y) + mPath1.lineTo(mBezierVertex1.x, mBezierVertex1.y) + mPath1.lineTo(mBezierEnd1.x, mBezierEnd1.y) + mPath1.lineTo(touchX, touchY) + mPath1.lineTo(mBezierEnd2.x, mBezierEnd2.y) + mPath1.close() + val mFolderShadowDrawable: GradientDrawable + val left: Int + val right: Int + if (mIsRT_LB) { + left = (mBezierStart1.x - 1).toInt() + right = (mBezierStart1.x + f3 + 1).toInt() + mFolderShadowDrawable = mFolderShadowDrawableLR!! + } else { + left = (mBezierStart1.x - f3 - 1).toInt() + right = (mBezierStart1.x + 1).toInt() + mFolderShadowDrawable = mFolderShadowDrawableRL!! + } + canvas.save() + try { + canvas.clipPath(mPath0) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + canvas.clipPath(mPath1) } else { - if (direction == Direction.NEXT) distanceX < 0 else distanceX > 0 + canvas.clipPath(mPath1, Region.Op.INTERSECT) } - isRunning = true - //设置触摸点 - setTouchPoint(e2.x, e2.y) + } catch (ignored: Exception) { } - return isMoved + mPaint!!.colorFilter = mColorMatrixFilter + val dis = hypot( + mCornerX - mBezierControl1.x.toDouble(), + mBezierControl2.y - mCornerY.toDouble() + ).toFloat() + val f8 = (mCornerX - mBezierControl1.x) / dis + val f9 = (mBezierControl2.y - mCornerY) / dis + mMatrixArray[0] = 1 - 2 * f9 * f9 + mMatrixArray[1] = 2 * f8 * f9 + mMatrixArray[3] = mMatrixArray[1] + mMatrixArray[4] = 1 - 2 * f8 * f8 + mMatrix.reset() + mMatrix.setValues(mMatrixArray) + mMatrix.preTranslate(-mBezierControl1.x, -mBezierControl1.y) + mMatrix.postTranslate(mBezierControl1.x, mBezierControl1.y) + canvas.drawBitmap(bitmap, mMatrix, mPaint) + mPaint.colorFilter = null + canvas.rotate(mDegrees, mBezierStart1.x, mBezierStart1.y) + mFolderShadowDrawable.setBounds( + left, mBezierStart1.y.toInt(), right, + (mBezierStart1.y + mMaxLength).toInt() + ) + mFolderShadowDrawable.draw(canvas) + canvas.restore() } - override fun onPageUp() { - curlView?.updatePages() - curlView?.requestRender() + /** + * 绘制翻起页的阴影 + */ + private fun drawCurrentPageShadow(canvas: Canvas) { + val degree: Double = if (mIsRT_LB) { + (Math.PI / 4 - atan2(mBezierControl1.y - touchX, touchY - mBezierControl1.x)) + } else { + (Math.PI / 4 - atan2(touchY - mBezierControl1.y, touchX - mBezierControl1.x)) + } + // 翻起页阴影顶点与touch点的距离 + val d1 = 25.toFloat() * 1.414 * cos(degree) + val d2 = 25.toFloat() * 1.414 * sin(degree) + val x = (touchX + d1).toFloat() + val y: Float + y = if (mIsRT_LB) { + (touchY + d2).toFloat() + } else { + (touchY - d2).toFloat() + } + mPath1.reset() + mPath1.moveTo(x, y) + mPath1.lineTo(touchX, touchY) + mPath1.lineTo(mBezierControl1.x, mBezierControl1.y) + mPath1.lineTo(mBezierStart1.x, mBezierStart1.y) + mPath1.close() + canvas.save() + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + canvas.clipOutPath(mPath0) + } else { + canvas.clipPath(mPath0, Region.Op.XOR) + } + canvas.clipPath(mPath1, Region.Op.INTERSECT) + } catch (ignored: java.lang.Exception) { + } + var leftX: Int + var rightX: Int + var mCurrentPageShadow: GradientDrawable + if (mIsRT_LB) { + leftX = mBezierControl1.x.toInt() + rightX = mBezierControl1.x.toInt() + 25 + mCurrentPageShadow = mFrontShadowDrawableVLR!! + } else { + leftX = (mBezierControl1.x - 25).toInt() + rightX = mBezierControl1.x.toInt() + 1 + mCurrentPageShadow = mFrontShadowDrawableVRL!! + } + var rotateDegrees: Float = + Math.toDegrees(atan2(touchX - mBezierControl1.x, mBezierControl1.y - touchY).toDouble()) + .toFloat() + canvas.rotate(rotateDegrees, mBezierControl1.x, mBezierControl1.y) + mCurrentPageShadow.setBounds( + leftX, + (mBezierControl1.y - mMaxLength).toInt(), rightX, + mBezierControl1.y.toInt() + ) + mCurrentPageShadow.draw(canvas) + canvas.restore() + mPath1.reset() + mPath1.moveTo(x, y) + mPath1.lineTo(touchX, touchY) + mPath1.lineTo(mBezierControl2.x, mBezierControl2.y) + mPath1.lineTo(mBezierStart2.x, mBezierStart2.y) + mPath1.close() + canvas.save() + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + canvas.clipOutPath(mPath0) + } else { + canvas.clipPath(mPath0, Region.Op.XOR) + } + canvas.clipPath(mPath1) + } catch (ignored: java.lang.Exception) { + } + if (mIsRT_LB) { + leftX = mBezierControl2.y.toInt() + rightX = (mBezierControl2.y + 25).toInt() + mCurrentPageShadow = mFrontShadowDrawableHTB!! + } else { + leftX = (mBezierControl2.y - 25).toInt() + rightX = (mBezierControl2.y + 1).toInt() + mCurrentPageShadow = mFrontShadowDrawableHBT!! + } + rotateDegrees = Math.toDegrees( + atan2(mBezierControl2.y - touchY, mBezierControl2.x - touchX).toDouble() + ).toFloat() + canvas.rotate(rotateDegrees, mBezierControl2.x, mBezierControl2.y) + val temp: Float = + if (mBezierControl2.y < 0) mBezierControl2.y - pageView.height else mBezierControl2.y + val hmg = hypot(mBezierControl2.x.toDouble(), temp.toDouble()).toInt() + if (hmg > mMaxLength) mCurrentPageShadow + .setBounds( + (mBezierControl2.x - 25).toInt() - hmg, leftX, + (mBezierControl2.x + mMaxLength).toInt() - hmg, + rightX + ) else mCurrentPageShadow.setBounds( + (mBezierControl2.x - mMaxLength).toInt(), leftX, + mBezierControl2.x.toInt(), rightX + ) + mCurrentPageShadow.draw(canvas) + canvas.restore() } - override fun pageChange(change: Int) { - pageView.post { - if (change > 0) { - pageView.moveToNextPage() + private fun drawNextPageAreaAndShadow( + canvas: Canvas, + bitmap: Bitmap + ) { + mPath1.reset() + mPath1.moveTo(mBezierStart1.x, mBezierStart1.y) + mPath1.lineTo(mBezierVertex1.x, mBezierVertex1.y) + mPath1.lineTo(mBezierVertex2.x, mBezierVertex2.y) + mPath1.lineTo(mBezierStart2.x, mBezierStart2.y) + mPath1.lineTo(mCornerX.toFloat(), mCornerY.toFloat()) + mPath1.close() + mDegrees = Math.toDegrees( + atan2( + (mBezierControl1.x - mCornerX).toDouble(), + mBezierControl2.y - mCornerY.toDouble() + ) + ).toFloat() + val leftX: Int + val rightY: Int + val mBackShadowDrawable: GradientDrawable + if (mIsRT_LB) { //左下及右上 + leftX = mBezierStart1.x.toInt() + rightY = (mBezierStart1.x + mTouchToCornerDis / 4).toInt() + mBackShadowDrawable = mBackShadowDrawableLR!! + } else { + leftX = (mBezierStart1.x - mTouchToCornerDis / 4).toInt() + rightY = mBezierStart1.x.toInt() + mBackShadowDrawable = mBackShadowDrawableRL!! + } + canvas.save() + try { + canvas.clipPath(mPath0) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + canvas.clipPath(mPath1) } else { - pageView.moveToPrevPage() + canvas.clipPath(mPath1, Region.Op.INTERSECT) } + //canvas.clipPath(mPath1, Region.Op.INTERSECT); + } catch (ignored: java.lang.Exception) { } + canvas.drawBitmap(bitmap, 0f, 0f, null) + canvas.rotate(mDegrees, mBezierStart1.x, mBezierStart1.y) + mBackShadowDrawable.setBounds( + leftX, mBezierStart1.y.toInt(), rightY, + (mMaxLength + mBezierStart1.y).toInt() + ) //左上及右下角的xy坐标值,构成一个矩形 + mBackShadowDrawable.draw(canvas) + canvas.restore() } - private inner class PageProvider : CurlView.PageProvider { + private fun drawCurrentPageArea( + canvas: Canvas, + bitmap: Bitmap, + path: Path + ) { + mPath0.reset() + mPath0.moveTo(mBezierStart1.x, mBezierStart1.y) + mPath0.quadTo( + mBezierControl1.x, mBezierControl1.y, mBezierEnd1.x, + mBezierEnd1.y + ) + mPath0.lineTo(touchX, touchY) + mPath0.lineTo(mBezierEnd2.x, mBezierEnd2.y) + mPath0.quadTo( + mBezierControl2.x, mBezierControl2.y, mBezierStart2.x, + mBezierStart2.y + ) + mPath0.lineTo(mCornerX.toFloat(), mCornerY.toFloat()) + mPath0.close() + canvas.save() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + canvas.clipOutPath(path) + } else { + canvas.clipPath(path, Region.Op.XOR) + } + canvas.drawBitmap(bitmap, 0f, 0f, null) + try { + canvas.restore() + } catch (e: java.lang.Exception) { + e.printStackTrace() + } + } - override val pageCount: Int - get() = 3 + /** + * 计算拖拽点对应的拖拽脚 + */ + private fun calcCornerXY(x: Float, y: Float) { + if (x <= pageView.width / 2.0) { + mCornerX = 0 + } else { + mCornerX = pageView.width + } + if (y <= pageView.height / 2.0) { + mCornerY = 0 + } else { + mCornerY = pageView.height + } + mIsRT_LB = (mCornerX == 0 && mCornerY == pageView.height + || mCornerX == pageView.width && mCornerY == 0) + } - override fun updatePage(page: CurlPage, width: Int, height: Int, index: Int) { - when (index) { - 0 -> page.setTexture(prevPage?.screenshot(), CurlPage.SIDE_BOTH) - 1 -> page.setTexture(curPage?.screenshot(), CurlPage.SIDE_BOTH) - 2 -> page.setTexture(nextPage?.screenshot(), CurlPage.SIDE_BOTH) + private fun calcPoints() { + mMiddleX = (touchX + mCornerX) / 2 + mMiddleY = (touchY + mCornerY) / 2 + mBezierControl1.x = + mMiddleX - (mCornerY - mMiddleY) * (mCornerY - mMiddleY) / (mCornerX - mMiddleX) + mBezierControl1.y = mCornerY.toFloat() + mBezierControl2.x = mCornerX.toFloat() + val f4 = mCornerY - mMiddleY + if (f4 == 0f) { + mBezierControl2.y = mMiddleY - (mCornerX - mMiddleX) * (mCornerX - mMiddleX) / 0.1f + } else { + mBezierControl2.y = + mMiddleY - (mCornerX - mMiddleX) * (mCornerX - mMiddleX) / (mCornerY - mMiddleY) + } + mBezierStart1.x = mBezierControl1.x - (mCornerX - mBezierControl1.x) / 2 + mBezierStart1.y = mCornerY.toFloat() + // 当mBezierStart1.x < 0或者mBezierStart1.x > 480时 + // 如果继续翻页,会出现BUG故在此限制 + if (touchX > 0 && touchX < pageView.width) { + if (mBezierStart1.x < 0 || mBezierStart1.x > pageView.width) { + if (mBezierStart1.x < 0) mBezierStart1.x = pageView.width - mBezierStart1.x + val f1: Float = abs(mCornerX - touchX) + val f2: Float = pageView.width * f1 / mBezierStart1.x + touchX = abs(mCornerX - f2) + val f3: Float = abs(mCornerX - touchX) * abs(mCornerY - touchX) / f1 + touchX = abs(mCornerY - f3) + mMiddleX = (touchX + mCornerX) / 2 + mMiddleY = (touchY + mCornerY) / 2 + mBezierControl1.x = + mMiddleX - (mCornerY - mMiddleY) * (mCornerY - mMiddleY) / (mCornerX - mMiddleX) + mBezierControl1.y = mCornerY.toFloat() + mBezierControl2.x = mCornerX.toFloat() + val f5 = mCornerY - mMiddleY + if (f5 == 0f) { + mBezierControl2.y = + mMiddleY - (mCornerX - mMiddleX) * (mCornerX - mMiddleX) / 0.1f + } else { + mBezierControl2.y = + mMiddleY - (mCornerX - mMiddleX) * (mCornerX - mMiddleX) / (mCornerY - mMiddleY) + } + mBezierStart1.x = (mBezierControl1.x + - (mCornerX - mBezierControl1.x) / 2) } } + mBezierStart2.x = mCornerX.toFloat() + mBezierStart2.y = mBezierControl2.y - (mCornerY - mBezierControl2.y) / 2 + mTouchToCornerDis = hypot(touchX - mCornerX, touchY - mCornerY) + mBezierEnd1 = getCross( + PointF(touchX, touchY), mBezierControl1, mBezierStart1, + mBezierStart2 + ) + mBezierEnd2 = getCross( + PointF(touchX, touchY), mBezierControl2, mBezierStart1, + mBezierStart2 + ) + mBezierVertex1.x = (mBezierStart1.x + 2 * mBezierControl1.x + mBezierEnd1.x) / 4 + mBezierVertex1.y = (2 * mBezierControl1.y + mBezierStart1.y + mBezierEnd1.y) / 4 + mBezierVertex2.x = (mBezierStart2.x + 2 * mBezierControl2.x + mBezierEnd2.x) / 4 + mBezierVertex2.y = (2 * mBezierControl2.y + mBezierStart2.y + mBezierEnd2.y) / 4 } - // 定义书籍尺寸的变化监听器 - private inner class SizeChangedObserver : CurlView.SizeChangedObserver { - override fun onSizeChanged(width: Int, height: Int) { - curlView?.setViewMode(CurlView.SHOW_ONE_PAGE) - } + /** + * 求解直线P1P2和直线P3P4的交点坐标 + */ + private fun getCross(P1: PointF, P2: PointF, P3: PointF, P4: PointF): PointF { + val crossP = PointF() + // 二元函数通式: y=ax+b + val a1 = (P2.y - P1.y) / (P2.x - P1.x) + val b1 = (P1.x * P2.y - P2.x * P1.y) / (P1.x - P2.x) + val a2 = (P4.y - P3.y) / (P4.x - P3.x) + val b2 = (P3.x * P4.y - P4.x * P3.y) / (P3.x - P4.x) + crossP.x = (b2 - b1) / (a1 - a2) + crossP.y = a1 * crossP.x + b1 + return crossP } } \ No newline at end of file