Merge pull request #4011 from nextcloud/contacts_theming
Contacts theming
This commit is contained in:
Коммит
85b94d679b
|
@ -158,6 +158,8 @@ ext {
|
|||
workVersion = "2.9.1"
|
||||
espressoVersion = "3.6.1"
|
||||
media3_version = "1.4.0"
|
||||
coroutines_version = "1.3.9"
|
||||
mockitoKotlinVersion = "4.1.0"
|
||||
}
|
||||
|
||||
configurations.configureEach {
|
||||
|
@ -333,6 +335,14 @@ dependencies {
|
|||
|
||||
implementation "com.google.dagger:hilt-android:$hilt_version"
|
||||
kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
|
||||
|
||||
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.3")
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
androidTestImplementation(platform("androidx.compose:compose-bom:2024.06.00"))
|
||||
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
|
||||
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion"
|
||||
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version"
|
||||
|
||||
}
|
||||
|
||||
tasks.register('installGitHooks', Copy) {
|
||||
|
|
|
@ -13,10 +13,8 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
|
@ -35,6 +33,7 @@ import androidx.compose.foundation.lazy.LazyColumn
|
|||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.automirrored.filled.List
|
||||
import androidx.compose.material.icons.filled.Search
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
|
@ -61,9 +60,8 @@ import androidx.compose.ui.unit.sp
|
|||
import androidx.lifecycle.ViewModelProvider
|
||||
import autodagger.AutoInjector
|
||||
import coil.compose.AsyncImage
|
||||
import coil.request.ImageRequest
|
||||
import coil.transform.CircleCropTransformation
|
||||
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.models.json.autocomplete.AutocompleteUser
|
||||
|
@ -72,7 +70,7 @@ import com.nextcloud.talk.utils.bundle.BundleKeys
|
|||
import javax.inject.Inject
|
||||
|
||||
@AutoInjector(NextcloudTalkApplication::class)
|
||||
class ContactsActivityCompose : ComponentActivity() {
|
||||
class ContactsActivityCompose : BaseActivity() {
|
||||
|
||||
@Inject
|
||||
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||
|
@ -83,9 +81,12 @@ class ContactsActivityCompose : ComponentActivity() {
|
|||
super.onCreate(savedInstanceState)
|
||||
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
|
||||
contactsViewModel = ViewModelProvider(this, viewModelFactory)[ContactsViewModel::class.java]
|
||||
|
||||
setContent {
|
||||
MaterialTheme {
|
||||
val colorScheme = viewThemeUtils.getColorScheme(this)
|
||||
val uiState = contactsViewModel.contactsViewState.collectAsState()
|
||||
MaterialTheme(
|
||||
colorScheme = colorScheme
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
Scaffold(
|
||||
topBar = {
|
||||
|
@ -96,7 +97,6 @@ class ContactsActivityCompose : ComponentActivity() {
|
|||
)
|
||||
},
|
||||
content = {
|
||||
val uiState = contactsViewModel.contactsViewState.collectAsState()
|
||||
Column(Modifier.padding(it)) {
|
||||
ConversationCreationOptions(context = context)
|
||||
ContactsList(
|
||||
|
@ -170,6 +170,7 @@ fun ContactsItem(contacts: List<AutocompleteUser>, contactsViewModel: ContactsVi
|
|||
}
|
||||
items(contactsForInitial) { contact ->
|
||||
ContactItemRow(contact = contact, contactsViewModel = contactsViewModel, context = context)
|
||||
Log.d(CompanionClass.TAG, "Contacts:$contact")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -205,15 +206,10 @@ fun ContactItemRow(contact: AutocompleteUser, contactsViewModel: ContactsViewMod
|
|||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
val imageUri = contact.id?.let { contactsViewModel.getImageUri(it, true) }
|
||||
val imageRequest = ImageRequest.Builder(context)
|
||||
.data(imageUri)
|
||||
.transformations(CircleCropTransformation())
|
||||
.error(R.drawable.account_circle_96dp)
|
||||
.placeholder(R.drawable.account_circle_96dp)
|
||||
.build()
|
||||
|
||||
val errorPlaceholderImage: Int = R.drawable.account_circle_96dp
|
||||
val loadedImage = loadImage(imageUri, context, errorPlaceholderImage)
|
||||
AsyncImage(
|
||||
model = imageRequest,
|
||||
model = loadedImage,
|
||||
contentDescription = stringResource(R.string.user_avatar),
|
||||
modifier = Modifier.size(width = 45.dp, height = 45.dp)
|
||||
)
|
||||
|
@ -246,8 +242,10 @@ fun ContactItemRow(contact: AutocompleteUser, contactsViewModel: ContactsViewMod
|
|||
fun AppBar(title: String, context: Context, contactsViewModel: ContactsViewModel) {
|
||||
val searchQuery by contactsViewModel.searchQuery.collectAsState()
|
||||
val searchState = contactsViewModel.searchState.collectAsState()
|
||||
|
||||
TopAppBar(
|
||||
title = { Text(text = title) },
|
||||
|
||||
navigationIcon = {
|
||||
IconButton(onClick = {
|
||||
(context as? Activity)?.finish()
|
||||
|
@ -282,13 +280,13 @@ fun ConversationCreationOptions(context: Context) {
|
|||
modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 16.dp, bottom = 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Image(
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.baseline_chat_bubble_outline_24),
|
||||
modifier = Modifier
|
||||
.width(40.dp)
|
||||
.height(40.dp)
|
||||
.padding(8.dp),
|
||||
painter = painterResource(R.drawable.baseline_chat_bubble_outline_24),
|
||||
contentDescription = stringResource(R.string.new_conversation_creation_icon)
|
||||
contentDescription = null
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
|
@ -308,13 +306,13 @@ fun ConversationCreationOptions(context: Context) {
|
|||
},
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Image(
|
||||
Icon(
|
||||
Icons.AutoMirrored.Filled.List,
|
||||
modifier = Modifier
|
||||
.width(40.dp)
|
||||
.height(40.dp)
|
||||
.padding(8.dp),
|
||||
painter = painterResource(R.drawable.baseline_format_list_bulleted_24),
|
||||
contentDescription = stringResource(R.string.join_open_conversations_icon)
|
||||
contentDescription = null
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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 android.app.Application
|
||||
import coil.ImageLoader
|
||||
import coil.ImageLoaderFactory
|
||||
import coil.disk.DiskCache
|
||||
import coil.memory.MemoryCache
|
||||
import coil.util.DebugLogger
|
||||
import com.nextcloud.talk.utils.ContactUtils
|
||||
|
||||
class ContactsApplication : Application(), ImageLoaderFactory {
|
||||
override fun newImageLoader(): ImageLoader {
|
||||
val imageLoader = ImageLoader.Builder(this)
|
||||
.memoryCache {
|
||||
MemoryCache.Builder(this)
|
||||
.maxSizePercent(ContactUtils.CACHE_MEMORY_SIZE_PERCENTAGE)
|
||||
.build()
|
||||
}
|
||||
.diskCache {
|
||||
DiskCache.Builder()
|
||||
.maxSizePercent(ContactUtils.CACHE_DISK_SIZE_PERCENTAGE)
|
||||
.directory(cacheDir)
|
||||
.build()
|
||||
}
|
||||
.logger(DebugLogger())
|
||||
.build()
|
||||
return imageLoader
|
||||
}
|
||||
}
|
|
@ -13,4 +13,5 @@ import com.nextcloud.talk.models.json.conversations.RoomOverall
|
|||
interface ContactsRepository {
|
||||
suspend fun getContacts(searchQuery: String?, shareTypes: List<String>): AutocompleteOverall
|
||||
suspend fun createRoom(roomType: String, sourceType: String, userId: String, conversationName: String?): RoomOverall
|
||||
fun getImageUri(avatarId: String, requestBigSize: Boolean): String
|
||||
}
|
||||
|
|
|
@ -64,4 +64,12 @@ class ContactsRepositoryImpl(
|
|||
)
|
||||
return response
|
||||
}
|
||||
|
||||
override fun getImageUri(avatarId: String, requestBigSize: Boolean): String {
|
||||
return ApiUtils.getUrlForAvatar(
|
||||
_currentUser.baseUrl,
|
||||
avatarId,
|
||||
requestBigSize
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,27 +9,21 @@ 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 ContactsViewModel @Inject constructor(
|
||||
private val repository: ContactsRepository,
|
||||
private val userManager: UserManager
|
||||
private val repository: ContactsRepository
|
||||
) : 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)
|
||||
|
@ -86,13 +80,8 @@ class ContactsViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getImageUri(avatarId: String, requestBigSize: Boolean): String {
|
||||
return ApiUtils.getUrlForAvatar(
|
||||
_currentUser.baseUrl,
|
||||
avatarId,
|
||||
requestBigSize
|
||||
)
|
||||
return repository.getImageUri(avatarId, requestBigSize)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Nextcloud Talk - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 Sowjanya Kota <sowjanya.kch@email.com>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package com.nextcloud.talk.contacts
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.runtime.Composable
|
||||
import coil.request.ImageRequest
|
||||
import coil.transform.CircleCropTransformation
|
||||
|
||||
@Composable
|
||||
fun loadImage(imageUri: String?, context: Context, errorPlaceholderImage: Int): ImageRequest {
|
||||
val imageRequest = ImageRequest.Builder(context)
|
||||
.data(imageUri)
|
||||
.transformations(CircleCropTransformation())
|
||||
.error(errorPlaceholderImage)
|
||||
.placeholder(errorPlaceholderImage)
|
||||
.build()
|
||||
return imageRequest
|
||||
}
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
package com.nextcloud.talk.contacts
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
|
@ -17,13 +16,10 @@ import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
|||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.material3.TextFieldDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
|
@ -34,82 +30,65 @@ import com.nextcloud.talk.R
|
|||
|
||||
@Composable
|
||||
fun DisplaySearch(text: String, onTextChange: (String) -> Unit, contactsViewModel: ContactsViewModel) {
|
||||
Surface(
|
||||
val keyboardController = LocalSoftwareKeyboardController.current
|
||||
TextField(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(60.dp)
|
||||
.background(Color.White)
|
||||
) {
|
||||
val keyboardController = LocalSoftwareKeyboardController.current
|
||||
TextField(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
value = text,
|
||||
onValueChange = { onTextChange(it) },
|
||||
placeholder = {
|
||||
Text(
|
||||
text = stringResource(R.string.nc_search),
|
||||
color = Color.DarkGray
|
||||
)
|
||||
},
|
||||
.height(60.dp),
|
||||
value = text,
|
||||
onValueChange = { onTextChange(it) },
|
||||
placeholder = {
|
||||
Text(
|
||||
text = stringResource(R.string.nc_search)
|
||||
)
|
||||
},
|
||||
|
||||
textStyle = TextStyle(
|
||||
color = Color.Black,
|
||||
fontSize = 16.sp
|
||||
),
|
||||
singleLine = true,
|
||||
leadingIcon = {
|
||||
textStyle = TextStyle(
|
||||
fontSize = 16.sp
|
||||
),
|
||||
singleLine = true,
|
||||
leadingIcon = {
|
||||
IconButton(
|
||||
onClick = {
|
||||
onTextChange("")
|
||||
contactsViewModel.updateSearchState(false)
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Default.ArrowBack,
|
||||
contentDescription = stringResource(R.string.back_button)
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
trailingIcon = {
|
||||
if (text.isNotEmpty()) {
|
||||
IconButton(
|
||||
onClick = {
|
||||
onTextChange("")
|
||||
contactsViewModel.updateSearchState(false)
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Default.ArrowBack,
|
||||
contentDescription = stringResource(R.string.back_button),
|
||||
tint = Color.Black
|
||||
imageVector = Icons.Default.Close,
|
||||
contentDescription = stringResource(R.string.close_icon)
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
trailingIcon = {
|
||||
if (text.isNotEmpty()) {
|
||||
IconButton(
|
||||
onClick = {
|
||||
onTextChange("")
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Close,
|
||||
contentDescription = stringResource(R.string.close_icon),
|
||||
tint = Color.Black
|
||||
)
|
||||
}
|
||||
keyboardOptions = KeyboardOptions(
|
||||
imeAction = ImeAction.Search
|
||||
),
|
||||
|
||||
keyboardActions = KeyboardActions(
|
||||
onSearch = {
|
||||
if (text.trim().isNotEmpty()) {
|
||||
keyboardController?.hide()
|
||||
} else {
|
||||
return@KeyboardActions
|
||||
}
|
||||
},
|
||||
|
||||
keyboardOptions = KeyboardOptions(
|
||||
imeAction = ImeAction.Search
|
||||
),
|
||||
|
||||
keyboardActions = KeyboardActions(
|
||||
onSearch = {
|
||||
if (text.trim().isNotEmpty()) {
|
||||
keyboardController?.hide()
|
||||
} else {
|
||||
return@KeyboardActions
|
||||
}
|
||||
}
|
||||
),
|
||||
maxLines = 1,
|
||||
colors = TextFieldDefaults.colors(
|
||||
focusedContainerColor = Color.White,
|
||||
unfocusedContainerColor = Color.White,
|
||||
disabledContainerColor = Color.White,
|
||||
focusedTextColor = Color.Black,
|
||||
cursorColor = Color.Black
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
),
|
||||
maxLines = 1
|
||||
)
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ import android.provider.ContactsContract
|
|||
object ContactUtils {
|
||||
|
||||
const val MAX_CONTACT_LIMIT = 50
|
||||
const val CACHE_MEMORY_SIZE_PERCENTAGE = 0.1
|
||||
const val CACHE_DISK_SIZE_PERCENTAGE = 0.02
|
||||
|
||||
fun getDisplayNameFromDeviceContact(context: Context, id: String?): String? {
|
||||
var displayName: String? = null
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
android:viewportHeight="24"
|
||||
android:viewportWidth="24"
|
||||
android:width="24dp">
|
||||
|
||||
|
||||
<path android:fillColor="@android:color/white"
|
||||
android:pathData="M20,2L4,2c-1.1,0 -2,0.9 -2,2v18l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM20,16L6,16l-2,2L4,4h16v12z"/>
|
||||
|
||||
|
||||
</vector>
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* 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.contacts
|
||||
|
||||
import com.nextcloud.talk.contacts.apiService.FakeItem
|
||||
import com.nextcloud.talk.contacts.repository.FakeRepositoryError
|
||||
import com.nextcloud.talk.contacts.repository.FakeRepositorySuccess
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.TestDispatcher
|
||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import kotlinx.coroutines.test.resetMain
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlinx.coroutines.test.setMain
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class ContactsViewModelTest {
|
||||
private lateinit var viewModel: ContactsViewModel
|
||||
private val repository: ContactsRepository = FakeRepositorySuccess()
|
||||
|
||||
val dispatcher: TestDispatcher = UnconfinedTestDispatcher()
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
Dispatchers.setMain(dispatcher)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
Dispatchers.resetMain()
|
||||
}
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
viewModel = ContactsViewModel(repository)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `fetch contacts`() =
|
||||
runTest {
|
||||
viewModel = ContactsViewModel(repository)
|
||||
viewModel.getContactsFromSearchParams()
|
||||
assert(viewModel.contactsViewState.value is ContactsUiState.Success)
|
||||
val successState = viewModel.contactsViewState.value as ContactsUiState.Success
|
||||
assert(successState.contacts == FakeItem.contacts)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test error contacts state`() =
|
||||
runTest {
|
||||
viewModel = ContactsViewModel(FakeRepositoryError())
|
||||
assert(viewModel.contactsViewState.value is ContactsUiState.Error)
|
||||
val errorState = viewModel.contactsViewState.value as ContactsUiState.Error
|
||||
assert(errorState.message == "unable to fetch contacts")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `update search query`() {
|
||||
viewModel.updateSearchQuery("Ma")
|
||||
assert(viewModel.searchQuery.value == "Ma")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `initial search query is empty string`() {
|
||||
viewModel.updateSearchQuery("")
|
||||
assert(viewModel.searchQuery.value == "")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `initial shareType is User`() {
|
||||
assert(viewModel.shareTypeList.contains(ShareType.User.shareType))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `update shareTypes`() {
|
||||
viewModel.updateShareTypes(ShareType.Group.shareType)
|
||||
assert(viewModel.shareTypeList.contains(ShareType.Group.shareType))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `initial room state is none`() =
|
||||
runTest {
|
||||
assert(viewModel.roomViewState.value is RoomUiState.None)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test success room state`() =
|
||||
runTest {
|
||||
viewModel.createRoom("1", "users", "s@gmail.com", null)
|
||||
assert(viewModel.roomViewState.value is RoomUiState.Success)
|
||||
val successState = viewModel.roomViewState.value as RoomUiState.Success
|
||||
assert(successState.conversation == FakeItem.roomOverall.ocs!!.data)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test failure room state`() =
|
||||
runTest {
|
||||
viewModel = ContactsViewModel(FakeRepositoryError())
|
||||
viewModel.createRoom("1", "users", "s@gmail.com", null)
|
||||
assert(viewModel.roomViewState.value is RoomUiState.Error)
|
||||
val errorState = viewModel.roomViewState.value as RoomUiState.Error
|
||||
assert(errorState.message == "unable to create room")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test image uri`() {
|
||||
val expectedImageUri = "https://mydomain.com/index.php/avatar/vidya/512"
|
||||
val imageUri = viewModel.getImageUri("vidya", false)
|
||||
assert(imageUri == expectedImageUri)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test error image uri`() {
|
||||
val expectedImageUri = "https://mydoman.com/index.php/avatar/vidya/512"
|
||||
val imageUri = viewModel.getImageUri("vidya", false)
|
||||
assert(imageUri != expectedImageUri)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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.contacts.apiService
|
||||
|
||||
import com.nextcloud.talk.models.json.autocomplete.AutocompleteOCS
|
||||
import com.nextcloud.talk.models.json.autocomplete.AutocompleteOverall
|
||||
import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser
|
||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||
import com.nextcloud.talk.models.json.conversations.RoomOCS
|
||||
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
||||
import com.nextcloud.talk.models.json.generic.GenericMeta
|
||||
import org.mockito.Mockito.mock
|
||||
|
||||
object FakeItem {
|
||||
val contacts: List<AutocompleteUser> =
|
||||
listOf(
|
||||
AutocompleteUser(id = "android", label = "Android", source = "users"),
|
||||
AutocompleteUser(id = "android1", label = "Android 1", source = "users"),
|
||||
AutocompleteUser(id = "android2", label = "Android 2", source = "users"),
|
||||
AutocompleteUser(id = "Benny", label = "Benny J", source = "users"),
|
||||
AutocompleteUser(id = "Benjamin", label = "Benjamin Schmidt", source = "users"),
|
||||
AutocompleteUser(id = "Chris", label = "Christoph Schmidt", source = "users"),
|
||||
AutocompleteUser(id = "Daniel", label = "Daniel H", source = "users"),
|
||||
AutocompleteUser(id = "Dennis", label = "Dennis Richard", source = "users"),
|
||||
AutocompleteUser(id = "Emma", label = "Emma Jackson", source = "users"),
|
||||
AutocompleteUser(id = "Emily", label = "Emily Jackson", source = "users"),
|
||||
AutocompleteUser(id = "Mario", label = "Mario Schmidt", source = "users"),
|
||||
AutocompleteUser(id = "Maria", label = "Maria Schmidt", source = "users"),
|
||||
AutocompleteUser(id = "Samsung", label = "Samsung A52", source = "users"),
|
||||
AutocompleteUser(id = "Tom", label = "Tom Müller", source = "users"),
|
||||
AutocompleteUser(id = "Tony", label = "Tony Baker", source = "users")
|
||||
)
|
||||
val contactsOverall = AutocompleteOverall(
|
||||
ocs = AutocompleteOCS(
|
||||
meta = GenericMeta(
|
||||
status = "ok",
|
||||
statusCode = 200,
|
||||
message = "OK"
|
||||
),
|
||||
data = contacts
|
||||
)
|
||||
)
|
||||
val roomOverall: RoomOverall = RoomOverall(
|
||||
ocs = RoomOCS(
|
||||
meta = GenericMeta(
|
||||
status = "ok",
|
||||
statusCode = 200,
|
||||
message = "OK"
|
||||
),
|
||||
data = mock(Conversation::class.java)
|
||||
)
|
||||
)
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Nextcloud Talk - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 Sowjanya Kota <sowjanya.kota@gmail.com>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package com.nextcloud.talk.contacts.repository
|
||||
|
||||
import com.nextcloud.talk.contacts.ContactsRepository
|
||||
import com.nextcloud.talk.models.json.autocomplete.AutocompleteOverall
|
||||
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
||||
|
||||
class FakeRepositoryError : ContactsRepository {
|
||||
override suspend fun getContacts(searchQuery: String?, shareTypes: List<String>): AutocompleteOverall {
|
||||
throw Exception("unable to fetch contacts")
|
||||
}
|
||||
|
||||
override suspend fun createRoom(
|
||||
roomType: String,
|
||||
sourceType: String,
|
||||
userId: String,
|
||||
conversationName: String?
|
||||
): RoomOverall {
|
||||
throw Exception("unable to create room")
|
||||
}
|
||||
|
||||
override fun getImageUri(avatarId: String, requestBigSize: Boolean): String {
|
||||
return "https://mydoman.com/index.php/avatar/$avatarId/512"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Nextcloud Talk - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 Sowjanya Kota <sowjanya.kch@email.com>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package com.nextcloud.talk.contacts.repository
|
||||
|
||||
import com.nextcloud.talk.contacts.ContactsRepository
|
||||
import com.nextcloud.talk.contacts.apiService.FakeItem
|
||||
import com.nextcloud.talk.models.json.autocomplete.AutocompleteOverall
|
||||
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
||||
|
||||
class FakeRepositorySuccess : ContactsRepository {
|
||||
override suspend fun getContacts(searchQuery: String?, shareTypes: List<String>): AutocompleteOverall {
|
||||
return FakeItem.contactsOverall
|
||||
}
|
||||
|
||||
override suspend fun createRoom(
|
||||
roomType: String,
|
||||
sourceType: String,
|
||||
userId: String,
|
||||
conversationName: String?
|
||||
): RoomOverall {
|
||||
return FakeItem.roomOverall
|
||||
}
|
||||
|
||||
override fun getImageUri(avatarId: String, requestBigSize: Boolean): String {
|
||||
return "https://mydomain.com/index.php/avatar/$avatarId/512"
|
||||
}
|
||||
}
|
|
@ -11,12 +11,10 @@
|
|||
buildscript {
|
||||
|
||||
ext {
|
||||
kotlinVersion = '1.9.23'
|
||||
hilt_version = '2.44'
|
||||
kotlinVersion = '2.0.0'
|
||||
hilt_version = '2.44'
|
||||
}
|
||||
|
||||
|
||||
repositories {
|
||||
google()
|
||||
gradlePluginPortal()
|
||||
|
|
|
@ -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 group="com.google.dagger" />
|
||||
<trust group="org.javassist" name="javassist" version="3.26.0-GA" reason="java assist"/>
|
||||
<trust group="androidx.fragment"/>
|
||||
<trust file="tensorflow-lite-metadata-0.1.0-rc2.pom" reason="differing hash on every CI run - temp global trust"/>
|
||||
</trusted-artifacts>
|
||||
<ignored-keys>
|
||||
<ignored-key id="0AA3E5C3D232E79B" reason="Key couldn't be downloaded from any key server"/>
|
||||
|
@ -39,7 +39,10 @@
|
|||
<trusted-key id="0F07D1201BDDAB67CFB84EB479752DB6C966F0B8" group="com.google.android" name="annotations" version="4.1.1.4"/>
|
||||
<trusted-key id="10F3C7A02ECA55E502BADCF3991EFB94DB91127D" group="org.ow2" name="ow2" version="1.5.1"/>
|
||||
<trusted-key id="120D6F34E627ED3A772EBBFE55C7E5E701832382" group="org.snakeyaml" name="snakeyaml-engine" version="2.6"/>
|
||||
<trusted-key id="147B691A19097624902F4EA9689CBE64F4BC997F" group="org.mockito"/>
|
||||
<trusted-key id="147B691A19097624902F4EA9689CBE64F4BC997F">
|
||||
<trusting group="org.mockito"/>
|
||||
<trusting group="org.mockito.kotlin" name="mockito-kotlin" version="4.1.0"/>
|
||||
</trusted-key>
|
||||
<trusted-key id="1597AB231B7ADD7E14B1D9C43F00DB67AE236E2E" group="org.conscrypt" name="conscrypt-android" version="2.5.2"/>
|
||||
<trusted-key id="190D5A957FF22273E601F7A7C92C5FEC70161C62" group="org.apache" name="apache" version="18"/>
|
||||
<trusted-key id="19BEAB2D799C020F17C69126B16698A4ADF4D638" group="org.checkerframework"/>
|
||||
|
@ -156,6 +159,7 @@
|
|||
<trusted-key id="8756C4F765C9AC3CB6B85D62379CE192D401AB61">
|
||||
<trusting group="eu.davidea"/>
|
||||
<trusting group="org.jetbrains.intellij.deps"/>
|
||||
<trusting group="org.jetbrains.kotlinx"/>
|
||||
</trusted-key>
|
||||
<trusted-key id="8E3A02905A1AE67E7B0F9ACD3967D4EDA591B991" group="org.jetbrains.kotlinx" name="kotlinx-html-jvm" version="0.8.1"/>
|
||||
<trusted-key id="8F9A3C6D105B9F57844A721D79E193516BE7998F" group="org.dom4j" name="dom4j" version="2.1.4"/>
|
||||
|
@ -232,6 +236,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"/>
|
||||
|
@ -294,6 +299,14 @@
|
|||
<sha256 value="f7a29bcba338575dcf89a553cff9cfad3f140340eaf2b56fd0193244da602c0a" 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.annotation" name="annotation" version="1.0.0">
|
||||
<artifact name="annotation-1.0.0.jar">
|
||||
<sha256 value="0baae9755f7caf52aa80cd04324b91ba93af55d4d1d17dcc9a7b53d99ef7c016" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
||||
|
@ -326,6 +339,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"/>
|
||||
|
@ -342,6 +399,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"/>
|
||||
|
@ -355,6 +420,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"/>
|
||||
|
@ -376,6 +446,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"/>
|
||||
|
@ -4902,6 +5042,14 @@
|
|||
<sha256 value="9a35e48f20f3021c21e469d52fa88b3acc08b20dab77b6c646f72f6fb205ec92" origin="Generated by Gradle" reason="A key couldn't be downloaded"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.novoda" name="merlin" version="1.2.1">
|
||||
<artifact name="merlin-1.2.1.aar">
|
||||
<sha256 value="c62d03d0fde57f26fa633feeee24d7dfed3d66cc81097e4d6306b076cc7d70b6" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
||||
</artifact>
|
||||
<artifact name="merlin-1.2.1.pom">
|
||||
<sha256 value="62dbaffb68b60ca317c05bba83a9fea8d866c3d3e7a2bd928c69591aa2fe4418" origin="Generated by Gradle" reason="Artifact is not signed"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.squareup" name="javapoet" version="1.2.0">
|
||||
<artifact name="javapoet-1.2.0.pom">
|
||||
<pgp value="9E84765A7AA3E3D3D5598A408E3F0DE7AE354651"/>
|
||||
|
@ -5860,7 +6008,7 @@
|
|||
<ignored-keys>
|
||||
<ignored-key id="DB0597E3144342256BC81E3EC727D053C4481CF5" reason="PGP verification failed"/>
|
||||
</ignored-keys>
|
||||
<sha256 value="8359ad51e0476c8e0df7188a43f16d49733c4a428fb45e99794b783f01b97520" origin="Generated by Gradle" reason="PGP signature verification failed!"/>
|
||||
<sha256 value="9a4f5e5674366c156c90391662f03ed7c5971d6aa63832df74a271da6ff82e96" origin="Generated by Gradle" reason="PGP signature verification failed!"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.xerial" name="sqlite-jdbc" version="3.41.2.2">
|
||||
|
|
Загрузка…
Ссылка в новой задаче