mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-19 11:39:42 +01:00
Create public conversation
Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com>
This commit is contained in:
parent
6b82d7209f
commit
2959d8e13a
@ -11,6 +11,7 @@ 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 retrofit2.http.DELETE
|
||||
import retrofit2.http.Field
|
||||
import retrofit2.http.FormUrlEncoded
|
||||
import retrofit2.http.GET
|
||||
@ -73,4 +74,10 @@ interface NcApiCoroutines {
|
||||
@Url url: String?,
|
||||
@QueryMap options: Map<String, String>?
|
||||
): AddParticipantOverall
|
||||
|
||||
@POST
|
||||
fun makeRoomPublic(@Header("Authorization") authorization: String?, @Url url: String?): GenericOverall
|
||||
|
||||
@DELETE
|
||||
fun makeRoomPrivate(@Header("Authorization") authorization: String?, @Url url: String?): GenericOverall
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
@ -101,12 +102,15 @@ class ContactsActivityCompose : BaseActivity() {
|
||||
}
|
||||
val colorScheme = viewThemeUtils.getColorScheme(this)
|
||||
val uiState = contactsViewModel.contactsViewState.collectAsState()
|
||||
val selectedParticipants: List<AutocompleteUser> = if (isAddParticipantsEdit) {
|
||||
intent.getParcelableArrayListExtra("selectedParticipants") ?: emptyList()
|
||||
} else {
|
||||
emptyList()
|
||||
val selectedParticipants: List<AutocompleteUser> = remember {
|
||||
if (isAddParticipants) {
|
||||
intent.getParcelableArrayListExtra("selected participants") ?: emptyList()
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
contactsViewModel.updateSelectedParticipants(selectedParticipants)
|
||||
val participants = selectedParticipants.toSet().toMutableList()
|
||||
contactsViewModel.updateSelectedParticipants(participants)
|
||||
MaterialTheme(
|
||||
colorScheme = colorScheme
|
||||
) {
|
||||
@ -143,7 +147,7 @@ fun ContactItemRow(
|
||||
context: Context,
|
||||
selectedContacts: MutableList<AutocompleteUser>
|
||||
) {
|
||||
val isSelected = contact in selectedContacts
|
||||
val isSelected = selectedContacts.contains(contact)
|
||||
val roomUiState by contactsViewModel.roomViewState.collectAsState()
|
||||
val isAddParticipants = contactsViewModel.isAddParticipantsView.collectAsState()
|
||||
Row(
|
||||
@ -177,16 +181,14 @@ fun ContactItemRow(
|
||||
modifier = Modifier.size(width = 45.dp, height = 45.dp)
|
||||
)
|
||||
Text(modifier = Modifier.padding(16.dp), text = contact.label!!)
|
||||
if (isAddParticipants.value) {
|
||||
if (isSelected) {
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Icon(
|
||||
imageVector = ImageVector.vectorResource(id = R.drawable.ic_check_circle),
|
||||
contentDescription = "Selected",
|
||||
tint = Color.Blue,
|
||||
modifier = Modifier.padding(end = 8.dp)
|
||||
)
|
||||
}
|
||||
if (isAddParticipants.value && isSelected) {
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Icon(
|
||||
imageVector = ImageVector.vectorResource(id = R.drawable.ic_check_circle),
|
||||
contentDescription = "Selected",
|
||||
tint = Color.Blue,
|
||||
modifier = Modifier.padding(end = 8.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
when (roomUiState) {
|
||||
|
@ -31,7 +31,7 @@ class ContactsViewModel @Inject constructor(
|
||||
private val _searchState = MutableStateFlow(false)
|
||||
val searchState: StateFlow<Boolean> = _searchState
|
||||
private val selectedParticipants = mutableListOf<AutocompleteUser>()
|
||||
val selectedParticipantsList: MutableList<AutocompleteUser> = selectedParticipants
|
||||
val selectedParticipantsList: List<AutocompleteUser> = selectedParticipants
|
||||
private val _isAddParticipantsView = MutableStateFlow(false)
|
||||
val isAddParticipantsView: StateFlow<Boolean> = _isAddParticipantsView
|
||||
|
||||
|
@ -24,6 +24,7 @@ import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
@ -45,6 +46,7 @@ import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
@ -60,9 +62,12 @@ 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.chat.ChatActivity
|
||||
import com.nextcloud.talk.contacts.ContactsActivityCompose
|
||||
import com.nextcloud.talk.contacts.RoomUiState
|
||||
import com.nextcloud.talk.contacts.loadImage
|
||||
import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||
import javax.inject.Inject
|
||||
|
||||
@AutoInjector(NextcloudTalkApplication::class)
|
||||
@ -80,10 +85,11 @@ class ConversationCreationActivity : BaseActivity() {
|
||||
)[ConversationCreationViewModel::class.java]
|
||||
setContent {
|
||||
val colorScheme = viewThemeUtils.getColorScheme(this)
|
||||
val context = LocalContext.current
|
||||
MaterialTheme(
|
||||
colorScheme = colorScheme
|
||||
) {
|
||||
ConversationCreationScreen(conversationCreationViewModel)
|
||||
ConversationCreationScreen(conversationCreationViewModel, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -91,7 +97,7 @@ class ConversationCreationActivity : BaseActivity() {
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun ConversationCreationScreen(conversationCreationViewModel: ConversationCreationViewModel) {
|
||||
fun ConversationCreationScreen(conversationCreationViewModel: ConversationCreationViewModel, context: Context) {
|
||||
val context = LocalContext.current
|
||||
val launcher = rememberLauncherForActivityResult(
|
||||
contract = ActivityResultContracts.StartActivityForResult(),
|
||||
@ -101,7 +107,8 @@ fun ConversationCreationScreen(conversationCreationViewModel: ConversationCreati
|
||||
val data = result.data
|
||||
val selectedParticipants = data?.getParcelableArrayListExtra<AutocompleteUser>("selectedParticipants")
|
||||
?: emptyList()
|
||||
conversationCreationViewModel.updateSelectedParticipants(selectedParticipants)
|
||||
val participants = selectedParticipants.toMutableList()
|
||||
conversationCreationViewModel.updateSelectedParticipants(participants)
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -133,7 +140,7 @@ fun ConversationCreationScreen(conversationCreationViewModel: ConversationCreati
|
||||
ConversationNameAndDescription(conversationCreationViewModel)
|
||||
AddParticipants(launcher, context, conversationCreationViewModel)
|
||||
RoomCreationOptions(conversationCreationViewModel)
|
||||
CreateConversation()
|
||||
CreateConversation(conversationCreationViewModel, context)
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -234,10 +241,11 @@ fun AddParticipants(
|
||||
context: Context,
|
||||
conversationCreationViewModel: ConversationCreationViewModel
|
||||
) {
|
||||
val participants = conversationCreationViewModel.selectedParticipants.collectAsState()
|
||||
val participants = conversationCreationViewModel.selectedParticipants.collectAsState().value
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxHeight()
|
||||
modifier = Modifier
|
||||
.fillMaxHeight()
|
||||
.padding(start = 16.dp, end = 16.dp, top = 16.dp)
|
||||
) {
|
||||
Row {
|
||||
@ -247,7 +255,7 @@ fun AddParticipants(
|
||||
modifier = Modifier.padding(start = 16.dp, bottom = 16.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
if (participants.value.isNotEmpty()) {
|
||||
if (participants.isNotEmpty()) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.nc_edit),
|
||||
fontSize = 12.sp,
|
||||
@ -257,8 +265,9 @@ fun AddParticipants(
|
||||
val intent = Intent(context, ContactsActivityCompose::class.java)
|
||||
intent.putParcelableArrayListExtra(
|
||||
"selected participants",
|
||||
participants.value as ArrayList<AutocompleteUser>
|
||||
participants as ArrayList<AutocompleteUser>
|
||||
)
|
||||
intent.putExtra("isAddParticipants", true)
|
||||
intent.putExtra("isAddParticipantsEdit", true)
|
||||
launcher.launch(intent)
|
||||
},
|
||||
@ -267,7 +276,9 @@ fun AddParticipants(
|
||||
}
|
||||
}
|
||||
|
||||
participants.value.forEach { participant ->
|
||||
val participant = participants.toSet()
|
||||
|
||||
participant.forEach { participant ->
|
||||
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
|
||||
val imageUri = participant.id?.let { conversationCreationViewModel.getImageUri(it, true) }
|
||||
val errorPlaceholderImage: Int = R.drawable.account_circle_96dp
|
||||
@ -298,7 +309,7 @@ fun AddParticipants(
|
||||
},
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
if (participants.value.isEmpty()) {
|
||||
if (participant.isEmpty()) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_account_plus),
|
||||
contentDescription = null,
|
||||
@ -402,18 +413,52 @@ fun ConversationOptions(icon: Int? = null, text: Int, switch: @Composable (() ->
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun CreateConversation() {
|
||||
fun CreateConversation(conversationCreationViewModel: ConversationCreationViewModel, context: Context) {
|
||||
val roomUiState by conversationCreationViewModel.roomViewState.collectAsState()
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(all = 16.dp),
|
||||
.padding(all = 16.dp)
|
||||
.clickable {
|
||||
},
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Button(
|
||||
onClick = {
|
||||
val roomType = if (conversationCreationViewModel.isGuestsAllowed.value) {
|
||||
"ROOM_TYPE_PUBLIC"
|
||||
} else {
|
||||
"ROOM_TYPE_PRIVATE"
|
||||
}
|
||||
conversationCreationViewModel.createRoom(
|
||||
roomType,
|
||||
conversationCreationViewModel.roomName.value
|
||||
)
|
||||
}
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.create_conversation))
|
||||
}
|
||||
}
|
||||
when (roomUiState) {
|
||||
is RoomUiState.Success -> {
|
||||
val conversation = (roomUiState as RoomUiState.Success).conversation
|
||||
val token = conversation?.token
|
||||
if (token != null) {
|
||||
conversationCreationViewModel.allowGuests(token, conversationCreationViewModel.isGuestsAllowed.value)
|
||||
}
|
||||
val bundle = Bundle()
|
||||
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, token)
|
||||
val chatIntent = Intent(context, ChatActivity::class.java)
|
||||
chatIntent.putExtras(bundle)
|
||||
chatIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
context.startActivity(chatIntent)
|
||||
}
|
||||
is RoomUiState.Error -> {
|
||||
val errorMessage = (roomUiState as RoomUiState.Error).message
|
||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
Text(text = "Error: $errorMessage", color = Color.Red)
|
||||
}
|
||||
}
|
||||
is RoomUiState.None -> {}
|
||||
}
|
||||
}
|
||||
|
@ -7,12 +7,16 @@
|
||||
|
||||
package com.nextcloud.talk.conversationcreation
|
||||
|
||||
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
||||
import com.nextcloud.talk.models.json.generic.GenericOverall
|
||||
import com.nextcloud.talk.models.json.participants.AddParticipantOverall
|
||||
|
||||
interface ConversationCreationRepository {
|
||||
|
||||
fun allowGuests(token: String, allow: Boolean): ConversationCreationRepositoryImpl.AllowGuestsResult
|
||||
suspend fun renameConversation(roomToken: String, roomNameNew: String?): GenericOverall
|
||||
suspend fun setConversationDescription(roomToken: String, description: String?): GenericOverall
|
||||
suspend fun addParticipants(conversationToken: String?, userId: String, sourceType: String): AddParticipantOverall
|
||||
suspend fun createRoom(roomType: String, conversationName: String?): RoomOverall
|
||||
fun getImageUri(avatarId: String, requestBigSize: Boolean): String
|
||||
}
|
||||
|
@ -10,8 +10,10 @@ 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.json.conversations.RoomOverall
|
||||
import com.nextcloud.talk.models.json.generic.GenericOverall
|
||||
import com.nextcloud.talk.models.json.participants.AddParticipantOverall
|
||||
import com.nextcloud.talk.repositories.conversations.ConversationsRepositoryImpl.Companion.STATUS_CODE_OK
|
||||
import com.nextcloud.talk.users.UserManager
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.ApiUtils.getRetrofitBucketForAddParticipant
|
||||
@ -25,6 +27,9 @@ class ConversationCreationRepositoryImpl(
|
||||
val currentUser: User = _currentUser
|
||||
val credentials = ApiUtils.getCredentials(_currentUser.username, _currentUser.token)
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(_currentUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V1))
|
||||
data class AllowGuestsResult(
|
||||
val allow: Boolean
|
||||
)
|
||||
|
||||
override suspend fun renameConversation(roomToken: String, roomNameNew: String?): GenericOverall {
|
||||
return ncApiCoroutines.renameRoom(
|
||||
@ -81,4 +86,55 @@ class ConversationCreationRepositoryImpl(
|
||||
requestBigSize
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun createRoom(roomType: String, conversationName: String?): RoomOverall {
|
||||
val retrofitBucket: RetrofitBucket =
|
||||
if (roomType == "ROOM_TYPE_PUBLIC") {
|
||||
ApiUtils.getRetrofitBucketForCreateRoom(
|
||||
apiVersion,
|
||||
currentUser.baseUrl!!,
|
||||
"ROOM_TYPE_PUBLIC",
|
||||
null,
|
||||
null,
|
||||
conversationName
|
||||
)
|
||||
} else {
|
||||
ApiUtils.getRetrofitBucketForCreateRoom(
|
||||
apiVersion,
|
||||
currentUser.baseUrl!!,
|
||||
"ROOM_TYPE_GROUP",
|
||||
null,
|
||||
null,
|
||||
conversationName
|
||||
)
|
||||
}
|
||||
val response = ncApiCoroutines.createRoom(
|
||||
credentials,
|
||||
retrofitBucket.url,
|
||||
retrofitBucket.queryMap
|
||||
)
|
||||
return response
|
||||
}
|
||||
|
||||
override fun allowGuests(token: String, allow: Boolean): AllowGuestsResult {
|
||||
val url = ApiUtils.getUrlForRoomPublic(
|
||||
apiVersion,
|
||||
_currentUser.baseUrl!!,
|
||||
token
|
||||
)
|
||||
|
||||
val result = if (allow) {
|
||||
ncApiCoroutines.makeRoomPublic(
|
||||
credentials,
|
||||
url
|
||||
)
|
||||
} else {
|
||||
ncApiCoroutines.makeRoomPrivate(
|
||||
credentials,
|
||||
url
|
||||
)
|
||||
}
|
||||
|
||||
return AllowGuestsResult(result.ocs!!.meta!!.statusCode == STATUS_CODE_OK && allow)
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,9 @@ import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.nextcloud.talk.contacts.AddParticipantsUiState
|
||||
import com.nextcloud.talk.contacts.RoomUiState
|
||||
import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser
|
||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
@ -23,6 +25,8 @@ class ConversationCreationViewModel @Inject constructor(
|
||||
) : ViewModel() {
|
||||
private val _selectedParticipants = MutableStateFlow<List<AutocompleteUser>>(emptyList())
|
||||
val selectedParticipants: StateFlow<List<AutocompleteUser>> = _selectedParticipants
|
||||
private val _roomViewState = MutableStateFlow<RoomUiState>(RoomUiState.None)
|
||||
val roomViewState: StateFlow<RoomUiState> = _roomViewState
|
||||
|
||||
fun updateSelectedParticipants(participants: List<AutocompleteUser>) {
|
||||
_selectedParticipants.value = participants
|
||||
@ -80,4 +84,24 @@ class ConversationCreationViewModel @Inject constructor(
|
||||
fun getImageUri(avatarId: String, requestBigSize: Boolean): String {
|
||||
return repository.getImageUri(avatarId, requestBigSize)
|
||||
}
|
||||
|
||||
fun createRoom(roomType: String, conversationName: String?) {
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
val room = repository.createRoom(
|
||||
roomType,
|
||||
conversationName
|
||||
)
|
||||
|
||||
val conversation: Conversation? = room.ocs?.data
|
||||
_roomViewState.value = RoomUiState.Success(conversation)
|
||||
} catch (exception: Exception) {
|
||||
_roomViewState.value = RoomUiState.Error(exception.message ?: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun allowGuests(token: String, allow: Boolean): ConversationCreationRepositoryImpl.AllowGuestsResult {
|
||||
return repository.allowGuests(token, allow)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user