Skip to content

Commit

Permalink
3.1.8 Bionic Reading
Browse files Browse the repository at this point in the history
  • Loading branch information
LagradOst committed Mar 14, 2024
1 parent f87615c commit 70b04bc
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 9 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ android {
applicationId "com.lagradost.quicknovel"
minSdkVersion 21
targetSdkVersion 34
versionCode 54
versionName "3.1.7"
versionCode 55
versionName "3.1.8"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/com/lagradost/quicknovel/DataStore.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const val DOWNLOAD_NORMAL_SORTING_METHOD: String = "download_normal_sorting"
const val DOWNLOAD_SETTINGS: String = "download_settings"
const val EPUB_LOCK_ROTATION: String = "reader_epub_rotation"
const val EPUB_TEXT_SIZE: String = "reader_epub_text_size"
const val EPUB_TEXT_BIONIC: String = "reader_epub_bionic_reading"
const val EPUB_SCROLL_VOL: String = "reader_epub_scroll_volume"
const val EPUB_TTS_LOCK: String = "reader_epub_scroll_lock"
const val EPUB_BG_COLOR: String = "reader_epub_bg_color"
Expand Down
15 changes: 13 additions & 2 deletions app/src/main/java/com/lagradost/quicknovel/ReadActivity2.kt
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,6 @@ class ReadActivity2 : AppCompatActivity(), ColorPickerDialogListener {
config.setArgs(binding.loadingText, CONFIG_FONT or CONFIG_COLOR)
config.setArgs(binding.readBattery, CONFIG_FONT or CONFIG_COLOR or CONFIG_FONT_BOLD)
config.setArgs(binding.readTimeClock, CONFIG_FONT or CONFIG_COLOR or CONFIG_FONT_BOLD)

config.setArgs(binding.readLoadingBar)
}

Expand Down Expand Up @@ -715,7 +714,8 @@ class ReadActivity2 : AppCompatActivity(), ColorPickerDialogListener {
textColor = viewModel.textColor,
textSize = viewModel.textSize,
textFont = viewModel.textFont,
backgroundColor = viewModel.backgroundColor
backgroundColor = viewModel.backgroundColor,
bionicReading = viewModel.bionicReading
).also { config ->
updateOtherTextConfig(config)
}
Expand Down Expand Up @@ -754,6 +754,12 @@ class ReadActivity2 : AppCompatActivity(), ColorPickerDialogListener {
}
}

observe(viewModel.bionicReadingLive) { color ->
if (textAdapter.changeBionicReading(color)) {
updateTextAdapterConfig()
}
}

