refactor: migrate resource handling to new data.resources module

This commit is contained in:
2026-07-02 16:55:14 +02:00
parent c307111ec1
commit 0c4dbff929
10 changed files with 102 additions and 19 deletions
+66
View File
@@ -0,0 +1,66 @@
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.androidMultiplatformLibrary)
alias(libs.plugins.composeMultiplatform)
alias(libs.plugins.composeCompiler)
}
kotlin {
iosArm64()
iosSimulatorArm64()
jvm()
js {
browser()
}
@OptIn(ExperimentalWasmDsl::class)
wasmJs {
browser()
}
androidLibrary {
namespace = "fr.ajaury.gwenedeg.resources"
compileSdk =
libs.versions.androidCompileSdk
.get()
.toInt()
minSdk =
libs.versions.androidMinSdk
.get()
.toInt()
compilerOptions {
jvmTarget = JvmTarget.JVM_11
}
androidResources {
enable = true
}
}
sourceSets {
commonMain.dependencies {
// Core modules
implementation(projects.core.coroutines)
// Compose resources
implementation(libs.compose.runtime)
implementation(libs.compose.components.resources)
// Coroutines
implementation(libs.kotlinx.coroutinesCore)
// DI
implementation(project.dependencies.platform(libs.koin.bom))
implementation(libs.koin.core)
}
}
}
compose.resources {
packageOfResClass = "fr.ajaury.gwenedeg.resources.generated.resources"
}
@@ -1,8 +1,8 @@
package fr.ajaury.gwenedeg.resourcereader.data
package fr.ajaury.gwenedeg.resources.data
import fr.ajaury.gwenedeg.core.coroutines.domain.DispatcherProvider
import fr.ajaury.gwenedeg.resourcereader.data.domain.ResourceReader
import gwenedeg.shared.generated.resources.Res
import fr.ajaury.gwenedeg.resources.domain.ResourceReader
import fr.ajaury.gwenedeg.resources.generated.resources.Res
import kotlinx.coroutines.withContext
internal class ComposeResourceReader(
@@ -12,4 +12,6 @@ internal class ComposeResourceReader(
withContext(dispatcherProvider.io) {
Res.readBytes(resourcePath).decodeToString()
}
override fun uri(resourcePath: String): String = Res.getUri(resourcePath)
}
@@ -0,0 +1,12 @@
package fr.ajaury.gwenedeg.resources.di
import fr.ajaury.gwenedeg.resources.data.ComposeResourceReader
import fr.ajaury.gwenedeg.resources.domain.ResourceReader
import org.koin.core.module.Module
import org.koin.core.module.dsl.bind
import org.koin.core.module.dsl.factoryOf
import org.koin.dsl.module
val resourcesModule: Module = module {
factoryOf(::ComposeResourceReader) { bind<ResourceReader>() }
}
@@ -0,0 +1,13 @@
package fr.ajaury.gwenedeg.resources.domain
/**
* Provides access to the app's bundled resources. Implemented by this module, which owns the
* resource bundle, so consumer modules stay free of any platform/resource dependency.
*/
interface ResourceReader {
/** Reads the raw text content of the resource at [resourcePath]. */
suspend fun read(resourcePath: String): String
/** Returns a platform URI pointing to the resource at [resourcePath]. */
fun uri(resourcePath: String): String
}
+1
View File
@@ -44,4 +44,5 @@ include(":core:logging")
include(":core:model")
// Data modules
include(":data:resources")
include(":data:subtitle")
+1 -1
View File
@@ -65,6 +65,7 @@ kotlin {
implementation(projects.core.model)
// Data modules
implementation(projects.data.resources)
implementation(projects.data.subtitle)
implementation(libs.compose.runtime)
@@ -72,7 +73,6 @@ kotlin {
implementation(libs.compose.material3)
implementation(libs.compose.material.icons.extended)
implementation(libs.compose.ui)
implementation(libs.compose.components.resources)
implementation(libs.compose.uiToolingPreview)
// Lifecycle
@@ -9,8 +9,7 @@ import fr.ajaury.gwenedeg.preferences.domain.PreferencesRepository
import fr.ajaury.gwenedeg.records.data.InMemoryRecordRepository
import fr.ajaury.gwenedeg.records.domain.RecordRepository
import fr.ajaury.gwenedeg.records.ui.viewmodel.RecordsViewModel
import fr.ajaury.gwenedeg.resourcereader.data.ComposeResourceReader
import fr.ajaury.gwenedeg.resourcereader.data.domain.ResourceReader
import fr.ajaury.gwenedeg.resources.di.resourcesModule
import org.koin.core.module.dsl.bind
import org.koin.core.module.dsl.factoryOf
import org.koin.core.module.dsl.singleOf
@@ -19,10 +18,10 @@ import org.koin.dsl.module
val sharedModule = module {
includes(loggingModule)
includes(resourcesModule)
factoryOf(::InMemoryRecordRepository) { bind<RecordRepository>() }
singleOf(::PlaybackRepositoryImpl) { bind<PlaybackRepository>() }
singleOf(::PreferencesRepositoryImpl) { bind<PreferencesRepository>() }
viewModelOf(::RecordsViewModel)
viewModelOf(::PlayerViewModel)
factoryOf(::ComposeResourceReader) { bind<ResourceReader>() }
}
@@ -8,11 +8,10 @@ import fr.ajaury.gwenedeg.player.domain.PlaybackRepository
import fr.ajaury.gwenedeg.player.model.PlaybackState
import fr.ajaury.gwenedeg.player.model.PlaybackTiming
import fr.ajaury.gwenedeg.player.model.PlayerState
import fr.ajaury.gwenedeg.resourcereader.data.domain.ResourceReader
import fr.ajaury.gwenedeg.resources.domain.ResourceReader
import fr.ajaury.gwenedeg.subtitle.domain.GetCurrentSubtitleIndexUseCase
import fr.ajaury.gwenedeg.subtitle.domain.SubtitleRepository
import fr.ajaury.gwenedeg.subtitle.model.Subtitle
import gwenedeg.shared.generated.resources.Res
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
@@ -96,7 +95,7 @@ internal class PlaybackRepositoryImpl(
private fun playAudio(filePath: String) {
try {
audioPlayer.load(uri = Res.getUri(filePath))
audioPlayer.load(uri = resourceReader.uri(filePath))
audioPlayer.play()
} catch (exception: Exception) {
logger.error(message = "Failed to play audio: $filePath", throwable = exception)
@@ -1,9 +0,0 @@
package fr.ajaury.gwenedeg.resourcereader.data.domain
/**
* Reads the raw text of a subtitle file. Implemented by the host app, which owns the resource
* bundle, so this module stays free of any platform/resource dependency.
*/
interface ResourceReader {
suspend fun read(resourcePath: String): String
}