Basic stuff working

This commit is contained in:
2025-02-02 15:32:19 +01:00
parent 450713ae38
commit 0d424ac413
6 changed files with 195 additions and 43 deletions

View File

@@ -83,6 +83,9 @@ kotlin {
implementation(libs.koin.core)
implementation(libs.koin.compose)
implementation(libs.koin.compose.viewmodel)
implementation(libs.composeIcons.tablerIcons)
implementation(libs.composeIcons.fontAwesome)
implementation(libs.korau)
}

View File

@@ -1,5 +1,6 @@
package org.neutrino.ktans.view
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.background
import androidx.compose.ui.graphics.Color
@@ -12,12 +13,14 @@ import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.material.TextField
import androidx.compose.material.IconButton
import androidx.compose.material.Icon
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.filled.Clear
import androidx.compose.material.icons.filled.Settings
import androidx.compose.runtime.Composable
import kotlinx.coroutines.flow.observeOn
import org.koin.compose.koinInject
@@ -28,6 +31,16 @@ import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.lifecycle.viewmodel.compose.viewModel
import compose.icons.TablerIcons
import compose.icons.tablericons.Table
import androidx.compose.foundation.layout.Arrangement
import compose.icons.FontAwesomeIcons
import compose.icons.fontawesomeicons.Solid
import compose.icons.tablericons.ArrowBigRight
import compose.icons.fontawesomeicons.solid.PlayCircle
import models.Term
import models.TermFull
import kotlinx.coroutines.*
@Composable
fun RowScope.TableCell(
@@ -39,37 +52,76 @@ fun RowScope.TableCell(
Modifier
.border(1.dp, Color.Black)
.weight(weight)
.padding(8.dp)
.padding(4.dp)
)
}
fun groupByString1(terms: List<TermFull>): MutableList<MutableList<TermFull>> {
val fullList: MutableList<MutableList<TermFull>> = mutableListOf()
var lastTerm: TermFull? = null
var termsEq: MutableList<TermFull> = mutableListOf()
for (t in terms) {
if (lastTerm == null) {
termsEq += t
} else {
if (lastTerm.string1 == t.string1){
termsEq += t
} else {
fullList += termsEq
termsEq = mutableListOf()
termsEq += t
}
}
lastTerm = t
}
fullList += termsEq
return fullList
}
@Composable
fun SearchBarTextField(viewModel: MainModelView) {
val query = remember { mutableStateOf("") }
val columnViewType = remember { mutableStateOf(false) }
Column {
TextField(
value = query.value,
onValueChange = {
query.value = it
viewModel.getTerms(query.value)
},
placeholder = { Text("Prelož...") },
singleLine = true,
leadingIcon = { Icon(Icons.Filled.Search, contentDescription = "Search Icon") },
trailingIcon = {
if (query.value.isNotEmpty()) {
IconButton(onClick = {
query.value = ""
viewModel.clearSearch()
}) {
Icon(Icons.Filled.Clear, contentDescription = "Clear Text")
}
}
},
modifier = Modifier
.fillMaxWidth()
)
Row(
verticalAlignment = Alignment.CenterVertically,
// horizontalArrangement = Arrangement.End,
modifier = Modifier.background(Color.LightGray)
) {
TextField(
value = query.value,
onValueChange = {
query.value = it
viewModel.getTerms(query.value)
},
placeholder = { Text("Prelož...") },
singleLine = true,
leadingIcon = { Icon(Icons.Filled.Search, contentDescription = "Search Icon") },
trailingIcon = {
if (query.value.isNotEmpty()) {
IconButton(onClick = {
query.value = ""
viewModel.clearSearch()
}) {
Icon(Icons.Filled.Clear, contentDescription = "Clear Text")
}
}
},
modifier = Modifier.weight(3f)
)
Row (Modifier.width(155.dp).border(width = 2.dp, Color.Black)) {
Spacer(modifier = Modifier.padding(2.dp))
Icon(TablerIcons.Table, contentDescription = "Table View", modifier = Modifier.size(width = 50.dp, height = 50.dp))
Spacer(modifier = Modifier.padding(2.dp))
Icon(TablerIcons.ArrowBigRight, contentDescription = "Table View", modifier = Modifier.size(width = 50.dp, height = 50.dp))
Spacer(modifier = Modifier.padding(2.dp))
Icon(Icons.Filled.Settings, contentDescription = "Table View", modifier = Modifier.size(width = 50.dp, height = 50.dp))
//Spacer(modifier = Modifier.fillMaxWidth())
}
}
Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally ) {
val terms by viewModel.terms.collectAsState()
@@ -77,27 +129,85 @@ fun SearchBarTextField(viewModel: MainModelView) {
if (terms != null) {
SelectionContainer {
Column {
Row(Modifier.background(Color.Gray)) {
TableCell(text = "Anglicky", weight = .5f)
TableCell(text = "Slovensky", weight = .5f)
}
val column1Weight = .5f // 50%
val column2Weight = .5f // 50%
// The LazyColumn will be our table. Notice the use of the weights below
LazyColumn(Modifier.fillMaxSize().padding(0.dp)) {
// Here is the header
if (columnViewType.value) {
Row(Modifier.background(Color.Gray)) {
TableCell(text = "Anglicky", weight = .5f)
TableCell(text = "Slovensky", weight = .5f)
}
val column1Weight = .5f // 50%
val column2Weight = .5f // 50%
// The LazyColumn will be our table. Notice the use of the weights below
LazyColumn(Modifier.fillMaxSize().padding(0.dp)) {
// Here is the header
items(items = terms!!, itemContent = { t ->
items(items = terms!!, itemContent = { t ->
Row(Modifier.fillMaxWidth()) {
TableCell(text = t.string1, weight = column1Weight)
TableCell(text = t.string2, weight = column2Weight)
}
Row(Modifier.fillMaxWidth()) {
TableCell(text = t.string1, weight = column1Weight)
TableCell(text = t.string2, weight = column2Weight)
}
})
})
}
} else {
val terms2: MutableList<MutableList<TermFull>> = groupByString1(terms!!)
LazyColumn(Modifier.fillMaxSize().padding(0.dp)) {
var i=0
var rowBackground = Color.LightGray
items(items = terms2, itemContent = { t2 ->
var t : TermFull? = null
if (t2.size > 0) t = t2[0]
else return@items
when ( i++ % 2 ) {
0 -> rowBackground = Color.LightGray
1 -> rowBackground = Color.Gray
}
Row(Modifier.fillMaxWidth().background(color = rowBackground)) {
Column {
Row( verticalAlignment = Alignment.CenterVertically) {
Text(t.string1, fontWeight = FontWeight.Bold)
for (p in t.pronunciations!!) {
Spacer(modifier = Modifier.padding(2.dp))
if (p.ipa != null) {
var color = Color.Blue
when (p.typeId) {
1 -> color = Color.Green
2 -> color = Color.Red
3 -> color = Color.Blue
}
Text("[${p.ipa}]", color = color)
}
if (p.filename != null) {
IconButton(
modifier = Modifier.size(20.dp),
onClick = {
viewModel.playSound("media/${p.filename}")
}) {
Icon(FontAwesomeIcons.Solid.PlayCircle,contentDescription = "Play sound",Modifier.size(20.dp).padding(start = 2.dp),)
}
}
Spacer(modifier = Modifier.padding(2.dp))
}
}
val str2 = t2.joinToString(separator = ", ") { it.string2 }
Text(text = str2, modifier = Modifier.padding(start = 20.dp))
Spacer(modifier = Modifier
.border(1.dp, Color.Black)
.padding(1.dp).fillMaxWidth())
}
}
})
}
}
}
}
}

View File

@@ -2,16 +2,18 @@ package org.neutrino.ktans.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import korlibs.audio.sound.*
import korlibs.io.file.std.resourcesVfs
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import models.TermFull
import service.TermService
import service.TermServiceImpl
import service.DatabaseFactory.getTranslationForLanguages
import service.SearchType
import kotlinx.coroutines.Dispatchers
import service.TermServiceImpl
import korlibs.audio.format.*
class MainModelView(private val repository: TermServiceImpl): ViewModel() {
val terms : StateFlow<List<TermFull>?> get() = _terms
private val _terms = MutableStateFlow<List<TermFull>?>(null)
@@ -28,5 +30,16 @@ class MainModelView(private val repository: TermServiceImpl): ViewModel() {
}
fun clearSearch() {
_terms.value = listOf()
}
fun playSound(file: String) {
viewModelScope.launch {
val sound = resourcesVfs[file.replace("ogg","mp3")].readMusic()
sound.play()
}
}
}

View File

@@ -1,6 +1,10 @@
sound {
database = "./data/media"
}
h2 {
driver = org.h2.Driver
url = "jdbc:h2:file:./data/%s;DB_CLOSE_DELAY=-1;"
user = "sa"
password = ""
}
}