diff --git a/core/accessibility/build.gradle.kts b/core/accessibility/build.gradle.kts new file mode 100644 index 0000000..6f1670e --- /dev/null +++ b/core/accessibility/build.gradle.kts @@ -0,0 +1,9 @@ +plugins { + id("gwenedeg.kmp.library") +} + +kotlin { + androidLibrary { + namespace = "bzh.ajaury.chombev.core.accessibility" + } +} diff --git a/core/accessibility/src/androidMain/kotlin/bzh/ajaury/chombev/core/accessibility/data/AndroidAccessibilityRepository.kt b/core/accessibility/src/androidMain/kotlin/bzh/ajaury/chombev/core/accessibility/data/AndroidAccessibilityRepository.kt new file mode 100644 index 0000000..31ae11f --- /dev/null +++ b/core/accessibility/src/androidMain/kotlin/bzh/ajaury/chombev/core/accessibility/data/AndroidAccessibilityRepository.kt @@ -0,0 +1,15 @@ +package bzh.ajaury.chombev.core.accessibility.data + +import android.content.Context +import android.view.accessibility.AccessibilityManager +import bzh.ajaury.chombev.core.accessibility.domain.AccessibilityRepository + +internal class AndroidAccessibilityRepository( + context: Context, +) : AccessibilityRepository { + private val accessibilityManager = context.getSystemService(AccessibilityManager::class.java) + + // Screen readers such as TalkBack turn on touch exploration. Other accessibility services + // (password managers, automation tools) do not, so `isEnabled` alone would misreport them. + override fun isScreenReaderEnabled(): Boolean = accessibilityManager?.isTouchExplorationEnabled == true +} diff --git a/core/accessibility/src/androidMain/kotlin/bzh/ajaury/chombev/core/accessibility/di/AccessibilityModule.android.kt b/core/accessibility/src/androidMain/kotlin/bzh/ajaury/chombev/core/accessibility/di/AccessibilityModule.android.kt new file mode 100644 index 0000000..f5f4b4d --- /dev/null +++ b/core/accessibility/src/androidMain/kotlin/bzh/ajaury/chombev/core/accessibility/di/AccessibilityModule.android.kt @@ -0,0 +1,12 @@ +package bzh.ajaury.chombev.core.accessibility.di + +import bzh.ajaury.chombev.core.accessibility.data.AndroidAccessibilityRepository +import bzh.ajaury.chombev.core.accessibility.domain.AccessibilityRepository +import org.koin.core.module.Module +import org.koin.core.module.dsl.bind +import org.koin.core.module.dsl.singleOf +import org.koin.dsl.module + +actual val accessibilityModule: Module = module { + singleOf(::AndroidAccessibilityRepository) { bind() } +} diff --git a/core/accessibility/src/commonMain/kotlin/bzh/ajaury/chombev/core/accessibility/data/UndetectableAccessibilityRepository.kt b/core/accessibility/src/commonMain/kotlin/bzh/ajaury/chombev/core/accessibility/data/UndetectableAccessibilityRepository.kt new file mode 100644 index 0000000..63fdc89 --- /dev/null +++ b/core/accessibility/src/commonMain/kotlin/bzh/ajaury/chombev/core/accessibility/data/UndetectableAccessibilityRepository.kt @@ -0,0 +1,7 @@ +package bzh.ajaury.chombev.core.accessibility.data + +import bzh.ajaury.chombev.core.accessibility.domain.AccessibilityRepository + +internal class UndetectableAccessibilityRepository : AccessibilityRepository { + override fun isScreenReaderEnabled(): Boolean = false +} diff --git a/core/accessibility/src/commonMain/kotlin/bzh/ajaury/chombev/core/accessibility/di/AccessibilityModule.kt b/core/accessibility/src/commonMain/kotlin/bzh/ajaury/chombev/core/accessibility/di/AccessibilityModule.kt new file mode 100644 index 0000000..1665e68 --- /dev/null +++ b/core/accessibility/src/commonMain/kotlin/bzh/ajaury/chombev/core/accessibility/di/AccessibilityModule.kt @@ -0,0 +1,5 @@ +package bzh.ajaury.chombev.core.accessibility.di + +import org.koin.core.module.Module + +expect val accessibilityModule: Module diff --git a/core/accessibility/src/commonMain/kotlin/bzh/ajaury/chombev/core/accessibility/domain/AccessibilityRepository.kt b/core/accessibility/src/commonMain/kotlin/bzh/ajaury/chombev/core/accessibility/domain/AccessibilityRepository.kt new file mode 100644 index 0000000..129e24d --- /dev/null +++ b/core/accessibility/src/commonMain/kotlin/bzh/ajaury/chombev/core/accessibility/domain/AccessibilityRepository.kt @@ -0,0 +1,5 @@ +package bzh.ajaury.chombev.core.accessibility.domain + +interface AccessibilityRepository { + fun isScreenReaderEnabled(): Boolean +} diff --git a/core/accessibility/src/iosMain/kotlin/bzh/ajaury/chombev/core/accessibility/data/IosAccessibilityRepository.kt b/core/accessibility/src/iosMain/kotlin/bzh/ajaury/chombev/core/accessibility/data/IosAccessibilityRepository.kt new file mode 100644 index 0000000..d3367f7 --- /dev/null +++ b/core/accessibility/src/iosMain/kotlin/bzh/ajaury/chombev/core/accessibility/data/IosAccessibilityRepository.kt @@ -0,0 +1,8 @@ +package bzh.ajaury.chombev.core.accessibility.data + +import bzh.ajaury.chombev.core.accessibility.domain.AccessibilityRepository +import platform.UIKit.UIAccessibilityIsVoiceOverRunning + +internal class IosAccessibilityRepository : AccessibilityRepository { + override fun isScreenReaderEnabled(): Boolean = UIAccessibilityIsVoiceOverRunning() +} diff --git a/core/accessibility/src/iosMain/kotlin/bzh/ajaury/chombev/core/accessibility/di/AccessibilityModule.ios.kt b/core/accessibility/src/iosMain/kotlin/bzh/ajaury/chombev/core/accessibility/di/AccessibilityModule.ios.kt new file mode 100644 index 0000000..a668785 --- /dev/null +++ b/core/accessibility/src/iosMain/kotlin/bzh/ajaury/chombev/core/accessibility/di/AccessibilityModule.ios.kt @@ -0,0 +1,12 @@ +package bzh.ajaury.chombev.core.accessibility.di + +import bzh.ajaury.chombev.core.accessibility.data.IosAccessibilityRepository +import bzh.ajaury.chombev.core.accessibility.domain.AccessibilityRepository +import org.koin.core.module.Module +import org.koin.core.module.dsl.bind +import org.koin.core.module.dsl.singleOf +import org.koin.dsl.module + +actual val accessibilityModule: Module = module { + singleOf(::IosAccessibilityRepository) { bind() } +} diff --git a/core/accessibility/src/jvmMain/kotlin/bzh/ajaury/chombev/core/accessibility/di/AccessibilityModule.jvm.kt b/core/accessibility/src/jvmMain/kotlin/bzh/ajaury/chombev/core/accessibility/di/AccessibilityModule.jvm.kt new file mode 100644 index 0000000..4b4a3d0 --- /dev/null +++ b/core/accessibility/src/jvmMain/kotlin/bzh/ajaury/chombev/core/accessibility/di/AccessibilityModule.jvm.kt @@ -0,0 +1,12 @@ +package bzh.ajaury.chombev.core.accessibility.di + +import bzh.ajaury.chombev.core.accessibility.data.UndetectableAccessibilityRepository +import bzh.ajaury.chombev.core.accessibility.domain.AccessibilityRepository +import org.koin.core.module.Module +import org.koin.core.module.dsl.bind +import org.koin.core.module.dsl.singleOf +import org.koin.dsl.module + +actual val accessibilityModule: Module = module { + singleOf(::UndetectableAccessibilityRepository) { bind() } +} diff --git a/core/accessibility/src/webMain/kotlin/bzh/ajaury/chombev/core/accessibility/di/AccessibilityModule.web.kt b/core/accessibility/src/webMain/kotlin/bzh/ajaury/chombev/core/accessibility/di/AccessibilityModule.web.kt new file mode 100644 index 0000000..4b4a3d0 --- /dev/null +++ b/core/accessibility/src/webMain/kotlin/bzh/ajaury/chombev/core/accessibility/di/AccessibilityModule.web.kt @@ -0,0 +1,12 @@ +package bzh.ajaury.chombev.core.accessibility.di + +import bzh.ajaury.chombev.core.accessibility.data.UndetectableAccessibilityRepository +import bzh.ajaury.chombev.core.accessibility.domain.AccessibilityRepository +import org.koin.core.module.Module +import org.koin.core.module.dsl.bind +import org.koin.core.module.dsl.singleOf +import org.koin.dsl.module + +actual val accessibilityModule: Module = module { + singleOf(::UndetectableAccessibilityRepository) { bind() } +} diff --git a/data/playback/src/commonMain/kotlin/bzh/ajaury/chombev/player/data/PlaybackRepositoryImpl.kt b/data/playback/src/commonMain/kotlin/bzh/ajaury/chombev/player/data/PlaybackRepositoryImpl.kt index 38c3ac9..4273702 100644 --- a/data/playback/src/commonMain/kotlin/bzh/ajaury/chombev/player/data/PlaybackRepositoryImpl.kt +++ b/data/playback/src/commonMain/kotlin/bzh/ajaury/chombev/player/data/PlaybackRepositoryImpl.kt @@ -138,13 +138,16 @@ internal class PlaybackRepositoryImpl( ) } - override suspend fun load(record: Record) { + override suspend fun load( + record: Record, + autoPlay: Boolean, + ) { phraseBreakJob?.cancel() cancelRunningBreak() pendingPhraseStart = null pendingSeekTarget = null - playAudio(filePath = record.audioResourcePath) + loadAudio(filePath = record.audioResourcePath, autoPlay = autoPlay) subtitle.value = loadSubtitle(record = record) reachedPhraseIndex = upcomingPhraseIndex(position = Duration.ZERO) recordTitle.value = record.title @@ -264,12 +267,15 @@ internal class PlaybackRepositoryImpl( audioPlayer.seekTo(position) } - private fun playAudio(filePath: String) { + private fun loadAudio( + filePath: String, + autoPlay: Boolean, + ) { try { audioPlayer.load(uri = resourceReader.uri(filePath)) - audioPlayer.play() + if (autoPlay) audioPlayer.play() } catch (exception: Exception) { - logger.error(message = "Failed to play audio: $filePath", throwable = exception) + logger.error(message = "Failed to load audio: $filePath", throwable = exception) } } diff --git a/data/playback/src/commonMain/kotlin/bzh/ajaury/chombev/player/domain/PlaybackRepository.kt b/data/playback/src/commonMain/kotlin/bzh/ajaury/chombev/player/domain/PlaybackRepository.kt index be21d80..c75da92 100644 --- a/data/playback/src/commonMain/kotlin/bzh/ajaury/chombev/player/domain/PlaybackRepository.kt +++ b/data/playback/src/commonMain/kotlin/bzh/ajaury/chombev/player/domain/PlaybackRepository.kt @@ -15,7 +15,10 @@ import kotlin.time.Duration interface PlaybackRepository { val playerState: Flow - suspend fun load(record: Record) + suspend fun load( + record: Record, + autoPlay: Boolean = true, + ) suspend fun play() diff --git a/data/resources/src/commonMain/composeResources/values/strings.xml b/data/resources/src/commonMain/composeResources/values/strings.xml index 8f52320..cc1df06 100644 --- a/data/resources/src/commonMain/composeResources/values/strings.xml +++ b/data/resources/src/commonMain/composeResources/values/strings.xml @@ -11,6 +11,7 @@ Sous-titres Préférences de sous-titrage + accéder aux paramètres Transcription (BZH) Afficher la transcription bretonne Traduction (FR) @@ -48,6 +49,7 @@ Chapitre %1$d Retour + revenir à la liste des contenus Phrase précédente Phrase suivante Lire diff --git a/feature/records/build.gradle.kts b/feature/records/build.gradle.kts index dedf59d..5e74eb2 100644 --- a/feature/records/build.gradle.kts +++ b/feature/records/build.gradle.kts @@ -14,6 +14,7 @@ kotlin { } commonMain.dependencies { // Core modules + implementation(projects.core.accessibility) implementation(projects.core.model) implementation(projects.core.logging) implementation(projects.core.audioplayer) diff --git a/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/PlayerScreen.kt b/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/PlayerScreen.kt index d3b4a40..90ec8a5 100644 --- a/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/PlayerScreen.kt +++ b/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/PlayerScreen.kt @@ -30,6 +30,10 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.shadow +import androidx.compose.ui.semantics.clearAndSetSemantics +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.onClick +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -43,6 +47,8 @@ import bzh.ajaury.chombev.player.ui.viewmodel.PlayerViewModel import bzh.ajaury.chombev.preferences.ui.SubtitlePreferencesBottomSheet import bzh.ajaury.chombev.resources.generated.resources.Res import bzh.ajaury.chombev.resources.generated.resources.player_back +import bzh.ajaury.chombev.resources.generated.resources.player_back_action_label +import bzh.ajaury.chombev.resources.generated.resources.settings_open_action_description import bzh.ajaury.chombev.resources.generated.resources.subtitle_preferences_action import bzh.ajaury.chombev.subtitle.model.SubtitleLine import org.jetbrains.compose.resources.stringResource @@ -198,6 +204,9 @@ private fun PlayerTopBar( label = "PlayerTitle", ) { (emoji, title) -> Row( + modifier = Modifier.clearAndSetSemantics { + contentDescription = title.translation ?: title.transcription + }, verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp), ) { @@ -227,15 +236,20 @@ private fun PlayerTopBar( } }, navigationIcon = { - IconButton(onClick = onBackClicked) { - Icon( - imageVector = Icons.AutoMirrored.Filled.ArrowBack, - contentDescription = stringResource(Res.string.player_back), - ) - } + BackButton(onBackClicked = onBackClicked) }, actions = { - IconButton(onClick = showPreferences) { + val openSettingsLabel = stringResource(Res.string.settings_open_action_description) + IconButton( + // Names the action: "double-tap to open settings" rather than the generic "to activate". + modifier = Modifier.semantics { + onClick(label = openSettingsLabel) { + showPreferences() + true + } + }, + onClick = showPreferences, + ) { Icon( imageVector = Icons.Filled.Subtitles, contentDescription = stringResource(Res.string.subtitle_preferences_action), @@ -245,6 +259,26 @@ private fun PlayerTopBar( ) } +@Composable +private fun BackButton(onBackClicked: () -> Unit) { + val backActionLabel = stringResource(Res.string.player_back_action_label) + IconButton( + onClick = onBackClicked, + modifier = Modifier + .semantics { + onClick(label = backActionLabel) { + onBackClicked() + true + } + }, + ) { + Icon( + imageVector = Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = stringResource(Res.string.player_back), + ) + } +} + private val previewSubtitleLines = listOf( SubtitleLine( diff --git a/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/SubtitleList.kt b/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/SubtitleList.kt index be11d2e..197cffa 100644 --- a/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/SubtitleList.kt +++ b/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/SubtitleList.kt @@ -29,6 +29,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.semantics.clearAndSetSemantics import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview @@ -97,7 +98,9 @@ fun SubtitleList( } val density = LocalDensity.current - BoxWithConstraints(modifier = modifier) { + // Subtitles transcribe the audio being played: hide them from screen readers, which would + // otherwise read the same phrases a second time. + BoxWithConstraints(modifier = modifier.clearAndSetSemantics {}) { // Half-height padding so the first and last lines can reach the vertical center. Captured here // because `maxHeight` (BoxWithConstraintsScope) is not in scope inside the provider lambda. val verticalPadding = maxHeight / 2 diff --git a/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/components/NextButton.kt b/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/components/NextButton.kt index 59e7e77..8da8681 100644 --- a/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/components/NextButton.kt +++ b/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/components/NextButton.kt @@ -17,10 +17,11 @@ import org.jetbrains.compose.resources.stringResource @Composable fun NextButton( canGoToNextSentence: Boolean, + modifier: Modifier = Modifier, onNextSentenceClicked: () -> Unit = {}, ) { IconButton( - modifier = Modifier.size(60.dp), + modifier = modifier.size(60.dp), enabled = canGoToNextSentence, onClick = onNextSentenceClicked, ) { diff --git a/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/components/PlayButton.kt b/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/components/PlayButton.kt index 3817864..5662f0a 100644 --- a/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/components/PlayButton.kt +++ b/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/components/PlayButton.kt @@ -38,6 +38,7 @@ private val BreakRingSize = 68.dp fun PlayButton( playbackState: PlaybackState, breakDuration: Duration = Duration.ZERO, + modifier: Modifier = Modifier, onMainPlayActionButtonClicked: () -> Unit = {}, ) { val isBreaking = playbackState == PlaybackState.BREAKING && breakDuration > Duration.ZERO @@ -61,7 +62,7 @@ fun PlayButton( // The ring reserves its footprint at all times so the transport row does not jump when a break // starts; the indicator itself is only drawn while breaking. Box( - modifier = Modifier.size(BreakRingSize), + modifier = modifier.size(BreakRingSize), contentAlignment = Alignment.Center, ) { if (isBreaking) { diff --git a/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/components/PlaybackProgress.kt b/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/components/PlaybackProgress.kt index 295a28f..b6e31af 100644 --- a/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/components/PlaybackProgress.kt +++ b/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/components/PlaybackProgress.kt @@ -9,6 +9,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.semantics.clearAndSetSemantics import androidx.compose.ui.tooling.preview.Preview import bzh.ajaury.chombev.player.model.PlaybackTiming import kotlin.time.Duration @@ -33,7 +34,9 @@ fun PlaybackProgress( } seekProgress = null }, - modifier = Modifier.fillMaxWidth(), + modifier = Modifier + .fillMaxWidth() + .clearAndSetSemantics { }, ) } diff --git a/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/components/PreviousButton.kt b/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/components/PreviousButton.kt index bcde2c3..bf54d90 100644 --- a/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/components/PreviousButton.kt +++ b/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/components/PreviousButton.kt @@ -17,10 +17,11 @@ import org.jetbrains.compose.resources.stringResource @Composable fun PreviousButton( canGoToPreviousSentence: Boolean, + modifier: Modifier = Modifier, onPreviousSentenceClicked: () -> Unit = {}, ) { IconButton( - modifier = Modifier.size(60.dp), + modifier = modifier.size(60.dp), enabled = canGoToPreviousSentence, onClick = onPreviousSentenceClicked, ) { diff --git a/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/components/SpeedPreferenceButton.kt b/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/components/SpeedPreferenceButton.kt index 44529b9..10221cc 100644 --- a/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/components/SpeedPreferenceButton.kt +++ b/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/components/SpeedPreferenceButton.kt @@ -9,10 +9,13 @@ import androidx.compose.material3.LocalContentColor import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.semantics.onClick +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import bzh.ajaury.chombev.resources.generated.resources.Res import bzh.ajaury.chombev.resources.generated.resources.playback_settings_action +import bzh.ajaury.chombev.resources.generated.resources.settings_open_action_description import org.jetbrains.compose.resources.stringResource /** @@ -22,10 +25,19 @@ import org.jetbrains.compose.resources.stringResource @Composable fun SpeedPreferenceButton( isActive: Boolean, + modifier: Modifier = Modifier, onSpeedClicked: () -> Unit = {}, ) { + val openSettingsLabel = stringResource(Res.string.settings_open_action_description) IconButton( - modifier = Modifier.size(60.dp), + modifier = modifier + .size(60.dp) + .semantics { + onClick(label = openSettingsLabel) { + onSpeedClicked() + true + } + }, onClick = onSpeedClicked, ) { Icon( diff --git a/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/viewmodel/PlayerViewModel.kt b/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/viewmodel/PlayerViewModel.kt index 25b4a2d..bd2dddb 100644 --- a/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/viewmodel/PlayerViewModel.kt +++ b/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/player/ui/viewmodel/PlayerViewModel.kt @@ -2,6 +2,7 @@ package bzh.ajaury.chombev.player.ui.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import bzh.ajaury.chombev.core.accessibility.domain.AccessibilityRepository import bzh.ajaury.chombev.core.logging.domain.Logger import bzh.ajaury.chombev.core.model.Phrase import bzh.ajaury.chombev.core.model.Record @@ -29,6 +30,7 @@ class PlayerViewModel( private val playbackRepository: PlaybackRepository, private val preferencesRepository: PreferencesRepository, private val audioSessionManager: AudioSessionManager, + private val accessibilityRepository: AccessibilityRepository, private val logger: Logger, ) : ViewModel() { private val record = MutableStateFlow(null) @@ -62,11 +64,14 @@ class PlayerViewModel( viewModelScope.launch { playbackRepository.stop() + // A screen reader speaks over the audio: let its user start playback once oriented. + val autoPlay = !accessibilityRepository.isScreenReaderEnabled() + logger.debug("Loading record $recordId") val alreadyLoadedRecord = record.value if (alreadyLoadedRecord != null) { logger.debug("Record $recordId already loaded") - playbackRepository.load(record = alreadyLoadedRecord) + playbackRepository.load(record = alreadyLoadedRecord, autoPlay = autoPlay) return@launch } @@ -76,7 +81,7 @@ class PlayerViewModel( return@launch } - playbackRepository.load(record = loadedRecord) + playbackRepository.load(record = loadedRecord, autoPlay = autoPlay) record.value = loadedRecord } } diff --git a/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/records/ui/di/RecordsFeatureModule.kt b/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/records/ui/di/RecordsFeatureModule.kt index 855dd83..2d12597 100644 --- a/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/records/ui/di/RecordsFeatureModule.kt +++ b/feature/records/src/commonMain/kotlin/bzh/ajaury/chombev/records/ui/di/RecordsFeatureModule.kt @@ -1,5 +1,6 @@ package bzh.ajaury.chombev.records.ui.di +import bzh.ajaury.chombev.core.accessibility.di.accessibilityModule import bzh.ajaury.chombev.player.di.audioPlayerModule import bzh.ajaury.chombev.player.di.playbackModule import bzh.ajaury.chombev.player.ui.viewmodel.PlayerViewModel @@ -23,6 +24,7 @@ val recordsFeatureModule: Module = module { recordsModule, resourcesModule, audioPlayerModule, + accessibilityModule, subtitleModule, ) diff --git a/settings.gradle.kts b/settings.gradle.kts index e25a9e3..f43a527 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -39,6 +39,7 @@ include(":webApp") include(":shared") // Core modules +include(":core:accessibility") include(":core:audioplayer") include(":core:coroutines") include(":core:logging")