ConversationCreationActivity UI

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 192da37c12
commit cd01c80d71
No known key found for this signature in database
GPG key ID: C793F8B59F43CE7B
15 changed files with 680 additions and 7 deletions

View file

@ -309,7 +309,7 @@ dependencies {
//compose
implementation(platform("androidx.compose:compose-bom:2024.09.00"))
implementation("androidx.compose.ui:ui")
implementation 'androidx.compose.material3:material3'
implementation 'androidx.compose.material3:material3:1.2.1'
implementation("androidx.compose.ui:ui-tooling-preview")
implementation 'androidx.activity:activity-compose:1.9.2'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.8.5'

View file

@ -129,6 +129,9 @@
<activity android:name=".contacts.ContactsActivityCompose"
android:theme="@style/AppTheme"/>
<activity android:name=".conversationcreation.ConversationCreationActivity"
android:theme="@style/AppTheme"/>
<activity
android:name=".account.AccountVerificationActivity"
android:theme="@style/AppTheme" />

View file

@ -9,9 +9,13 @@ package com.nextcloud.talk.api
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 retrofit2.http.Field
import retrofit2.http.FormUrlEncoded
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Query
import retrofit2.http.QueryMap
import retrofit2.http.Url
@ -39,4 +43,26 @@ interface NcApiCoroutines {
@Url url: String?,
@QueryMap options: Map<String, String>?
): RoomOverall
/*
QueryMap items are as follows:
- "roomName" : "newName"
Server URL is: baseUrl + ocsApiVersion + spreedApiVersion + /room/roomToken
*/
@FormUrlEncoded
@PUT
fun renameRoom(
@Header("Authorization") authorization: String?,
@Url url: String,
@Field("roomName") roomName: String?
): GenericOverall
@FormUrlEncoded
@PUT
fun setConversationDescription(
@Header("Authorization") authorization: String?,
@Url url: String,
@Field("description") description: String?
): GenericOverall
}

View file

