refactor: integrate ViewModel and repository for record management

This commit is contained in:
2026-06-09 16:11:53 +02:00
parent 6f811fbeea
commit 235bd40296
9 changed files with 89 additions and 36 deletions
@@ -2,13 +2,20 @@ package fr.ajaury.gwenedeg
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import fr.ajaury.gwenedeg.records.data.InMemoryRecordRepository
import fr.ajaury.gwenedeg.records.ui.RecordsScreen import fr.ajaury.gwenedeg.records.ui.RecordsScreen
import fr.ajaury.gwenedeg.records.ui.viewmodel.RecordsViewModel
@Composable @Composable
@Preview @Preview
fun App() { fun App() {
val viewModel = remember {
RecordsViewModel(InMemoryRecordRepository())
}
MaterialTheme { MaterialTheme {
RecordsScreen() RecordsScreen(viewModel)
} }
} }
@@ -0,0 +1,35 @@
package fr.ajaury.gwenedeg.records.data
import fr.ajaury.gwenedeg.records.domain.Record
import fr.ajaury.gwenedeg.records.domain.RecordRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
class InMemoryRecordRepository : RecordRepository {
private val records =
listOf(
"An onestiz",
"En em brezntiñ",
"An amzer a ra",
"E komz get unan arall",
"Me hag ar brezhoneg",
"Ar yec'hed",
"Deskriviñ",
"Me 'gar / Ne garan ket",
"C'hoantoù",
"Penaos 'peus kavet...?",
"Oberiantizoù",
"Debriñ hag evet",
"Bale, pourmen ha beajiñ",
"Ma c'horf",
"Dle eo / ret eo / dav eo / mall eo...",
"Deizioù ar sizhun",
"Mizioù ha kourzoù ar blez",
"Bez'zo / N'eus ket...",
"Banne.../Tamm...",
"Stad a vuhez",
"Lec'hiiñ",
).map { Record(it) }
override fun getRecords(): Flow<List<Record>> = flowOf(records)
}
@@ -0,0 +1,5 @@
package fr.ajaury.gwenedeg.records.domain
data class Record(
val title: String,
)
@@ -0,0 +1,7 @@
package fr.ajaury.gwenedeg.records.domain
import kotlinx.coroutines.flow.Flow
interface RecordRepository {
fun getRecords(): Flow<List<Record>>
}
@@ -5,11 +5,12 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import fr.ajaury.gwenedeg.records.domain.Record
@Composable @Composable
fun RecordView(record: String) { fun RecordView(record: Record) {
Text( Text(
text = record, text = record.title,
modifier = Modifier.padding(16.dp), modifier = Modifier.padding(16.dp),
) )
} }
@@ -5,41 +5,20 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeContentPadding import androidx.compose.foundation.layout.safeContentPadding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
private val records = import fr.ajaury.gwenedeg.records.ui.viewmodel.RecordsViewModel
listOf(
"An onestiz",
"En em brezntiñ",
"An amzer a ra",
"E komz get unan arall",
"Me hag ar brezhoneg",
"Ar yec'hed",
"Deskriviñ",
"Me 'gar / Ne garan ket",
"C'hoantoù",
"Penaos 'peus kavet...?",
"Oberiantizoù",
"Debriñ hag evet",
"Bale, pourmen ha beajiñ",
"Ma c'horf",
"Dle eo / ret eo / dav eo / mall eo...",
"Deizioù ar sizhun",
"Mizioù ha kourzoù ar blez",
"Bez'zo / N'eus ket...",
"Banne.../Tamm...",
"Stad a vuhez",
"Lec'hiiñ",
)
@Composable @Composable
fun RecordsScreen() { fun RecordsScreen(viewModel: RecordsViewModel) {
val records by viewModel.uiState.collectAsStateWithLifecycle()
Scaffold { innerPadding -> Scaffold { innerPadding ->
LazyColumn( LazyColumn(
modifier = modifier =
@@ -48,12 +27,12 @@ fun RecordsScreen() {
.background(MaterialTheme.colorScheme.primaryContainer) .background(MaterialTheme.colorScheme.primaryContainer)
.fillMaxSize(), .fillMaxSize(),
) { ) {
items(records) { item -> itemsIndexed(records) { index, item ->
RecordView( RecordView(
record = item, record = item,
) )
if (!item.isLastItem()) { if (index < records.lastIndex) {
HorizontalDivider( HorizontalDivider(
modifier = Modifier.padding(horizontal = 16.dp), modifier = Modifier.padding(horizontal = 16.dp),
thickness = 1.dp, thickness = 1.dp,
@@ -64,5 +43,3 @@ fun RecordsScreen() {
} }
} }
} }
private fun String.isLastItem(): Boolean = this == records.last()
@@ -0,0 +1,21 @@
package fr.ajaury.gwenedeg.records.ui.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import fr.ajaury.gwenedeg.records.domain.Record
import fr.ajaury.gwenedeg.records.domain.RecordRepository
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.stateIn
class RecordsViewModel(
recordRepository: RecordRepository,
) : ViewModel() {
val uiState: StateFlow<List<Record>> = recordRepository
.getRecords()
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = emptyList(),
)
}