ContextualMenu
This commit is contained in:
parent
82f0624095
commit
e261be48f0
19 changed files with 159 additions and 125 deletions
|
|
@ -29,6 +29,7 @@ kotlin {
|
|||
implementation(compose.preview)
|
||||
implementation(libs.androidx.activity.compose)
|
||||
implementation(libs.koin.android) // Koin Android-specific extensions
|
||||
implementation(libs.koin.androidx.compose)
|
||||
|
||||
}
|
||||
commonMain.dependencies {
|
||||
|
|
@ -48,6 +49,11 @@ kotlin {
|
|||
implementation(libs.serialization)
|
||||
api(libs.kmp.observableviewmodel.core)
|
||||
implementation(libs.kotlinx.serialization.json)
|
||||
implementation(libs.androidx.material3)
|
||||
implementation(libs.koin.compose)
|
||||
implementation(libs.koin.compose.viewmodel)
|
||||
implementation(libs.koin.compose.viewmodel.navigation)
|
||||
|
||||
}
|
||||
commonTest.dependencies {
|
||||
implementation(libs.kotlin.test)
|
||||
|
|
@ -56,7 +62,6 @@ kotlin {
|
|||
implementation(compose.desktop.currentOs)
|
||||
implementation(libs.kotlinx.coroutinesSwing)
|
||||
}
|
||||
//androidMain.dependsOn(androidAndJvmMain)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application
|
||||
android:name=".AndroidApp"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import org.koin.android.ext.koin.androidLogger
|
|||
import org.koin.core.logger.Level
|
||||
import mg.dot.feufaro.di.androidModule
|
||||
|
||||
class AndroidApp: Application {
|
||||
class AndroidApp: Application() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
startKoin {
|
||||
|
|
|
|||
|
|
@ -1,46 +0,0 @@
|
|||
package mg.dot.feufaro
|
||||
|
||||
|
||||
import android.content.Context
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.BufferedReader
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.io.InputStreamReader
|
||||
|
||||
// This is just a regular class that implements the common 'FileRepository' interface.
|
||||
// It is NOT an 'actual' declaration of 'FileRepository'.
|
||||
class AndroidFileRepository(private val context: Context) : FileRepository { // IMPORTS AND IMPLEMENTS THE commonMain 'FileRepository' interface
|
||||
override suspend fun readFileLines(filePath: String): List<String> = withContext(Dispatchers.IO) {
|
||||
try {
|
||||
when {
|
||||
filePath.startsWith("assets://") -> {
|
||||
readAssetFileLines(filePath)
|
||||
}
|
||||
|
||||
else -> {
|
||||
File(filePath).readLines()
|
||||
}
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
throw IOException("Failed to read file or asset '$filePath'")
|
||||
}
|
||||
|
||||
}
|
||||
override suspend fun readFileContent(filePath: String): String = withContext(Dispatchers.IO) { "" }
|
||||
private fun readAssetFileLines(assetFileName: String): List<String> {
|
||||
return context.assets.open(assetFileName).use { inputStream ->
|
||||
BufferedReader(InputStreamReader(inputStream)).useLines { it.toList() }
|
||||
}
|
||||
}
|
||||
private fun readAssetFileContent(assetFileName: String): String {
|
||||
|
||||
return context.assets.open(assetFileName).use { inputStream ->
|
||||
// BufferedReader(InputStreamReader(inputStream)) permet de lire le texte ligne par ligne.
|
||||
BufferedReader(InputStreamReader(inputStream)).use { reader ->
|
||||
reader.readText() // Lit tout le contenu en une seule chaîne.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import androidx.activity.compose.setContent
|
|||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import org.koin.androidx.compose.koinViewModel
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
|
@ -13,7 +14,8 @@ class MainActivity : ComponentActivity() {
|
|||
super.onCreate(savedInstanceState)
|
||||
|
||||
setContent {
|
||||
App()
|
||||
val sharedViewModel: SharedViewModel = koinViewModel()
|
||||
App(sharedViewModel = sharedViewModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package mg.dot.feufaro.di
|
||||
|
||||
import android.content.Context
|
||||
import mg.dot.feufaro.AndroidFileRepository // Import the actual Android implementation
|
||||
import mg.dot.feufaro.config.AppConfig
|
||||
import org.koin.core.module.dsl.singleOf // Import for Koin DSL
|
||||
import org.koin.core.module.dsl.bind // Import for Koin DSL
|
||||
|
|
@ -12,15 +11,10 @@ import org.koin.android.ext.koin.androidContext // Import for androidContext()
|
|||
val androidModule = module {
|
||||
// Koin will automatically provide the Android Context because you called androidContext() in AndroidApp.
|
||||
// It then uses this Context to construct AndroidFileRepository.
|
||||
singleOf(::AndroidFileRepository) { bind<FileRepository>() }
|
||||
single<AppConfig> {
|
||||
AppConfig(
|
||||
transposeto = "C",
|
||||
transposeasif = "C",
|
||||
buttonContainerColorHex = "#ff00f0",
|
||||
buttonContentColorHex = "#ffffff",
|
||||
buttonDisabledContainerColorHex = "#999999",
|
||||
buttonDisabledContentColorHex = "#ffffff",
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package mg.dot.feufaro
|
|||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.gestures.detectTapGestures
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.FlowRow
|
||||
|
|
@ -26,6 +27,7 @@ import androidx.compose.runtime.*
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
|
@ -41,7 +43,10 @@ import kotlinx.coroutines.launch
|
|||
import mg.dot.feufaro.solfa.LazyVerticalGridTUO
|
||||
import mg.dot.feufaro.solfa.Solfa
|
||||
import org.koin.compose.koinInject
|
||||
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.window.Popup
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
|
|
@ -53,6 +58,8 @@ fun App(sharedViewModel: SharedViewModel = SharedViewModel()
|
|||
val currentDisplayConfig by displayConfigManager.displayConfig.collectAsState()
|
||||
// Load Configurations
|
||||
val configScope = CoroutineScope(Dispatchers.Default)
|
||||
var showContextualMenu by remember { mutableStateOf(false)}
|
||||
var menuPosition by remember { mutableStateOf(Offset.Zero)}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
configScope.launch {
|
||||
|
|
@ -82,7 +89,34 @@ fun App(sharedViewModel: SharedViewModel = SharedViewModel()
|
|||
MaterialTheme {
|
||||
var showContent by remember { mutableStateOf(false) }
|
||||
var gridWidthPx by remember { mutableStateOf(0) }
|
||||
Column(Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
Column(
|
||||
Modifier.fillMaxSize()
|
||||
.pointerInput(Unit) {
|
||||
detectTapGestures(
|
||||
onDoubleTap = {
|
||||
offset ->
|
||||
menuPosition = offset
|
||||
showContextualMenu = true
|
||||
}
|
||||
)
|
||||
},
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
if (showContextualMenu) {
|
||||
Popup(
|
||||
alignment = Alignment.TopStart,
|
||||
offset = IntOffset(menuPosition.x.roundToInt(),
|
||||
menuPosition.y.roundToInt()),
|
||||
onDismissRequest = {
|
||||
showContextualMenu = false
|
||||
}
|
||||
) {
|
||||
ContextualMenu(onMenuItemClick = { item ->
|
||||
println("Clicked: $item")
|
||||
showContextualMenu = false
|
||||
})
|
||||
}
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
package mg.dot.feufaro
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material.icons.filled.Edit
|
||||
import androidx.compose.material.icons.filled.List
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.ui.unit.TextUnitType
|
||||
@Composable
|
||||
fun ContextualMenu (onMenuItemClick: (String) -> Unit){
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.background(Color.DarkGray.copy(alpha = 0.8f), RoundedCornerShape(8.dp))
|
||||
.padding(8.dp)
|
||||
) {
|
||||
MenuItem(icon = Icons.Default.Add, text = "+") { onMenuItemClick("Ajouter")}
|
||||
MenuItem(icon = Icons.Default.Edit, text = "!") { onMenuItemClick("Modifier")}
|
||||
MenuItem(icon = Icons.Default.List, text = "-") { onMenuItemClick("Liste")}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun MenuItem(icon: androidx.compose.ui.graphics.vector.ImageVector, text: String, onClick: () -> Unit) {
|
||||
IconButton(onClick = onClick) {
|
||||
Column(horizontalAlignment = androidx.compose.ui.Alignment.CenterHorizontally) {
|
||||
Icon(icon, contentDescription = text, tint = Color.White)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,50 @@
|
|||
package mg.dot.feufaro
|
||||
|
||||
import java.io.IOException // Java.io.IOException est généralement partagée sur JVM/Android
|
||||
import feufaro.composeapp.generated.resources.Res
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
|
||||
// Définissez une expect interface. Elle spécifie le contrat de votre repository.
|
||||
// Utilisez 'expect interface' car l'implémentation (actual) variera selon la plateforme.
|
||||
expect interface FileRepository {
|
||||
interface FileRepository {
|
||||
// Lecture de fichier ligne par ligne
|
||||
suspend fun readFileLines(filePath: String): List<String>
|
||||
|
||||
// Lecture de fichier entier en tant que String
|
||||
suspend fun readFileContent(filePath: String): String
|
||||
}
|
||||
|
||||
// This is just a regular class that implements the common 'FileRepository' interface.
|
||||
// It is NOT an 'actual' declaration of 'FileRepository'.
|
||||
class CommonFileRepository : FileRepository { // IMPORTS AND IMPLEMENTS THE commonMain 'FileRepository' interface
|
||||
override suspend fun readFileLines(filePath: String): List<String> = withContext(Dispatchers.IO) {
|
||||
try {
|
||||
when {
|
||||
filePath.startsWith("assets://") -> {
|
||||
readAssetFileLines(filePath)
|
||||
}
|
||||
|
||||
else -> {
|
||||
File(filePath).readLines()
|
||||
}
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
throw IOException("Failed to read file or asset '$filePath'")
|
||||
}
|
||||
}
|
||||
override suspend fun readFileContent(filePath: String): String = withContext(Dispatchers.IO) {
|
||||
val lines = readFileLines(filePath)
|
||||
lines.joinToString("\n") { it }
|
||||
}
|
||||
private suspend fun readAssetFileLines(assetFileName: String): List<String> {
|
||||
return try {
|
||||
Res.readBytes("files/"+assetFileName.removePrefix("assets://")).decodeToString().split("\n")
|
||||
} catch (e: IOException) {
|
||||
println("Could not read /"+assetFileName.removePrefix("assets://"))
|
||||
throw IOException("Could not read asset file: $assetFileName", e)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -29,6 +29,8 @@ open class SharedViewModel(): ViewModel() {
|
|||
val tuoList: StateFlow<List<TimeUnitObject>> = _tuoList.asStateFlow()
|
||||
private var _playlist = MutableStateFlow<List<String>>(viewModelScope, emptyList())
|
||||
val playlist: StateFlow<List<String>> = _playlist.asStateFlow()
|
||||
private var _nextPlayed = MutableStateFlow(viewModelScope, -1)
|
||||
val nextPlayed: StateFlow<Int> = _nextPlayed.asStateFlow()
|
||||
private val tempTimeUnitObjectList = mutableListOf<TimeUnitObject>()
|
||||
var _hasMarker = MutableStateFlow<Boolean>(viewModelScope, false)
|
||||
val hasMarker: StateFlow<Boolean> = _hasMarker.asStateFlow()
|
||||
|
|
@ -83,4 +85,12 @@ open class SharedViewModel(): ViewModel() {
|
|||
_hasMarker.value = theHasMarker
|
||||
|
||||
}
|
||||
fun playNext() {
|
||||
val nextIndex = (_nextPlayed.value + 1) % _playlist.value.size
|
||||
_nextPlayed.value = nextIndex
|
||||
}
|
||||
fun currentPlayed(): String {
|
||||
val playlistIndex = _nextPlayed.value
|
||||
return _playlist.value[playlistIndex]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,22 @@
|
|||
package mg.dot.feufaro.di
|
||||
|
||||
import mg.dot.feufaro.CommonFileRepository
|
||||
import mg.dot.feufaro.FileRepository
|
||||
import mg.dot.feufaro.SharedViewModel
|
||||
import mg.dot.feufaro.DisplayConfigManager // Importez DisplayConfigManager
|
||||
import mg.dot.feufaro.config.AppConfig
|
||||
import mg.dot.feufaro.musicXML.MusicXML
|
||||
import org.koin.dsl.module
|
||||
import org.koin.core.module.dsl.singleOf
|
||||
import org.koin.core.module.Module
|
||||
import org.koin.core.module.dsl.viewModel
|
||||
|
||||
val commonModule = module {
|
||||
// Déclarez FileRepository comme un singleton.
|
||||
// L'implémentation concrète (actual) sera résolue par Koin en fonction de la plateforme.
|
||||
// Pour Android, Koin injectera le Context que vous avez fourni via androidContext().
|
||||
singleOf(::MusicXML)
|
||||
single<FileRepository> { CommonFileRepository() }
|
||||
single { DisplayConfigManager(fileRepository = get())}
|
||||
|
||||
viewModel { SharedViewModel() }
|
||||
}
|
||||
|
|
@ -36,7 +36,6 @@ class Solfa(val sharedViewModel: SharedViewModel, private val fileRepository: Fi
|
|||
var nextLIndex: Int = -1
|
||||
var inGroup: Boolean = false
|
||||
var templateString: String = ""
|
||||
var nextPlayed = -1
|
||||
|
||||
private val meta: MutableMap<String, String> = mutableMapOf()
|
||||
private val lyricsComment: MutableList<String> = mutableListOf()
|
||||
|
|
@ -94,15 +93,16 @@ class Solfa(val sharedViewModel: SharedViewModel, private val fileRepository: Fi
|
|||
}
|
||||
nextTimeUnitObject()
|
||||
}
|
||||
fun loadSolfa(sourceFileName: String) {
|
||||
fun loadSolfa() {
|
||||
val sourceFileName: String = sharedViewModel.currentPlayed()
|
||||
sharedViewModel.reset()
|
||||
parse(sourceFileName)
|
||||
}
|
||||
fun loadNextInPlaylist() {
|
||||
val playlist = sharedViewModel?.playlist?.value ?: listOf()
|
||||
val playlist = sharedViewModel.playlist.value
|
||||
if (playlist.isNotEmpty()) {
|
||||
nextPlayed = (nextPlayed + 1) % playlist.size
|
||||
loadSolfa(playlist[nextPlayed])
|
||||
sharedViewModel.playNext()
|
||||
loadSolfa()
|
||||
}
|
||||
}
|
||||
fun parse(sourceFile: String) {
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ import androidx.compose.foundation.layout.*
|
|||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.material.LocalTextStyle
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.LocalTextStyle
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
package mg.dot.feufaro
|
||||
|
||||
import feufaro.composeapp.generated.resources.Res
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
|
||||
// This is just a regular class that implements the common 'FileRepository' interface.
|
||||
// It is NOT an 'actual' declaration of 'FileRepository'.
|
||||
class DesktopFileRepository : FileRepository { // IMPORTS AND IMPLEMENTS THE commonMain 'FileRepository' interface
|
||||
override suspend fun readFileLines(filePath: String): List<String> = withContext(Dispatchers.IO) {
|
||||
try {
|
||||
when {
|
||||
filePath.startsWith("assets://") -> {
|
||||
readAssetFileLines(filePath)
|
||||
}
|
||||
|
||||
else -> {
|
||||
File(filePath).readLines()
|
||||
}
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
throw IOException("Failed to read file or asset '$filePath'")
|
||||
}
|
||||
}
|
||||
override suspend fun readFileContent(filePath: String): String = withContext(Dispatchers.IO) {
|
||||
val lines = readFileLines(filePath)
|
||||
lines.joinToString("\n") { it }
|
||||
}
|
||||
private suspend fun readAssetFileLines(assetFileName: String): List<String> {
|
||||
return try {
|
||||
Res.readBytes("files/"+assetFileName.removePrefix("assets://")).decodeToString().split("\n")
|
||||
} catch (e: IOException) {
|
||||
println("Could not read /"+assetFileName.removePrefix("assets://"))
|
||||
throw IOException("Could not read asset file: $assetFileName", e)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
package mg.dot.feufaro
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import mg.dot.feufaro.FileRepository
|
||||
|
||||
|
||||
actual interface FileRepository {
|
||||
actual suspend fun readFileLines(filePath: String): List<String>
|
||||
actual suspend fun readFileContent(filePath: String): String
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
package mg.dot.feufaro.di
|
||||
|
||||
import mg.dot.feufaro.DesktopFileRepository // Import the actual desktop implementation
|
||||
import org.koin.core.module.dsl.singleOf // Import for Koin DSL
|
||||
import org.koin.core.module.dsl.bind // Import for Koin DSL
|
||||
import org.koin.dsl.module
|
||||
|
|
@ -10,11 +9,10 @@ import mg.dot.feufaro.config.AppConfig
|
|||
val desktopModule = module {
|
||||
// When Koin is initialized on Desktop, it will use DesktopFileRepository
|
||||
// as the implementation for the FileRepository interface.
|
||||
singleOf(::DesktopFileRepository) { bind<FileRepository>() }
|
||||
single<AppConfig> {
|
||||
AppConfig(
|
||||
transposeto = "C",
|
||||
transposeasif = "C"
|
||||
transposeasif = "C"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ import org.koin.core.context.KoinContext
|
|||
import org.koin.core.logger.Level
|
||||
import org.koin.compose.KoinContext
|
||||
|
||||
|
||||
fun main() = application {
|
||||
startKoin {
|
||||
printLogger(Level.INFO) // Mettez Level.INFO pour voir les logs de Koin
|
||||
|
|
@ -24,7 +25,8 @@ fun main() = application {
|
|||
title = "Feufaro",
|
||||
) {
|
||||
KoinContext {
|
||||
App()
|
||||
val sharedViewModel: SharedViewModel = SharedViewModel()
|
||||
App(sharedViewModel = sharedViewModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
[versions]
|
||||
agp = "8.7.3"
|
||||
agp = "8.10.1"
|
||||
android-compileSdk = "35"
|
||||
android-minSdk = "24"
|
||||
android-targetSdk = "35"
|
||||
|
|
@ -20,8 +20,11 @@ koin = "4.0.4"
|
|||
core = "0.91.1"
|
||||
kmpObservableviewmodelCore = "1.0.0-BETA-3"
|
||||
kotlinxSerializationJson = "1.8.1"
|
||||
material3 = "1.3.2"
|
||||
|
||||
[libraries]
|
||||
koin-compose-viewmodel = { module = "io.insert-koin:koin-compose-viewmodel", version.ref = "koin" }
|
||||
koin-compose-viewmodel-navigation = { module = "io.insert-koin:koin-compose-viewmodel-navigation", version.ref = "koin" }
|
||||
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
|
||||
kotlin-testJunit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" }
|
||||
junit = { module = "junit:junit", version.ref = "junit" }
|
||||
|
|
@ -39,13 +42,15 @@ koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" }
|
|||
koin-compose = { module = "io.insert-koin:koin-compose", version.ref = "koin" }
|
||||
koin-core-viewmodel = { module = "io.insert-koin:koin-core-viewmodel", version.ref = "koin" }
|
||||
koin-android = { module = "io.insert-koin:koin-android", version.ref = "koin" }
|
||||
#20250704
|
||||
koin-androidx-compose = { module = "io.insert-koin:koin-androidx-compose", version.ref = "koin" }
|
||||
|
||||
core = { module = "io.github.pdvrieze.xmlutil:core", version.ref = "core" }
|
||||
#core-android = { module = "io.github.pdvrieze.xmlutil:core-android", version.ref = "core" }
|
||||
#core-jdk = { module = "io.github.pdvrieze.xmlutil:core-jdk", version.ref = "core" }
|
||||
serialization = { module = "io.github.pdvrieze.xmlutil:serialization", version.ref = "core" }
|
||||
kmp-observableviewmodel-core = { module = "com.rickclephas.kmp:kmp-observableviewmodel-core", version.ref = "kmpObservableviewmodelCore" }
|
||||
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
|
||||
androidx-material3 = { module = "androidx.compose.material3:material3", version.ref = "material3" }
|
||||
|
||||
[plugins]
|
||||
androidApplication = { id = "com.android.application", version.ref = "agp" }
|
||||
|
|
|
|||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
|
@ -1,6 +1,6 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue