From 30175b3e4a78bef8422f3c2783ac496f5d092b9f Mon Sep 17 00:00:00 2001 From: LagradOst <11805592+LagradOst@users.noreply.github.com> Date: Thu, 10 Aug 2023 17:18:31 +0200 Subject: [PATCH] readded monocolor + added button scroll --- .../com/lagradost/quicknovel/DataStore.kt | 1 + .../com/lagradost/quicknovel/ReadActivity2.kt | 28 +++++- .../quicknovel/ReadActivityViewModel.kt | 95 ++++++++++++++----- .../com/lagradost/quicknovel/TTSHelper.kt | 11 +++ .../lagradost/quicknovel/ui/TextAdapter.kt | 47 ++++++++- .../main/res/drawable/ic_icon_monochrome.xml | 40 +++++--- .../main/res/layout/read_bottom_settings.xml | 15 +++ app/src/main/res/layout/single_load.xml | 19 ++++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 1 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 1 + app/src/main/res/values/strings.xml | 6 ++ 11 files changed, 223 insertions(+), 41 deletions(-) create mode 100644 app/src/main/res/layout/single_load.xml diff --git a/app/src/main/java/com/lagradost/quicknovel/DataStore.kt b/app/src/main/java/com/lagradost/quicknovel/DataStore.kt index bada0a9b..c8dcf0d5 100644 --- a/app/src/main/java/com/lagradost/quicknovel/DataStore.kt +++ b/app/src/main/java/com/lagradost/quicknovel/DataStore.kt @@ -33,6 +33,7 @@ const val EPUB_TWELVE_HOUR_TIME: String = "reader_epub_twelve_hour_time" const val EPUB_FONT: String = "reader_epub_font" const val EPUB_LANG: String = "reader_epub_lang" const val EPUB_VOICE: String = "reader_epub_voice" +const val EPUB_READER_TYPE: String = "reader_reader_type" const val EPUB_CURRENT_POSITION: String = "reader_epub_position" const val EPUB_CURRENT_POSITION_SCROLL: String = "reader_epub_position_scroll" const val EPUB_CURRENT_POSITION_SCROLL_CHAR: String = "reader_epub_position_scroll_char" diff --git a/app/src/main/java/com/lagradost/quicknovel/ReadActivity2.kt b/app/src/main/java/com/lagradost/quicknovel/ReadActivity2.kt index b6598eb3..36d371c4 100644 --- a/app/src/main/java/com/lagradost/quicknovel/ReadActivity2.kt +++ b/app/src/main/java/com/lagradost/quicknovel/ReadActivity2.kt @@ -53,6 +53,7 @@ import com.lagradost.quicknovel.ui.CONFIG_COLOR import com.lagradost.quicknovel.ui.CONFIG_FONT import com.lagradost.quicknovel.ui.CONFIG_FONT_BOLD import com.lagradost.quicknovel.ui.OrientationType +import com.lagradost.quicknovel.ui.ReadingType import com.lagradost.quicknovel.ui.ScrollIndex import com.lagradost.quicknovel.ui.ScrollVisibilityIndex import com.lagradost.quicknovel.ui.ScrollVisibilityItem @@ -656,7 +657,8 @@ class ReadActivity2 : AppCompatActivity(), ColorPickerDialogListener { defaultFont = binding.readText.typeface, textColor = viewModel.textColor, textSize = viewModel.textSize, - textFont = viewModel.textFont + textFont = viewModel.textFont, + backgroundColor = viewModel.backgroundColor ).also { config -> updateOtherTextConfig(config) } @@ -683,6 +685,9 @@ class ReadActivity2 : AppCompatActivity(), ColorPickerDialogListener { observe(viewModel.backgroundColorLive) { color -> binding.root.setBackgroundColor(color) binding.readOverlay.setBackgroundColor(color) + if (textAdapter.changeBackgroundColor(color)) { + updateTextAdapterConfig() + } } observe(viewModel.showBatteryLive) { show -> @@ -930,6 +935,27 @@ class ReadActivity2 : AppCompatActivity(), ColorPickerDialogListener { val fontSizeProgressOffset = 10 + binding.readReadingType.setText(viewModel.readerType.stringRes) + binding.readReadingType.setOnLongClickListener { + it.popupMenu(items = listOf(Pair(1, R.string.reset_value)), selectedItemId = null) { + if (itemId == 1) { + binding.readReadingType.setText(ReadingType.DEFAULT.stringRes) + viewModel.readerType = ReadingType.DEFAULT + } + } + return@setOnLongClickListener true + } + binding.readReadingType.setOnClickListener { + it.popupMenu( + items = ReadingType.values().map { v -> v.prefValue to v.stringRes }, + selectedItemId = viewModel.readerType.prefValue + ) { + val set = ReadingType.fromSpinner(itemId) + binding.readReadingType.setText(set.stringRes) + viewModel.readerType = set + } + } + binding.readSettingsTextSizeText.setOnClickListener { it.popupMenu(items = listOf(Pair(1, R.string.reset_value)), selectedItemId = null) { if (itemId == 1) { diff --git a/app/src/main/java/com/lagradost/quicknovel/ReadActivityViewModel.kt b/app/src/main/java/com/lagradost/quicknovel/ReadActivityViewModel.kt index d8002e7f..1eaf2af7 100644 --- a/app/src/main/java/com/lagradost/quicknovel/ReadActivityViewModel.kt +++ b/app/src/main/java/com/lagradost/quicknovel/ReadActivityViewModel.kt @@ -38,6 +38,7 @@ import com.lagradost.quicknovel.mvvm.map import com.lagradost.quicknovel.mvvm.safeApiCall import com.lagradost.quicknovel.providers.RedditProvider import com.lagradost.quicknovel.ui.OrientationType +import com.lagradost.quicknovel.ui.ReadingType import com.lagradost.quicknovel.ui.ScrollIndex import com.lagradost.quicknovel.ui.ScrollVisibilityIndex import com.lagradost.quicknovel.ui.UiText @@ -426,33 +427,69 @@ class ReadActivityViewModel : ViewModel() { } } + private fun chapterIdxToSpanDisplay(index: Int): List { + return when (val data = chapterData[index]) { + null -> emptyList() + is Resource.Loading -> { + listOf(LoadingSpanned(data.url, index)) + } + + is Resource.Success -> { + data.value.spans + } + + is Resource.Failure -> listOf( + FailedSpanned( + reason = data.errorString.toUiText(), + index = index, + canReload = data.isNetworkError + ) + ) + } + } + + private fun chapterIdxToSpanDisplayNext(index: Int, fromIndex : Int) : SpanDisplay? { + return when (val data = chapterData[index]) { + is Resource.Loading -> LoadingSpanned(data.url, index) + is Resource.Failure -> + FailedSpanned( + reason = data.errorString.toUiText(), + index = index, + canReload = data.isNetworkError + ) + else -> chaptersTitlesInternal.getOrNull(index)?.let { text -> ChapterLoadSpanned(fromIndex, 0, index, text) } + } + } + private fun updateReadArea(seekToDesired: Boolean = false) { val cIndex = currentIndex val chapters = ArrayList() - for (idx in cIndex - chapterPaddingBottom..cIndex + chapterPaddingTop) { - val append: List = when (val data = chapterData[idx]) { - null -> emptyList() - is Resource.Loading -> { - listOf(LoadingSpanned(data.url, idx)) + when (readerType) { + ReadingType.DEFAULT, ReadingType.INF_SCROLL -> { + for (idx in cIndex - chapterPaddingBottom..cIndex + chapterPaddingTop) { + if (idx < chaptersTitlesInternal.size && idx >= 0) + chapters.add(ChapterStartSpanned(idx, 0, chaptersTitlesInternal[idx])) + chapters.addAll(chapterIdxToSpanDisplay(idx)) } + } - is Resource.Success -> { - data.value.spans + ReadingType.BTT_SCROLL -> { + chapterIdxToSpanDisplayNext(cIndex - 1, cIndex)?.let { + chapters.add(it) } - is Resource.Failure -> listOf( - FailedSpanned( - reason = data.errorString.toUiText(), - index = idx, - canReload = data.isNetworkError - ) - ) - } + chaptersTitlesInternal.getOrNull(cIndex)?.let { text -> + chapters.add(ChapterStartSpanned(cIndex, 0, text)) + } - if (idx < chaptersTitlesInternal.size && idx >= 0) - chapters.add(ChapterStartSpanned(idx, 0, chaptersTitlesInternal[idx])) - chapters.addAll(append) + chapters.addAll(chapterIdxToSpanDisplay(cIndex)) + + chapterIdxToSpanDisplayNext(cIndex + 1, cIndex)?.let { + chapters.add(it) + } + } } + _chapterData.postValue(ChapterUpdate(data = chapters, seekToDesired = seekToDesired)) } @@ -538,11 +575,11 @@ class ReadActivityViewModel : ViewModel() { book.getChapterData(index, reload) }.map { text -> val rawText = preParseHtml(text) - // val renderedBuilder = SpannableStringBuilder() - // val lengths : IntArray + // val renderedBuilder = SpannableStringBuilder() + // val lengths : IntArray //val nodes : Array - val rendered : Spanned - val parsed : Node + val rendered: Spanned + val parsed: Node markwonMutex.withLock { parsed = markwon.parse(rawText) rendered = markwon.render(parsed) @@ -1058,6 +1095,20 @@ class ReadActivityViewModel : ViewModel() { } + private var readerTypeInternal by PreferenceDelegate( + EPUB_READER_TYPE, + ReadingType.DEFAULT.prefValue, + Int::class + ) + + var readerType + get() = ReadingType.fromSpinner(readerTypeInternal) + set(value) { + readerTypeInternal = value.prefValue + updateReadArea(seekToDesired = true) + } + + var scrollWithVolume by PreferenceDelegate(EPUB_SCROLL_VOL, true, Boolean::class) var ttsLock by PreferenceDelegate(EPUB_TTS_LOCK, true, Boolean::class) val textFontLive: MutableLiveData = MutableLiveData(null) diff --git a/app/src/main/java/com/lagradost/quicknovel/TTSHelper.kt b/app/src/main/java/com/lagradost/quicknovel/TTSHelper.kt index 562e8333..8dc5ca7d 100644 --- a/app/src/main/java/com/lagradost/quicknovel/TTSHelper.kt +++ b/app/src/main/java/com/lagradost/quicknovel/TTSHelper.kt @@ -308,6 +308,17 @@ data class FailedSpanned(val reason: UiText, override val index: Int, val canRel } } +data class ChapterLoadSpanned( + override val index: Int, + override val innerIndex: Int, + val loadIndex : Int, + val name: UiText +) : SpanDisplay() { + override fun id(): Long { + return generateId(4, index, 0, 0) + } +} + object TTSHelper { data class TTSLine( val speakOutMsg: String, diff --git a/app/src/main/java/com/lagradost/quicknovel/ui/TextAdapter.kt b/app/src/main/java/com/lagradost/quicknovel/ui/TextAdapter.kt index 9442ecbe..e5c36426 100644 --- a/app/src/main/java/com/lagradost/quicknovel/ui/TextAdapter.kt +++ b/app/src/main/java/com/lagradost/quicknovel/ui/TextAdapter.kt @@ -15,6 +15,7 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import androidx.viewbinding.ViewBinding +import com.lagradost.quicknovel.ChapterLoadSpanned import com.lagradost.quicknovel.ChapterStartSpanned import com.lagradost.quicknovel.CommonActivity.showToast import com.lagradost.quicknovel.FailedSpanned @@ -27,6 +28,7 @@ import com.lagradost.quicknovel.TextSpan import com.lagradost.quicknovel.databinding.SingleFailedBinding import com.lagradost.quicknovel.databinding.SingleFinishedChapterBinding import com.lagradost.quicknovel.databinding.SingleImageBinding +import com.lagradost.quicknovel.databinding.SingleLoadBinding import com.lagradost.quicknovel.databinding.SingleLoadingBinding import com.lagradost.quicknovel.databinding.SingleTextBinding import com.lagradost.quicknovel.mvvm.logError @@ -41,6 +43,7 @@ const val DRAW_TEXT = 0 const val DRAW_LOADING = 2 const val DRAW_FAILED = 3 const val DRAW_CHAPTER = 4 +const val DRAW_LOAD = 5 data class ScrollVisibilityItem( @@ -154,6 +157,7 @@ const val CONFIG_FONT = 1 shl 1 const val CONFIG_SIZE = 1 shl 2 const val CONFIG_FONT_BOLD = 1 shl 3 const val CONFIG_FONT_ITALIC = 1 shl 4 +const val CONFIG_BG_COLOR = 1 shl 5 // this uses val to make it explicit copy because of lazy properties data class TextConfig( @@ -161,7 +165,8 @@ data class TextConfig( val textColor: Int, val textSize: Int, val textFont: String, - val defaultFont: Typeface + val defaultFont: Typeface, + val backgroundColor : Int, ) { private val fontFile: File? by lazy { if (textFont == "") null else systemFonts.firstOrNull { it.name == textFont } @@ -194,7 +199,9 @@ data class TextConfig( private fun setTextColor(textView: TextView) { textView.setTextColor(textColor) } - + private fun setBgTextColor(textView: TextView) { + textView.setTextColor(backgroundColor) + } fun setArgs(progressBar: ProgressBar) { progressBar.progressTintList = ColorStateList.valueOf(textColor) progressBar.indeterminateTintList = ColorStateList.valueOf(textColor) @@ -204,6 +211,9 @@ data class TextConfig( if ((args and CONFIG_COLOR) != 0) { setTextColor(textView) } + if ((args and CONFIG_BG_COLOR) != 0) { + setBgTextColor(textView) + } if ((args and CONFIG_FONT) != 0) { val bold = (args and CONFIG_FONT_BOLD) != 0 val italic = (args and CONFIG_FONT_ITALIC) != 0 @@ -251,7 +261,11 @@ class TextAdapter(private val viewModel: ReadActivityViewModel, var config: Text config = config.copy(textFont = font) return true } - + fun changeBackgroundColor(color: Int): Boolean { + if (config.backgroundColor == color) return false + config = config.copy(backgroundColor = color) + return true + } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TextAdapterHolder { val inflater = LayoutInflater.from(parent.context) val binding: ViewBinding = when (viewType) { @@ -260,6 +274,7 @@ class TextAdapter(private val viewModel: ReadActivityViewModel, var config: Text DRAW_LOADING -> SingleLoadingBinding.inflate(inflater, parent, false) DRAW_FAILED -> SingleFailedBinding.inflate(inflater, parent, false) DRAW_CHAPTER -> SingleFinishedChapterBinding.inflate(inflater, parent, false) + DRAW_LOAD -> SingleLoadBinding.inflate(inflater, parent, false) else -> throw NotImplementedError() } @@ -432,6 +447,10 @@ class TextAdapter(private val viewModel: ReadActivityViewModel, var config: Text DRAW_CHAPTER } + is ChapterLoadSpanned -> { + DRAW_LOAD + } + else -> throw NotImplementedError() } } @@ -470,6 +489,11 @@ class TextAdapter(private val viewModel: ReadActivityViewModel, var config: Text binding.root.minHeight = config.toolbarHeight } + is SingleLoadBinding -> { + config.setArgs(binding.root, CONFIG_BG_COLOR or CONFIG_FONT or CONFIG_FONT_BOLD) + binding.root.backgroundTintList = ColorStateList.valueOf(config.textColor) + } + else -> {} } } @@ -557,6 +581,14 @@ class TextAdapter(private val viewModel: ReadActivityViewModel, var config: Text } } + private fun bindLoadChapter(obj: ChapterLoadSpanned) { + if (binding !is SingleLoadBinding) throw NotImplementedError() + binding.root.setText(obj.name) + binding.root.setOnClickListener { + viewModel.seekToChapter(obj.loadIndex) + } + } + private fun bindChapter(obj: ChapterStartSpanned) { if (binding !is SingleFinishedChapterBinding) throw NotImplementedError() binding.root.setText(obj.name) @@ -602,6 +634,10 @@ class TextAdapter(private val viewModel: ReadActivityViewModel, var config: Text this.bindChapter(obj) } + is ChapterLoadSpanned -> { + this.bindLoadChapter(obj) + } + else -> throw NotImplementedError() } setConfig(config) @@ -638,6 +674,11 @@ class TextAdapter(private val viewModel: ReadActivityViewModel, var config: Text newItem.id == oldItem.id && oldItem.name == newItem.name } + is ChapterLoadSpanned -> { + if (newItem !is ChapterLoadSpanned) return false + newItem.id == oldItem.id && oldItem.name == newItem.name + } + else -> throw NotImplementedError() } } diff --git a/app/src/main/res/drawable/ic_icon_monochrome.xml b/app/src/main/res/drawable/ic_icon_monochrome.xml index bcf040b3..5503eb22 100644 --- a/app/src/main/res/drawable/ic_icon_monochrome.xml +++ b/app/src/main/res/drawable/ic_icon_monochrome.xml @@ -1,17 +1,27 @@ - - - - - - + android:width="108dp" + android:height="108dp" + android:viewportWidth="1000" + android:viewportHeight="1000"> + + + + + - \ No newline at end of file + + diff --git a/app/src/main/res/layout/read_bottom_settings.xml b/app/src/main/res/layout/read_bottom_settings.xml index 3244ea95..a036bc65 100644 --- a/app/src/main/res/layout/read_bottom_settings.xml +++ b/app/src/main/res/layout/read_bottom_settings.xml @@ -1,6 +1,7 @@ + + + + + + diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index 7353dbd1..7185740a 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -2,4 +2,5 @@ + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index 7353dbd1..7185740a 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -2,4 +2,5 @@ + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0ecf3bf6..60b5060a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -82,6 +82,11 @@ Locked portrait Locked landscape + + Infinite scroll + Chapter buttons + + Reading On-Hold @@ -119,6 +124,7 @@ Text Side Margin Reset to default Text Font + Scroll Type No chapters found Error loading novel Error loading chapter