observe(viewModel.showBatteryLive) { show ->
binding.readBattery.isVisible = show
binding.readOverlay.isVisible = show && viewModel.showTime
Expand Down Expand Up @@ -1266,6 +1272,11 @@ class ReadActivity2 : AppCompatActivity(), ColorPickerDialogListener {
viewModel.scrollWithVolume = isChecked
}

readSettingsShowBionic.isChecked = viewModel.bionicReading
readSettingsShowBionic.setOnCheckedChangeListener { _, isChecked ->
viewModel.bionicReading = isChecked
}

readSettingsLockTts.isChecked = viewModel.ttsLock
readSettingsLockTts.setOnCheckedChangeListener { _, isChecked ->
viewModel.ttsLock = isChecked
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,14 @@ class ReadActivityViewModel : ViewModel() {
textSizeLive
)

val bionicReadingLive: MutableLiveData<Boolean> = MutableLiveData(null)
var bionicReading by PreferenceDelegateLiveView(
EPUB_TEXT_BIONIC,
false,
Boolean::class,
bionicReadingLive
)

val orientationLive: MutableLiveData<Int> = MutableLiveData(null)
var orientation by PreferenceDelegateLiveView(
EPUB_LOCK_ROTATION,
Expand Down
34 changes: 32 additions & 2 deletions app/src/main/java/com/lagradost/quicknovel/TTSHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.graphics.Typeface
import android.media.AudioAttributes
import android.media.AudioFocusRequest
import android.media.AudioManager
Expand All @@ -12,21 +13,26 @@ import android.speech.tts.TextToSpeech
import android.speech.tts.UtteranceProgressListener
import android.speech.tts.Voice
import android.support.v4.media.session.MediaSessionCompat
import android.text.Spannable
import android.text.SpannableString
import android.text.Spanned
import android.text.style.StyleSpan
import android.view.KeyEvent
import androidx.media.session.MediaButtonReceiver
import com.lagradost.quicknovel.ui.UiText
import com.lagradost.quicknovel.ui.txt
import com.lagradost.quicknovel.BaseApplication.Companion.removeKey
import com.lagradost.quicknovel.BaseApplication.Companion.setKey
import com.lagradost.quicknovel.mvvm.debugAssert
import com.lagradost.quicknovel.receivers.BecomingNoisyReceiver
import com.lagradost.quicknovel.ui.UiText
import com.lagradost.quicknovel.ui.txt
import com.lagradost.quicknovel.util.UIHelper.requestAudioFocus
import io.noties.markwon.Markwon
import kotlinx.coroutines.delay
import org.jsoup.Jsoup
import java.util.Locale
import java.util.Stack
import kotlin.math.roundToInt


class TTSSession(val context: Context, event: (TTSHelper.TTSActionType) -> Boolean) {
private val intentFilter = IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY)
Expand Down Expand Up @@ -266,6 +272,30 @@ data class TextSpan(
override val index: Int,
override var innerIndex: Int,
) : SpanDisplay() {
val bionicText : Spanned by lazy {
val wordToSpan: Spannable = SpannableString(text)
val length = wordToSpan.length
Regex("([a-zà-ýA-ZÀ-ÝåäöÅÄÖ].*?)[^a-zà-ýA-ZÀ-ÝåäöÅÄÖ'’]").findAll(text).forEach { match ->
val range = match.groups[1]!!.range
// https://github.com/gBloxy/Bionic-Reader/blob/main/bionic-reader.py#L167
val correctLength = when (val rangeLength = range.last + 1 - range.first) {
0 -> return@forEach // this should never happened
1, 2, 3 -> 1
4 -> 2
else -> {
(rangeLength.toFloat() * 0.4).roundToInt()
}
}
wordToSpan.setSpan(
StyleSpan(Typeface.BOLD),
minOf(maxOf(match.range.first, 0), length),
minOf(maxOf(match.range.first + correctLength, 0), length),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
}

wordToSpan
}
override fun id(): Long {
return generateId(0, index, start, end)
}
Expand Down
17 changes: 14 additions & 3 deletions app/src/main/java/com/lagradost/quicknovel/ui/TextAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ data class TextConfig(
val textFont: String,
val defaultFont: Typeface,
val backgroundColor : Int,
val bionicReading : Boolean
) {
private val fontFile: File? by lazy {
if (textFont == "") null else systemFonts.firstOrNull { it.name == textFont }
Expand Down Expand Up @@ -251,6 +252,12 @@ class TextAdapter(private val viewModel: ReadActivityViewModel, var config: Text
return true
}

fun changeBionicReading(to : Boolean) : Boolean {
if (config.bionicReading == to) return false
config = config.copy(bionicReading = to)
return true
}

fun changeColor(color: Int): Boolean {
if (config.textColor == color) return false
config = config.copy(textColor = color)
Expand Down Expand Up @@ -547,7 +554,7 @@ class TextAdapter(private val viewModel: ReadActivityViewModel, var config: Text
UIHelper.bindImage(binding.root, img)
}

private fun bindText(obj: TextSpan) {
private fun bindText(obj: TextSpan, config: TextConfig) {
when (binding) {
is SingleImageBinding -> {
val img = obj.text.getSpans<AsyncDrawableSpan>(0, obj.text.length)[0]
Expand Down Expand Up @@ -586,7 +593,11 @@ class TextAdapter(private val viewModel: ReadActivityViewModel, var config: Text
binding.root.apply {
// this is set to fix the nonclick https://stackoverflow.com/questions/8641343/android-clickablespan-not-calling-onclick
movementMethod = LinkMovementMethod.getInstance()
text = obj.text
text = if (config.bionicReading) {
obj.bionicText
} else {
obj.text
}

//val links = obj.text.getSpans<io.noties.markwon.core.spans.LinkSpan>()
//if (links.isNotEmpty()) {
Expand Down Expand Up @@ -671,7 +682,7 @@ class TextAdapter(private val viewModel: ReadActivityViewModel, var config: Text
span = obj
when (obj) {
is TextSpan -> {
this.bindText(obj)
this.bindText(obj, config)
// because we bind text here we know that it will be cleared and thus
// we do not have to update it with null
if (ttsLine != null)
Expand Down
11 changes: 11 additions & 0 deletions app/src/main/res/layout/read_bottom_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,17 @@
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<com.google.android.material.checkbox.MaterialCheckBox
android:textSize="16sp"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:text="@string/bionic_reading"
android:id="@+id/read_settings_show_bionic"
android:textColor="?attr/textColor"
app:buttonTint="?attr/colorOnPrimary"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<com.google.android.material.checkbox.MaterialCheckBox
android:textSize="16sp"
android:paddingStart="5dp"
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -207,4 +207,5 @@
<string name="more_info">More Info</string>
<string name="download_path_key">download_path_key</string>
<string name="download_path_pref">Download path</string>
<string name="bionic_reading">Bionic Reading</string>
</resources>

0 comments on commit 70b04bc

Please sign in to comment.