Basic stuff working
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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 = ""
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user