new: extract Records feature module

This commit is contained in:
2026-07-08 14:44:55 +02:00
parent 0151d92b6a
commit 6a10c0c510
33 changed files with 138 additions and 81 deletions
@@ -1,6 +1,4 @@
package bzh.ajaury.chombev.records.model package bzh.ajaury.chombev.core.model
import bzh.ajaury.chombev.core.model.Phrase
data class Record( data class Record(
val id: Int, val id: Int,
@@ -3,13 +3,13 @@ package bzh.ajaury.chombev.player.data
import bzh.ajaury.chombev.core.coroutines.domain.DispatcherProvider import bzh.ajaury.chombev.core.coroutines.domain.DispatcherProvider
import bzh.ajaury.chombev.core.logging.domain.Logger import bzh.ajaury.chombev.core.logging.domain.Logger
import bzh.ajaury.chombev.core.model.Phrase import bzh.ajaury.chombev.core.model.Phrase
import bzh.ajaury.chombev.core.model.Record
import bzh.ajaury.chombev.player.domain.AudioPlayer import bzh.ajaury.chombev.player.domain.AudioPlayer
import bzh.ajaury.chombev.player.domain.PlaybackRepository import bzh.ajaury.chombev.player.domain.PlaybackRepository
import bzh.ajaury.chombev.player.model.PlaybackState import bzh.ajaury.chombev.player.model.PlaybackState
import bzh.ajaury.chombev.player.model.PlaybackTiming import bzh.ajaury.chombev.player.model.PlaybackTiming
import bzh.ajaury.chombev.player.model.PlayerState import bzh.ajaury.chombev.player.model.PlayerState
import bzh.ajaury.chombev.preferences.domain.PreferencesRepository import bzh.ajaury.chombev.preferences.domain.PreferencesRepository
import bzh.ajaury.chombev.records.model.Record
import bzh.ajaury.chombev.resources.domain.ResourceReader import bzh.ajaury.chombev.resources.domain.ResourceReader
import bzh.ajaury.chombev.subtitle.domain.GetCurrentSubtitleIndexUseCase import bzh.ajaury.chombev.subtitle.domain.GetCurrentSubtitleIndexUseCase
import bzh.ajaury.chombev.subtitle.domain.SubtitleRepository import bzh.ajaury.chombev.subtitle.domain.SubtitleRepository
@@ -1,7 +1,7 @@
package bzh.ajaury.chombev.player.domain package bzh.ajaury.chombev.player.domain
import bzh.ajaury.chombev.core.model.Record
import bzh.ajaury.chombev.player.model.PlayerState import bzh.ajaury.chombev.player.model.PlayerState
import bzh.ajaury.chombev.records.model.Record
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlin.time.Duration import kotlin.time.Duration
+1 -1
View File
@@ -5,7 +5,7 @@ plugins {
kotlin { kotlin {
androidLibrary { androidLibrary {
namespace = "bzh.ajaury.chombev.records" namespace = "bzh.ajaury.chombev.records.data"
} }
sourceSets { sourceSets {
@@ -2,10 +2,10 @@ package bzh.ajaury.chombev.records.data
import bzh.ajaury.chombev.core.coroutines.domain.DispatcherProvider import bzh.ajaury.chombev.core.coroutines.domain.DispatcherProvider
import bzh.ajaury.chombev.core.logging.domain.Logger import bzh.ajaury.chombev.core.logging.domain.Logger
import bzh.ajaury.chombev.core.model.Record
import bzh.ajaury.chombev.records.data.local.model.RecordDataModel import bzh.ajaury.chombev.records.data.local.model.RecordDataModel
import bzh.ajaury.chombev.records.data.mappers.RecordMapper import bzh.ajaury.chombev.records.data.mappers.RecordMapper
import bzh.ajaury.chombev.records.domain.RecordRepository import bzh.ajaury.chombev.records.domain.RecordRepository
import bzh.ajaury.chombev.records.model.Record
import bzh.ajaury.chombev.resources.domain.ResourceReader import bzh.ajaury.chombev.resources.domain.ResourceReader
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
@@ -5,7 +5,7 @@ import kotlinx.serialization.Serializable
/** /**
* A single record entry as stored in the un-versioned `files/records.json` data file. * A single record entry as stored in the un-versioned `files/records.json` data file.
* *
* This mirrors the JSON schema exactly; it is mapped to the domain [bzh.ajaury.chombev.records.model.Record] * This mirrors the JSON schema exactly; it is mapped to the domain [bzh.ajaury.chombev.core.model.Record]
* by [bzh.ajaury.chombev.records.data.mappers.RecordMapper]. * by [bzh.ajaury.chombev.records.data.mappers.RecordMapper].
*/ */
@Serializable @Serializable
@@ -1,8 +1,8 @@
package bzh.ajaury.chombev.records.data.mappers package bzh.ajaury.chombev.records.data.mappers
import bzh.ajaury.chombev.core.model.Phrase import bzh.ajaury.chombev.core.model.Phrase
import bzh.ajaury.chombev.core.model.Record
import bzh.ajaury.chombev.records.data.local.model.RecordDataModel import bzh.ajaury.chombev.records.data.local.model.RecordDataModel
import bzh.ajaury.chombev.records.model.Record
/** /**
* Maps the serialized [RecordDataModel]s from the data file to domain [Record]s, assigning a * Maps the serialized [RecordDataModel]s from the data file to domain [Record]s, assigning a
@@ -1,6 +1,6 @@
package bzh.ajaury.chombev.records.domain package bzh.ajaury.chombev.records.domain
import bzh.ajaury.chombev.records.model.Record import bzh.ajaury.chombev.core.model.Record
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
interface RecordRepository { interface RecordRepository {
+52
View File
@@ -0,0 +1,52 @@
plugins {
id("gwenedeg.kmp.library")
id("gwenedeg.compose")
}
kotlin {
androidLibrary {
namespace = "bzh.ajaury.chombev.records"
}
sourceSets {
androidMain.dependencies {
implementation(libs.compose.uiToolingPreview)
}
commonMain.dependencies {
// Core modules
implementation(projects.core.model)
implementation(projects.core.logging)
implementation(projects.core.audioplayer)
// Data modules
implementation(projects.data.playback)
implementation(projects.data.preferences)
implementation(projects.data.records)
implementation(projects.data.subtitle)
implementation(projects.data.resources)
// UI - Compose
implementation(libs.compose.runtime)
implementation(libs.compose.foundation)
implementation(libs.compose.material3)
implementation(libs.compose.material.icons.extended)
implementation(libs.compose.ui)
implementation(libs.compose.uiToolingPreview)
implementation(libs.compose.components.resources)
// Lifecycle
implementation(libs.lifecycle.viewmodelCompose)
implementation(libs.lifecycle.runtimeCompose)
// DI
implementation(project.dependencies.platform(libs.koin.bom))
implementation(libs.koin.core)
implementation(libs.koin.core.viewmodel)
implementation(libs.koin.compose.viewmodel)
}
}
}
dependencies {
androidRuntimeClasspath(libs.compose.uiTooling)
}
@@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.SheetState import androidx.compose.material3.SheetState
import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.material3.rememberModalBottomSheetState
@@ -18,7 +19,6 @@ import bzh.ajaury.chombev.resources.generated.resources.Res
import bzh.ajaury.chombev.resources.generated.resources.break_between_phrases_title import bzh.ajaury.chombev.resources.generated.resources.break_between_phrases_title
import bzh.ajaury.chombev.resources.generated.resources.break_between_phrases_value import bzh.ajaury.chombev.resources.generated.resources.break_between_phrases_value
import bzh.ajaury.chombev.resources.generated.resources.playback_speed_title import bzh.ajaury.chombev.resources.generated.resources.playback_speed_title
import bzh.ajaury.chombev.theme.ChomBevTheme
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import kotlin.math.roundToInt import kotlin.math.roundToInt
@@ -102,7 +102,7 @@ internal fun formatPlaybackSpeed(speed: Float): String {
@Preview @Preview
@Composable @Composable
private fun PlaybackSpeedContentPreview() { private fun PlaybackSpeedContentPreview() {
ChomBevTheme { MaterialTheme {
PlaybackSpeedContent( PlaybackSpeedContent(
speed = 0.7f, speed = 0.7f,
breakSeconds = 2f, breakSeconds = 2f,
@@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@@ -18,7 +19,6 @@ import bzh.ajaury.chombev.player.ui.components.PlayButton
import bzh.ajaury.chombev.player.ui.components.PlaybackProgress import bzh.ajaury.chombev.player.ui.components.PlaybackProgress
import bzh.ajaury.chombev.player.ui.components.PreviousButton import bzh.ajaury.chombev.player.ui.components.PreviousButton
import bzh.ajaury.chombev.player.ui.components.SpeedPreferenceButton import bzh.ajaury.chombev.player.ui.components.SpeedPreferenceButton
import bzh.ajaury.chombev.theme.ChomBevTheme
import kotlin.time.Duration import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
@@ -93,7 +93,7 @@ fun PlayerControl(
@Preview @Preview
@Composable @Composable
private fun PlayerControlPreview() { private fun PlayerControlPreview() {
ChomBevTheme { MaterialTheme {
PlayerControl( PlayerControl(
playbackState = PlaybackState.PLAYING, playbackState = PlaybackState.PLAYING,
playbackTiming = PlaybackTiming(position = 1.2.seconds, duration = 5.seconds), playbackTiming = PlaybackTiming(position = 1.2.seconds, duration = 5.seconds),
@@ -108,7 +108,7 @@ private fun PlayerControlPreview() {
@Preview @Preview
@Composable @Composable
private fun PlayerControlFirstSentencePreview() { private fun PlayerControlFirstSentencePreview() {
ChomBevTheme { MaterialTheme {
PlayerControl( PlayerControl(
playbackState = PlaybackState.PLAYING, playbackState = PlaybackState.PLAYING,
playbackTiming = PlaybackTiming(position = 1.2.seconds, duration = 5.seconds), playbackTiming = PlaybackTiming(position = 1.2.seconds, duration = 5.seconds),
@@ -123,7 +123,7 @@ private fun PlayerControlFirstSentencePreview() {
@Preview @Preview
@Composable @Composable
private fun PlayerControlActiveSpeedPreview() { private fun PlayerControlActiveSpeedPreview() {
ChomBevTheme { MaterialTheme {
PlayerControl( PlayerControl(
playbackState = PlaybackState.PLAYING, playbackState = PlaybackState.PLAYING,
playbackTiming = PlaybackTiming(position = 1.2.seconds, duration = 5.seconds), playbackTiming = PlaybackTiming(position = 1.2.seconds, duration = 5.seconds),
@@ -138,7 +138,7 @@ private fun PlayerControlActiveSpeedPreview() {
@Preview @Preview
@Composable @Composable
private fun PlayerControlLastSentencePreview() { private fun PlayerControlLastSentencePreview() {
ChomBevTheme { MaterialTheme {
PlayerControl( PlayerControl(
playbackState = PlaybackState.PLAYING, playbackState = PlaybackState.PLAYING,
playbackTiming = PlaybackTiming(position = 1.2.seconds, duration = 5.seconds), playbackTiming = PlaybackTiming(position = 1.2.seconds, duration = 5.seconds),
@@ -39,7 +39,6 @@ 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
import bzh.ajaury.chombev.resources.generated.resources.subtitle_preferences_action import bzh.ajaury.chombev.resources.generated.resources.subtitle_preferences_action
import bzh.ajaury.chombev.subtitle.model.SubtitleLine import bzh.ajaury.chombev.subtitle.model.SubtitleLine
import bzh.ajaury.chombev.theme.ChomBevTheme
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel import org.koin.compose.viewmodel.koinViewModel
import org.koin.core.parameter.parametersOf import org.koin.core.parameter.parametersOf
@@ -239,7 +238,7 @@ private val previewSubtitleLines =
@Preview @Preview
@Composable @Composable
private fun PlayerScreenPlayingPreview() { private fun PlayerScreenPlayingPreview() {
ChomBevTheme { MaterialTheme {
PlayerScreen( PlayerScreen(
uiState = PlayerUiState( uiState = PlayerUiState(
recordEmoji = "🙏", recordEmoji = "🙏",
@@ -264,7 +263,7 @@ private fun PlayerScreenPlayingPreview() {
@Preview @Preview
@Composable @Composable
private fun PlayerScreenPausedPreview() { private fun PlayerScreenPausedPreview() {
ChomBevTheme { MaterialTheme {
PlayerScreen( PlayerScreen(
uiState = PlayerUiState( uiState = PlayerUiState(
recordEmoji = "🙏", recordEmoji = "🙏",
@@ -289,7 +288,7 @@ private fun PlayerScreenPausedPreview() {
@Preview @Preview
@Composable @Composable
private fun PlayerScreenEndedPreview() { private fun PlayerScreenEndedPreview() {
ChomBevTheme { MaterialTheme {
PlayerScreen( PlayerScreen(
uiState = PlayerUiState( uiState = PlayerUiState(
recordEmoji = "🙏", recordEmoji = "🙏",
@@ -39,7 +39,6 @@ import bzh.ajaury.chombev.core.model.Phrase
import bzh.ajaury.chombev.player.ui.components.TranscriptionText import bzh.ajaury.chombev.player.ui.components.TranscriptionText
import bzh.ajaury.chombev.preferences.model.SubtitlePreferences import bzh.ajaury.chombev.preferences.model.SubtitlePreferences
import bzh.ajaury.chombev.subtitle.model.SubtitleLine import bzh.ajaury.chombev.subtitle.model.SubtitleLine
import bzh.ajaury.chombev.theme.ChomBevTheme
import kotlin.math.abs import kotlin.math.abs
import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.milliseconds
@@ -250,7 +249,7 @@ private val previewSubtitleLines =
@Preview @Preview
@Composable @Composable
private fun SubtitleListPreview() { private fun SubtitleListPreview() {
ChomBevTheme { MaterialTheme {
SubtitleList( SubtitleList(
lines = previewSubtitleLines, lines = previewSubtitleLines,
currentIndex = 1, currentIndex = 1,
@@ -12,7 +12,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import bzh.ajaury.chombev.theme.ChomBevTheme
@Composable @Composable
fun LabeledSlider( fun LabeledSlider(
@@ -51,7 +50,7 @@ fun LabeledSlider(
@Preview @Preview
@Composable @Composable
private fun LabeledSliderPreview() { private fun LabeledSliderPreview() {
ChomBevTheme { MaterialTheme {
LabeledSlider( LabeledSlider(
title = "Playback speed", title = "Playback speed",
valueLabel = "x0.7", valueLabel = "x0.7",
@@ -5,13 +5,13 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.SkipNext import androidx.compose.material.icons.filled.SkipNext
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import bzh.ajaury.chombev.resources.generated.resources.Res import bzh.ajaury.chombev.resources.generated.resources.Res
import bzh.ajaury.chombev.resources.generated.resources.player_next_sentence import bzh.ajaury.chombev.resources.generated.resources.player_next_sentence
import bzh.ajaury.chombev.theme.ChomBevTheme
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
@Composable @Composable
@@ -34,7 +34,7 @@ fun NextButton(
@Preview @Preview
@Composable @Composable
private fun NextButtonCanGoToNextSentencePreview() { private fun NextButtonCanGoToNextSentencePreview() {
ChomBevTheme { MaterialTheme {
NextButton( NextButton(
canGoToNextSentence = true, canGoToNextSentence = true,
) )
@@ -44,7 +44,7 @@ private fun NextButtonCanGoToNextSentencePreview() {
@Preview @Preview
@Composable @Composable
private fun NextButtonCanNotGoToNextSentencePreview() { private fun NextButtonCanNotGoToNextSentencePreview() {
ChomBevTheme { MaterialTheme {
NextButton( NextButton(
canGoToNextSentence = false, canGoToNextSentence = false,
) )
@@ -13,6 +13,7 @@ import androidx.compose.material.icons.filled.Replay
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
@@ -26,7 +27,6 @@ import bzh.ajaury.chombev.resources.generated.resources.Res
import bzh.ajaury.chombev.resources.generated.resources.player_pause import bzh.ajaury.chombev.resources.generated.resources.player_pause
import bzh.ajaury.chombev.resources.generated.resources.player_play import bzh.ajaury.chombev.resources.generated.resources.player_play
import bzh.ajaury.chombev.resources.generated.resources.player_replay import bzh.ajaury.chombev.resources.generated.resources.player_replay
import bzh.ajaury.chombev.theme.ChomBevTheme
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import kotlin.time.Duration import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
@@ -103,7 +103,7 @@ private fun PlaybackState.toActionContentDescription(): String =
@Preview @Preview
@Composable @Composable
private fun PlayButtonPlayingPreview() { private fun PlayButtonPlayingPreview() {
ChomBevTheme { MaterialTheme {
PlayButton( PlayButton(
playbackState = PlaybackState.PLAYING, playbackState = PlaybackState.PLAYING,
) )
@@ -113,7 +113,7 @@ private fun PlayButtonPlayingPreview() {
@Preview @Preview
@Composable @Composable
private fun PlayButtonBreakingPreview() { private fun PlayButtonBreakingPreview() {
ChomBevTheme { MaterialTheme {
PlayButton( PlayButton(
playbackState = PlaybackState.BREAKING, playbackState = PlaybackState.BREAKING,
breakDuration = 3.seconds, breakDuration = 3.seconds,
@@ -124,7 +124,7 @@ private fun PlayButtonBreakingPreview() {
@Preview @Preview
@Composable @Composable
private fun PlayButtonPausedPreview() { private fun PlayButtonPausedPreview() {
ChomBevTheme { MaterialTheme {
PlayButton( PlayButton(
playbackState = PlaybackState.PAUSED, playbackState = PlaybackState.PAUSED,
) )
@@ -134,7 +134,7 @@ private fun PlayButtonPausedPreview() {
@Preview @Preview
@Composable @Composable
private fun PlayButtonEndedPreview() { private fun PlayButtonEndedPreview() {
ChomBevTheme { MaterialTheme {
PlayButton( PlayButton(
playbackState = PlaybackState.ENDED, playbackState = PlaybackState.ENDED,
) )
@@ -144,7 +144,7 @@ private fun PlayButtonEndedPreview() {
@Preview @Preview
@Composable @Composable
private fun PlayButtonIdlePreview() { private fun PlayButtonIdlePreview() {
ChomBevTheme { MaterialTheme {
PlayButton( PlayButton(
playbackState = PlaybackState.IDLE, playbackState = PlaybackState.IDLE,
) )
@@ -1,6 +1,7 @@
package bzh.ajaury.chombev.player.ui.components package bzh.ajaury.chombev.player.ui.components
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Slider import androidx.compose.material3.Slider
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
@@ -10,7 +11,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import bzh.ajaury.chombev.player.model.PlaybackTiming import bzh.ajaury.chombev.player.model.PlaybackTiming
import bzh.ajaury.chombev.theme.ChomBevTheme
import kotlin.time.Duration import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
@@ -40,7 +40,7 @@ fun PlaybackProgress(
@Preview @Preview
@Composable @Composable
private fun PlaybackProgressPreview() { private fun PlaybackProgressPreview() {
ChomBevTheme { MaterialTheme {
PlaybackProgress( PlaybackProgress(
playbackTiming = PlaybackTiming(0.seconds, 0.seconds), playbackTiming = PlaybackTiming(0.seconds, 0.seconds),
) )
@@ -50,7 +50,7 @@ private fun PlaybackProgressPreview() {
@Preview @Preview
@Composable @Composable
private fun PlaybackProgressInProgressPreview() { private fun PlaybackProgressInProgressPreview() {
ChomBevTheme { MaterialTheme {
PlaybackProgress( PlaybackProgress(
playbackTiming = PlaybackTiming(7.seconds, 10.seconds), playbackTiming = PlaybackTiming(7.seconds, 10.seconds),
) )
@@ -60,7 +60,7 @@ private fun PlaybackProgressInProgressPreview() {
@Preview @Preview
@Composable @Composable
private fun PlaybackProgressEndedPreview() { private fun PlaybackProgressEndedPreview() {
ChomBevTheme { MaterialTheme {
PlaybackProgress( PlaybackProgress(
playbackTiming = PlaybackTiming(10.seconds, 10.seconds), playbackTiming = PlaybackTiming(10.seconds, 10.seconds),
) )
@@ -5,13 +5,13 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.SkipPrevious import androidx.compose.material.icons.filled.SkipPrevious
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import bzh.ajaury.chombev.resources.generated.resources.Res import bzh.ajaury.chombev.resources.generated.resources.Res
import bzh.ajaury.chombev.resources.generated.resources.player_previous_sentence import bzh.ajaury.chombev.resources.generated.resources.player_previous_sentence
import bzh.ajaury.chombev.theme.ChomBevTheme
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
@Composable @Composable
@@ -34,7 +34,7 @@ fun PreviousButton(
@Preview @Preview
@Composable @Composable
private fun PreviousButtonCanGoToPreviousSentencePreview() { private fun PreviousButtonCanGoToPreviousSentencePreview() {
ChomBevTheme { MaterialTheme {
PreviousButton( PreviousButton(
canGoToPreviousSentence = true, canGoToPreviousSentence = true,
) )
@@ -44,7 +44,7 @@ private fun PreviousButtonCanGoToPreviousSentencePreview() {
@Preview @Preview
@Composable @Composable
private fun PreviousButtonCanNotGoToPreviousSentencePreview() { private fun PreviousButtonCanNotGoToPreviousSentencePreview() {
ChomBevTheme { MaterialTheme {
PreviousButton( PreviousButton(
canGoToPreviousSentence = false, canGoToPreviousSentence = false,
) )
@@ -13,7 +13,6 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import bzh.ajaury.chombev.resources.generated.resources.Res 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.playback_settings_action
import bzh.ajaury.chombev.theme.ChomBevTheme
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
/** /**
@@ -40,7 +39,7 @@ fun SpeedPreferenceButton(
@Preview @Preview
@Composable @Composable
private fun SpeedPreferenceButtonDefaultPreview() { private fun SpeedPreferenceButtonDefaultPreview() {
ChomBevTheme { MaterialTheme {
SpeedPreferenceButton( SpeedPreferenceButton(
isActive = false, isActive = false,
) )
@@ -50,7 +49,7 @@ private fun SpeedPreferenceButtonDefaultPreview() {
@Preview @Preview
@Composable @Composable
private fun SpeedPreferenceButtonActivePreview() { private fun SpeedPreferenceButtonActivePreview() {
ChomBevTheme { MaterialTheme {
SpeedPreferenceButton( SpeedPreferenceButton(
isActive = true, isActive = true,
) )
@@ -28,7 +28,6 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.em import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import bzh.ajaury.chombev.theme.ChomBevTheme
/** /**
* Matches a single letter marked in a transcription, either: * Matches a single letter marked in a transcription, either:
@@ -243,7 +242,7 @@ private fun inlineId(index: Int): String = "marked-letter-$index"
@Preview(backgroundColor = 0xFFFFFFFF) @Preview(backgroundColor = 0xFFFFFFFF)
@Composable @Composable
private fun TranscriptionTextLiaisonPreview() { private fun TranscriptionTextLiaisonPreview() {
ChomBevTheme { MaterialTheme {
TranscriptionText( TranscriptionText(
text = "Tomm eo ma(n) divskouarn, penn ma fri", text = "Tomm eo ma(n) divskouarn, penn ma fri",
color = MaterialTheme.colorScheme.onSurface, color = MaterialTheme.colorScheme.onSurface,
@@ -255,7 +254,7 @@ private fun TranscriptionTextLiaisonPreview() {
@Preview(backgroundColor = 0xFFFFFFFF) @Preview(backgroundColor = 0xFFFFFFFF)
@Composable @Composable
private fun TranscriptionTextBracketPreview() { private fun TranscriptionTextBracketPreview() {
ChomBevTheme { MaterialTheme {
TranscriptionText( TranscriptionText(
text = "Lârit[t] din, mar plij[k] geneoc'h.", text = "Lârit[t] din, mar plij[k] geneoc'h.",
color = MaterialTheme.colorScheme.onSurface, color = MaterialTheme.colorScheme.onSurface,
@@ -267,7 +266,7 @@ private fun TranscriptionTextBracketPreview() {
@Preview(backgroundColor = 0xFFFFFFFF) @Preview(backgroundColor = 0xFFFFFFFF)
@Composable @Composable
private fun LiaisonLetterPreview() { private fun LiaisonLetterPreview() {
ChomBevTheme { MaterialTheme {
LiaisonLetter( LiaisonLetter(
letter = "D", letter = "D",
color = MaterialTheme.colorScheme.onSurface, color = MaterialTheme.colorScheme.onSurface,
@@ -4,6 +4,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import bzh.ajaury.chombev.core.logging.domain.Logger import bzh.ajaury.chombev.core.logging.domain.Logger
import bzh.ajaury.chombev.core.model.Phrase import bzh.ajaury.chombev.core.model.Phrase
import bzh.ajaury.chombev.core.model.Record
import bzh.ajaury.chombev.player.domain.AudioSessionManager import bzh.ajaury.chombev.player.domain.AudioSessionManager
import bzh.ajaury.chombev.player.domain.PlaybackRepository import bzh.ajaury.chombev.player.domain.PlaybackRepository
import bzh.ajaury.chombev.player.model.PlaybackState import bzh.ajaury.chombev.player.model.PlaybackState
@@ -11,7 +12,6 @@ import bzh.ajaury.chombev.preferences.domain.PreferencesRepository
import bzh.ajaury.chombev.preferences.model.PlaybackPreferences import bzh.ajaury.chombev.preferences.model.PlaybackPreferences
import bzh.ajaury.chombev.preferences.model.SubtitlePreferences import bzh.ajaury.chombev.preferences.model.SubtitlePreferences
import bzh.ajaury.chombev.records.domain.RecordRepository import bzh.ajaury.chombev.records.domain.RecordRepository
import bzh.ajaury.chombev.records.model.Record
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
@@ -19,7 +19,6 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.Role
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import bzh.ajaury.chombev.theme.ChomBevTheme
@Composable @Composable
fun PreferenceToggle( fun PreferenceToggle(
@@ -66,7 +65,7 @@ fun PreferenceToggle(
@Preview @Preview
@Composable @Composable
private fun PreferenceTogglePreview() { private fun PreferenceTogglePreview() {
ChomBevTheme { MaterialTheme {
PreferenceToggle( PreferenceToggle(
title = "Subtitle", title = "Subtitle",
subtitle = "Subtitle", subtitle = "Subtitle",
@@ -79,7 +78,7 @@ private fun PreferenceTogglePreview() {
@Preview @Preview
@Composable @Composable
private fun PreferenceToggleWithIconPreview() { private fun PreferenceToggleWithIconPreview() {
ChomBevTheme { MaterialTheme {
PreferenceToggle( PreferenceToggle(
title = "Subtitle", title = "Subtitle",
subtitle = "Subtitle", subtitle = "Subtitle",
@@ -33,7 +33,6 @@ import bzh.ajaury.chombev.resources.generated.resources.subtitle_transcription_d
import bzh.ajaury.chombev.resources.generated.resources.subtitle_transcription_label import bzh.ajaury.chombev.resources.generated.resources.subtitle_transcription_label
import bzh.ajaury.chombev.resources.generated.resources.subtitle_translation_description import bzh.ajaury.chombev.resources.generated.resources.subtitle_translation_description
import bzh.ajaury.chombev.resources.generated.resources.subtitle_translation_label import bzh.ajaury.chombev.resources.generated.resources.subtitle_translation_label
import bzh.ajaury.chombev.theme.ChomBevTheme
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import kotlin.math.roundToInt import kotlin.math.roundToInt
@@ -166,7 +165,7 @@ private fun formatTextScale(scale: Float): String {
@Preview @Preview
@Composable @Composable
private fun SubtitlePreferencesContentPreview() { private fun SubtitlePreferencesContentPreview() {
ChomBevTheme { MaterialTheme {
SubtitlePreferencesContent( SubtitlePreferencesContent(
subtitlePreferences = SubtitlePreferences( subtitlePreferences = SubtitlePreferences(
showTranscription = true, showTranscription = true,
@@ -15,7 +15,7 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import bzh.ajaury.chombev.core.model.Phrase import bzh.ajaury.chombev.core.model.Phrase
import bzh.ajaury.chombev.records.model.Record import bzh.ajaury.chombev.core.model.Record
@Composable @Composable
fun RecordView( fun RecordView(
@@ -14,9 +14,8 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import bzh.ajaury.chombev.core.model.Phrase import bzh.ajaury.chombev.core.model.Phrase
import bzh.ajaury.chombev.records.model.Record import bzh.ajaury.chombev.core.model.Record
import bzh.ajaury.chombev.records.ui.viewmodel.RecordsViewModel import bzh.ajaury.chombev.records.ui.viewmodel.RecordsViewModel
import bzh.ajaury.chombev.theme.ChomBevTheme
import org.koin.compose.viewmodel.koinViewModel import org.koin.compose.viewmodel.koinViewModel
@Composable @Composable
@@ -68,7 +67,7 @@ fun RecordsScreen(
@Preview @Preview
@Composable @Composable
private fun RecordsScreenPreview() { private fun RecordsScreenPreview() {
ChomBevTheme { MaterialTheme {
RecordsScreen( RecordsScreen(
records = listOf( records = listOf(
Record( Record(
@@ -0,0 +1,31 @@
package bzh.ajaury.chombev.records.ui.di
import bzh.ajaury.chombev.player.di.audioPlayerModule
import bzh.ajaury.chombev.player.di.playbackModule
import bzh.ajaury.chombev.player.ui.viewmodel.PlayerViewModel
import bzh.ajaury.chombev.preferences.di.preferencesModule
import bzh.ajaury.chombev.records.di.recordsModule
import bzh.ajaury.chombev.records.ui.viewmodel.RecordsViewModel
import bzh.ajaury.chombev.resources.di.resourcesModule
import bzh.ajaury.chombev.subtitle.di.subtitleModule
import org.koin.core.module.Module
import org.koin.core.module.dsl.viewModelOf
import org.koin.dsl.module
/**
* DI for the records feature: the record list, the player, and subtitle preferences UI.
*/
val recordsFeatureModule: Module = module {
includes(
playbackModule,
preferencesModule,
recordsModule,
resourcesModule,
audioPlayerModule,
subtitleModule,
)
viewModelOf(::RecordsViewModel)
viewModelOf(::PlayerViewModel)
}
@@ -2,8 +2,8 @@ package bzh.ajaury.chombev.records.ui.viewmodel
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import bzh.ajaury.chombev.core.model.Record
import bzh.ajaury.chombev.records.domain.RecordRepository import bzh.ajaury.chombev.records.domain.RecordRepository
import bzh.ajaury.chombev.records.model.Record
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
@@ -1,10 +1,12 @@
package bzh.ajaury.chombev.web.di package bzh.ajaury.chombev.web.di
import bzh.ajaury.chombev.resources.di.resourcesModule
import bzh.ajaury.chombev.web.ui.viewmodel.WebViewModel import bzh.ajaury.chombev.web.ui.viewmodel.WebViewModel
import org.koin.core.module.Module import org.koin.core.module.Module
import org.koin.core.module.dsl.viewModelOf import org.koin.core.module.dsl.viewModelOf
import org.koin.dsl.module import org.koin.dsl.module
val webviewModule: Module = module { val webviewModule: Module = module {
includes(resourcesModule)
viewModelOf(::WebViewModel) viewModelOf(::WebViewModel)
} }
+1
View File
@@ -52,4 +52,5 @@ include(":data:resources")
include(":data:subtitle") include(":data:subtitle")
// Feature modules // Feature modules
include(":feature:records")
include(":feature:webview") include(":feature:webview")
+1 -5
View File
@@ -33,19 +33,15 @@ kotlin {
} }
commonMain.dependencies { commonMain.dependencies {
// Core modules // Core modules
implementation(projects.core.audioplayer)
implementation(projects.core.coroutines) implementation(projects.core.coroutines)
implementation(projects.core.logging) implementation(projects.core.logging)
implementation(projects.core.model) implementation(projects.core.model)
// Data modules // Data modules
implementation(projects.data.playback)
implementation(projects.data.preferences)
implementation(projects.data.records)
implementation(projects.data.resources) implementation(projects.data.resources)
implementation(projects.data.subtitle)
// Feature modules // Feature modules
implementation(projects.feature.records)
implementation(projects.feature.webview) implementation(projects.feature.webview)
implementation(libs.compose.runtime) implementation(libs.compose.runtime)
@@ -17,10 +17,8 @@ import bzh.ajaury.chombev.navigation.MainBottomBar
import bzh.ajaury.chombev.navigation.MainTopBar import bzh.ajaury.chombev.navigation.MainTopBar
import bzh.ajaury.chombev.navigation.Route import bzh.ajaury.chombev.navigation.Route
import bzh.ajaury.chombev.navigation.WebPages import bzh.ajaury.chombev.navigation.WebPages
import bzh.ajaury.chombev.player.di.audioPlayerModule
import bzh.ajaury.chombev.player.ui.PlayerScreen import bzh.ajaury.chombev.player.ui.PlayerScreen
import bzh.ajaury.chombev.records.ui.RecordsScreen import bzh.ajaury.chombev.records.ui.RecordsScreen
import bzh.ajaury.chombev.subtitle.di.subtitleModule
import bzh.ajaury.chombev.theme.ChomBevTheme import bzh.ajaury.chombev.theme.ChomBevTheme
import bzh.ajaury.chombev.web.model.WebPage import bzh.ajaury.chombev.web.model.WebPage
import bzh.ajaury.chombev.web.ui.WebViewScreen import bzh.ajaury.chombev.web.ui.WebViewScreen
@@ -32,9 +30,7 @@ val appModule = module {
includes( includes(
loggingModule, loggingModule,
sharedModule, sharedModule,
audioPlayerModule,
coroutinesModule, coroutinesModule,
subtitleModule,
) )
} }
@@ -1,23 +1,12 @@
package bzh.ajaury.chombev.di package bzh.ajaury.chombev.di
import bzh.ajaury.chombev.core.logging.di.loggingModule import bzh.ajaury.chombev.core.logging.di.loggingModule
import bzh.ajaury.chombev.player.di.playbackModule import bzh.ajaury.chombev.records.ui.di.recordsFeatureModule
import bzh.ajaury.chombev.player.ui.viewmodel.PlayerViewModel
import bzh.ajaury.chombev.preferences.di.preferencesModule
import bzh.ajaury.chombev.records.di.recordsModule
import bzh.ajaury.chombev.records.ui.viewmodel.RecordsViewModel
import bzh.ajaury.chombev.resources.di.resourcesModule
import bzh.ajaury.chombev.web.di.webviewModule import bzh.ajaury.chombev.web.di.webviewModule
import org.koin.core.module.dsl.viewModelOf
import org.koin.dsl.module import org.koin.dsl.module
val sharedModule = module { val sharedModule = module {
includes(loggingModule) includes(loggingModule)
includes(playbackModule) includes(recordsFeatureModule)
includes(preferencesModule)
includes(recordsModule)
includes(resourcesModule)
includes(webviewModule) includes(webviewModule)
viewModelOf(::RecordsViewModel)
viewModelOf(::PlayerViewModel)
} }