diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml
index e0be883ca7..e543e1eec5 100644
--- a/.github/workflows/checks.yml
+++ b/.github/workflows/checks.yml
@@ -13,9 +13,9 @@ jobs:
if: ${{ !github.event.pull_request.draft }}
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Set up JDK 17
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'adopt'
@@ -30,9 +30,9 @@ jobs:
if: ${{ !github.event.pull_request.draft }}
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Set up JDK 17
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'adopt'
@@ -47,14 +47,14 @@ jobs:
scripts: ${{ 'readium/navigator/src/main/assets/_scripts' }}
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Install pnpm
- uses: pnpm/action-setup@v2
+ uses: pnpm/action-setup@v4
with:
package_json_file: readium/navigator/src/main/assets/_scripts/package.json
run_install: false
- name: Setup cache
- uses: actions/setup-node@v3
+ uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
diff --git a/.gitignore b/.gitignore
index 7ff29501cc..cb239629fc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -91,3 +91,6 @@ lcp.patch
# direnv file containing Maven Central secrets
.envrc
+
+# Kotlin
+.kotlin/
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index b589d56e9f..b86273d942 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
index 148fdd2469..c224ad564b 100644
--- a/.idea/kotlinc.xml
+++ b/.idea/kotlinc.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
new file mode 100644
index 0000000000..16660f1d80
--- /dev/null
+++ b/.idea/runConfigurations.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 371f5a73bf..ac4cfbada2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,10 +4,16 @@ All notable changes to this project will be documented in this file. Take a look
**Warning:** Features marked as *experimental* may change or be removed in a future release without notice. Use with caution.
-## [Unreleased]
+
+
+## [3.0.1]
### Fixed
+#### Shared
+
+* Improved performance when accessing a publication from the Shared Storage.
+
#### Navigator
* Fixed crash in the image navigator.
@@ -895,4 +901,5 @@ progression. Now if no reading progression is set, the `effectiveReadingProgress
[3.0.0-beta.1]: https://github.com/readium/kotlin-toolkit/compare/3.0.0-alpha.2...3.0.0-beta.1
[3.0.0-beta.2]: https://github.com/readium/kotlin-toolkit/compare/3.0.0-beta.1...3.0.0-beta.2
[3.0.0]: https://github.com/readium/kotlin-toolkit/compare/3.0.0-beta.2...3.0.0
+[3.0.1]: https://github.com/readium/kotlin-toolkit/compare/3.0.0...3.0.1
diff --git a/README.md b/README.md
index 10663ca82d..9d77ff4fa5 100644
--- a/README.md
+++ b/README.md
@@ -8,10 +8,11 @@
## Minimum Requirements
-| Readium | Android min SDK | Android compile SDK | Kotlin compiler (✻) | Gradle (✻) |
-|---------|-----------------|---------------------|---------------------|------------|
-| 3.0.0 | 21 | 34 | 1.9.24 | 8.6.0 |
-| 2.3.0 | 21 | 33 | 1.7.10 | 6.9.3 |
+| Readium | Android min SDK | Android compile SDK | Kotlin compiler (✻) | Gradle (✻) |
+|-----------|-----------------|---------------------|---------------------|------------|
+| `develop` | 21 | 35 | 2.0.21 | 8.10.2 |
+| 3.0.0 | 21 | 34 | 1.9.24 | 8.6.0 |
+| 2.3.0 | 21 | 33 | 1.7.10 | 6.9.3 |
✻ Only required if you integrate Readium as a submodule instead of using Maven Central.
@@ -21,7 +22,7 @@ Readium modules are distributed with [Maven Central](https://search.maven.org/se
```groovy
buildscript {
- ext.readium_version = '3.0.0'
+ ext.readium_version = '3.0.1'
}
allprojects {
@@ -43,6 +44,8 @@ dependencies {
}
```
+:warning: If you target Android devices running below API 26, you must enable [core library desugaring](https://developer.android.com/studio/write/java8-support#library-desugaring) in your application module.
+
### Using a local Git clone
You may prefer to use a local Git clone if you want to contribute to Readium, or if you are using your own fork.
diff --git a/build.gradle.kts b/build.gradle.kts
index 5a6a65465e..9d79e831e0 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -9,6 +9,7 @@ import org.jetbrains.dokka.gradle.DokkaTaskPartial
plugins {
alias(libs.plugins.dokka)
alias(libs.plugins.ktlint)
+ alias(libs.plugins.compose.compiler) apply false
}
subprojects {
diff --git a/gradle.properties b/gradle.properties
index 87d64aadb5..dd882096fb 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -6,11 +6,11 @@
# http://www.gradle.org/docs/current/userguide/build_environment.html
pom.groupId=org.readium.kotlin-toolkit
-pom.version=3.0.0
+pom.version=3.0.1
android.minSdk=21
-android.compileSdk=34
-android.targetSdk=34
+android.compileSdk=35
+android.targetSdk=35
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
@@ -27,3 +27,7 @@ android.useAndroidX=true
android.enableJetifier=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
+
+# FIXME: There are still a few issues with KSP and K2. It probably won't be ready until Room is
+# updated to 2.7.0 (currently in alpha), and the KSP2 issue with @TypeConverters is fixed.
+#ksp.useKSP2=true
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 715917ead8..20d7a0030b 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,61 +1,56 @@
[versions]
-kotlin = "1.9.24"
-agp = "8.4.0"
-desugar_jdk_libs = "2.0.4"
+kotlin = "2.0.21"
+agp = "8.7.2"
+desugar_jdk_libs = "2.1.2"
gradle-maven-publish-plugin = "0.28.0"
-androidx-activity = "1.9.0"
-androidx-appcompat = "1.6.1"
+androidx-activity = "1.9.3"
+androidx-annotation = "1.9.1"
+androidx-appcompat = "1.7.0"
androidx-browser = "1.8.0"
androidx-cardview = "1.0.0"
-# Make sure to align with the Kotlin version
-# https://developer.android.com/jetpack/androidx/releases/compose-kotlin
-androidx-compose-compiler = "1.5.14"
-androidx-compose-animation = "1.7.0"
-androidx-compose-foundation = "1.7.0"
-androidx-compose-material = "1.7.0"
-androidx-compose-material3 = "1.3.0"
-androidx-compose-runtime = "1.7.0"
-androidx-compose-ui = "1.7.0"
-androidx-constraintlayout = "2.1.4"
-androidx-core = "1.13.1"
+androidx-compose-animation = "1.7.5"
+androidx-compose-foundation = "1.7.5"
+androidx-compose-material = "1.7.5"
+androidx-compose-material3 = "1.3.1"
+androidx-compose-runtime = "1.7.5"
+androidx-compose-ui = "1.7.5"
+androidx-constraintlayout = "2.2.0"
+androidx-core = "1.15.0"
androidx-datastore = "1.1.1"
-androidx-expresso-core = "3.5.1"
-androidx-ext-junit = "1.1.5"
-androidx-fragment = "1.8.4"
+androidx-fragment-ktx = "1.8.5"
androidx-legacy = "1.0.0"
-androidx-lifecycle = "2.8.0"
-androidx-lifecycle-extensions = "2.2.0"
+androidx-lifecycle = "2.8.7"
androidx-media = "1.7.0"
androidx-media2 = "1.3.0"
-androidx-media3 = "1.3.1"
-androidx-navigation = "2.7.7"
-androidx-paging = "3.3.0"
+androidx-media3 = "1.4.1"
+androidx-navigation = "2.8.3"
+androidx-paging = "3.3.2"
androidx-recyclerview = "1.3.2"
androidx-room = "2.6.1"
androidx-viewpager2 = "1.1.0"
-androidx-webkit = "1.11.0"
+androidx-webkit = "1.12.1"
-assertj = "3.25.3"
+assertj = "3.26.3"
dokka = "1.9.20"
google-exoplayer = "2.19.1"
google-material = "1.12.0"
-joda-time = "2.12.7"
-jsoup = "1.17.2"
+joda-time = "2.13.0"
+jsoup = "1.18.1"
junit = "4.13.2"
-kotlinx-coroutines = "1.8.1"
-kotlinx-coroutines-test = "1.8.1"
-kotlinx-datetime = "0.6.0"
-kotlinx-serialization-json = "1.6.3"
+kotlinx-coroutines = "1.9.0"
+kotlinx-coroutines-test = "1.9.0"
+kotlinx-datetime = "0.6.1"
+kotlinx-serialization-json = "1.7.3"
# Make sure to align with the Kotlin version.
# See https://github.com/google/ksp/releases
-ksp = "1.9.24-1.0.20"
+ksp = "2.0.21-1.0.25"
ktlint = "11.5.1"
@@ -68,7 +63,7 @@ pdf-viewer = "2.8.2"
picasso = "2.8"
pspdfkit = "8.4.1"
-robolectric = "4.12.2"
+robolectric = "4.13"
timber = "5.0.1"
@@ -76,6 +71,7 @@ timber = "5.0.1"
[libraries]
androidx-activity-ktx = { group = "androidx.activity", name = "activity-ktx", version.ref = "androidx-activity" }
+androidx-annotation = { group = "androidx.annotation", name = "annotation", version.ref = "androidx-annotation" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "androidx-appcompat" }
androidx-browser = { group = "androidx.browser", name = "browser", version.ref = "androidx-browser" }
androidx-cardview = { group = "androidx.cardview", name = "cardview", version.ref = "androidx-cardview" }
@@ -91,19 +87,9 @@ androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-toolin
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "androidx-constraintlayout" }
androidx-core = { group = "androidx.core", name = "core-ktx", version.ref = "androidx-core" }
androidx-datastore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "androidx-datastore" }
-androidx-expresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "androidx-expresso-core" }
-androidx-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-ext-junit" }
-androidx-fragment-ktx = { group = "androidx.fragment", name = "fragment-ktx", version.ref = "androidx-fragment" }
-androidx-fragment-compose = { group = "androidx.fragment", name = "fragment-compose", version.ref = "androidx-fragment" }
-androidx-legacy-v4 = { group = "androidx.legacy", name = "legacy-support-v4", version.ref = "androidx-legacy" }
+androidx-fragment-ktx = { group = "androidx.fragment", name = "fragment-ktx", version.ref = "androidx-fragment-ktx" }
androidx-legacy-ui = { group = "androidx.legacy", name = "legacy-support-core-ui", version.ref = "androidx-legacy" }
androidx-lifecycle-common = { group = "androidx.lifecycle", name = "lifecycle-common-java8", version.ref = "androidx-lifecycle" }
-androidx-lifecycle-extensions = { group = "androidx.lifecycle", name = "lifecycle-extensions", version.ref = "androidx-lifecycle-extensions" }
-androidx-lifecycle-livedata = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "androidx-lifecycle" }
-androidx-lifecycle-runtime = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "androidx-lifecycle" }
-androidx-lifecycle-viewmodel = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "androidx-lifecycle" }
-androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" }
-androidx-lifecycle-vmsavedstate = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-savedstate", version.ref = "androidx-lifecycle" }
androidx-media = { group = "androidx.media", name = "media", version.ref = "androidx-media" }
androidx-media2-session = { group = "androidx.media2", name = "media2-session", version.ref = "androidx-media2" }
androidx-media2-player = { group = "androidx.media2", name = "media2-player", version.ref = "androidx-media2" }
@@ -161,12 +147,12 @@ kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", versi
dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" }
+compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
[bundles]
compose = ["androidx-compose-activity", "androidx-compose-animation", "androidx-compose-foundation", "androidx-compose-material", "androidx-compose-material3", "androidx-compose-material-icons", "androidx-compose-runtime", "androidx-compose-ui", "androidx-compose-ui-tooling"]
exoplayer = ["google-exoplayer-core", "google-exoplayer-ui", "google-exoplayer-mediasession", "google-exoplayer-workmanager", "google-exoplayer-extension-media2"]
-lifecycle = ["androidx-lifecycle-common", "androidx-lifecycle-extensions", "androidx-lifecycle-livedata", "androidx-lifecycle-runtime", "androidx-lifecycle-viewmodel", "androidx-lifecycle-vmsavedstate", "androidx-lifecycle-viewmodel-compose"]
media2 = ["androidx-media2-session", "androidx-media2-player", "google-exoplayer-core", "google-exoplayer-extension-media2"]
media3 = ["androidx-media3-session", "androidx-media3-common", "androidx-media3-exoplayer"]
room = ["androidx-room-runtime", "androidx-room-ktx"]
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 17655d0ef2..1e2fbf0d45 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/readium/adapters/exoplayer/audio/src/main/java/org/readium/adapter/exoplayer/audio/ExoPlayerEngine.kt b/readium/adapters/exoplayer/audio/src/main/java/org/readium/adapter/exoplayer/audio/ExoPlayerEngine.kt
index 94cd4beb57..e048da9682 100644
--- a/readium/adapters/exoplayer/audio/src/main/java/org/readium/adapter/exoplayer/audio/ExoPlayerEngine.kt
+++ b/readium/adapters/exoplayer/audio/src/main/java/org/readium/adapter/exoplayer/audio/ExoPlayerEngine.kt
@@ -120,13 +120,13 @@ public class ExoPlayerEngine private constructor(
private suspend fun prepareExoPlayer(player: ExoPlayer) {
lateinit var listener: Player.Listener
- suspendCancellableCoroutine { continuation ->
+ suspendCancellableCoroutine { continuation ->
listener = object : Player.Listener {
override fun onPlaybackStateChanged(playbackState: Int) {
when (playbackState) {
- Player.STATE_READY -> continuation.resume(Unit) {}
+ Player.STATE_READY -> continuation.resume(Unit) { _, _, _ -> }
Player.STATE_IDLE -> if (player.playerError != null) {
- continuation.resume(Unit) {}
+ continuation.resume(Unit) { _, _, _ -> }
}
else -> {}
}
diff --git a/readium/adapters/pdfium/document/build.gradle.kts b/readium/adapters/pdfium/document/build.gradle.kts
index 93b145f568..d1eab7034c 100644
--- a/readium/adapters/pdfium/document/build.gradle.kts
+++ b/readium/adapters/pdfium/document/build.gradle.kts
@@ -15,13 +15,7 @@ android {
dependencies {
api(project(":readium:readium-shared"))
- implementation(libs.androidx.core)
implementation(libs.pdfium)
implementation(libs.timber)
implementation(libs.kotlinx.coroutines.android)
-
- testImplementation(libs.junit)
-
- androidTestImplementation(libs.androidx.ext.junit)
- androidTestImplementation(libs.androidx.expresso.core)
}
diff --git a/readium/adapters/pdfium/navigator/build.gradle.kts b/readium/adapters/pdfium/navigator/build.gradle.kts
index 8a30470160..8243f6d3c6 100644
--- a/readium/adapters/pdfium/navigator/build.gradle.kts
+++ b/readium/adapters/pdfium/navigator/build.gradle.kts
@@ -28,9 +28,4 @@ dependencies {
implementation(libs.timber)
implementation(libs.kotlinx.coroutines.android)
implementation(libs.kotlinx.serialization.json)
-
- testImplementation(libs.junit)
-
- androidTestImplementation(libs.androidx.ext.junit)
- androidTestImplementation(libs.androidx.expresso.core)
}
diff --git a/readium/adapters/pspdfkit/document/build.gradle.kts b/readium/adapters/pspdfkit/document/build.gradle.kts
index bbfbaadbd9..74cddccd99 100644
--- a/readium/adapters/pspdfkit/document/build.gradle.kts
+++ b/readium/adapters/pspdfkit/document/build.gradle.kts
@@ -15,13 +15,7 @@ android {
dependencies {
api(project(":readium:readium-shared"))
- implementation(libs.androidx.core)
implementation(libs.timber)
implementation(libs.pspdfkit)
implementation(libs.kotlinx.coroutines.android)
-
- testImplementation(libs.junit)
-
- androidTestImplementation(libs.androidx.ext.junit)
- androidTestImplementation(libs.androidx.expresso.core)
}
diff --git a/readium/adapters/pspdfkit/navigator/build.gradle.kts b/readium/adapters/pspdfkit/navigator/build.gradle.kts
index 67f4dd44e8..34f1b27a23 100644
--- a/readium/adapters/pspdfkit/navigator/build.gradle.kts
+++ b/readium/adapters/pspdfkit/navigator/build.gradle.kts
@@ -26,9 +26,4 @@ dependencies {
implementation(libs.pspdfkit)
implementation(libs.kotlinx.coroutines.android)
implementation(libs.kotlinx.serialization.json)
-
- testImplementation(libs.junit)
-
- androidTestImplementation(libs.androidx.ext.junit)
- androidTestImplementation(libs.androidx.expresso.core)
}
diff --git a/readium/lcp/build.gradle.kts b/readium/lcp/build.gradle.kts
index 8a2aec53ef..f0dd3a6f49 100644
--- a/readium/lcp/build.gradle.kts
+++ b/readium/lcp/build.gradle.kts
@@ -11,6 +11,11 @@ plugins {
android {
namespace = "org.readium.r2.lcp"
+
+ kotlinOptions {
+ // See https://github.com/readium/kotlin-toolkit/pull/525#issuecomment-2300084041
+ freeCompilerArgs = freeCompilerArgs + ("-Xconsistent-data-class-copy-visibility")
+ }
}
dependencies {
@@ -37,7 +42,4 @@ dependencies {
// Tests
testImplementation(libs.junit)
testImplementation(libs.kotlin.junit)
-
- androidTestImplementation(libs.androidx.ext.junit)
- androidTestImplementation(libs.androidx.expresso.core)
}
diff --git a/readium/navigator-media2/build.gradle.kts b/readium/navigator-media2/build.gradle.kts
index eb8d371d5d..c1c4acc55e 100644
--- a/readium/navigator-media2/build.gradle.kts
+++ b/readium/navigator-media2/build.gradle.kts
@@ -27,7 +27,4 @@ dependencies {
implementation(libs.bundles.media2)
testImplementation(libs.junit)
-
- androidTestImplementation(libs.androidx.ext.junit)
- androidTestImplementation(libs.androidx.expresso.core)
}
diff --git a/readium/navigator/build.gradle.kts b/readium/navigator/build.gradle.kts
index 4f126d7141..013535d3d1 100644
--- a/readium/navigator/build.gradle.kts
+++ b/readium/navigator/build.gradle.kts
@@ -15,6 +15,11 @@ android {
buildFeatures {
viewBinding = true
}
+
+ kotlinOptions {
+ // See https://github.com/readium/kotlin-toolkit/pull/525#issuecomment-2300084041
+ freeCompilerArgs = freeCompilerArgs + ("-Xconsistent-data-class-copy-visibility")
+ }
}
dependencies {
@@ -22,27 +27,22 @@ dependencies {
implementation(files("libs/PhotoView-2.3.0.jar"))
- implementation(libs.androidx.activity.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.browser)
implementation(libs.androidx.constraintlayout)
implementation(libs.androidx.core)
implementation(libs.androidx.fragment.ktx)
implementation(libs.androidx.legacy.ui)
- implementation(libs.androidx.legacy.v4)
- implementation(libs.bundles.lifecycle)
+ implementation(libs.androidx.lifecycle.common)
implementation(libs.androidx.recyclerview)
implementation(libs.androidx.media)
implementation(libs.bundles.media3)
- implementation(libs.androidx.viewpager2)
implementation(libs.androidx.webkit)
implementation(libs.bundles.media2)
// ExoPlayer is used by the Audio Navigator.
api(libs.bundles.exoplayer)
- implementation(libs.google.material)
implementation(libs.timber)
- implementation(libs.joda.time)
implementation(libs.kotlinx.coroutines.android)
implementation(libs.kotlinx.serialization.json)
implementation(libs.jsoup)
@@ -50,8 +50,6 @@ dependencies {
// Tests
testImplementation(libs.junit)
- androidTestImplementation(libs.androidx.ext.junit)
- androidTestImplementation(libs.androidx.expresso.core)
testImplementation(libs.kotlin.junit)
testImplementation(libs.kotlinx.coroutines.test)
testImplementation(libs.robolectric)
diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt
index a6cbda9ad7..baad948843 100644
--- a/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt
+++ b/readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt
@@ -481,6 +481,7 @@ internal class R2WebView(context: Context, attrs: AttributeSet) : R2BasicWebView
}
}
+ @Deprecated("Deprecated in Java")
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
val count = childCount
val width = r - l
diff --git a/readium/navigators/common/build.gradle.kts b/readium/navigators/common/build.gradle.kts
index 723865ffac..f74eb7a507 100644
--- a/readium/navigators/common/build.gradle.kts
+++ b/readium/navigators/common/build.gradle.kts
@@ -7,14 +7,12 @@
plugins {
id("readium.library-conventions")
alias(libs.plugins.kotlin.serialization)
+ alias(libs.plugins.compose.compiler)
}
android {
namespace = "org.readium.navigators.common"
- composeOptions {
- kotlinCompilerExtensionVersion = libs.versions.androidx.compose.compiler.get()
- }
buildFeatures {
compose = true
}
diff --git a/readium/navigators/demo/build.gradle.kts b/readium/navigators/demo/build.gradle.kts
index 4dd3f3106a..26dfc39076 100644
--- a/readium/navigators/demo/build.gradle.kts
+++ b/readium/navigators/demo/build.gradle.kts
@@ -3,48 +3,48 @@ plugins {
kotlin("android")
kotlin("plugin.parcelize")
alias(libs.plugins.ksp)
+ alias(libs.plugins.compose.compiler)
}
android {
- namespace = "org.readium.navigator.demo"
- compileSdk = 34
+ compileSdk = (property("android.compileSdk") as String).toInt()
defaultConfig {
+ minSdk = (property("android.minSdk") as String).toInt()
+ targetSdk = (property("android.targetSdk") as String).toInt()
+
applicationId = "org.readium.navigator.demo"
- minSdk = 21
- targetSdk = 34
+
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
- buildTypes {
- release {
- isMinifyEnabled = false
- proguardFiles(
- getDefaultProguardFile("proguard-android-optimize.txt"),
- "proguard-rules.pro"
- )
- }
- }
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
isCoreLibraryDesugaringEnabled = true
}
kotlinOptions {
- jvmTarget = "1.8"
+ jvmTarget = JavaVersion.VERSION_1_8.toString()
freeCompilerArgs = freeCompilerArgs + "-opt-in=kotlin.RequiresOptIn"
}
- composeOptions {
- kotlinCompilerExtensionVersion = libs.versions.androidx.compose.compiler.get()
- }
buildFeatures {
viewBinding = true
compose = true
buildConfig = true
}
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
packaging {
resources.excludes.add("META-INF/*")
}
@@ -56,6 +56,7 @@ android {
assets.srcDirs("src/main/assets")
}
}
+ namespace = "org.readium.navigator.demo"
}
dependencies {
@@ -70,11 +71,9 @@ dependencies {
implementation(libs.timber)
implementation(libs.kotlinx.coroutines.android)
implementation(libs.kotlin.stdlib)
- implementation(libs.androidx.legacy.v4)
implementation(libs.bundles.compose)
implementation(libs.androidx.core)
implementation(libs.androidx.fragment.ktx)
- implementation(libs.androidx.fragment.compose)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.browser)
}
diff --git a/readium/navigators/media/audio/build.gradle.kts b/readium/navigators/media/audio/build.gradle.kts
index cb5f55932d..b65100f7df 100644
--- a/readium/navigators/media/audio/build.gradle.kts
+++ b/readium/navigators/media/audio/build.gradle.kts
@@ -22,7 +22,6 @@ dependencies {
implementation(libs.androidx.media3.common)
implementation(libs.androidx.media3.session)
- implementation(libs.androidx.core)
implementation(libs.timber)
implementation(libs.kotlinx.coroutines.android)
}
diff --git a/readium/navigators/media/tts/src/main/java/org/readium/navigator/media/tts/TtsEngineFacade.kt b/readium/navigators/media/tts/src/main/java/org/readium/navigator/media/tts/TtsEngineFacade.kt
index e96eaadada..5b849f87cc 100644
--- a/readium/navigators/media/tts/src/main/java/org/readium/navigator/media/tts/TtsEngineFacade.kt
+++ b/readium/navigators/media/tts/src/main/java/org/readium/navigator/media/tts/TtsEngineFacade.kt
@@ -76,11 +76,11 @@ internal class TtsEngineFacade }
}
override fun onError(requestId: TtsEngine.RequestId, error: E) {
- popTask(requestId)?.continuation?.resume(error) {}
+ popTask(requestId)?.continuation?.resume(error) { _, _, _ -> }
}
}
}
diff --git a/readium/navigators/web/build.gradle.kts b/readium/navigators/web/build.gradle.kts
index be938e68e3..2115fd95e5 100644
--- a/readium/navigators/web/build.gradle.kts
+++ b/readium/navigators/web/build.gradle.kts
@@ -7,14 +7,12 @@
plugins {
id("readium.library-conventions")
alias(libs.plugins.kotlin.serialization)
+ alias(libs.plugins.compose.compiler)
}
android {
namespace = "org.readium.navigators.web"
- composeOptions {
- kotlinCompilerExtensionVersion = libs.versions.androidx.compose.compiler.get()
- }
buildFeatures {
compose = true
}
diff --git a/readium/navigators/web/src/main/java/org/readium/navigator/web/FixedWebRenditionState.kt b/readium/navigators/web/src/main/java/org/readium/navigator/web/FixedWebRenditionState.kt
index 05317fe60e..baf3cd1d04 100644
--- a/readium/navigators/web/src/main/java/org/readium/navigator/web/FixedWebRenditionState.kt
+++ b/readium/navigators/web/src/main/java/org/readium/navigator/web/FixedWebRenditionState.kt
@@ -7,6 +7,7 @@
package org.readium.navigator.web
import android.app.Application
+import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.pager.PagerState
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.Stable
@@ -39,6 +40,7 @@ import org.readium.r2.shared.util.data.Container
import org.readium.r2.shared.util.mediatype.MediaType
import org.readium.r2.shared.util.resource.Resource
+@OptIn(ExperimentalFoundationApi::class)
@ExperimentalReadiumApi
@Stable
public class FixedWebRenditionState internal constructor(
diff --git a/readium/opds/build.gradle.kts b/readium/opds/build.gradle.kts
index 5a8d26219a..a65810aac4 100644
--- a/readium/opds/build.gradle.kts
+++ b/readium/opds/build.gradle.kts
@@ -15,16 +15,10 @@ android {
dependencies {
api(project(":readium:readium-shared"))
- implementation(libs.androidx.appcompat)
implementation(libs.timber)
- implementation(libs.joda.time)
implementation(libs.kotlinx.coroutines.android)
// Tests
testImplementation(libs.junit)
-
- androidTestImplementation(libs.androidx.ext.junit)
- androidTestImplementation(libs.androidx.expresso.core)
-
testImplementation(libs.robolectric)
}
diff --git a/readium/shared/build.gradle.kts b/readium/shared/build.gradle.kts
index bc31c9a0ab..ee22eadb29 100644
--- a/readium/shared/build.gradle.kts
+++ b/readium/shared/build.gradle.kts
@@ -14,8 +14,7 @@ android {
}
dependencies {
- implementation(libs.androidx.appcompat)
- implementation(libs.androidx.browser)
+ implementation(libs.androidx.annotation)
implementation(libs.timber)
implementation(libs.kotlin.reflect)
implementation(libs.kotlinx.coroutines.android)
@@ -26,9 +25,6 @@ dependencies {
// Tests
testImplementation(libs.junit)
- androidTestImplementation(libs.androidx.ext.junit)
- androidTestImplementation(libs.androidx.expresso.core)
-
testImplementation(libs.assertj)
testImplementation(libs.kotlin.junit)
testImplementation(libs.kotlinx.coroutines.test)
diff --git a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt
index e8eea0687f..d0ee39afb0 100644
--- a/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt
+++ b/readium/shared/src/main/java/org/readium/r2/shared/publication/services/content/iterators/HtmlResourceContentIterator.kt
@@ -392,7 +392,7 @@ public class HtmlResourceContentIterator internal constructor(
if (node.isBlock) {
assert(breadcrumbs.last().element == node)
flushText()
- breadcrumbs.removeLast()
+ breadcrumbs.removeAt(breadcrumbs.lastIndex)
}
}
}
diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/MemoryObserver.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/MemoryObserver.kt
index b839e13264..eb5435f558 100644
--- a/readium/shared/src/main/java/org/readium/r2/shared/util/MemoryObserver.kt
+++ b/readium/shared/src/main/java/org/readium/r2/shared/util/MemoryObserver.kt
@@ -14,14 +14,25 @@ public interface MemoryObserver {
* Level of memory trim.
*/
public enum class Level {
- Moderate, Low, Critical;
+ /**
+ * The process has gone on to the LRU list. This is a good opportunity to clean up resources
+ * that can efficiently and quickly be re-built if the user returns to the app.
+ */
+ Background,
+
+ /**
+ * The process had been showing a user interface, and is no longer doing so. Large
+ * allocations with the UI should be released at this point to allow memory to be better
+ * managed.
+ */
+ UiHidden;
public companion object {
public fun fromLevel(level: Int): Level =
- when {
- level <= ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE -> Moderate
- level == ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW -> Low
- else -> Critical
+ when (level) {
+ ComponentCallbacks2.TRIM_MEMORY_BACKGROUND -> Background
+ ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN -> UiHidden
+ else -> Background
}
}
}
@@ -40,6 +51,8 @@ public interface MemoryObserver {
public fun asComponentCallbacks2(observer: MemoryObserver): ComponentCallbacks2 =
object : ComponentCallbacks2 {
override fun onConfigurationChanged(config: Configuration) {}
+
+ @Deprecated("Deprecated in Java")
override fun onLowMemory() {}
override fun onTrimMemory(level: Int) {
diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/Url.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/Url.kt
index b404d6bf05..4cc174133f 100644
--- a/readium/shared/src/main/java/org/readium/r2/shared/util/Url.kt
+++ b/readium/shared/src/main/java/org/readium/r2/shared/util/Url.kt
@@ -205,7 +205,6 @@ public sealed class Url : Parcelable {
* WARNING: Strict URL comparisons can be a source of bug, if the URLs are not normalized.
* In most cases, you should compare using [Url.isEquivalent].
*/
- @DelicateReadiumApi
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
diff --git a/readium/shared/src/main/java/org/readium/r2/shared/util/cache/Cache.kt b/readium/shared/src/main/java/org/readium/r2/shared/util/cache/Cache.kt
index e55ccb6559..d9ba96765b 100644
--- a/readium/shared/src/main/java/org/readium/r2/shared/util/cache/Cache.kt
+++ b/readium/shared/src/main/java/org/readium/r2/shared/util/cache/Cache.kt
@@ -123,7 +123,7 @@ public class InMemoryCache : Cache {
@OptIn(DelicateCoroutinesApi::class)
override fun onTrimMemory(level: MemoryObserver.Level) {
- if (level == MemoryObserver.Level.Critical) {
+ if (level == MemoryObserver.Level.Background) {
GlobalScope.launch { transaction { clear() } }
}
}
diff --git a/readium/streamer/build.gradle.kts b/readium/streamer/build.gradle.kts
index 506d0951b5..2493ff3b0b 100644
--- a/readium/streamer/build.gradle.kts
+++ b/readium/streamer/build.gradle.kts
@@ -17,26 +17,17 @@ dependencies {
api(files("libs/nanohttpd-2.3.2.jar", "libs/nanohttpd-nanolets-2.3.2.jar"))
- implementation(libs.androidx.appcompat)
@Suppress("GradleDependency")
implementation(libs.timber)
// AM NOTE: conflicting support libraries, excluding these
implementation("com.mcxiaoke.koi:core:0.5.5") {
exclude(module = "support-v4")
}
- // useful extensions (only ~100k)
- implementation("com.mcxiaoke.koi:async:0.5.5") {
- exclude(module = "support-v4")
- }
- implementation(libs.joda.time)
implementation(libs.kotlinx.coroutines.android)
// Tests
testImplementation(libs.junit)
testImplementation(libs.kotlin.junit)
-
- androidTestImplementation(libs.androidx.ext.junit)
- androidTestImplementation(libs.androidx.expresso.core)
testImplementation(libs.assertj)
testImplementation(libs.robolectric)
}
diff --git a/test-app/build.gradle.kts b/test-app/build.gradle.kts
index 4e4186121b..bff512d1bb 100644
--- a/test-app/build.gradle.kts
+++ b/test-app/build.gradle.kts
@@ -9,18 +9,19 @@ plugins {
kotlin("android")
kotlin("plugin.parcelize")
alias(libs.plugins.ksp)
+ alias(libs.plugins.compose.compiler)
}
android {
- compileSdk = 34
+ compileSdk = (property("android.compileSdk") as String).toInt()
defaultConfig {
- minSdk = 21
- targetSdk = 34
+ minSdk = (property("android.minSdk") as String).toInt()
+ targetSdk = (property("android.targetSdk") as String).toInt()
applicationId = "org.readium.r2reader"
- versionName = "3.0.0"
- versionCode = 300000
+ versionName = "3.0.1"
+ versionCode = 300001
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
ndk.abiFilters.add("armeabi-v7a")
@@ -37,9 +38,6 @@ android {
jvmTarget = JavaVersion.VERSION_1_8.toString()
freeCompilerArgs = freeCompilerArgs + "-opt-in=kotlin.RequiresOptIn"
}
- composeOptions {
- kotlinCompilerExtensionVersion = libs.versions.androidx.compose.compiler.get()
- }
buildFeatures {
viewBinding = true
compose = true
@@ -69,7 +67,6 @@ dependencies {
coreLibraryDesugaring(libs.desugar.jdk.libs)
implementation(libs.kotlin.stdlib)
- implementation(libs.androidx.legacy.v4)
implementation(project(":readium:readium-shared"))
implementation(project(":readium:readium-streamer"))
@@ -96,7 +93,7 @@ dependencies {
implementation(libs.androidx.core)
implementation(libs.androidx.datastore.preferences)
implementation(libs.androidx.fragment.ktx)
- implementation(libs.bundles.lifecycle)
+ implementation(libs.androidx.lifecycle.common)
implementation(libs.androidx.navigation.fragment)
implementation(libs.androidx.navigation.ui)
implementation(libs.androidx.paging)
@@ -115,10 +112,4 @@ dependencies {
// Room database
implementation(libs.bundles.room)
ksp(libs.androidx.room.compiler)
-
- // Tests
- testImplementation(libs.junit)
-
- androidTestImplementation(libs.androidx.ext.junit)
- androidTestImplementation(libs.androidx.expresso.core)
}
diff --git a/test-app/src/main/java/org/readium/r2/testapp/MainActivity.kt b/test-app/src/main/java/org/readium/r2/testapp/MainActivity.kt
index 1127436189..c7b13e7c83 100644
--- a/test-app/src/main/java/org/readium/r2/testapp/MainActivity.kt
+++ b/test-app/src/main/java/org/readium/r2/testapp/MainActivity.kt
@@ -7,8 +7,11 @@
package org.readium.r2.testapp
import android.os.Bundle
+import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.AppBarConfiguration
@@ -24,7 +27,13 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ enableEdgeToEdge()
setContentView(R.layout.activity_main)
+ ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.container)) { v, insets ->
+ val statusBars = insets.getInsets(WindowInsetsCompat.Type.statusBars())
+ v.setPadding(statusBars.left, statusBars.top, statusBars.right, statusBars.bottom)
+ insets
+ }
val navView: BottomNavigationView = findViewById(R.id.nav_view)
val navHostFragment =
diff --git a/test-app/src/main/java/org/readium/r2/testapp/reader/MediaService.kt b/test-app/src/main/java/org/readium/r2/testapp/reader/MediaService.kt
index e3eaaeaf43..fc51c220ba 100644
--- a/test-app/src/main/java/org/readium/r2/testapp/reader/MediaService.kt
+++ b/test-app/src/main/java/org/readium/r2/testapp/reader/MediaService.kt
@@ -171,7 +171,7 @@ class MediaService : MediaSessionService() {
return binder.session.value?.mediaSession
}
- override fun onTaskRemoved(rootIntent: Intent) {
+ override fun onTaskRemoved(rootIntent: Intent?) {
super.onTaskRemoved(rootIntent)
Timber.d("Task removed. Stopping session and service.")
// Close the session to allow the service to be stopped.
diff --git a/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/Flow.kt b/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/Flow.kt
index 1d2f058aae..6c3ccdc435 100644
--- a/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/Flow.kt
+++ b/test-app/src/main/java/org/readium/r2/testapp/utils/extensions/Flow.kt
@@ -15,7 +15,14 @@ import androidx.lifecycle.flowWithLifecycle
import kotlin.time.Duration
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.*
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.conflate
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
/**
* Collects safely the [Flow] as a [State] when the local lifecycle is started.