@ -64,6 +64,7 @@ import com.nextcloud.talk.R
import com.nextcloud.talk.activities.BaseActivity
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.chat.ChatActivity
import com.nextcloud.talk.conversationcreation.ConversationCreationActivity
import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser
import com.nextcloud.talk.openconversations.ListOpenConversationsActivity
import com.nextcloud.talk.utils.bundle.BundleKeys
@ -278,7 +279,11 @@ fun AppBar(title: String, context: Context, contactsViewModel: ContactsViewModel
fun ConversationCreationOptions(context: Context) {
Column {
Row(
modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 16.dp, bottom = 8.dp),
modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 16.dp, bottom = 8.dp)
.clickable {
val intent = Intent(context, ConversationCreationActivity::class.java)
context.startActivity(intent)
},
verticalAlignment = Alignment.CenterVertically
) {
Icon(
@ -326,6 +331,8 @@ fun ConversationCreationOptions(context: Context) {
}
}
class CompanionClass {
companion object {
internal val TAG = ContactsActivityCompose::class.simpleName

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

@ -0,0 +1,246 @@
/*
* Nextcloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2024 Sowjanya Kota <sowjanya.kch@gmail.com>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.nextcloud.talk.conversationcreation
import android.app.Activity
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.ViewModelProvider
import autodagger.AutoInjector
import coil.compose.AsyncImage
import com.nextcloud.talk.R
import com.nextcloud.talk.activities.BaseActivity
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.contacts.ContactsViewModel
import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class)
class ConversationCreationActivity : BaseActivity() {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
private lateinit var conversationCreationViewModel: ConversationCreationViewModel
private lateinit var contactsViewModel: ContactsViewModel
@OptIn(ExperimentalMaterial3Api::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
conversationCreationViewModel =
ViewModelProvider(this, viewModelFactory)[ConversationCreationViewModel::class.java]
contactsViewModel = ViewModelProvider(this, viewModelFactory)[ContactsViewModel::class.java]
setContent {
val colorScheme = viewThemeUtils.getColorScheme(this)
MaterialTheme(
colorScheme = colorScheme
) {
val context = LocalContext.current
Scaffold(
topBar = {
TopAppBar(
title = { Text(text = stringResource(id = R.string.nc_new_conversation)) },
navigationIcon = {
IconButton(onClick = {
(context as? Activity)?.finish()
}) {
Icon(
Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = stringResource(R.string.back_button)
)
}
}
)
},
content = {
Column(Modifier.padding(it)) {
DefaultUserAvatar()
UploadAvatar()
ConversationNameAndDescription(conversationCreationViewModel)
AddParticipants(contactsViewModel)
RoomCreationOptions(conversationCreationViewModel)
}
}
)
}
}
}
}
@Composable
fun DefaultUserAvatar() {
Box(
modifier = Modifier.fillMaxWidth(),
contentAlignment = Alignment.Center
) {
AsyncImage(
model = R.drawable.ic_circular_group,
contentDescription = "User Avatar",
modifier = Modifier
.size(width = 84.dp, height = 84.dp)
.padding(top = 8.dp)
)
}
}
@Composable
fun UploadAvatar() {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
horizontalArrangement = Arrangement.Center
) {
IconButton(onClick = {
}) {
Icon(
painter = painterResource(id = R.drawable.ic_baseline_photo_camera_24),
contentDescription = null,
modifier = Modifier.size(24.dp)
)
}
IconButton(onClick = {
}) {
Icon(
painter = painterResource(id = R.drawable.ic_folder_multiple_image),
contentDescription = null,
modifier = Modifier.size(24.dp)
)
}
IconButton(onClick = {
}) {
Icon(
painter = painterResource(id = R.drawable.baseline_tag_faces_24),
contentDescription = null,
modifier = Modifier.size(24.dp)
)
}
IconButton(onClick = {
}) {
Icon(
painter = painterResource(id = R.drawable.ic_delete_grey600_24dp),
contentDescription = null,
modifier = Modifier.size(24.dp)
)
}
}
}
@Composable
fun ConversationNameAndDescription(conversationCreationViewModel: ConversationCreationViewModel) {
val conversationRoomName = conversationCreationViewModel.roomName.collectAsState()
val conversationDescription = conversationCreationViewModel.conversationDescription.collectAsState()
OutlinedTextField(
value = conversationRoomName.value,
onValueChange = {
conversationCreationViewModel.updateRoomName(it)
},
label = { Text(text = stringResource(id = R.string.nc_call_name)) },
modifier = Modifier
.padding(start = 16.dp, end = 16.dp)
.fillMaxWidth()
)
OutlinedTextField(
value = conversationDescription.value,
onValueChange = {
conversationCreationViewModel.updateRoomName(it)
},
label = { Text(text = stringResource(id = R.string.nc_conversation_description)) },
modifier = Modifier
.padding(top = 8.dp, start = 16.dp, end = 16.dp)
.fillMaxWidth()
)
}
@Composable
fun AddParticipants(contactsViewModel: ContactsViewModel) {
Text(
text = stringResource(id = R.string.nc_participants).uppercase(),
fontSize = 14.sp,
modifier = Modifier.padding(top = 24.dp, start = 16.dp, end = 16.dp)
)
Row(
modifier = Modifier
.padding(start = 16.dp, end = 16.dp)
.clickable {
// Show contacts
},
verticalAlignment = Alignment
.CenterVertically
) {
Icon(
painter = painterResource(id = R.drawable.ic_account_plus),
contentDescription = null,
modifier = Modifier.size(24.dp)
)
Text(text = stringResource(id = R.string.nc_add_participants), modifier = Modifier.padding(start = 16.dp))
}
}
@Composable
fun RoomCreationOptions(conversationCreationViewModel: ConversationCreationViewModel) {
val isChecked = conversationCreationViewModel.isGuestsAllowed.value
Text(
text = stringResource(id = R.string.nc_visible).uppercase(),
fontSize = 14.sp,
modifier = Modifier.padding(top = 24.dp, start = 16.dp, end = 16.dp)
)
Row(
modifier = Modifier.padding(start = 16.dp, top = 16.dp, end = 16.dp).fillMaxWidth(),
verticalAlignment = Alignment
.CenterVertically
) {
Icon(
painter = painterResource(id = R.drawable.ic_avatar_link),
contentDescription = null,
modifier = Modifier.size(24.dp)
)
Text(text = stringResource(id = R.string.nc_guest_access_allow_title))
Spacer(modifier = Modifier.weight(1f))
Switch(
checked = isChecked,
onCheckedChange = {
conversationCreationViewModel.isGuestsAllowed.value = it
}
)
}
}

View file

@ -0,0 +1,15 @@
/*
* Nextcloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2024 Sowjanya Kota <sowjanya.kch@gmail.com>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.nextcloud.talk.conversationcreation
import com.nextcloud.talk.models.json.generic.GenericOverall
interface ConversationCreationRepository {
suspend fun renameConversation(roomToken: String, roomNameNew: String?): GenericOverall
suspend fun setConversationDescription(roomToken: String, description: String?): GenericOverall
}

View file

@ -0,0 +1,48 @@
/*
* Nextcloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2024 Sowjanya Kota <sowjanya.kch@gmail.com>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.nextcloud.talk.conversationcreation
import com.nextcloud.talk.api.NcApiCoroutines
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.ApiUtils
class ConversationCreationRepositoryImpl(
private val ncApiCoroutines: NcApiCoroutines,
private val userManager: UserManager
) : ConversationCreationRepository {
private val _currentUser = userManager.currentUser.blockingGet()
val currentUser: User = _currentUser
val credentials = ApiUtils.getCredentials(_currentUser.username, _currentUser.token)
val apiVersion = ApiUtils.getConversationApiVersion(_currentUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V1))
override suspend fun renameConversation(roomToken: String, roomNameNew: String?): GenericOverall {
return ncApiCoroutines.renameRoom(
credentials,
ApiUtils.getUrlForRoom(
apiVersion,
_currentUser.baseUrl,
roomToken
),
roomNameNew
)
}
override suspend fun setConversationDescription(roomToken: String, description: String?): GenericOverall {
return ncApiCoroutines.setConversationDescription(
credentials,
ApiUtils.getUrlForConversationDescription(
apiVersion,
_currentUser.baseUrl,
roomToken
),
description
)
}
}

View file

@ -0,0 +1,57 @@
/*
* Nextcloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2024 Sowjanya Kota <sowjanya.kch@gmail.com>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.nextcloud.talk.conversationcreation
import android.util.Log
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
class ConversationCreationViewModel @Inject constructor(
private val repository: ConversationCreationRepository
) : ViewModel() {
private val _roomName = MutableStateFlow("")
val roomName: StateFlow<String> = _roomName
private val _conversationDescription = MutableStateFlow("")
val conversationDescription: StateFlow<String> = _conversationDescription
var isGuestsAllowed = mutableStateOf(false)
var isConversationAvailableForRegisteredUsers = mutableStateOf(false)
var openForGuestAppUsers = mutableStateOf(false)
fun updateRoomName(roomName: String) {
_roomName.value = roomName
}
fun updateConversationDescription(conversationDescription: String) {
_conversationDescription.value = conversationDescription
}
fun renameConversation(roomToken: String) {
viewModelScope.launch {
try {
repository.renameConversation(roomToken, roomName.value)
} catch (e: Exception) {
Log.d("ConversationCreationViewModel", "${e.message}")
}
}
}
fun setConversationDescription(roomToken: String) {
viewModelScope.launch {
try {
repository.setConversationDescription(roomToken, conversationDescription.value)
} catch (e: Exception) {
Log.d("ConversationCreationViewModel", "${e.message}")
}
}
}
}

View file

@ -19,6 +19,8 @@ import com.nextcloud.talk.contacts.ContactsRepository
import com.nextcloud.talk.contacts.ContactsRepositoryImpl
import com.nextcloud.talk.conversation.repository.ConversationRepository
import com.nextcloud.talk.conversation.repository.ConversationRepositoryImpl
import com.nextcloud.talk.conversationcreation.ConversationCreationRepository
import com.nextcloud.talk.conversationcreation.ConversationCreationRepositoryImpl
import com.nextcloud.talk.conversationinfoedit.data.ConversationInfoEditRepository
import com.nextcloud.talk.conversationinfoedit.data.ConversationInfoEditRepositoryImpl
import com.nextcloud.talk.conversationlist.data.OfflineConversationsRepository
@ -208,4 +210,12 @@ class RepositoryModule {
fun provideContactsRepository(ncApiCoroutines: NcApiCoroutines, userManager: UserManager): ContactsRepository {
return ContactsRepositoryImpl(ncApiCoroutines, userManager)
}
@Provides
fun provideConversationCreationRepository(
ncApiCoroutines: NcApiCoroutines,
userManager: UserManager
): ConversationCreationRepository {
return ConversationCreationRepositoryImpl(ncApiCoroutines, userManager)
}
}

View file

@ -14,6 +14,7 @@ import com.nextcloud.talk.contacts.ContactsViewModel
import com.nextcloud.talk.chat.viewmodels.MessageInputViewModel
import com.nextcloud.talk.conversation.viewmodel.ConversationViewModel
import com.nextcloud.talk.conversation.viewmodel.RenameConversationViewModel
import com.nextcloud.talk.conversationcreation.ConversationCreationViewModel
import com.nextcloud.talk.conversationinfo.viewmodel.ConversationInfoViewModel
import com.nextcloud.talk.conversationinfoedit.viewmodel.ConversationInfoEditViewModel
import com.nextcloud.talk.conversationlist.viewmodels.ConversationsListViewModel
@ -156,4 +157,9 @@ abstract class ViewModelModule {
@IntoMap
@ViewModelKey(ContactsViewModel::class)
abstract fun contactsViewModel(viewModel: ContactsViewModel): ViewModel
@Binds
@IntoMap
@ViewModelKey(ConversationCreationViewModel::class)
abstract fun conversationCreationViewModel(viewModel: ConversationCreationViewModel): ViewModel
}

View file

@ -0,0 +1,18 @@
<!--
~ Nextcloud Talk - Android Client
~
~ SPDX-FileCopyrightText: 2024 Your Name <your@email.com>
~ SPDX-License-Identifier: GPL-3.0-or-later
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:tint="#000000"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp">
<path android:fillColor="@android:color/white"
android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8zM15.5,11c0.83,0 1.5,-0.67 1.5,-1.5S16.33,8 15.5,8 14,8.67 14,9.5s0.67,1.5 1.5,1.5zM8.5,11c0.83,0 1.5,-0.67 1.5,-1.5S9.33,8 8.5,8 7,8.67 7,9.5 7.67,11 8.5,11zM12,17.5c2.33,0 4.31,-1.46 5.11,-3.5L6.89,14c0.8,2.04 2.78,3.5 5.11,3.5z"/>
</vector>

View file

@ -386,6 +386,7 @@ How to translate with transifex:
<string name="close_icon">Close Icon</string>
<string name="nc_refresh">Refresh</string>
<string name="nc_check_your_internet">Please check your internet connection</string>
<string name="nc_visible">Visible</string>
<!-- Chat -->
<string name="nc_hint_enter_a_message">Enter a message …</string>

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"/>
@ -145,7 +145,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"/>
@ -157,6 +156,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"/>
@ -246,6 +246,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"/>
@ -343,6 +344,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"/>
@ -359,6 +404,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"/>
@ -372,6 +425,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"/>
@ -393,6 +451,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"/>