Add endpoints upload and delete Conversation Avatar

Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com>
This commit is contained in:
sowjanyakch 2024-05-22 16:09:12 +02:00 committed by Marcel Hibbe
parent 9976767591
commit df6d54d51c
No known key found for this signature in database
GPG Key ID: C793F8B59F43CE7B
7 changed files with 334 additions and 5 deletions

View File

@ -11,13 +11,16 @@ import com.nextcloud.talk.models.json.autocomplete.AutocompleteOverall
import com.nextcloud.talk.models.json.conversations.RoomOverall
import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.models.json.participants.AddParticipantOverall
import okhttp3.MultipartBody
import retrofit2.http.DELETE
import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Multipart
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Part
import retrofit2.http.Query
import retrofit2.http.QueryMap
import retrofit2.http.Url
@ -96,4 +99,15 @@ interface NcApiCoroutines {
@Url url: String?,
@Field("password") password: String?
): GenericOverall
@Multipart
@POST
suspend fun uploadConversationAvatar(
@Header("Authorization") authorization: String,
@Url url: String,
@Part("attachment") attachment: MultipartBody.Part
): RoomOverall
@DELETE
suspend fun deleteConversationAvatar(@Header("Authorization") authorization: String, @Url url: String): RoomOverall
}

View File

@ -0,0 +1,104 @@
/*
* Nextcloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2024 Your Name <your@email.com>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.nextcloud.talk.contacts
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser
import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.ApiUtils
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
class ContactsActivityViewModel @Inject constructor(
private val repository: ContactsRepository,
private val userManager: UserManager
) : ViewModel() {
private val _contactsViewState = MutableStateFlow<ContactsUiState>(ContactsUiState.None)
val contactsViewState: StateFlow<ContactsUiState> = _contactsViewState
private val _roomViewState = MutableStateFlow<RoomUiState>(RoomUiState.None)
val roomViewState: StateFlow<RoomUiState> = _roomViewState
private val _currentUser = userManager.currentUser.blockingGet()
val currentUser: User = _currentUser
private val _searchQuery = MutableStateFlow("")
val searchQuery: StateFlow<String> = _searchQuery
private val shareTypes: MutableList<String> = mutableListOf(ShareType.User.shareType)
val shareTypeList: List<String> = shareTypes
init {
getContactsFromSearchParams()
}
fun updateSearchQuery(query: String) {
_searchQuery.value = query
}
fun updateShareTypes(value: String) {
shareTypes.add(value)
}
fun getContactsFromSearchParams() {
_contactsViewState.value = ContactsUiState.Loading
viewModelScope.launch {
try {
val contacts = repository.getContacts(
searchQuery.value,
shareTypeList
)
val contactsList: List<AutocompleteUser>? = contacts.ocs!!.data
_contactsViewState.value = ContactsUiState.Success(contactsList)
} catch (exception: Exception) {
_contactsViewState.value = ContactsUiState.Error(exception.message ?: "")
}
}
}
fun createRoom(roomType: String, sourceType: String, userId: String, conversationName: String?) {
viewModelScope.launch {
try {
val room = repository.createRoom(
roomType,
sourceType,
userId,
conversationName
)
val conversation: Conversation? = room.ocs?.data
_roomViewState.value = RoomUiState.Success(conversation)
} catch (exception: Exception) {
_roomViewState.value = RoomUiState.Error(exception.message ?: "")
}
}
}
fun getImageUri(avatarId: String, requestBigSize: Boolean): String {
return ApiUtils.getUrlForAvatar(
_currentUser.baseUrl,
avatarId,
requestBigSize
)
}
}
sealed class ContactsUiState {
data object None : ContactsUiState()
data object Loading : ContactsUiState()
data class Success(val contacts: List<AutocompleteUser>?) : ContactsUiState()
data class Error(val message: String) : ContactsUiState()
}
sealed class RoomUiState {
data object None : RoomUiState()
data class Success(val conversation: Conversation?) : RoomUiState()
data class Error(val message: String) : RoomUiState()
}

View File

@ -7,9 +7,11 @@
package com.nextcloud.talk.conversationcreation
import com.nextcloud.talk.models.domain.ConversationModel
import com.nextcloud.talk.models.json.conversations.RoomOverall
import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.models.json.participants.AddParticipantOverall
import java.io.File
interface ConversationCreationRepository {
@ -21,4 +23,6 @@ interface ConversationCreationRepository {
suspend fun createRoom(roomType: String, conversationName: String?): RoomOverall
fun getImageUri(avatarId: String, requestBigSize: Boolean): String
suspend fun setPassword(roomToken: String, password: String): GenericOverall
suspend fun uploadConversationAvatar(file: File, roomToken: String): ConversationModel
suspend fun deleteConversationAvatar(roomToken: String): ConversationModel
}

View File

@ -10,6 +10,7 @@ package com.nextcloud.talk.conversationcreation
import com.nextcloud.talk.api.NcApiCoroutines
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.models.RetrofitBucket
import com.nextcloud.talk.models.domain.ConversationModel
import com.nextcloud.talk.models.json.conversations.RoomOverall
import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.models.json.participants.AddParticipantOverall
@ -17,6 +18,11 @@ import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.ApiUtils.getRetrofitBucketForAddParticipant
import com.nextcloud.talk.utils.ApiUtils.getRetrofitBucketForAddParticipantWithSource
import com.nextcloud.talk.utils.Mimetype
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.asRequestBody
import java.io.File
class ConversationCreationRepositoryImpl(
private val ncApiCoroutines: NcApiCoroutines,
@ -126,6 +132,33 @@ class ConversationCreationRepositoryImpl(
return result
}
override suspend fun uploadConversationAvatar(file: File, roomToken: String): ConversationModel {
val builder = MultipartBody.Builder()
builder.setType(MultipartBody.FORM)
builder.addFormDataPart(
"file",
file.name,
file.asRequestBody(Mimetype.IMAGE_PREFIX_GENERIC.toMediaTypeOrNull())
)
val filePart: MultipartBody.Part = MultipartBody.Part.createFormData(
"file",
file.name,
file.asRequestBody(Mimetype.IMAGE_JPG.toMediaTypeOrNull())
)
val response = ncApiCoroutines.uploadConversationAvatar(
credentials!!,
ApiUtils.getUrlForConversationAvatar(1, _currentUser.baseUrl!!, roomToken),
filePart
)
return ConversationModel.mapToConversationModel(response.ocs?.data!!, _currentUser)
}
override suspend fun deleteConversationAvatar(roomToken: String): ConversationModel {
val url = ApiUtils.getUrlForConversationAvatar(1, _currentUser.baseUrl!!, roomToken)
val response = ncApiCoroutines.deleteConversationAvatar(credentials!!, url)
return ConversationModel.mapToConversationModel(response.ocs?.data!!, _currentUser)
}
override suspend fun allowGuests(token: String, allow: Boolean): GenericOverall {
val url = ApiUtils.getUrlForRoomPublic(
apiVersion,

View File

@ -11,6 +11,7 @@ import android.util.Log
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.nextcloud.talk.models.domain.ConversationModel
import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser
import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.models.json.generic.GenericMeta
@ -18,6 +19,7 @@ import com.nextcloud.talk.repositories.conversations.ConversationsRepositoryImpl
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import java.io.File
import javax.inject.Inject
class ConversationCreationViewModel @Inject constructor(
@ -27,6 +29,12 @@ class ConversationCreationViewModel @Inject constructor(
val selectedParticipants: StateFlow<List<AutocompleteUser>> = _selectedParticipants
private val roomViewState = MutableStateFlow<RoomUIState>(RoomUIState.None)
private val _uploadState = MutableStateFlow<UploadAvatarState>(UploadAvatarState.Loading)
val uploadState: StateFlow<UploadAvatarState> = _uploadState
private val _deleteState = MutableStateFlow<DeleteAvatarState>(DeleteAvatarState.Loading)
val deleteState: StateFlow<DeleteAvatarState> = _deleteState
fun updateSelectedParticipants(participants: List<AutocompleteUser>) {
_selectedParticipants.value = participants
}
@ -116,6 +124,28 @@ class ConversationCreationViewModel @Inject constructor(
}
}
fun uploadConversationAvatar(file: File, roomToken: String) {
viewModelScope.launch {
try {
val response = repository.uploadConversationAvatar(file, roomToken)
_uploadState.value = UploadAvatarState.Success(response)
} catch (e: Exception) {
_uploadState.value = UploadAvatarState.Error(e)
}
}
}
fun deleteConversationAvatar(roomToken: String) {
viewModelScope.launch {
try {
val result = repository.deleteConversationAvatar(roomToken)
_deleteState.value = DeleteAvatarState.Success(result)
} catch (e: Exception) {
_deleteState.value = DeleteAvatarState.Error(e)
}
}
}
fun getImageUri(avatarId: String, requestBigSize: Boolean): String {
return repository.getImageUri(avatarId, requestBigSize)
}
@ -154,3 +184,15 @@ sealed class AddParticipantsUiState {
data class Success(val participants: List<Conversation>?) : AddParticipantsUiState()
data class Error(val message: String) : AddParticipantsUiState()
}
sealed class UploadAvatarState {
object Loading : UploadAvatarState()
data class Success(val roomOverall: ConversationModel) : UploadAvatarState()
data class Error(val exception: Exception) : UploadAvatarState()
}
sealed class DeleteAvatarState {
object Loading : DeleteAvatarState()
data class Success(val roomOverall: ConversationModel) : DeleteAvatarState()
data class Error(val exception: Exception) : DeleteAvatarState()
}

View File

@ -29,4 +29,8 @@ class FakeRepositorySuccess : ContactsRepository {
override fun getImageUri(avatarId: String, requestBigSize: Boolean): String {
return "https://mydomain.com/index.php/avatar/$avatarId/512"
}
override fun getImageUri(avatarId: String, requestBigSize: Boolean): String {
TODO("Not yet implemented")
}
}

View File

@ -4,13 +4,13 @@
<verify-metadata>true</verify-metadata>
<verify-signatures>true</verify-signatures>
<trusted-artifacts>
<trust file="tensorflow-lite-metadata-0.1.0-rc2.pom" reason="differing hash on every CI run - temp global trust"/>
<trust group="androidx.fragment"/>
<trust group="com.android.tools.build" name="aapt2" version="8.4.1-11315950" reason="ships OS specific artifacts (win/linux) - temp global trust"/>
<trust group="com.github.nextcloud-deps" name="android-talk-webrtc" version="110.5481.0" reason="ships OS specific artifacts (win/linux) - temp global trust"/>
<trust group="com.google.dagger"/>
<trust group="org.javassist" name="javassist" version="3.26.0-GA" reason="java assist"/>
<trust file=".*-sources[.]jar" regex="true"/>
<trust file="tensorflow-lite-metadata-0.1.0-rc2.pom" reason="differing hash on every CI run - temp global trust"/>
<trust group="com.google.dagger" />
<trust group="org.javassist" name="javassist" version="3.26.0-GA" reason="java assist"/>
<trust group="androidx.fragment"/>
</trusted-artifacts>
<ignored-keys>
<ignored-key id="0AA3E5C3D232E79B" reason="Key couldn't be downloaded from any key server"/>
@ -151,7 +151,6 @@
<trusting group="androidx.annotation"/>
<trusting group="androidx.camera"/>
<trusting group="androidx.collection"/>
<trusting group="androidx.compose.foundation"/>
<trusting group="androidx.compose.material3"/>
<trusting group="androidx.core"/>
<trusting group="androidx.emoji2"/>
@ -163,6 +162,7 @@
<trusting group="androidx.sqlite"/>
<trusting group="androidx.webkit"/>
<trusting group="androidx.work"/>
<trusting group="androidx.compose.foundation"/>
</trusted-key>
<trusted-key id="84789D24DF77A32433CE1F079EB80E92EB2135B1">
<trusting group="org.apache" name="apache"/>
@ -252,6 +252,7 @@
<trusted-key id="E4AC7874F3479A0F1F8ECF9960BB45F36B649F22" group="fr.dudie" name="nominatim-api" version="3.4"/>
<trusted-key id="E77417AC194160A3FABD04969A259C7EE636C5ED" group="^com[.]google($|([.].*))" regex="true"/>
<trusted-key id="E7DC75FC24FB3C8DFE8086AD3D5839A2262CBBFB" group="org.jetbrains.kotlinx"/>
<trusted-key id="64B9B09F164AA0BF88742EB61188B69F6D6259CA" group="com.google.accompanist"/>
<trusted-key id="E82D2EAF2E83830CE1F7F6BE571A5291E827E1C7" group="net.java" name="jvnet-parent" version="3"/>
<trusted-key id="E85AED155021AF8A6C6B7A4A7C7D8456294423BA" group="org.objenesis"/>
<trusted-key id="EAA526B91DD83BA3E1B9636FA730529CA355A63E" group="org.ccil.cowan.tagsoup" name="tagsoup" version="1.2.1"/>
@ -349,6 +350,50 @@
<sha256 value="9516c2ae44284ea0bd3d0eade0ee638879b708cbe31e3af92ba96c300604ebc3" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="androidx.exifinterface" name="exifinterface" version="1.3.6">
<artifact name="exifinterface-1.3.6.aar">
<sha256 value="1804105e9e05fdd8f760413bad5de498c381aa329f4f9d94c851bc891ac654c6" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
<artifact name="exifinterface-1.3.6.module">
<sha256 value="5e9fd84ca3fd3b7706f6856fa4383107de8676bf7c42b7d4b8108949414d6201" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="androidx.core" name="core" version="1.1.0">
<artifact name="core-1.1.0.pom">
<sha256 value="dae46132cdcd46b798425f7cb78fd65890869b6d26101ccdcd43461a4f51754c" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="androidx.core" name="core" version="1.3.2">
<artifact name="core-1.3.2.pom">
<sha256 value="afb5ea494dd083ed404cd51f580d218e37362f8ae326e893bee521290ed34920" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="androidx.test.ext" name="junit" version="1.1.5">
<artifact name="junit-1.1.5.aar">
<sha256 value="4307c0e60f5d701db9c59bcd9115af705113c36a9132fa3dbad58db1294e9bfd" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
<artifact name="junit-1.1.5.pom">
<sha256 value="4cff0df04cae25831e821ef2f9129245783460e98d0fd67d8f6824065a134c4e" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="androidx.core" name="core-ktx" version="1.8.0">
<artifact name="core-ktx-1.8.0.module">
<sha256 value="a91bc3e02f209f643dd8275345a9e3003ce20d64fc0760eccf479c1709842f72" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="androidx.annotation" name="annotation-experimental" version="1.3.0">
<artifact name="annotation-experimental-1.3.0.aar">
<sha256 value="abfd29c8556e5bd0325a9f769ab9e9d154ff4a5515c476cdd5a2a8285b1b19dc" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
<artifact name="annotation-experimental-1.3.0.module">
<sha256 value="5eebeaff01d042e06dcf292abf8964ad391e4b0159f0090f16253d6045d38da0" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="androidx.annotation" name="annotation-experimental" version="1.1.0-rc01">
<artifact name="annotation-experimental-1.1.0-rc01.module">
<sha256 value="d45ac493e84d968aabb2bea2b7744031a98cf5074447c0f3b862d600fc44b55c" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="androidx.annotation" name="annotation" version="1.5.0">
<artifact name="annotation-1.5.0.jar">
<sha256 value="261fb7c0210858500bab66d34354972a75166ab4182add283780b05513d6ec4a" origin="Generated by Gradle" reason="Artifact is not signed"/>
@ -365,6 +410,14 @@
<sha256 value="fbc64f5c44a7added8b6eab517cf7d70555e25153bf5d44a6ed9b0e5312f7de9" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="androidx.exifinterface" name="exifinterface" version="1.3.2">
<artifact name="exifinterface-1.3.2.aar">
<sha256 value="8770c180103e0b8c04a07eb4c59153af639b09eca25deae9bdcdaf869d1e5b6b" origin="Generated by Gradle"/>
</artifact>
<artifact name="exifinterface-1.3.2.module">
<sha256 value="10ba5b5cbea7f5c8758be4fdaec60a3545e891a1130d830a442b88cf5336a885" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.annotation" name="annotation-experimental" version="1.0.0">
<artifact name="annotation-experimental-1.0.0.pom">
<sha256 value="6b73ff6608f4b1d6cbab620b65708a382d0b39901cf4e6b0d16f84a1b04d7732" origin="Generated by Gradle" reason="Artifact is not signed"/>
@ -378,6 +431,11 @@
<sha256 value="0361d1526a4d7501255e19779e09e93cdbd07fee0e2f5c50b7a137432d510119" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="androidx.annotation" name="annotation-experimental" version="1.1.0-rc01">
<artifact name="annotation-experimental-1.1.0-rc01.module">
<sha256 value="d45ac493e84d968aabb2bea2b7744031a98cf5074447c0f3b862d600fc44b55c" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="androidx.annotation" name="annotation-experimental" version="1.1.0-rc01">
<artifact name="annotation-experimental-1.1.0-rc01.module">
<sha256 value="d45ac493e84d968aabb2bea2b7744031a98cf5074447c0f3b862d600fc44b55c" origin="Generated by Gradle" reason="Artifact is not signed"/>
@ -399,6 +457,76 @@
<sha256 value="9b6974a7dfe26d3c209dd63e16f8ee2461b57a091789160ca1eb492bb1bf3f84" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="androidx.annotation" name="annotation-experimental" version="1.3.0">
<artifact name="annotation-experimental-1.3.0.aar">
<sha256 value="abfd29c8556e5bd0325a9f769ab9e9d154ff4a5515c476cdd5a2a8285b1b19dc" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
<artifact name="annotation-experimental-1.3.0.module">
<sha256 value="5eebeaff01d042e06dcf292abf8964ad391e4b0159f0090f16253d6045d38da0" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="androidx.activity" name="activity-compose" version="1.7.0">
<artifact name="activity-compose-1.7.0.aar">
<sha256 value="caa72885d1ce7979c1d6c59a8b255c6097b770780d4d4da95d56979a348646cd" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
<artifact name="activity-compose-1.7.0.module">
<sha256 value="f7a29bcba338575dcf89a553cff9cfad3f140340eaf2b56fd0193244da602c0a" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="androidx.compose.runtime" name="runtime" version="1.0.1">
<artifact name="runtime-1.0.1.module">
<sha256 value="2543a8c7edc16bde91f140286b4fd3773d7204a283a4ec99f6e5e286aa92c0c3" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.compose.runtime" name="runtime-saveable" version="1.0.1">
<artifact name="runtime-saveable-1.0.1.module">
<sha256 value="c0d6f142542d8d74f65481ef6526d2be265f01f812a112948fcde87a458f4fb6" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.compose.ui" name="ui" version="1.0.1">
<artifact name="ui-1.0.1.aar">
<sha256 value="1943daa4a3412861b9a2bdc1a7c8c2ff05d9b8191c1d3e56ebb223d2eb4a8526" origin="Generated by Gradle"/>
</artifact>
<artifact name="ui-1.0.1.module">
<sha256 value="57031a6ac9b60e5b56792ebf5cde6e16812ff566ed9190cbd188b00b46c13779" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.compose" name="compose-bom" version="2024.06.00">
<artifact name="compose-bom-2024.06.00.pom">
<sha256 value="1b391a969ff81c0bb43b3711e92d977e8bfa72457a11d8a37910a7051bdc3045" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="androidx.activity" name="activity-compose" version="1.7.0">
<artifact name="activity-compose-1.7.0.aar">
<sha256 value="caa72885d1ce7979c1d6c59a8b255c6097b770780d4d4da95d56979a348646cd" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
<artifact name="activity-compose-1.7.0.module">
<sha256 value="f7a29bcba338575dcf89a553cff9cfad3f140340eaf2b56fd0193244da602c0a" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="androidx.compose.runtime" name="runtime" version="1.0.1">
<artifact name="runtime-1.0.1.module">
<sha256 value="2543a8c7edc16bde91f140286b4fd3773d7204a283a4ec99f6e5e286aa92c0c3" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.compose.runtime" name="runtime-saveable" version="1.0.1">
<artifact name="runtime-saveable-1.0.1.module">
<sha256 value="c0d6f142542d8d74f65481ef6526d2be265f01f812a112948fcde87a458f4fb6" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.compose.ui" name="ui" version="1.0.1">
<artifact name="ui-1.0.1.aar">
<sha256 value="1943daa4a3412861b9a2bdc1a7c8c2ff05d9b8191c1d3e56ebb223d2eb4a8526" origin="Generated by Gradle"/>
</artifact>
<artifact name="ui-1.0.1.module">
<sha256 value="57031a6ac9b60e5b56792ebf5cde6e16812ff566ed9190cbd188b00b46c13779" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="androidx.compose" name="compose-bom" version="2024.06.00">
<artifact name="compose-bom-2024.06.00.pom">
<sha256 value="1b391a969ff81c0bb43b3711e92d977e8bfa72457a11d8a37910a7051bdc3045" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="androidx.appcompat" name="appcompat" version="1.1.0">
<artifact name="appcompat-1.1.0.pom">
<sha256 value="340d617121f8ef8e02a6680c8f357aa3e542276d0c8a1cdcb6fd98984b2cb7b9" origin="Generated by Gradle" reason="Artifact is not signed"/>