diff --git a/app/src/main/kotlin/com/chmouel/liseur/reader/ReaderScreen.kt b/app/src/main/kotlin/com/chmouel/liseur/reader/ReaderScreen.kt index 2581b624..7cd4b6f4 100644 --- a/app/src/main/kotlin/com/chmouel/liseur/reader/ReaderScreen.kt +++ b/app/src/main/kotlin/com/chmouel/liseur/reader/ReaderScreen.kt @@ -3,6 +3,7 @@ package com.chmouel.liseur.reader import android.app.Activity import android.graphics.BitmapFactory import android.graphics.Rect +import android.os.Build import android.util.Log import android.view.WindowManager import androidx.activity.compose.BackHandler @@ -190,6 +191,7 @@ import com.chmouel.liseur.reader.chrome.AutoScrollTicker import com.chmouel.liseur.reader.chrome.autoScrollControlsShown import com.chmouel.liseur.reader.chrome.JumpBackPill import com.chmouel.liseur.reader.chrome.PageCurl +import com.chmouel.liseur.reader.chrome.isPageCurlSupportedOnDevice import com.chmouel.liseur.reader.chrome.PageCurlOverlay import com.chmouel.liseur.reader.chrome.PageCurlState import com.chmouel.liseur.reader.chrome.PageTurnDrag @@ -1145,6 +1147,14 @@ fun ReaderScreen( val eInk = LocalEInk.current val eInkNow by rememberUpdatedState(eInk) + val pageCurlSupportedOnDevice = remember { + isPageCurlSupportedOnDevice( + manufacturer = Build.MANUFACTURER.orEmpty(), + brand = Build.BRAND.orEmpty(), + model = Build.MODEL.orEmpty(), + device = Build.DEVICE.orEmpty(), + ) + } var showingEnd by remember { mutableStateOf(false) } chromeTransition.targetState = chromeVisible && !showingEnd val showingEndNow by rememberUpdatedState(showingEnd) @@ -1245,7 +1255,7 @@ fun ReaderScreen( tappedSelection == null && viewedImageNow == null && !openingImageNow }, - interactive = { !eInkNow }, + interactive = { !eInkNow && pageCurlSupportedOnDevice }, isRtl = { navigatorNow?.overflow?.value?.readingProgression == ReadingProgression.RTL }, diff --git a/app/src/main/kotlin/com/chmouel/liseur/reader/chrome/PageCurlCompatibility.kt b/app/src/main/kotlin/com/chmouel/liseur/reader/chrome/PageCurlCompatibility.kt new file mode 100644 index 00000000..86933977 --- /dev/null +++ b/app/src/main/kotlin/com/chmouel/liseur/reader/chrome/PageCurlCompatibility.kt @@ -0,0 +1,28 @@ +package com.chmouel.liseur.reader.chrome + +import java.util.Locale + +private val DEVICE_NAME_SEPARATORS = Regex("[^a-z0-9]+") + +/** + * Whether the custom page curl should be used on this device. + */ +internal fun isPageCurlSupportedOnDevice( + manufacturer: String, + brand: String, + model: String, + device: String, +): Boolean { + val names = listOf(manufacturer, brand, model, device) + .map { it.lowercase(Locale.ROOT).replace(DEVICE_NAME_SEPARATORS, " ").trim() } + + val isTecnoKj5 = + names.any { it.hasToken("tecno") } && + names.any { it == "kj5" || it.endsWith(" kj5") } + val isAir1Ultra = names.any { it == "air1 ultra" || it.endsWith(" air1 ultra") } + + return !(isTecnoKj5 || isAir1Ultra) +} + +private fun String.hasToken(token: String): Boolean = + split(' ').any { it == token } diff --git a/app/src/test/kotlin/com/chmouel/liseur/reader/chrome/PageCurlCompatibilityTest.kt b/app/src/test/kotlin/com/chmouel/liseur/reader/chrome/PageCurlCompatibilityTest.kt new file mode 100644 index 00000000..ecb3b858 --- /dev/null +++ b/app/src/test/kotlin/com/chmouel/liseur/reader/chrome/PageCurlCompatibilityTest.kt @@ -0,0 +1,72 @@ +package com.chmouel.liseur.reader.chrome + +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test + +class PageCurlCompatibilityTest { + + @Test + fun `TECNO KJ5 is kept off the custom curl`() { + assertFalse( + isPageCurlSupportedOnDevice( + manufacturer = "TECNO", + brand = "TECNO", + model = "TECNO-KJ5", + device = "KJ5", + ), + ) + } + + @Test + fun `the TECNO Spark 20 sample is matched by its KJ5 device code`() { + assertFalse( + isPageCurlSupportedOnDevice( + manufacturer = "TECNO", + brand = "TECNO", + model = "TECNO SPARK 20", + device = "KJ5", + ), + ) + } + + @Test + fun `IIIF150 Air1 Ultra is kept off the custom curl`() { + assertFalse( + isPageCurlSupportedOnDevice( + manufacturer = "Unknown", + brand = "Unknown", + model = "Air1_Ultra", + device = "Air1_Ultra", + ), + ) + } + + @Test + fun `unreported models keep the custom curl`() { + assertTrue( + isPageCurlSupportedOnDevice( + manufacturer = "TECNO", + brand = "TECNO", + model = "TECNO-KJ50", + device = "KJ50", + ), + ) + assertTrue( + isPageCurlSupportedOnDevice( + manufacturer = "IIIF150", + brand = "IIIF150", + model = "Air1", + device = "Air1", + ), + ) + assertTrue( + isPageCurlSupportedOnDevice( + manufacturer = "Google", + brand = "Google", + model = "Pixel 10", + device = "generic", + ), + ) + } +} diff --git a/app/src/test/kotlin/com/chmouel/liseur/reader/chrome/PageTurnDragTest.kt b/app/src/test/kotlin/com/chmouel/liseur/reader/chrome/PageTurnDragTest.kt index 43853c14..bd870244 100644 --- a/app/src/test/kotlin/com/chmouel/liseur/reader/chrome/PageTurnDragTest.kt +++ b/app/src/test/kotlin/com/chmouel/liseur/reader/chrome/PageTurnDragTest.kt @@ -125,6 +125,23 @@ class PageTurnDragTest { assertTrue(h.curl.log.isEmpty()) } + @Test + fun `a reported device leaves the horizontal drag to the navigator`() { + val h = Harness( + interactive = isPageCurlSupportedOnDevice( + manufacturer = "TECNO", + brand = "TECNO", + model = "TECNO-KJ5", + device = "KJ5", + ), + ) + + assertFalse(h.drag.offer(pointers = 1, dx = -200f, dy = 4f)) + assertFalse(h.drag.release()) + assertTrue(h.turns.isEmpty()) + assertTrue(h.curl.log.isEmpty()) + } + // Curls. @Test