feat(feature:ui): implement iOS file sharing and improve Android logic (#1884)

Co-authored-by: Sk Niyaj Ali <niyaj639@gmail.com>
This commit is contained in:
Hekmatullah 2025-07-18 13:35:06 +01:00 committed by GitHub
parent 627d878b51
commit 75f2c9212d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 735 additions and 519 deletions

View File

@ -40,8 +40,8 @@ kotlin {
implementation(compose.components.resources)
implementation(compose.components.uiToolingPreview)
implementation(libs.jb.composeNavigation)
implementation(libs.filekit.compose)
implementation(libs.filekit.core)
implementation(libs.filekit.dialogs.compose)
}
androidInstrumentedTest.dependencies {
implementation(libs.bundles.androidx.compose.ui.test)

View File

@ -12,22 +12,28 @@ package org.mifospay.core.ui.utils
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.net.Uri
import android.util.Log
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.core.content.FileProvider
import co.touchlab.kermit.Logger
import io.github.vinceglb.filekit.FileKit
import io.github.vinceglb.filekit.ImageFormat
import io.github.vinceglb.filekit.compressImage
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.jetbrains.compose.resources.ExperimentalResourceApi
import org.jetbrains.compose.resources.decodeToImageBitmap
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
/**
* Actual implementation of [ShareUtils] for Android platform.
*
* This utility enables sharing of text and files (PDF, image, text) through Android's
* native `Intent`-based sharing system.
*/
actual object ShareUtils {
/**
* Provider function to retrieve the current [Activity].
* This must be set before using [shareText] or [shareFile].
*/
private var activityProvider: () -> Activity = {
throw IllegalArgumentException(
"You need to implement the 'activityProvider' to provide the required Activity. " +
@ -36,11 +42,23 @@ actual object ShareUtils {
)
}
/**
* Sets the activity provider function to be used internally for context retrieval.
*
* This is required to initialize before calling any sharing methods.
*
* @param provider A lambda that returns the current [Activity].
*/
fun setActivityProvider(provider: () -> Activity) {
activityProvider = provider
}
actual fun shareText(text: String) {
/**
* Shares plain text content using an Android share sheet (`Intent.ACTION_SEND`).
*
* @param text The text content to share.
*/
actual suspend fun shareText(text: String) {
val intent = Intent(Intent.ACTION_SEND).apply {
type = "text/plain"
putExtra(Intent.EXTRA_TEXT, text)
@ -49,57 +67,93 @@ actual object ShareUtils {
activityProvider.invoke().startActivity(intentChooser)
}
actual suspend fun shareImage(title: String, image: ImageBitmap) {
val context = activityProvider.invoke().application.baseContext
val uri = saveImage(image.asAndroidBitmap(), context)
val sendIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_STREAM, uri)
setDataAndType(uri, "image/png")
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
val shareIntent = Intent.createChooser(sendIntent, title)
activityProvider.invoke().startActivity(shareIntent)
}
/**
* Shares a file (e.g. PDF, text, image) using Android's file sharing mechanism.
*
* If the file is an image, it is compressed before sharing.
* The file is temporarily saved to internal cache and shared using a `FileProvider`.
*
* @param file A [ShareFileModel] containing file metadata and binary content.
*/
@OptIn(ExperimentalResourceApi::class)
actual suspend fun shareImage(title: String, byte: ByteArray) {
actual suspend fun shareFile(file: ShareFileModel) {
val context = activityProvider.invoke().application.baseContext
val imageBitmap = byte.decodeToImageBitmap()
val uri = saveImage(imageBitmap.asAndroidBitmap(), context)
try {
withContext(Dispatchers.IO) {
val compressedBytes = if (file.mime == MimeType.IMAGE) {
compressImage(file.bytes)
} else {
file.bytes
}
val sendIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_STREAM, uri)
setDataAndType(uri, "image/png")
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
val savedFile = saveFile(file.fileName, compressedBytes, context = context)
val uri = FileProvider.getUriForFile(
context,
"${context.packageName}.provider",
savedFile,
)
withContext(Dispatchers.Main) {
val intent = Intent(Intent.ACTION_SEND).apply {
putExtra(Intent.EXTRA_STREAM, uri)
flags += Intent.FLAG_ACTIVITY_NEW_TASK
flags += Intent.FLAG_GRANT_READ_URI_PERMISSION
setDataAndType(uri, file.mime.toAndroidMimeType())
}
val chooser = Intent.createChooser(intent, null)
activityProvider.invoke().startActivity(chooser)
}
}
} catch (e: Exception) {
e.printStackTrace()
Logger.e(e) { "Failed to share file: ${e.message}" }
}
val shareIntent = Intent.createChooser(sendIntent, title)
activityProvider.invoke().startActivity(shareIntent)
}
private suspend fun saveImage(image: Bitmap, context: Context): Uri? {
return withContext(Dispatchers.IO) {
try {
val imagesFolder = File(context.cacheDir, "images")
imagesFolder.mkdirs()
val file = File(imagesFolder, "shared_image.png")
/**
* Saves the provided byte array as a temporary file in the internal cache directory.
*
* @param name The name of the file to be saved.
* @param data Byte array representing the file content.
* @param context Android [Context] used to access the cache directory.
* @return The saved [File] object.
*/
private fun saveFile(name: String, data: ByteArray, context: Context): File {
val cache = context.cacheDir
val savedFile = File(cache, name)
savedFile.writeBytes(data)
return savedFile
}
val stream = FileOutputStream(file)
image.compress(Bitmap.CompressFormat.PNG, 100, stream)
stream.flush()
stream.close()
/**
* Maps [MimeType] to a corresponding Android MIME type string.
*
* @return Android-compatible MIME type string.
*/
private fun MimeType.toAndroidMimeType(): String = when (this) {
MimeType.PDF -> "application/pdf"
MimeType.TEXT -> "text/plain"
MimeType.IMAGE -> "image/*"
}
FileProvider.getUriForFile(context, "${context.packageName}.provider", file)
} catch (e: IOException) {
Log.d("saving bitmap", "saving bitmap error ${e.message}")
null
}
}
/**
* Compresses an image file using [FileKit] logic.
*
* @param imageBytes The original image byte array.
* @return A compressed image as a byte array.
*/
private suspend fun compressImage(imageBytes: ByteArray): ByteArray {
return FileKit.compressImage(
bytes = imageBytes,
// Compression quality (0100)
quality = 100,
// Max width in pixels
maxWidth = 1024,
// Max height in pixels
maxHeight = 1024,
// Image format (e.g., PNG or JPEG)
imageFormat = ImageFormat.PNG,
)
}
}

View File

@ -9,13 +9,70 @@
*/
package org.mifospay.core.ui.utils
import androidx.compose.ui.graphics.ImageBitmap
/**
* Platform-specific utilities for sharing content such as text and files.
*
* This expect declaration should be implemented for each platform (e.g., Android, iOS) to handle
* the specifics of sharing functionality.
*/
expect object ShareUtils {
fun shareText(text: String)
/**
* Shares plain text content using the platform's native sharing mechanism.
*
* @param text The text content to be shared.
*/
suspend fun shareText(text: String)
suspend fun shareImage(title: String, image: ImageBitmap)
suspend fun shareImage(title: String, byte: ByteArray)
/**
* Shares a file using the platform's native sharing mechanism.
*
* This is a suspend function, allowing for asynchronous operations such as file preparation
* or permission handling if needed.
*
* @param file A [ShareFileModel] containing the file's metadata and content.
*/
suspend fun shareFile(file: ShareFileModel)
}
/**
* Represents supported MIME types for file sharing.
*/
enum class MimeType {
PDF,
TEXT,
IMAGE,
}
/**
* Model representing a file to be shared.
*
* @property mime The MIME type of the file. Defaults to [MimeType.PDF].
* @property fileName The name of the file, including its extension.
* @property bytes The binary content of the file.
*/
data class ShareFileModel(
val mime: MimeType = MimeType.PDF,
val fileName: String,
val bytes: ByteArray,
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false
other as ShareFileModel
if (mime != other.mime) return false
if (fileName != other.fileName) return false
if (!bytes.contentEquals(other.bytes)) return false
return true
}
override fun hashCode(): Int {
var result = mime.hashCode()
result = 31 * result + fileName.hashCode()
result = 31 * result + bytes.contentHashCode()
return result
}
}

View File

@ -9,27 +9,46 @@
*/
package org.mifospay.core.ui.utils
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asSkiaBitmap
import io.github.vinceglb.filekit.core.FileKit
import io.github.vinceglb.filekit.FileKit
import io.github.vinceglb.filekit.dialogs.openFileSaver
import io.github.vinceglb.filekit.write
/**
* JVM-specific implementation of [ShareUtils] for desktop platforms.
*
* This object simulates file sharing by prompting the user with a "Save As" dialog
* using [FileKit.openFileSaver]. It allows the user to save the content locally,
* which is the most suitable alternative to "sharing" in desktop environments.
*/
actual object ShareUtils {
actual fun shareText(text: String) {
/**
* Prompts the user to save the given text content as a file on their system.
*
* This method uses [FileKit.openFileSaver] to open a native "Save As" dialog,
* and writes the provided text to the selected file location.
*
* @param text The plain text content the user will save to disk.
*/
actual suspend fun shareText(text: String) {
val newFile = FileKit.openFileSaver(
suggestedName = "text.txt",
)
newFile?.write(text.encodeToByteArray())
}
actual suspend fun shareImage(title: String, image: ImageBitmap) {
FileKit.saveFile(
bytes = image.asSkiaBitmap().readPixels(),
baseName = "MifosQrCode",
extension = "png",
)
}
actual suspend fun shareImage(title: String, byte: ByteArray) {
FileKit.saveFile(
bytes = byte,
baseName = "MifosQrCode",
extension = "png",
/**
* Prompts the user to save a binary file (e.g., image, PDF) to their local system.
*
* This is used as a desktop-friendly alternative to file sharing, using
* [FileKit.openFileSaver] to let the user choose the destination file path.
*
* @param file The file to be "shared", including its filename and byte content.
*/
actual suspend fun shareFile(file: ShareFileModel) {
val newFile = FileKit.openFileSaver(
suggestedName = file.fileName,
)
newFile?.write(file.bytes)
}
}

View File

@ -9,27 +9,40 @@
*/
package org.mifospay.core.ui.utils
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asSkiaBitmap
import io.github.vinceglb.filekit.core.FileKit
import io.github.vinceglb.filekit.FileKit
import io.github.vinceglb.filekit.download
/**
* Provides utility functions for sharing content on JS and WASM platforms.
*
* This implementation uses [FileKit.download] to trigger file downloads
* in web environments (JS), as native share dialogs are not supported
* on these platforms.
*/
actual object ShareUtils {
actual fun shareText(text: String) {
/**
* Shares plain text content by triggering a file download.
*
* The text is saved to a file named `text.txt` and offered to the user
* as a downloadable file in the browser.
*
* @param text The plain text content to be shared.
*/
actual suspend fun shareText(text: String) {
FileKit.download(bytes = text.encodeToByteArray(), fileName = "text.txt")
}
actual suspend fun shareImage(title: String, image: ImageBitmap) {
FileKit.saveFile(
bytes = image.asSkiaBitmap().readPixels(),
baseName = "MifosQrCode",
extension = "png",
)
}
actual suspend fun shareImage(title: String, byte: ByteArray) {
FileKit.saveFile(
bytes = byte,
baseName = "MifosQrCode",
extension = "png",
)
/**
* Shares a file by triggering a download of the file's byte content.
*
* This method creates a download link in the browser for the given
* [ShareFileModel.bytes], using the provided [ShareFileModel.fileName]
* as the download file name.
*
* @param file The [ShareFileModel] containing file name and content to be downloaded.
*/
actual suspend fun shareFile(file: ShareFileModel) {
FileKit.download(bytes = file.bytes, fileName = file.fileName)
}
}

View File

@ -9,12 +9,32 @@
*/
package org.mifospay.core.ui.utils
import androidx.compose.ui.graphics.ImageBitmap
import co.touchlab.kermit.Logger
import io.github.vinceglb.filekit.FileKit
import io.github.vinceglb.filekit.ImageFormat
import io.github.vinceglb.filekit.PlatformFile
import io.github.vinceglb.filekit.absolutePath
import io.github.vinceglb.filekit.cacheDir
import io.github.vinceglb.filekit.compressImage
import io.github.vinceglb.filekit.dialogs.shareFile
import io.github.vinceglb.filekit.write
import platform.Foundation.NSURL
import platform.UIKit.UIActivityViewController
import platform.UIKit.UIApplication
/**
* Actual implementation of [ShareUtils] for iOS platform.
*
* Provides functionality to share text and files using iOS native `UIActivityViewController`.
*/
actual object ShareUtils {
actual fun shareText(text: String) {
/**
* Shares plain text using the iOS share sheet (`UIActivityViewController`).
*
* @param text The text content to be shared.
*/
actual suspend fun shareText(text: String) {
val currentViewController = UIApplication.sharedApplication().keyWindow?.rootViewController
val activityViewController = UIActivityViewController(listOf(text), null)
currentViewController?.presentViewController(
@ -24,9 +44,74 @@ actual object ShareUtils {
)
}
actual suspend fun shareImage(title: String, image: ImageBitmap) {
/**
* Shares a file (image or other binary) using the iOS share sheet.
*
* If the file is an image, it will be compressed before sharing.
*
* @param file The file metadata and byte content to share.
*/
actual suspend fun shareFile(file: ShareFileModel) {
try {
val compressedBytes = if (file.mime == MimeType.IMAGE) {
compressImage(file.bytes)
} else {
file.bytes
}
val fileToShare = saveFile(data = compressedBytes, fileName = file.fileName)
FileKit.shareFile(fileToShare)
} catch (e: Exception) {
Logger.e(e) { "Failed to share file: ${e.message}" }
e.printStackTrace()
}
}
actual suspend fun shareImage(title: String, byte: ByteArray) {
/**
* Saves a byte array as a file inside the iOS app's cache directory.
*
* Converts the resulting file path to a properly scoped [NSURL],
* which is necessary for iOS to allow sharing via `UIActivityViewController`.
*
* @param data The file content to write.
* @param fileName The name of the file to create.
* @return A [PlatformFile] backed by a scoped `NSURL`, ready for sharing.
*/
private suspend fun saveFile(data: ByteArray, fileName: String): PlatformFile {
val tempFile = PlatformFile(FileKit.cacheDir, fileName)
tempFile.write(data)
/**
* iOS requires file URLs used in `UIActivityViewController` to be created
* with `NSURL.fileURLWithPath(...)` to ensure they have proper sandbox access.
*
* If the file is created from a raw path string, the system may reject it
* with a sandbox extension error (e.g., "Cannot issue sandbox extension for URL").
*
* Wrapping the path in `NSURL` ensures the file is treated as a valid
* security-scoped resource.
*/
val nsUrl = NSURL.fileURLWithPath(tempFile.absolutePath())
return PlatformFile(nsUrl)
}
/**
* Compresses an image file using [FileKit] logic.
*
* @param imageBytes The original image byte array.
* @return A compressed image as a byte array.
*/
private suspend fun compressImage(imageBytes: ByteArray): ByteArray {
return FileKit.compressImage(
bytes = imageBytes,
// Compression quality (0100)
quality = 100,
// Max width in pixels
maxWidth = 1024,
// Max height in pixels
maxHeight = 1024,
// Image format (e.g., PNG or JPEG)
imageFormat = ImageFormat.PNG,
)
}
}

View File

@ -9,27 +9,40 @@
*/
package org.mifospay.core.ui.utils
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asSkiaBitmap
import io.github.vinceglb.filekit.core.FileKit
import io.github.vinceglb.filekit.FileKit
import io.github.vinceglb.filekit.download
/**
* Provides utility functions for sharing content on JS and WASM platforms.
*
* This implementation uses [FileKit.download] to trigger file downloads
* in web environments (WASM), as native share dialogs are not supported
* on these platforms.
*/
actual object ShareUtils {
actual fun shareText(text: String) {
/**
* Shares plain text content by triggering a file download.
*
* The text is saved to a file named `text.txt` and offered to the user
* as a downloadable file in the browser.
*
* @param text The plain text content to be shared.
*/
actual suspend fun shareText(text: String) {
FileKit.download(bytes = text.encodeToByteArray(), fileName = "text.txt")
}
actual suspend fun shareImage(title: String, image: ImageBitmap) {
FileKit.saveFile(
bytes = image.asSkiaBitmap().readPixels(),
baseName = "MifosQrCode",
extension = "png",
)
}
actual suspend fun shareImage(title: String, byte: ByteArray) {
FileKit.saveFile(
bytes = byte,
baseName = "MifosQrCode",
extension = "png",
)
/**
* Shares a file by triggering a download of the file's byte content.
*
* This method creates a download link in the browser for the given
* [ShareFileModel.bytes], using the provided [ShareFileModel.fileName]
* as the download file name.
*
* @param file The [ShareFileModel] containing file name and content to be downloaded.
*/
actual suspend fun shareFile(file: ShareFileModel) {
FileKit.download(bytes = file.bytes, fileName = file.fileName)
}
}

View File

@ -206,4 +206,4 @@ private fun EditPasswordDialogs(
null -> Unit
}
}
}

View File

@ -179,7 +179,7 @@ internal class EditPasswordViewModel(
it.copy(
dialogState = Error(
Res.string.feature_editpassword_error_password_min_length,
listOf(MIN_PASSWORD_LENGTH)
listOf(MIN_PASSWORD_LENGTH),
),
)
}
@ -233,12 +233,12 @@ internal data class EditPasswordState(
PasswordStrengthState.WEAK_1,
PasswordStrengthState.WEAK_2,
PasswordStrengthState.WEAK_3,
-> false
-> false
PasswordStrengthState.GOOD,
PasswordStrengthState.STRONG,
PasswordStrengthState.VERY_STRONG,
-> true
-> true
}
val isPasswordMatch: Boolean
@ -252,7 +252,7 @@ internal sealed interface EditPasswordDialog {
data object Loading : EditPasswordDialog
data class Error(
val message: StringResource,
val formatArgs: List<Any> = emptyList()
val formatArgs: List<Any> = emptyList(),
) : EditPasswordDialog
data class ApiError(val message: String) : EditPasswordDialog
}
@ -281,4 +281,4 @@ internal sealed interface EditPasswordAction {
val result: PasswordStrengthResult,
) : Internal()
}
}
}

View File

@ -24,8 +24,9 @@ kotlin {
implementation(compose.components.resources)
implementation(compose.components.uiToolingPreview)
implementation(libs.filekit.core)
implementation(libs.filekit.compose)
implementation(libs.coil.kt.compose)
implementation(libs.filekit.dialogs)
implementation(libs.filekit.dialogs.compose)
}
}
}

View File

@ -27,10 +27,8 @@ import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
@ -43,9 +41,6 @@ import coil3.compose.LocalPlatformContext
import coil3.compose.SubcomposeAsyncImage
import coil3.compose.SubcomposeAsyncImageContent
import coil3.compose.rememberAsyncImagePainter
import io.github.vinceglb.filekit.compose.rememberFilePickerLauncher
import io.github.vinceglb.filekit.core.PickerMode
import io.github.vinceglb.filekit.core.PlatformFile
import kotlinx.coroutines.launch
import mobile_wallet.feature.kyc.generated.resources.Res
import mobile_wallet.feature.kyc.generated.resources.feature_kyc_file_name
@ -143,8 +138,9 @@ private fun KYCLevel2ScreenContent(
horizontalAlignment = Alignment.CenterHorizontally,
) {
DocumentPicker(
onChooseDocument = {
onAction(KycLevel2Action.FileChanged(it))
uploadedFile = state.uploadedFile,
onPickFile = {
onAction(KycLevel2Action.PickFile)
},
)
@ -157,9 +153,6 @@ private fun KYCLevel2ScreenContent(
onClickClearIcon = {
onAction(KycLevel2Action.NameChanged(""))
},
// textStyle = TextStyle(
// color = MaterialTheme.colorScheme.onSurface,
// ),
)
MifosTextField(
@ -171,9 +164,6 @@ private fun KYCLevel2ScreenContent(
onClickClearIcon = {
onAction(KycLevel2Action.DescriptionChanged(""))
},
// textStyle = TextStyle(
// color = MaterialTheme.colorScheme.onSurface,
// ),
)
MifosButton(
@ -190,53 +180,16 @@ private fun KYCLevel2ScreenContent(
@Composable
private fun DocumentPicker(
modifier: Modifier = Modifier,
onChooseDocument: (PlatformFile) -> Unit,
uploadedFile: ByteArray?,
onPickFile: () -> Unit,
) {
val scope = rememberCoroutineScope()
val context = LocalPlatformContext.current
var uploadedImage by remember { mutableStateOf<ByteArray?>(null) }
val painter = rememberAsyncImagePainter(
model = uploadedImage,
model = uploadedFile,
imageLoader = ImageLoader(context),
)
val filePicker = rememberFilePickerLauncher(
mode = PickerMode.Single,
) {
scope.launch {
it?.let { file ->
onChooseDocument(file)
uploadedImage = if (file.supportsStreams()) {
val size = file.getSize()
if (size != null && size > 0L) {
val buffer = ByteArray(size.toInt())
val tmpBuffer = ByteArray(1000)
var totalBytesRead = 0
file.getStream().use {
while (it.hasBytesAvailable()) {
val numRead = it.readInto(tmpBuffer, 1000)
tmpBuffer.copyInto(
buffer,
destinationOffset = totalBytesRead,
endIndex = numRead,
)
totalBytesRead += numRead
}
}
buffer
} else {
file.readBytes()
}
} else {
file.readBytes()
}
}
}
}
OutlinedCard(
modifier = modifier
.fillMaxWidth()
@ -253,14 +206,14 @@ private fun DocumentPicker(
),
),
),
onClick = filePicker::launch,
onClick = onPickFile,
) {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center,
) {
SubcomposeAsyncImage(
model = uploadedImage,
model = uploadedFile,
imageLoader = ImageLoader(context),
contentScale = ContentScale.None,
contentDescription = "Uploaded Image",
@ -278,18 +231,11 @@ private fun DocumentPicker(
}
is AsyncImagePainter.State.Error -> {
if (uploadedImage == null) {
AvatarBox(
icon = MifosIcons.Add,
size = 120,
contentColor = MaterialTheme.colorScheme.secondary,
)
} else {
Text(
text = "Unsupported Media Type for Preview",
modifier = Modifier.align(Alignment.Center),
)
}
AvatarBox(
icon = MifosIcons.Add,
size = 120,
contentColor = MaterialTheme.colorScheme.secondary,
)
}
is AsyncImagePainter.State.Loading -> {

View File

@ -11,9 +11,12 @@ package org.mifospay.feature.kyc
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
import io.github.vinceglb.filekit.core.PlatformFile
import io.github.vinceglb.filekit.core.baseName
import io.github.vinceglb.filekit.core.extension
import io.github.vinceglb.filekit.FileKit
import io.github.vinceglb.filekit.dialogs.FileKitMode
import io.github.vinceglb.filekit.dialogs.openFilePicker
import io.github.vinceglb.filekit.extension
import io.github.vinceglb.filekit.name
import io.github.vinceglb.filekit.readBytes
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.update
@ -54,13 +57,18 @@ internal class KYCLevel2ViewModel(
override fun handleAction(action: KycLevel2Action) {
when (action) {
is KycLevel2Action.FileChanged -> {
mutableStateFlow.update {
it.copy(
file = action.file,
name = action.file.baseName,
extension = action.file.extension,
)
is KycLevel2Action.PickFile -> {
viewModelScope.launch {
val file = FileKit.openFilePicker(mode = FileKitMode.Single)
file?.let {
mutableStateFlow.update { state ->
state.copy(
uploadedFile = it.readBytes(),
name = it.name,
extension = it.extension,
)
}
}
}
}
@ -93,7 +101,7 @@ internal class KYCLevel2ViewModel(
}
private fun initiateUploadDocument() = when {
state.file == null -> {
state.uploadedFile == null -> {
mutableStateFlow.update {
it.copy(dialogState = Error("Upload an image or pdf"))
}
@ -120,34 +128,7 @@ internal class KYCLevel2ViewModel(
}
viewModelScope.launch {
val file = state.file?.let { file ->
if (file.supportsStreams()) {
val size = file.getSize()
if (size != null && size > 0L) {
val buffer = ByteArray(size.toInt())
val tmpBuffer = ByteArray(1000)
var totalBytesRead = 0
file.getStream().use {
while (it.hasBytesAvailable()) {
val numRead = it.readInto(tmpBuffer, 1000)
tmpBuffer.copyInto(
buffer,
destinationOffset = totalBytesRead,
endIndex = numRead,
)
totalBytesRead += numRead
}
}
buffer
} else {
file.readBytes()
}
} else {
file.readBytes()
}
}
file?.let {
state.uploadedFile?.let {
val result = repository.createDocument(
entityType = state.entityType,
entityId = state.entityId,
@ -161,7 +142,6 @@ internal class KYCLevel2ViewModel(
}
}
// region HandleDocumentUploadResult
/**
* API call to upload document fails with the following error:
* Unable to create parent directories
@ -193,15 +173,13 @@ internal class KYCLevel2ViewModel(
}
}
}
// endregion
}
@Serializable
internal data class KycLevel2State(
val entityId: Long,
val description: String = "",
@Transient
val file: PlatformFile? = null,
@Transient val uploadedFile: ByteArray? = null,
val name: String = "",
val extension: String = "",
val entityType: String = Constants.ENTITY_TYPE_CLIENTS,
@ -215,6 +193,36 @@ internal data class KycLevel2State(
data object Loading : DialogState
data class Error(val message: String) : DialogState
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false
other as KycLevel2State
if (entityId != other.entityId) return false
if (description != other.description) return false
if (!uploadedFile.contentEquals(other.uploadedFile)) return false
if (name != other.name) return false
if (extension != other.extension) return false
if (entityType != other.entityType) return false
if (dialogState != other.dialogState) return false
if (fileName != other.fileName) return false
return true
}
override fun hashCode(): Int {
var result = entityId.hashCode()
result = 31 * result + description.hashCode()
result = 31 * result + (uploadedFile?.contentHashCode() ?: 0)
result = 31 * result + name.hashCode()
result = 31 * result + extension.hashCode()
result = 31 * result + entityType.hashCode()
result = 31 * result + (dialogState?.hashCode() ?: 0)
result = 31 * result + fileName.hashCode()
return result
}
}
internal sealed interface KycLevel2Event {
@ -225,13 +233,13 @@ internal sealed interface KycLevel2Event {
internal sealed interface KycLevel2Action {
data class DescriptionChanged(val desc: String) : KycLevel2Action
data class FileChanged(val file: PlatformFile) : KycLevel2Action
data class NameChanged(val name: String) : KycLevel2Action
data object SubmitClicked : KycLevel2Action
data object NavigateBack : KycLevel2Action
data object DismissDialog : KycLevel2Action
data object PickFile : KycLevel2Action
sealed interface Internal : KycLevel2Action {
data class HandleDocumentUploadResult(val result: DataState<String>) : Internal

View File

@ -30,7 +30,8 @@ kotlin {
implementation(compose.components.uiToolingPreview)
implementation(libs.coil.kt.compose)
implementation(libs.filekit.core)
implementation(libs.filekit.compose)
implementation(libs.filekit.dialogs)
implementation(libs.filekit.dialogs.compose)
}
}
}

View File

@ -19,12 +19,6 @@ import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@ -34,9 +28,6 @@ import coil3.ImageLoader
import coil3.compose.AsyncImage
import coil3.compose.LocalPlatformContext
import coil3.request.ImageRequest
import io.github.vinceglb.filekit.compose.rememberFilePickerLauncher
import io.github.vinceglb.filekit.core.PickerMode
import kotlinx.coroutines.launch
import mobile_wallet.feature.profile.generated.resources.Res
import mobile_wallet.feature.profile.generated.resources.placeholder
import org.jetbrains.compose.resources.painterResource
@ -86,58 +77,10 @@ fun ProfileImage(
@Composable
fun EditableProfileImage(
modifier: Modifier = Modifier,
serverImage: String? = null,
onChooseImage: (String) -> Unit,
profileImage: ByteArray? = null,
onPickImage: () -> Unit,
) {
val context = LocalPlatformContext.current
val scope = rememberCoroutineScope()
var bytes by remember(serverImage) { mutableStateOf<ByteArray?>(null) }
LaunchedEffect(serverImage) {
if (serverImage != null) {
bytes = try {
Base64.decode(serverImage)
} catch (e: Exception) {
null
}
}
}
// Pick files from Compose
val launcher = rememberFilePickerLauncher(mode = PickerMode.Single) { file ->
scope.launch {
if (file != null) {
bytes = if (file.supportsStreams()) {
val size = file.getSize()
if (size != null && size > 0L) {
val buffer = ByteArray(size.toInt())
val tmpBuffer = ByteArray(1000)
var totalBytesRead = 0
file.getStream().use {
while (it.hasBytesAvailable()) {
val numRead = it.readInto(tmpBuffer, 1000)
tmpBuffer.copyInto(
buffer,
destinationOffset = totalBytesRead,
endIndex = numRead,
)
totalBytesRead += numRead
}
}
buffer
} else {
file.readBytes()
}
} else {
file.readBytes()
}
bytes?.let {
onChooseImage(Base64.encode(it))
}
}
}
}
Box(
modifier = modifier
@ -145,7 +88,7 @@ fun EditableProfileImage(
contentAlignment = Alignment.Center,
) {
AsyncImage(
model = bytes,
model = profileImage,
error = painterResource(Res.drawable.placeholder),
fallback = painterResource(Res.drawable.placeholder),
imageLoader = ImageLoader(context),
@ -158,9 +101,7 @@ fun EditableProfileImage(
)
IconButton(
onClick = {
launcher.launch()
},
onClick = onPickImage,
modifier = Modifier
.offset(y = 12.dp)
.size(36.dp)

View File

@ -114,9 +114,9 @@ private fun EditProfileScreenContent(
) {
item {
EditableProfileImage(
serverImage = state.imageInput,
onChooseImage = {
onAction(EditProfileAction.ProfileImageChange(it))
profileImage = state.profileImage,
onPickImage = {
onAction(EditProfileAction.PickProfileImage)
},
)
}

View File

@ -11,6 +11,10 @@ package org.mifospay.feature.profile.edit
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
import io.github.vinceglb.filekit.FileKit
import io.github.vinceglb.filekit.dialogs.FileKitType
import io.github.vinceglb.filekit.dialogs.openFilePicker
import io.github.vinceglb.filekit.readBytes
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.update
@ -104,7 +108,7 @@ internal class EditProfileViewModel(
sendEvent(EditProfileEvent.NavigateBack)
}
is EditProfileAction.ProfileImageChange -> handleChangeProfileImage(action)
is EditProfileAction.PickProfileImage -> handlePickProfileImage(action)
is OnUpdateProfileResult -> handleUpdateProfileResult(action)
@ -122,7 +126,7 @@ internal class EditProfileViewModel(
when (action.result) {
is DataState.Success -> {
mutableStateFlow.update {
it.copy(imageInput = action.result.data)
it.copy(profileImage = action.result.data.encodeToByteArray())
}
}
@ -146,9 +150,14 @@ internal class EditProfileViewModel(
}.launchIn(viewModelScope)
}
private fun handleChangeProfileImage(action: EditProfileAction.ProfileImageChange) {
mutableStateFlow.update {
it.copy(imageInput = action.imageString)
private fun handlePickProfileImage(action: EditProfileAction.PickProfileImage) {
viewModelScope.launch {
val file = FileKit.openFilePicker(FileKitType.Image)
file?.let {
mutableStateFlow.update { state ->
state.copy(profileImage = it.readBytes())
}
}
}
}
@ -216,10 +225,10 @@ internal class EditProfileViewModel(
is DataState.Success -> {
viewModelScope.launch {
if (state.imageInput != null) {
if (state.profileImage != null) {
val result = clientRepository.updateClientImage(
state.clientId,
state.imageInput!!,
state.profileImage!!.decodeToString(),
)
sendAction(HandleUpdateClientImageResult(result))
}
@ -268,7 +277,7 @@ internal data class EditProfileState(
val phoneNumberInput: String,
val emailInput: String,
val externalIdInput: String,
val imageInput: String? = null,
val profileImage: ByteArray? = null,
val dialogState: DialogState? = null,
) {
@Transient
@ -288,6 +297,38 @@ internal data class EditProfileState(
@Serializable
data class Error(val message: String) : DialogState
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false
other as EditProfileState
if (clientId != other.clientId) return false
if (firstNameInput != other.firstNameInput) return false
if (lastNameInput != other.lastNameInput) return false
if (phoneNumberInput != other.phoneNumberInput) return false
if (emailInput != other.emailInput) return false
if (externalIdInput != other.externalIdInput) return false
if (!profileImage.contentEquals(other.profileImage)) return false
if (dialogState != other.dialogState) return false
if (updatedClient != other.updatedClient) return false
return true
}
override fun hashCode(): Int {
var result = clientId.hashCode()
result = 31 * result + firstNameInput.hashCode()
result = 31 * result + lastNameInput.hashCode()
result = 31 * result + phoneNumberInput.hashCode()
result = 31 * result + emailInput.hashCode()
result = 31 * result + externalIdInput.hashCode()
result = 31 * result + (profileImage?.contentHashCode() ?: 0)
result = 31 * result + (dialogState?.hashCode() ?: 0)
result = 31 * result + updatedClient.hashCode()
return result
}
}
sealed interface EditProfileEvent {
@ -302,12 +343,11 @@ sealed interface EditProfileAction {
data class EmailInputChange(val email: String) : EditProfileAction
data class ExternalIdInputChange(val externalId: String) : EditProfileAction
data class ProfileImageChange(val imageString: String) : EditProfileAction
data object DismissErrorDialog : EditProfileAction
data object NavigateBack : EditProfileAction
data object UpdateProfile : EditProfileAction
data object PickProfileImage : EditProfileAction
sealed interface Internal : EditProfileAction {
data class LoadClientImage(val clientId: Long) : Internal

View File

@ -28,8 +28,6 @@ kotlin {
implementation(compose.components.resources)
implementation(compose.components.uiToolingPreview)
implementation(libs.coil.kt.compose)
implementation(libs.filekit.core)
implementation(libs.filekit.compose)
}
androidMain.dependencies {

View File

@ -48,6 +48,8 @@ import org.mifospay.core.model.account.DefaultAccount
import org.mifospay.core.model.client.Client
import org.mifospay.core.model.utils.PaymentQrData
import org.mifospay.core.ui.utils.BaseViewModel
import org.mifospay.core.ui.utils.MimeType
import org.mifospay.core.ui.utils.ShareFileModel
import org.mifospay.core.ui.utils.ShareUtils
class ShowQrViewModel(
@ -127,9 +129,12 @@ class ShowQrViewModel(
is ShowQrAction.ShareQrCode -> {
viewModelScope.launch {
ShareUtils.shareImage(
title = "Share QR Code",
byte = action.data,
ShareUtils.shareFile(
file = ShareFileModel(
fileName = "qr_code.png",
bytes = action.data,
mime = MimeType.IMAGE,
),
)
}
}

View File

@ -103,7 +103,7 @@ mokoPermission = "0.18.0"
qroseVersion = "1.0.1"
okioVersion = "3.9.1"
kermit = "2.0.4"
fileKit = "0.8.7"
fileKit = "0.10.0-beta04"
wire = "5.0.0"
# Jetbrains CMP
@ -311,7 +311,8 @@ squareup-okio = { group = "com.squareup.okio", name = "okio", version.ref = "oki
back-handler = { group = "com.arkivanov.essenty", name = "back-handler", version.ref = "backHandlerVersion" }
constraint-layout = { group = "tech.annexflow.compose", name="constraintlayout-compose-multiplatform", version.ref = "constraintLayout" }
filekit-core = { group = "io.github.vinceglb", name = "filekit-core", version.ref = "fileKit" }
filekit-compose = { group = "io.github.vinceglb", name = "filekit-compose", version.ref = "fileKit" }
filekit-dialogs = { module = "io.github.vinceglb:filekit-dialogs", version.ref = "fileKit" }
filekit-dialogs-compose = { module = "io.github.vinceglb:filekit-dialogs-compose", version.ref = "fileKit" }
qrose = { group = "io.github.alexzhirkevich", name="qrose", version.ref = "qroseVersion" }
kermit-logging = { group = "co.touchlab", name = "kermit", version.ref = "kermit" }

View File

@ -84,6 +84,8 @@ dependencies {
implementation(projects.core.data)
implementation(projects.core.ui)
implementation(libs.filekit.dialogs)
// Compose
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)

View File

@ -27,15 +27,15 @@
| | \--- androidx.lifecycle:lifecycle-common-jvm:2.8.7
| | +--- androidx.annotation:annotation:1.8.1 -> 1.9.1 (*)
| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (*)
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.10.1
| | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.1
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.10.2
| | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.2
| | | +--- org.jetbrains:annotations:23.0.0
| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.1
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.1 (c)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.1 (c)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (c)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.10.1 (c)
| | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:1.10.1 (c)
| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.2
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2 (c)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.2 (c)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 (c)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.10.2 (c)
| | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:1.10.2 (c)
| | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.0 -> 2.1.21 (*)
| | +--- androidx.lifecycle:lifecycle-common-java8:2.8.7 (c)
| | +--- androidx.lifecycle:lifecycle-livedata:2.8.7 (c)
@ -55,16 +55,16 @@
| | +--- androidx.concurrent:concurrent-futures:1.1.0
| | | +--- androidx.annotation:annotation:1.1.0 -> 1.9.1 (*)
| | | \--- com.google.guava:listenablefuture:1.0 -> 9999.0-empty-to-avoid-conflict-with-guava
| | +--- androidx.startup:startup-runtime:1.1.1
| | | +--- androidx.annotation:annotation:1.1.0 -> 1.9.1 (*)
| | +--- androidx.startup:startup-runtime:1.1.1 -> 1.2.0
| | | +--- androidx.annotation:annotation:1.8.1 -> 1.9.1 (*)
| | | \--- androidx.tracing:tracing:1.0.0 -> 1.3.0-alpha02
| | | +--- androidx.annotation:annotation:1.2.0 -> 1.9.1 (*)
| | | \--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (c)
| | \--- com.google.guava:listenablefuture:1.0 -> 9999.0-empty-to-avoid-conflict-with-guava
| +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (*)
| +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.1
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.1 (*)
| +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.2
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 (*)
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.2 (*)
| | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.0 -> 2.1.21 (*)
| +--- androidx.lifecycle:lifecycle-common:2.8.7 (c)
| +--- androidx.lifecycle:lifecycle-common-java8:2.8.7 (c)
@ -88,13 +88,13 @@
| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.9.20 -> 2.1.21 (*)
| | \--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.20
| | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.20 -> 2.1.21 (*)
| +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1 -> 1.10.1 (*)
| +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1 -> 1.10.2 (*)
| +--- androidx.lifecycle:lifecycle-runtime-ktx:2.6.1 -> 2.8.7
| | \--- androidx.lifecycle:lifecycle-runtime-ktx-android:2.8.7
| | +--- androidx.annotation:annotation:1.8.0 -> 1.9.1 (*)
| | +--- androidx.lifecycle:lifecycle-runtime:2.8.7 (*)
| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (*)
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.1 (*)
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.2 (*)
| | +--- androidx.lifecycle:lifecycle-common:2.8.7 (c)
| | +--- androidx.lifecycle:lifecycle-common-java8:2.8.7 (c)
| | +--- androidx.lifecycle:lifecycle-livedata:2.8.7 (c)
@ -146,7 +146,7 @@
| | | +--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7 (c)
| | | \--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.7 (c)
| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (*)
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.10.1 (*)
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.10.2 (*)
| | +--- androidx.lifecycle:lifecycle-common:2.8.7 (c)
| | +--- androidx.lifecycle:lifecycle-common-java8:2.8.7 (c)
| | +--- androidx.lifecycle:lifecycle-livedata-core:2.8.7 (c)
@ -163,7 +163,7 @@
| +--- androidx.lifecycle:lifecycle-process:2.6.1 -> 2.8.7
| | +--- androidx.annotation:annotation:1.2.0 -> 1.9.1 (*)
| | +--- androidx.lifecycle:lifecycle-runtime:2.8.7 (*)
| | +--- androidx.startup:startup-runtime:1.1.1 (*)
| | +--- androidx.startup:startup-runtime:1.1.1 -> 1.2.0 (*)
| | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (*)
| | +--- androidx.lifecycle:lifecycle-common:2.8.7 (c)
| | +--- androidx.lifecycle:lifecycle-common-java8:2.8.7 (c)
@ -198,8 +198,8 @@
| \--- androidx.lifecycle:lifecycle-viewmodel-android:2.8.7
| +--- androidx.annotation:annotation:1.8.0 -> 1.9.1 (*)
| +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (*)
| +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.1 (*)
| +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.10.1 (*)
| +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.2 (*)
| +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.10.2 (*)
| +--- androidx.lifecycle:lifecycle-common:2.8.7 (c)
| +--- androidx.lifecycle:lifecycle-common-java8:2.8.7 (c)
| +--- androidx.lifecycle:lifecycle-livedata:2.8.7 (c)
@ -265,8 +265,8 @@
| | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.7.10 -> 2.1.21 (*)
| | +--- androidx.collection:collection:1.5.0 (*)
| | +--- org.jetbrains.kotlin:kotlin-stdlib -> 2.1.21 (*)
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.1 (*)
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.10.1 (*)
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.2 (*)
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.10.2 (*)
| | +--- androidx.compose.runtime:runtime-tracing:1.8.2 (c)
| | +--- androidx.compose.runtime:runtime-saveable:1.8.2 (c)
| | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.24 -> 2.1.21 (c)
@ -302,33 +302,36 @@
| | +--- androidx.compose.runtime:runtime:1.6.0 -> 1.8.2 (*)
| | +--- androidx.compose.ui:ui:1.6.0 -> 1.8.2
| | | \--- androidx.compose.ui:ui-android:1.8.2
| | | +--- androidx.activity:activity-ktx:1.7.0 -> 1.9.3
| | | | +--- androidx.activity:activity:1.9.3
| | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.9.1 (*)
| | | | | +--- androidx.collection:collection:1.0.0 -> 1.5.0 (*)
| | | | | +--- androidx.core:core:1.13.0 -> 1.15.0
| | | +--- androidx.activity:activity-ktx:1.7.0 -> 1.10.1
| | | | +--- androidx.activity:activity:1.10.1
| | | | | +--- androidx.annotation:annotation:1.8.1 -> 1.9.1 (*)
| | | | | +--- androidx.core:core-ktx:1.13.0 -> 1.15.0
| | | | | | +--- androidx.annotation:annotation:1.8.1 -> 1.9.1 (*)
| | | | | | +--- androidx.annotation:annotation-experimental:1.4.1 (*)
| | | | | | +--- androidx.collection:collection:1.4.2 -> 1.5.0 (*)
| | | | | | +--- androidx.concurrent:concurrent-futures:1.0.0 -> 1.1.0 (*)
| | | | | | +--- androidx.interpolator:interpolator:1.0.0
| | | | | | | \--- androidx.annotation:annotation:1.0.0 -> 1.9.1 (*)
| | | | | | +--- androidx.lifecycle:lifecycle-runtime:2.6.2 -> 2.8.7 (*)
| | | | | | +--- androidx.tracing:tracing:1.2.0 -> 1.3.0-alpha02 (*)
| | | | | | +--- androidx.versionedparcelable:versionedparcelable:1.1.1
| | | | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.9.1 (*)
| | | | | | | \--- androidx.collection:collection:1.0.0 -> 1.5.0 (*)
| | | | | | +--- androidx.core:core:1.15.0
| | | | | | | +--- androidx.annotation:annotation:1.8.1 -> 1.9.1 (*)
| | | | | | | +--- androidx.annotation:annotation-experimental:1.4.1 (*)
| | | | | | | +--- androidx.collection:collection:1.4.2 -> 1.5.0 (*)
| | | | | | | +--- androidx.concurrent:concurrent-futures:1.0.0 -> 1.1.0 (*)
| | | | | | | +--- androidx.interpolator:interpolator:1.0.0
| | | | | | | | \--- androidx.annotation:annotation:1.0.0 -> 1.9.1 (*)
| | | | | | | +--- androidx.lifecycle:lifecycle-runtime:2.6.2 -> 2.8.7 (*)
| | | | | | | +--- androidx.tracing:tracing:1.2.0 -> 1.3.0-alpha02 (*)
| | | | | | | +--- androidx.versionedparcelable:versionedparcelable:1.1.1
| | | | | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.9.1 (*)
| | | | | | | | \--- androidx.collection:collection:1.0.0 -> 1.5.0 (*)
| | | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (*)
| | | | | | | \--- androidx.core:core-ktx:1.15.0 (c)
| | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (*)
| | | | | | \--- androidx.core:core-ktx:1.15.0 (c)
| | | | | | \--- androidx.core:core:1.15.0 (c)
| | | | | +--- androidx.core:core-viewtree:1.0.0
| | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib -> 2.1.21 (*)
| | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (c)
| | | | | +--- androidx.lifecycle:lifecycle-common:2.6.1 -> 2.8.7 (*)
| | | | | +--- androidx.lifecycle:lifecycle-runtime:2.6.1 -> 2.8.7 (*)
| | | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.6.1 -> 2.8.7 (*)
| | | | | +--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.1 -> 2.8.7
| | | | | | +--- androidx.annotation:annotation:1.0.0 -> 1.9.1 (*)
| | | | | | +--- androidx.core:core-ktx:1.2.0 -> 1.15.0
| | | | | | | +--- androidx.annotation:annotation:1.8.1 -> 1.9.1 (*)
| | | | | | | +--- androidx.core:core:1.15.0 (*)
| | | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (*)
| | | | | | | \--- androidx.core:core:1.15.0 (c)
| | | | | | +--- androidx.core:core-ktx:1.2.0 -> 1.15.0 (*)
| | | | | | +--- androidx.lifecycle:lifecycle-livedata-core:2.8.7 (*)
| | | | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.8.7 (*)
| | | | | | +--- androidx.savedstate:savedstate:1.2.1
@ -338,7 +341,7 @@
| | | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.10 -> 2.1.21 (*)
| | | | | | | \--- androidx.savedstate:savedstate-ktx:1.2.1 (c)
| | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (*)
| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.1 (*)
| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.2 (*)
| | | | | | +--- androidx.lifecycle:lifecycle-common:2.8.7 (c)
| | | | | | +--- androidx.lifecycle:lifecycle-common-java8:2.8.7 (c)
| | | | | | +--- androidx.lifecycle:lifecycle-livedata:2.8.7 (c)
@ -352,18 +355,19 @@
| | | | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.8.7 (c)
| | | | | | +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.7 (c)
| | | | | | \--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7 (c)
| | | | | +--- androidx.profileinstaller:profileinstaller:1.3.1 -> 1.4.1 (*)
| | | | | +--- androidx.profileinstaller:profileinstaller:1.4.0 -> 1.4.1 (*)
| | | | | +--- androidx.savedstate:savedstate:1.2.1 (*)
| | | | | +--- androidx.tracing:tracing:1.0.0 -> 1.3.0-alpha02 (*)
| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (*)
| | | | | +--- androidx.activity:activity-compose:1.9.3 (c)
| | | | | \--- androidx.activity:activity-ktx:1.9.3 (c)
| | | | +--- androidx.core:core-ktx:1.13.0 -> 1.15.0 (*)
| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib -> 2.1.21 (*)
| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.10.2 (*)
| | | | | +--- androidx.activity:activity-compose:1.10.1 (c)
| | | | | +--- androidx.activity:activity-ktx:1.10.1 (c)
| | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (c)
| | | | +--- androidx.lifecycle:lifecycle-runtime-ktx:2.6.1 -> 2.8.7 (*)
| | | | +--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1 -> 2.8.7
| | | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.8.7 (*)
| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (*)
| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.1 (*)
| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.2 (*)
| | | | | +--- androidx.lifecycle:lifecycle-livedata:2.8.7 (c)
| | | | | +--- androidx.lifecycle:lifecycle-process:2.8.7 (c)
| | | | | +--- androidx.lifecycle:lifecycle-runtime:2.8.7 (c)
@ -381,9 +385,8 @@
| | | | | +--- androidx.savedstate:savedstate:1.2.1 (*)
| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.10 -> 2.1.21 (*)
| | | | | \--- androidx.savedstate:savedstate:1.2.1 (c)
| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (*)
| | | | +--- androidx.activity:activity:1.9.3 (c)
| | | | \--- androidx.activity:activity-compose:1.9.3 (c)
| | | | +--- androidx.activity:activity:1.10.1 (c)
| | | | \--- androidx.activity:activity-compose:1.10.1 (c)
| | | +--- androidx.annotation:annotation:1.8.1 -> 1.9.1 (*)
| | | +--- androidx.annotation:annotation-experimental:1.4.1 (*)
| | | +--- androidx.autofill:autofill:1.0.0
@ -478,10 +481,10 @@
| | | | | +--- androidx.collection:collection:1.1.0 -> 1.5.0 (*)
| | | | | +--- androidx.core:core:1.3.0 -> 1.15.0 (*)
| | | | | +--- androidx.lifecycle:lifecycle-process:2.4.1 -> 2.8.7 (*)
| | | | | +--- androidx.startup:startup-runtime:1.0.0 -> 1.1.1 (*)
| | | | | +--- androidx.startup:startup-runtime:1.0.0 -> 1.2.0 (*)
| | | | | \--- androidx.emoji2:emoji2-views-helper:1.4.0 (c)
| | | | +--- org.jetbrains.kotlin:kotlin-stdlib -> 2.1.21 (*)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.10.1 (*)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.10.2 (*)
| | | | +--- androidx.compose.ui:ui:1.8.2 (c)
| | | | +--- androidx.compose.ui:ui-geometry:1.8.2 (c)
| | | | +--- androidx.compose.ui:ui-graphics:1.8.2 (c)
@ -502,8 +505,8 @@
| | | +--- androidx.profileinstaller:profileinstaller:1.4.0 -> 1.4.1 (*)
| | | +--- androidx.savedstate:savedstate-ktx:1.2.1 (*)
| | | +--- org.jetbrains.kotlin:kotlin-stdlib -> 2.1.21 (*)
| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.1 (*)
| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.10.1 (*)
| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.2 (*)
| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.10.2 (*)
| | | +--- org.jspecify:jspecify:1.0.0
| | | +--- androidx.compose.ui:ui-geometry:1.8.2 (c)
| | | +--- androidx.compose.ui:ui-graphics:1.8.2 (c)
@ -564,7 +567,7 @@
| | | | +--- org.jetbrains.compose.annotation-internal:annotation:1.6.11 -> 1.8.2
| | | | | \--- androidx.annotation:annotation:1.9.1 (*)
| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.9.24 -> 2.1.21 (*)
| | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.1 (*)
| | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.2 (*)
| | | +--- org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.3
| | | | +--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.5 -> 2.8.7 (*)
| | | | +--- org.jetbrains.androidx.core:core-bundle:1.0.1
@ -575,7 +578,7 @@
| | | | | +--- androidx.lifecycle:lifecycle-common:2.8.5 -> 2.8.7 (*)
| | | | | +--- org.jetbrains.compose.annotation-internal:annotation:1.6.11 -> 1.8.2 (*)
| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.9.24 -> 2.1.21 (*)
| | | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.1 (*)
| | | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.2 (*)
| | | | +--- org.jetbrains.androidx.lifecycle:lifecycle-viewmodel:2.8.3 -> 2.8.4 (*)
| | | | +--- org.jetbrains.androidx.savedstate:savedstate:1.2.2
| | | | | +--- androidx.arch.core:core-common:2.2.0 (*)
@ -590,7 +593,7 @@
| | | +--- org.jetbrains.androidx.savedstate:savedstate:1.2.2 (*)
| | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.21 -> 2.1.21 (*)
| | +--- androidx.appcompat:appcompat:1.7.0
| | | +--- androidx.activity:activity:1.7.0 -> 1.9.3 (*)
| | | +--- androidx.activity:activity:1.7.0 -> 1.10.1 (*)
| | | +--- androidx.annotation:annotation:1.3.0 -> 1.9.1 (*)
| | | +--- androidx.appcompat:appcompat-resources:1.7.0
| | | | +--- androidx.annotation:annotation:1.2.0 -> 1.9.1 (*)
@ -624,7 +627,7 @@
| | | | +--- androidx.emoji2:emoji2:1.4.0 (*)
| | | | \--- androidx.emoji2:emoji2:1.4.0 (c)
| | | +--- androidx.fragment:fragment:1.5.4 -> 1.8.5
| | | | +--- androidx.activity:activity:1.8.1 -> 1.9.3 (*)
| | | | +--- androidx.activity:activity:1.8.1 -> 1.10.1 (*)
| | | | +--- androidx.annotation:annotation:1.1.0 -> 1.9.1 (*)
| | | | +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*)
| | | | +--- androidx.collection:collection:1.1.0 -> 1.5.0 (*)
@ -655,9 +658,9 @@
| | | +--- androidx.savedstate:savedstate:1.2.1 (*)
| | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (*)
| | | \--- androidx.appcompat:appcompat-resources:1.7.0 (c)
| | +--- androidx.activity:activity-ktx:1.9.3 (*)
| | +--- androidx.activity:activity-ktx:1.9.3 -> 1.10.1 (*)
| | +--- androidx.fragment:fragment-ktx:1.8.5
| | | +--- androidx.activity:activity-ktx:1.8.1 -> 1.9.3 (*)
| | | +--- androidx.activity:activity-ktx:1.8.1 -> 1.10.1 (*)
| | | +--- androidx.collection:collection-ktx:1.1.0 -> 1.5.0 (*)
| | | +--- androidx.core:core-ktx:1.2.0 -> 1.15.0 (*)
| | | +--- androidx.fragment:fragment:1.8.5 (*)
@ -696,7 +699,7 @@
| | | | | +--- androidx.collection:collection:1.5.0 (*)
| | | | | \--- org.jetbrains.kotlin:kotlin-stdlib -> 2.1.21 (*)
| | | | +--- org.jetbrains.kotlin:kotlin-stdlib -> 2.1.21 (*)
| | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.1 (*)
| | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.2 (*)
| | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.21 -> 2.1.21 (*)
| | +--- androidx.compose.runtime:runtime:1.6.8 -> 1.8.2 (*)
| | +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.7 (*)
@ -707,7 +710,7 @@
| | | +--- androidx.navigation:navigation-fragment:2.8.5
| | | | +--- androidx.fragment:fragment-ktx:1.6.2 -> 1.8.5 (*)
| | | | +--- androidx.navigation:navigation-runtime:2.8.5
| | | | | +--- androidx.activity:activity-ktx:1.7.1 -> 1.9.3 (*)
| | | | | +--- androidx.activity:activity-ktx:1.7.1 -> 1.10.1 (*)
| | | | | +--- androidx.annotation:annotation-experimental:1.4.1 (*)
| | | | | +--- androidx.collection:collection:1.4.2 -> 1.5.0 (*)
| | | | | +--- androidx.lifecycle:lifecycle-runtime-ktx:2.6.2 -> 2.8.7 (*)
@ -759,7 +762,7 @@
| | | | | | | +--- androidx.annotation:annotation:1.6.0 -> 1.9.1 (*)
| | | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.8.20 -> 2.1.21 (*)
| | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (*)
| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.1 (*)
| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.2 (*)
| | | | | | \--- androidx.window:window-core:1.3.0 (c)
| | | | | \--- androidx.transition:transition:1.4.1
| | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.9.1 (*)
@ -802,7 +805,7 @@
| | +--- androidx.tracing:tracing-ktx:1.3.0-alpha02 (*)
| | +--- io.insert-koin:koin-android:4.0.1-RC1 (*)
| | +--- project :core:common
| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0 -> 1.10.1 (*)
| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0 -> 1.10.2 (*)
| | | +--- io.coil-kt.coil3:coil:3.0.0-alpha10
| | | | \--- io.coil-kt.coil3:coil-android:3.0.0-alpha10
| | | | +--- io.coil-kt.coil3:coil-core:3.0.0-alpha10
@ -811,11 +814,12 @@
| | | | | +--- androidx.annotation:annotation:1.8.1 -> 1.9.1 (*)
| | | | | +--- androidx.appcompat:appcompat-resources:1.7.0 (*)
| | | | | +--- androidx.core:core-ktx:1.13.1 -> 1.15.0 (*)
| | | | | +--- androidx.exifinterface:exifinterface:1.3.7
| | | | | | \--- androidx.annotation:annotation:1.2.0 -> 1.9.1 (*)
| | | | | +--- androidx.exifinterface:exifinterface:1.3.7 -> 1.4.1
| | | | | | +--- androidx.annotation:annotation:1.8.1 -> 1.9.1 (*)
| | | | | | \--- org.jspecify:jspecify:1.0.0
| | | | | +--- androidx.profileinstaller:profileinstaller:1.3.1 -> 1.4.1 (*)
| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1 -> 1.10.1 (*)
| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1 -> 1.10.1 (*)
| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1 -> 1.10.2 (*)
| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1 -> 1.10.2 (*)
| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.10 -> 2.1.21 (*)
| | | | | \--- com.squareup.okio:okio:3.9.0 -> 3.10.2
| | | | | \--- com.squareup.okio:okio-jvm:3.10.2
@ -839,25 +843,25 @@
| | | | +--- io.ktor:ktor-client-core:3.0.0-beta-2 -> 3.1.2
| | | | | \--- io.ktor:ktor-client-core-jvm:3.1.2
| | | | | +--- org.slf4j:slf4j-api:2.0.16
| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 -> 1.10.2 (*)
| | | | | +--- io.ktor:ktor-http:3.1.2
| | | | | | \--- io.ktor:ktor-http-jvm:3.1.2
| | | | | | +--- org.slf4j:slf4j-api:2.0.16
| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 -> 1.10.2 (*)
| | | | | | +--- io.ktor:ktor-utils:3.1.2
| | | | | | | \--- io.ktor:ktor-utils-jvm:3.1.2
| | | | | | | +--- org.slf4j:slf4j-api:2.0.16
| | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 -> 1.10.2 (*)
| | | | | | | +--- io.ktor:ktor-io:3.1.2
| | | | | | | | \--- io.ktor:ktor-io-jvm:3.1.2
| | | | | | | | +--- org.slf4j:slf4j-api:2.0.16
| | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-io-core:0.6.0
| | | | | | | | | \--- org.jetbrains.kotlinx:kotlinx-io-core-jvm:0.6.0
| | | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-io-bytestring:0.6.0
| | | | | | | | | | \--- org.jetbrains.kotlinx:kotlinx-io-bytestring-jvm:0.6.0
| | | | | | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0 -> 2.1.21 (*)
| | | | | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0 -> 2.1.21 (*)
| | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 -> 1.10.2 (*)
| | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-io-core:0.6.0 -> 0.7.0
| | | | | | | | | \--- org.jetbrains.kotlinx:kotlinx-io-core-jvm:0.7.0
| | | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-io-bytestring:0.7.0
| | | | | | | | | | \--- org.jetbrains.kotlinx:kotlinx-io-bytestring-jvm:0.7.0
| | | | | | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.0 -> 2.1.21 (*)
| | | | | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.0 -> 2.1.21 (*)
| | | | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
| | | | | | | +--- org.jetbrains.kotlinx:kotlinx-serialization-core:1.8.0 (*)
| | | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
@ -869,31 +873,31 @@
| | | | | | +--- io.ktor:ktor-network:3.1.2
| | | | | | | \--- io.ktor:ktor-network-jvm:3.1.2
| | | | | | | +--- org.slf4j:slf4j-api:2.0.16
| | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 -> 1.10.2 (*)
| | | | | | | +--- io.ktor:ktor-utils:3.1.2 (*)
| | | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 -> 1.10.2 (*)
| | | | | | +--- io.ktor:ktor-http:3.1.2 (*)
| | | | | | +--- io.ktor:ktor-io:3.1.2 (*)
| | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
| | | | | +--- io.ktor:ktor-events:3.1.2
| | | | | | \--- io.ktor:ktor-events-jvm:3.1.2
| | | | | | +--- org.slf4j:slf4j-api:2.0.16
| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 -> 1.10.2 (*)
| | | | | | +--- io.ktor:ktor-utils:3.1.2 (*)
| | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
| | | | | +--- io.ktor:ktor-websocket-serialization:3.1.2
| | | | | | \--- io.ktor:ktor-websocket-serialization-jvm:3.1.2
| | | | | | +--- org.slf4j:slf4j-api:2.0.16
| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 -> 1.10.2 (*)
| | | | | | +--- io.ktor:ktor-serialization:3.1.2
| | | | | | | \--- io.ktor:ktor-serialization-jvm:3.1.2
| | | | | | | +--- org.slf4j:slf4j-api:2.0.16
| | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 -> 1.10.2 (*)
| | | | | | | +--- io.ktor:ktor-websockets:3.1.2
| | | | | | | | \--- io.ktor:ktor-websockets-jvm:3.1.2
| | | | | | | | +--- org.slf4j:slf4j-api:2.0.16
| | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 -> 1.10.2 (*)
| | | | | | | | +--- io.ktor:ktor-utils:3.1.2 (*)
| | | | | | | | +--- io.ktor:ktor-http:3.1.2 (*)
| | | | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
@ -902,14 +906,14 @@
| | | | | +--- io.ktor:ktor-sse:3.1.2
| | | | | | \--- io.ktor:ktor-sse-jvm:3.1.2
| | | | | | +--- org.slf4j:slf4j-api:2.0.16
| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 -> 1.10.2 (*)
| | | | | | +--- io.ktor:ktor-utils:3.1.2 (*)
| | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
| | | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:1.10.1
| | | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:1.10.1 -> 1.10.2
| | | | | +--- org.slf4j:slf4j-api:1.7.32 -> 2.0.16
| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.1 (*)
| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 (*)
| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.2 (*)
| | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.0 -> 2.1.21 (*)
| | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.10 -> 2.1.21 (*)
| | | +--- co.touchlab:kermit:2.0.4
@ -928,7 +932,7 @@
| | | +--- io.insert-koin:koin-annotations:1.4.0-RC4
| | | | \--- io.insert-koin:koin-annotations-jvm:1.4.0-RC4
| | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.24 -> 2.1.21 (*)
| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0 -> 1.10.1 (*)
| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0 -> 1.10.2 (*)
| | | +--- org.jetbrains.compose.components:components-resources:1.8.2
| | | | \--- org.jetbrains.compose.components:components-resources-android:1.8.2
| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.0 -> 2.1.21 (*)
@ -954,7 +958,7 @@
| | | | | | | | +--- androidx.compose.ui:ui-unit:1.8.2 (*)
| | | | | | | | +--- androidx.compose.ui:ui-util:1.8.2 (*)
| | | | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib -> 2.1.21 (*)
| | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.10.1 (*)
| | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.10.2 (*)
| | | | | | | | +--- androidx.compose.animation:animation:1.8.2 (c)
| | | | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.24 -> 2.1.21 (c)
| | | | | | | +--- androidx.compose.foundation:foundation-layout:1.8.2
@ -1005,7 +1009,7 @@
| | | | | | | | | +--- org.jetbrains.androidx.lifecycle:lifecycle-common:2.8.4 (*)
| | | | | | | | | +--- org.jetbrains.compose.annotation-internal:annotation:1.6.11 -> 1.8.2 (*)
| | | | | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.9.24 -> 2.1.21 (*)
| | | | | | | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.1 (*)
| | | | | | | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.2 (*)
| | | | | | | | +--- org.jetbrains.androidx.lifecycle:lifecycle-runtime-compose:2.8.4
| | | | | | | | | +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.5 -> 2.8.7 (*)
| | | | | | | | | +--- org.jetbrains.androidx.lifecycle:lifecycle-common:2.8.4 (*)
@ -1056,15 +1060,15 @@
| | | | | | | | | +--- org.jetbrains.compose.ui:ui-unit:1.8.2 (*)
| | | | | | | | | +--- org.jetbrains.compose.ui:ui-util:1.8.2 (*)
| | | | | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib -> 2.1.21 (*)
| | | | | | | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.1 (*)
| | | | | | | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.2 (*)
| | | | | | | | +--- org.jetbrains.compose.ui:ui-unit:1.8.2 (*)
| | | | | | | | +--- org.jetbrains.compose.ui:ui-util:1.8.2 (*)
| | | | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib -> 2.1.21 (*)
| | | | | | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.1 (*)
| | | | | | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.2 (*)
| | | | | | | +--- org.jetbrains.compose.ui:ui-unit:1.8.2 (*)
| | | | | | | +--- org.jetbrains.compose.ui:ui-util:1.8.2 (*)
| | | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib -> 2.1.21 (*)
| | | | | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.1 (*)
| | | | | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.2 (*)
| | | | | | +--- org.jetbrains.compose.collection-internal:collection:1.8.2 (*)
| | | | | | +--- org.jetbrains.compose.foundation:foundation-layout:1.8.2
| | | | | | | +--- androidx.compose.foundation:foundation-layout:1.8.2 (*)
@ -1087,7 +1091,7 @@
| | | | | +--- org.jetbrains.compose.ui:ui-text:1.8.2 (*)
| | | | | +--- org.jetbrains.compose.ui:ui-util:1.8.2 (*)
| | | | | \--- org.jetbrains.kotlin:kotlin-stdlib -> 2.1.21 (*)
| | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.1 (*)
| | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.2 (*)
| | | +--- org.jetbrains.compose.runtime:runtime:1.7.0 -> 1.8.2 (*)
| | | +--- org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.3 (*)
| | | +--- org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3 -> 1.8.0
@ -1109,7 +1113,7 @@
| | | +--- io.insert-koin:koin-annotations:1.4.0-RC4 (*)
| | | +--- com.russhwolf:multiplatform-settings-no-arg:1.2.0
| | | | \--- com.russhwolf:multiplatform-settings-no-arg-android:1.2.0
| | | | +--- androidx.startup:startup-runtime:1.1.1 (*)
| | | | +--- androidx.startup:startup-runtime:1.1.1 -> 1.2.0 (*)
| | | | +--- com.russhwolf:multiplatform-settings:1.2.0
| | | | | \--- com.russhwolf:multiplatform-settings-android:1.2.0
| | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0 -> 2.1.21 (*)
@ -1123,8 +1127,8 @@
| | | | \--- com.russhwolf:multiplatform-settings-coroutines-android:1.2.0
| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0 -> 2.1.21 (*)
| | | | +--- com.russhwolf:multiplatform-settings:1.2.0 (*)
| | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.1 (*)
| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0 -> 1.10.1 (*)
| | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.2 (*)
| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0 -> 1.10.2 (*)
| | | +--- org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3 -> 1.8.0 (*)
| | | +--- project :core:model
| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
@ -1148,7 +1152,7 @@
| | | | | +--- com.squareup.okhttp3:okhttp:4.12.0 (*)
| | | | | \--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.21 -> 1.9.20 (*)
| | | | +--- com.squareup.okio:okio:3.10.2 (*)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 -> 1.10.2 (*)
| | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
| | | +--- io.insert-koin:koin-android:4.0.1-RC1 (*)
| | | +--- project :core:common (*)
@ -1163,20 +1167,20 @@
| | | +--- io.ktor:ktor-client-json:3.1.2
| | | | \--- io.ktor:ktor-client-json-jvm:3.1.2
| | | | +--- org.slf4j:slf4j-api:2.0.16
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 -> 1.10.2 (*)
| | | | +--- io.ktor:ktor-client-core:3.1.2 (*)
| | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
| | | +--- io.ktor:ktor-client-logging:3.1.2
| | | | \--- io.ktor:ktor-client-logging-jvm:3.1.2
| | | | +--- org.slf4j:slf4j-api:2.0.16
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:1.10.1 (*)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:1.10.1 -> 1.10.2 (*)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 -> 1.10.2 (*)
| | | | +--- io.ktor:ktor-client-core:3.1.2 (*)
| | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
| | | +--- io.ktor:ktor-client-serialization:3.1.2
| | | | \--- io.ktor:ktor-client-serialization-jvm:3.1.2
| | | | +--- org.slf4j:slf4j-api:2.0.16
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 -> 1.10.2 (*)
| | | | +--- io.ktor:ktor-client-core:3.1.2 (*)
| | | | +--- org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.0 (*)
| | | | +--- io.ktor:ktor-client-json:3.1.2 (*)
@ -1184,24 +1188,24 @@
| | | +--- io.ktor:ktor-client-content-negotiation:3.1.2
| | | | \--- io.ktor:ktor-client-content-negotiation-jvm:3.1.2
| | | | +--- org.slf4j:slf4j-api:2.0.16
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 -> 1.10.2 (*)
| | | | +--- io.ktor:ktor-client-core:3.1.2 (*)
| | | | +--- io.ktor:ktor-serialization:3.1.2 (*)
| | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
| | | +--- io.ktor:ktor-client-auth:3.1.2
| | | | \--- io.ktor:ktor-client-auth-jvm:3.1.2
| | | | +--- org.slf4j:slf4j-api:2.0.16
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 -> 1.10.2 (*)
| | | | +--- io.ktor:ktor-client-core:3.1.2 (*)
| | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
| | | +--- io.ktor:ktor-serialization-kotlinx-json:3.1.2
| | | | \--- io.ktor:ktor-serialization-kotlinx-json-jvm:3.1.2
| | | | +--- org.slf4j:slf4j-api:2.0.16
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 -> 1.10.2 (*)
| | | | +--- io.ktor:ktor-serialization-kotlinx:3.1.2
| | | | | \--- io.ktor:ktor-serialization-kotlinx-jvm:3.1.2
| | | | | +--- org.slf4j:slf4j-api:2.0.16
| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 -> 1.10.2 (*)
| | | | | +--- io.ktor:ktor-serialization:3.1.2 (*)
| | | | | +--- org.jetbrains.kotlinx:kotlinx-serialization-core:1.8.0 (*)
| | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
@ -1212,7 +1216,7 @@
| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.0 -> 2.1.21 (*)
| | | | | +--- org.jetbrains.kotlinx:kotlinx-serialization-core:1.8.0 (*)
| | | | | +--- org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.0 (*)
| | | | | \--- org.jetbrains.kotlinx:kotlinx-io-core:0.4.0 -> 0.6.0 (*)
| | | | | \--- org.jetbrains.kotlinx:kotlinx-io-core:0.4.0 -> 0.7.0 (*)
| | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
| | | +--- de.jensklingenberg.ktorfit:ktorfit-lib:2.5.0
| | | | \--- de.jensklingenberg.ktorfit:ktorfit-lib-android:2.5.0
@ -1245,8 +1249,10 @@
| | | | | | +--- androidx.legacy:legacy-support-core-utils:1.0.0
| | | | | | | +--- androidx.annotation:annotation:1.0.0 -> 1.9.1 (*)
| | | | | | | +--- androidx.core:core:1.0.0 -> 1.15.0 (*)
| | | | | | | +--- androidx.documentfile:documentfile:1.0.0
| | | | | | | | \--- androidx.annotation:annotation:1.0.0 -> 1.9.1 (*)
| | | | | | | +--- androidx.documentfile:documentfile:1.0.0 -> 1.1.0
| | | | | | | | +--- androidx.annotation:annotation:1.8.1 -> 1.9.1 (*)
| | | | | | | | +--- androidx.core:core:1.7.0 -> 1.15.0 (*)
| | | | | | | | \--- org.jspecify:jspecify:1.0.0
| | | | | | | +--- androidx.loader:loader:1.0.0 -> 1.1.0 (*)
| | | | | | | +--- androidx.localbroadcastmanager:localbroadcastmanager:1.0.0
| | | | | | | | \--- androidx.annotation:annotation:1.0.0 -> 1.9.1 (*)
@ -1267,7 +1273,7 @@
| | | | | | | | +--- androidx.annotation:annotation:1.6.0 -> 1.9.1 (*)
| | | | | | | | +--- androidx.core:core-ktx:1.8.0 -> 1.15.0 (*)
| | | | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.21 -> 2.1.21 (*)
| | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.10.1 (*)
| | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.10.2 (*)
| | | | | | | | \--- androidx.privacysandbox.ads:ads-adservices-java:1.0.0-beta05 (c)
| | | | | | | +--- androidx.privacysandbox.ads:ads-adservices-java:1.0.0-beta05
| | | | | | | | +--- androidx.annotation:annotation:1.2.0 -> 1.9.1 (*)
@ -1283,7 +1289,7 @@
| | | | | | | | | \--- com.google.j2objc:j2objc-annotations:3.0.0
| | | | | | | | +--- com.google.guava:listenablefuture:1.0 -> 9999.0-empty-to-avoid-conflict-with-guava
| | | | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.21 -> 2.1.21 (*)
| | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.10.1 (*)
| | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1 -> 1.10.2 (*)
| | | | | | | | \--- androidx.privacysandbox.ads:ads-adservices:1.0.0-beta05 (c)
| | | | | | | +--- com.google.android.gms:play-services-ads-identifier:18.0.0 (*)
| | | | | | | +--- com.google.android.gms:play-services-base:18.5.0
@ -1310,9 +1316,9 @@
| | | | | | | \--- com.google.android.gms:play-services-measurement-base:22.1.2 (*)
| | | | | | +--- com.google.android.gms:play-services-tasks:18.2.0 (*)
| | | | | | +--- com.google.firebase:firebase-common:21.0.0
| | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.6.4 -> 1.10.1
| | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 (*)
| | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.1 (*)
| | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.6.4 -> 1.10.2
| | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 (*)
| | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.2 (*)
| | | | | | | | +--- com.google.android.gms:play-services-tasks:16.0.1 -> 18.2.0 (*)
| | | | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.0 -> 2.1.21 (*)
| | | | | | | +--- com.google.firebase:firebase-components:18.0.0
@ -1385,7 +1391,7 @@
| | | \--- com.google.guava:listenablefuture:1.0 -> 9999.0-empty-to-avoid-conflict-with-guava
| | +--- androidx.compose.runtime:runtime -> 1.8.2 (*)
| | +--- com.google.accompanist:accompanist-pager:0.34.0
| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4 -> 1.10.1 (*)
| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4 -> 1.10.2 (*)
| | | +--- androidx.compose.foundation:foundation:1.6.0 -> 1.8.2 (*)
| | | +--- dev.chrisbanes.snapper:snapper:0.2.2
| | | | +--- androidx.compose.foundation:foundation:1.1.1 -> 1.8.2 (*)
@ -1394,18 +1400,24 @@
| | +--- project :core:analytics (*)
| | +--- project :core:designsystem
| | | +--- androidx.compose.ui:ui-tooling-preview -> 1.8.2 (*)
| | | +--- androidx.activity:activity-compose:1.9.3
| | | | +--- androidx.activity:activity-ktx:1.9.3 (*)
| | | | +--- androidx.compose.runtime:runtime:1.0.1 -> 1.8.2 (*)
| | | | +--- androidx.compose.runtime:runtime-saveable:1.0.1 -> 1.8.2 (*)
| | | +--- androidx.activity:activity-compose:1.9.3 -> 1.10.1
| | | | +--- androidx.activity:activity-ktx:1.10.1 (*)
| | | | +--- androidx.compose.runtime:runtime:1.7.0 -> 1.8.2 (*)
| | | | +--- androidx.compose.runtime:runtime-saveable:1.7.0 -> 1.8.2 (*)
| | | | +--- androidx.compose.ui:ui:1.0.1 -> 1.8.2 (*)
| | | | +--- androidx.core:core-ktx:1.13.0 -> 1.15.0 (*)
| | | | +--- androidx.lifecycle:lifecycle-common:2.6.1 -> 2.8.7 (*)
| | | | +--- androidx.lifecycle:lifecycle-runtime:2.6.1 -> 2.8.7 (*)
| | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.6.1 -> 2.8.7 (*)
| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (*)
| | | | +--- androidx.activity:activity:1.9.3 (c)
| | | | \--- androidx.activity:activity-ktx:1.9.3 (c)
| | | | +--- androidx.savedstate:savedstate:1.2.1 (*)
| | | | +--- org.jetbrains.kotlin:kotlin-stdlib -> 2.1.21 (*)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.10.2 (*)
| | | | +--- androidx.activity:activity:1.10.1 (c)
| | | | +--- androidx.activity:activity-ktx:1.10.1 (c)
| | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (c)
| | | +--- com.arkivanov.essenty:back-handler:2.1.0
| | | | \--- com.arkivanov.essenty:back-handler-android:2.1.0
| | | | +--- androidx.activity:activity-ktx:1.8.1 -> 1.9.3 (*)
| | | | +--- androidx.activity:activity-ktx:1.8.1 -> 1.10.1 (*)
| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0 -> 2.1.21 (*)
| | | | \--- com.arkivanov.essenty:utils-internal:2.1.0
| | | | \--- com.arkivanov.essenty:utils-internal-android:2.1.0
@ -1423,7 +1435,7 @@
| | | | \--- io.coil-kt.coil3:coil-compose-core-android:3.0.0-alpha10
| | | | +--- com.google.accompanist:accompanist-drawablepainter:0.34.0
| | | | | +--- androidx.compose.ui:ui:1.6.0 -> 1.8.2 (*)
| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4 -> 1.10.1 (*)
| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4 -> 1.10.2 (*)
| | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.22 -> 2.1.21 (*)
| | | | +--- io.coil-kt.coil3:coil-core:3.0.0-alpha10 (*)
| | | | +--- org.jetbrains.compose.foundation:foundation:1.6.11 -> 1.8.2 (*)
@ -1433,7 +1445,7 @@
| | | +--- org.jetbrains.compose.material3:material3:1.8.2
| | | | +--- androidx.compose.material3:material3:1.3.2
| | | | | \--- androidx.compose.material3:material3-android:1.3.2
| | | | | +--- androidx.activity:activity-compose:1.8.2 -> 1.9.3 (*)
| | | | | +--- androidx.activity:activity-compose:1.8.2 -> 1.10.1 (*)
| | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.9.1 (*)
| | | | | +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*)
| | | | | +--- androidx.collection:collection:1.4.0 -> 1.5.0 (*)
@ -1474,13 +1486,13 @@
| | | | +--- org.jetbrains.compose.runtime:runtime:1.8.2 (*)
| | | | +--- org.jetbrains.compose.ui:ui-backhandler:1.8.2
| | | | | \--- org.jetbrains.compose.ui:ui-backhandler-android:1.8.2
| | | | | +--- androidx.activity:activity-compose:1.8.0 -> 1.9.3 (*)
| | | | | +--- androidx.activity:activity-compose:1.8.0 -> 1.10.1 (*)
| | | | | +--- org.jetbrains.androidx.lifecycle:lifecycle-runtime-compose:2.8.4 (*)
| | | | | +--- org.jetbrains.compose.annotation-internal:annotation:1.8.2 (*)
| | | | | +--- org.jetbrains.compose.runtime:runtime:1.8.2 (*)
| | | | | +--- org.jetbrains.compose.ui:ui-util:1.8.2 (*)
| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib -> 2.1.21 (*)
| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.1 (*)
| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0 -> 1.10.2 (*)
| | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21 (c)
| | | | +--- org.jetbrains.compose.ui:ui-graphics:1.8.2 (*)
| | | | +--- org.jetbrains.compose.ui:ui-text:1.8.2 (*)
@ -1530,9 +1542,9 @@
| | +--- org.jetbrains.compose.components:components-resources:1.8.2 (*)
| | +--- org.jetbrains.compose.components:components-ui-tooling-preview:1.8.2 (*)
| | +--- org.jetbrains.androidx.navigation:navigation-compose:2.8.0-alpha10
| | | +--- androidx.activity:activity-compose:1.8.0 -> 1.9.3 (*)
| | | +--- androidx.activity:activity-compose:1.8.0 -> 1.10.1 (*)
| | | +--- androidx.navigation:navigation-compose:2.8.0-rc01 -> 2.8.5
| | | | +--- androidx.activity:activity-compose:1.8.0 -> 1.9.3 (*)
| | | | +--- androidx.activity:activity-compose:1.8.0 -> 1.10.1 (*)
| | | | +--- androidx.compose.animation:animation:1.7.2 -> 1.8.2 (*)
| | | | +--- androidx.compose.foundation:foundation-layout:1.7.2 -> 1.8.2 (*)
| | | | +--- androidx.compose.runtime:runtime:1.7.2 -> 1.8.2 (*)
@ -1570,7 +1582,7 @@
| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.9.24 -> 2.1.21 (*)
| | | | \--- org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.2 -> 1.8.0 (*)
| | | +--- org.jetbrains.androidx.navigation:navigation-runtime:2.8.0-alpha10
| | | | +--- androidx.activity:activity-ktx:1.7.1 -> 1.9.3 (*)
| | | | +--- androidx.activity:activity-ktx:1.7.1 -> 1.10.1 (*)
| | | | +--- androidx.navigation:navigation-runtime:2.8.0-rc01 -> 2.8.5 (*)
| | | | +--- org.jetbrains.androidx.core:core-bundle:1.0.1 (*)
| | | | +--- org.jetbrains.androidx.lifecycle:lifecycle-common:2.8.2 -> 2.8.4 (*)
@ -1591,19 +1603,30 @@
| | | +--- org.jetbrains.compose.runtime:runtime-saveable:1.7.0-beta02 -> 1.8.2 (*)
| | | +--- org.jetbrains.compose.ui:ui:1.7.0-beta02 -> 1.8.2 (*)
| | | \--- org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.2 -> 1.8.0 (*)
| | +--- io.github.vinceglb:filekit-compose:0.8.7
| | | \--- io.github.vinceglb:filekit-compose-android:0.8.7
| | | +--- androidx.activity:activity-compose:1.9.2 -> 1.9.3 (*)
| | | +--- io.github.vinceglb:filekit-core:0.8.7
| | | | \--- io.github.vinceglb:filekit-core-android:0.8.7
| | | | +--- androidx.activity:activity-ktx:1.9.2 -> 1.9.3 (*)
| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 -> 2.1.21 (*)
| | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0 -> 1.10.1 (*)
| | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.20 -> 2.1.21 (*)
| | | +--- org.jetbrains.compose.runtime:runtime:1.6.11 -> 1.8.2 (*)
| | | +--- org.jetbrains.compose.ui:ui:1.6.11 -> 1.8.2 (*)
| | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0 -> 1.10.1 (*)
| | \--- io.github.vinceglb:filekit-core:0.8.7 (*)
| | +--- io.github.vinceglb:filekit-core:0.10.0-beta04
| | | \--- io.github.vinceglb:filekit-core-android:0.10.0-beta04
| | | +--- androidx.documentfile:documentfile:1.1.0 (*)
| | | +--- androidx.startup:startup-runtime:1.2.0 (*)
| | | +--- androidx.exifinterface:exifinterface:1.4.1 (*)
| | | +--- org.jetbrains.kotlinx:kotlinx-io-core:0.7.0 (*)
| | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21-RC2 -> 2.1.21 (*)
| | | +--- androidx.annotation:annotation:1.9.1 (*)
| | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 (*)
| | \--- io.github.vinceglb:filekit-dialogs-compose:0.10.0-beta04
| | \--- io.github.vinceglb:filekit-dialogs-compose-android:0.10.0-beta04
| | +--- androidx.activity:activity-compose:1.10.1 (*)
| | +--- androidx.exifinterface:exifinterface:1.4.1 (*)
| | +--- io.github.vinceglb:filekit-dialogs:0.10.0-beta04
| | | \--- io.github.vinceglb:filekit-dialogs-android:0.10.0-beta04
| | | +--- androidx.activity:activity-ktx:1.10.1 (*)
| | | +--- io.github.vinceglb:filekit-core:0.10.0-beta04 (*)
| | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21-RC2 -> 2.1.21 (*)
| | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 (*)
| | +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21-RC2 -> 2.1.21 (*)
| | +--- org.jetbrains.compose.runtime:runtime:1.8.0 -> 1.8.2 (*)
| | +--- org.jetbrains.compose.ui:ui:1.8.0 -> 1.8.2 (*)
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 (*)
| | \--- androidx.annotation:annotation:1.9.1 (*)
| +--- project :core:designsystem (*)
| +--- io.insert-koin:koin-compose:4.0.1-RC1 (*)
| +--- io.insert-koin:koin-compose-viewmodel:4.0.1-RC1
@ -1647,7 +1670,7 @@
| | +--- androidx.credentials:credentials:1.3.0
| | | +--- androidx.annotation:annotation:1.5.0 -> 1.9.1 (*)
| | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (*)
| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.10.1 (*)
| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.10.2 (*)
| | | \--- androidx.credentials:credentials-play-services-auth:1.3.0 (c)
| | +--- androidx.credentials:credentials-play-services-auth:1.3.0
| | | +--- androidx.credentials:credentials:1.3.0 (*)
@ -1670,7 +1693,7 @@
| | | | | +--- com.google.android.gms:play-services-basement:18.3.0 -> 18.4.0 (*)
| | | | | +--- com.google.android.gms:play-services-tasks:18.1.0 -> 18.2.0 (*)
| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0 -> 1.9.20 (*)
| | | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.10.1 (*)
| | | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3 -> 1.10.2 (*)
| | | | \--- com.google.android.gms:play-services-tasks:18.2.0 (*)
| | | +--- com.google.android.gms:play-services-fido:21.0.0 (*)
| | | +--- com.google.android.libraries.identity.googleid:googleid:1.1.0 -> 1.1.1
@ -1746,7 +1769,7 @@
| | +--- com.russhwolf:multiplatform-settings-no-arg:1.2.0 (*)
| | +--- com.russhwolf:multiplatform-settings-serialization:1.2.0 (*)
| | +--- com.russhwolf:multiplatform-settings-coroutines:1.2.0 (*)
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0 -> 1.10.1 (*)
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0 -> 1.10.2 (*)
| | \--- org.jetbrains.kotlin:kotlin-parcelize-runtime:2.1.20 (*)
| +--- project :feature:home
| | +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.7 (*)
@ -1905,8 +1928,9 @@
| | +--- org.jetbrains.compose.components:components-resources:1.8.2 (*)
| | +--- org.jetbrains.compose.components:components-ui-tooling-preview:1.8.2 (*)
| | +--- io.coil-kt.coil3:coil-compose-core:3.0.0-alpha10 (*)
| | +--- io.github.vinceglb:filekit-core:0.8.7 (*)
| | \--- io.github.vinceglb:filekit-compose:0.8.7 (*)
| | +--- io.github.vinceglb:filekit-core:0.10.0-beta04 (*)
| | +--- io.github.vinceglb:filekit-dialogs:0.10.0-beta04 (*)
| | \--- io.github.vinceglb:filekit-dialogs-compose:0.10.0-beta04 (*)
| +--- project :feature:history
| | +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.7 (*)
| | +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.7 (*)
@ -2094,9 +2118,10 @@
| | +--- org.jetbrains.compose.material3:material3:1.8.2 (*)
| | +--- org.jetbrains.compose.components:components-resources:1.8.2 (*)
| | +--- org.jetbrains.compose.components:components-ui-tooling-preview:1.8.2 (*)
| | +--- io.github.vinceglb:filekit-core:0.8.7 (*)
| | +--- io.github.vinceglb:filekit-compose:0.8.7 (*)
| | \--- io.coil-kt.coil3:coil-compose-core:3.0.0-alpha10 (*)
| | +--- io.github.vinceglb:filekit-core:0.10.0-beta04 (*)
| | +--- io.coil-kt.coil3:coil-compose-core:3.0.0-alpha10 (*)
| | +--- io.github.vinceglb:filekit-dialogs:0.10.0-beta04 (*)
| | \--- io.github.vinceglb:filekit-dialogs-compose:0.10.0-beta04 (*)
| +--- project :feature:notification
| | +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.7 (*)
| | +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.7 (*)
@ -2281,7 +2306,7 @@
| | +--- io.insert-koin:koin-androidx-navigation:4.0.1-RC1 (*)
| | +--- io.insert-koin:koin-core-viewmodel:4.0.1-RC1 (*)
| | +--- com.google.android.gms:play-services-code-scanner:16.1.0
| | | +--- androidx.activity:activity:1.3.1 -> 1.9.3 (*)
| | | +--- androidx.activity:activity:1.3.1 -> 1.10.1 (*)
| | | +--- com.google.android.datatransport:transport-api:2.2.1
| | | | \--- androidx.annotation:annotation:1.1.0 -> 1.9.1 (*)
| | | +--- com.google.android.datatransport:transport-backend-cct:2.3.3
@ -2306,7 +2331,7 @@
| | | +--- com.google.mlkit:barcode-scanning-common:17.0.0
| | | | +--- com.google.android.gms:play-services-basement:18.0.0 -> 18.4.0 (*)
| | | | \--- com.google.mlkit:vision-common:17.0.0 -> 17.3.0
| | | | +--- androidx.exifinterface:exifinterface:1.0.0 -> 1.3.7 (*)
| | | | +--- androidx.exifinterface:exifinterface:1.0.0 -> 1.4.1 (*)
| | | | +--- com.google.android.datatransport:transport-api:2.2.1 (*)
| | | | +--- com.google.android.datatransport:transport-backend-cct:2.3.3 (*)
| | | | +--- com.google.android.datatransport:transport-runtime:2.2.6 (*)
@ -2404,16 +2429,16 @@
| | | | +--- androidx.concurrent:concurrent-futures-ktx:1.1.0
| | | | | +--- androidx.concurrent:concurrent-futures:1.1.0 (*)
| | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.3.71 -> 2.1.21 (*)
| | | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.4 -> 1.10.1 (*)
| | | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.4 -> 1.10.2 (*)
| | | | +--- androidx.core:core:1.1.0 -> 1.15.0 (*)
| | | | +--- androidx.exifinterface:exifinterface:1.3.2 -> 1.3.7 (*)
| | | | +--- androidx.exifinterface:exifinterface:1.3.2 -> 1.4.1 (*)
| | | | +--- androidx.lifecycle:lifecycle-common:2.1.0 -> 2.8.7 (*)
| | | | +--- androidx.lifecycle:lifecycle-livedata:2.1.0 -> 2.8.7 (*)
| | | | +--- androidx.tracing:tracing:1.2.0 -> 1.3.0-alpha02 (*)
| | | | +--- com.google.auto.value:auto-value-annotations:1.6.3
| | | | +--- com.google.guava:listenablefuture:1.0 -> 9999.0-empty-to-avoid-conflict-with-guava
| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (*)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.1 (*)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.2 (*)
| | | | +--- androidx.camera:camera-camera2:1.4.1 (c)
| | | | +--- androidx.camera:camera-lifecycle:1.4.1 (c)
| | | | +--- androidx.camera:camera-video:1.4.1 (c)
@ -2427,7 +2452,7 @@
| | | | +--- androidx.tracing:tracing-ktx:1.2.0 -> 1.3.0-alpha02 (*)
| | | | +--- com.google.auto.value:auto-value-annotations:1.6.3
| | | | +--- com.google.guava:listenablefuture:1.0 -> 9999.0-empty-to-avoid-conflict-with-guava
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.1 (*)
| | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 -> 1.10.2 (*)
| | | | +--- androidx.camera:camera-camera2:1.4.1 (c)
| | | | +--- androidx.camera:camera-core:1.4.1 (c)
| | | | +--- androidx.camera:camera-video:1.4.1 (c)
@ -2465,9 +2490,9 @@
| | | \--- androidx.camera:camera-view:1.4.1 (c)
| | +--- androidx.camera:camera-lifecycle:1.4.1 (*)
| | +--- com.google.accompanist:accompanist-permissions:0.34.0
| | | +--- androidx.activity:activity-compose:1.7.2 -> 1.9.3 (*)
| | | +--- androidx.activity:activity-compose:1.7.2 -> 1.10.1 (*)
| | | +--- androidx.compose.foundation:foundation:1.6.0 -> 1.8.2 (*)
| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4 -> 1.10.1 (*)
| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4 -> 1.10.2 (*)
| | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.22 -> 2.1.21 (*)
| | +--- com.google.mlkit:barcode-scanning:17.3.0
| | | +--- com.google.android.gms:play-services-basement:18.4.0 (*)
@ -2514,9 +2539,7 @@
| | +--- org.jetbrains.compose.material3:material3:1.8.2 (*)
| | +--- org.jetbrains.compose.components:components-resources:1.8.2 (*)
| | +--- org.jetbrains.compose.components:components-ui-tooling-preview:1.8.2 (*)
| | +--- io.coil-kt.coil3:coil-compose-core:3.0.0-alpha10 (*)
| | +--- io.github.vinceglb:filekit-core:0.8.7 (*)
| | \--- io.github.vinceglb:filekit-compose:0.8.7 (*)
| | \--- io.coil-kt.coil3:coil-compose-core:3.0.0-alpha10 (*)
| +--- project :feature:merchants
| | +--- androidx.lifecycle:lifecycle-runtime-compose:2.8.7 (*)
| | +--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.7 (*)
@ -2582,10 +2605,11 @@
| \--- org.jetbrains.kotlin:kotlin-parcelize-runtime:2.1.20 (*)
+--- project :core:data (*)
+--- project :core:ui (*)
+--- io.github.vinceglb:filekit-dialogs:0.10.0-beta04 (*)
+--- androidx.core:core-ktx:1.15.0 (*)
+--- androidx.appcompat:appcompat:1.7.0 (*)
+--- androidx.activity:activity-compose:1.9.3 (*)
+--- androidx.activity:activity-ktx:1.9.3 (*)
+--- androidx.activity:activity-compose:1.9.3 -> 1.10.1 (*)
+--- androidx.activity:activity-ktx:1.9.3 -> 1.10.1 (*)
+--- androidx.core:core-splashscreen:1.0.1
| +--- androidx.annotation:annotation:1.2.0 -> 1.9.1 (*)
| \--- org.jetbrains.kotlin:kotlin-stdlib:1.6.21 -> 2.1.21 (*)
@ -2626,7 +2650,7 @@
| \--- androidx.compose.material3.adaptive:adaptive-navigation:1.0.0 (c)
+--- androidx.compose.material3.adaptive:adaptive-navigation:1.0.0
| \--- androidx.compose.material3.adaptive:adaptive-navigation-android:1.0.0
| +--- androidx.activity:activity-compose:1.8.2 -> 1.9.3 (*)
| +--- androidx.activity:activity-compose:1.8.2 -> 1.10.1 (*)
| +--- androidx.annotation:annotation:1.1.0 -> 1.9.1 (*)
| +--- androidx.annotation:annotation-experimental:1.4.0 -> 1.4.1 (*)
| +--- androidx.compose.foundation:foundation:1.6.5 -> 1.8.2 (*)
@ -2639,17 +2663,17 @@
+--- androidx.compose.runtime:runtime-tracing:1.7.6 -> 1.8.2
| +--- androidx.annotation:annotation:1.8.1 -> 1.9.1 (*)
| +--- androidx.compose.runtime:runtime:1.3.3 -> 1.8.2 (*)
| +--- androidx.startup:startup-runtime:1.1.1 (*)
| +--- androidx.startup:startup-runtime:1.1.1 -> 1.2.0 (*)
| +--- androidx.tracing:tracing-perfetto:1.0.0
| | +--- androidx.annotation:annotation:1.3.0 -> 1.9.1 (*)
| | +--- androidx.startup:startup-runtime:1.1.1 (*)
| | +--- androidx.startup:startup-runtime:1.1.1 -> 1.2.0 (*)
| | \--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 -> 2.1.21 (*)
| +--- org.jetbrains.kotlin:kotlin-stdlib -> 2.1.21 (*)
| +--- androidx.compose.runtime:runtime:1.8.2 (c)
| +--- androidx.compose.runtime:runtime-saveable:1.8.2 (c)
| \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.24 -> 2.1.21 (c)
+--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0 -> 1.10.1 (*)
+--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0 -> 1.10.1 (*)
+--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0 -> 1.10.2 (*)
+--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0 -> 1.10.2 (*)
+--- androidx.lifecycle:lifecycle-runtime-compose:2.8.7 (*)
+--- androidx.lifecycle:lifecycle-viewmodel-compose:2.8.7 (*)
+--- androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7 (*)

View File

@ -31,9 +31,9 @@
:feature:upi-setup
:libs:mifos-passcode
:mifospay-shared
androidx.activity:activity-compose:1.9.3
androidx.activity:activity-ktx:1.9.3
androidx.activity:activity:1.9.3
androidx.activity:activity-compose:1.10.1
androidx.activity:activity-ktx:1.10.1
androidx.activity:activity:1.10.1
androidx.annotation:annotation-experimental:1.4.1
androidx.annotation:annotation-jvm:1.9.1
androidx.annotation:annotation:1.9.1
@ -97,6 +97,7 @@ androidx.concurrent:concurrent-futures-ktx:1.1.0
androidx.concurrent:concurrent-futures:1.1.0
androidx.core:core-ktx:1.15.0
androidx.core:core-splashscreen:1.0.1
androidx.core:core-viewtree:1.0.0
androidx.core:core:1.15.0
androidx.credentials:credentials-play-services-auth:1.3.0
androidx.credentials:credentials:1.3.0
@ -108,11 +109,11 @@ androidx.databinding:databinding-common:8.7.2
androidx.databinding:databinding-ktx:8.7.2
androidx.databinding:databinding-runtime:8.7.2
androidx.databinding:viewbinding:8.7.2
androidx.documentfile:documentfile:1.0.0
androidx.documentfile:documentfile:1.1.0
androidx.drawerlayout:drawerlayout:1.0.0
androidx.emoji2:emoji2-views-helper:1.4.0
androidx.emoji2:emoji2:1.4.0
androidx.exifinterface:exifinterface:1.3.7
androidx.exifinterface:exifinterface:1.4.1
androidx.fragment:fragment-ktx:1.8.5
androidx.fragment:fragment:1.8.5
androidx.graphics:graphics-path:1.0.1
@ -157,7 +158,7 @@ androidx.resourceinspection:resourceinspection-annotation:1.0.1
androidx.savedstate:savedstate-ktx:1.2.1
androidx.savedstate:savedstate:1.2.1
androidx.slidingpanelayout:slidingpanelayout:1.2.0
androidx.startup:startup-runtime:1.1.1
androidx.startup:startup-runtime:1.2.0
androidx.tracing:tracing-ktx:1.3.0-alpha02
androidx.tracing:tracing-perfetto:1.0.0
androidx.tracing:tracing:1.3.0-alpha02
@ -274,10 +275,12 @@ io.github.alexzhirkevich:qrose-android:1.0.1
io.github.alexzhirkevich:qrose-core-android:1.0.1
io.github.alexzhirkevich:qrose-core:1.0.1
io.github.alexzhirkevich:qrose:1.0.1
io.github.vinceglb:filekit-compose-android:0.8.7
io.github.vinceglb:filekit-compose:0.8.7
io.github.vinceglb:filekit-core-android:0.8.7
io.github.vinceglb:filekit-core:0.8.7
io.github.vinceglb:filekit-core-android:0.10.0-beta04
io.github.vinceglb:filekit-core:0.10.0-beta04
io.github.vinceglb:filekit-dialogs-android:0.10.0-beta04
io.github.vinceglb:filekit-dialogs-compose-android:0.10.0-beta04
io.github.vinceglb:filekit-dialogs-compose:0.10.0-beta04
io.github.vinceglb:filekit-dialogs:0.10.0-beta04
io.insert-koin:koin-android:4.0.1-RC1
io.insert-koin:koin-androidx-compose:4.0.1-RC1
io.insert-koin:koin-androidx-navigation:4.0.1-RC1
@ -377,18 +380,18 @@ org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.20
org.jetbrains.kotlin:kotlin-stdlib:2.1.21
org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.8
org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.8
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.1
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.1
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.1
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1
org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.10.1
org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:1.10.1
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.2
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.2
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2
org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.10.2
org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:1.10.2
org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.1
org.jetbrains.kotlinx:kotlinx-datetime:0.6.1
org.jetbrains.kotlinx:kotlinx-io-bytestring-jvm:0.6.0
org.jetbrains.kotlinx:kotlinx-io-bytestring:0.6.0
org.jetbrains.kotlinx:kotlinx-io-core-jvm:0.6.0
org.jetbrains.kotlinx:kotlinx-io-core:0.6.0
org.jetbrains.kotlinx:kotlinx-io-bytestring-jvm:0.7.0
org.jetbrains.kotlinx:kotlinx-io-bytestring:0.7.0
org.jetbrains.kotlinx:kotlinx-io-core-jvm:0.7.0
org.jetbrains.kotlinx:kotlinx-io-core:0.7.0
org.jetbrains.kotlinx:kotlinx-serialization-bom:1.8.0
org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.8.0
org.jetbrains.kotlinx:kotlinx-serialization-core:1.8.0

View File

@ -1,4 +1,5 @@
package: name='org.mifospay' versionCode='1' versionName='2025.7.3-beta.0.13' platformBuildVersionName='15' platformBuildVersionCode='35' compileSdkVersion='35' compileSdkVersionCodename='15'
sdkVersion:'26'
targetSdkVersion:'34'
uses-permission: name='android.permission.INTERNET'
@ -107,9 +108,9 @@ application-icon-640:'res/mipmap-anydpi-v26/ic_launcher.xml'
application-icon-65534:'res/mipmap-anydpi-v26/ic_launcher.xml'
application: label='Mifos Pay' icon='res/mipmap-anydpi-v26/ic_launcher.xml'
launchable-activity: name='org.mifospay.MainActivity' label='' icon=''
property: name='android.adservices.AD_SERVICES_CONFIG' resource='res/xml/ga_ad_services_config.xml'
uses-library-not-required:'androidx.window.extensions'
uses-library-not-required:'androidx.window.sidecar'
property: name='android.adservices.AD_SERVICES_CONFIG' resource='res/xml/ga_ad_services_config.xml'
uses-library-not-required:'android.ext.adservices'
feature-group: label=''
uses-feature: name='android.hardware.camera'

View File

@ -21,6 +21,8 @@ import androidx.core.view.WindowCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import io.github.vinceglb.filekit.FileKit
import io.github.vinceglb.filekit.dialogs.init
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
@ -46,6 +48,9 @@ class MainActivity : ComponentActivity() {
WindowCompat.setDecorFitsSystemWindows(window, false)
enableEdgeToEdge()
// Initialize FileKit
FileKit.init(this)
var uiState: MainUiState by mutableStateOf(MainUiState.Loading)
// Update the uiState

View File

@ -37,6 +37,7 @@ kotlin {
implementation(compose.desktop.currentOs)
implementation(libs.jb.kotlin.stdlib)
implementation(libs.kotlin.reflect)
implementation(libs.filekit.core)
}
}
}

View File

@ -11,12 +11,15 @@
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import androidx.compose.ui.window.rememberWindowState
import io.github.vinceglb.filekit.FileKit
import org.mifospay.shared.MifosPaySharedApp
import org.mifospay.shared.di.initKoin
fun main() {
application {
initKoin()
// Initialize FileKit
FileKit.init(appId = "org.mifospay.desktop")
val windowState = rememberWindowState()
Window(
onCloseRequest = ::exitApplication,

View File

@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
@ -20,15 +22,8 @@
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Allow access to add photos to your library so you can save artworks directly to your device and view them offline.</string>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
</dict>
<string>Allow access to add photos to your library so you can save artworks directly to your device and view them offline.</string>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>