diff --git a/app/src/main/java/org/linphone/ui/main/chat/fragment/StartConversationFragment.kt b/app/src/main/java/org/linphone/ui/main/chat/fragment/StartConversationFragment.kt index b3a995c1a..452827579 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/fragment/StartConversationFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/fragment/StartConversationFragment.kt @@ -26,7 +26,7 @@ import android.view.ViewGroup import androidx.annotation.UiThread import androidx.annotation.WorkerThread import androidx.core.view.doOnPreDraw -import androidx.navigation.navGraphViewModels +import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import org.linphone.R import org.linphone.core.Address @@ -49,9 +49,7 @@ class StartConversationFragment : GenericAddressPickerFragment() { private lateinit var binding: StartChatFragmentBinding - private val viewModel: StartConversationViewModel by navGraphViewModels( - R.id.main_nav_graph - ) + private lateinit var viewModel: StartConversationViewModel private lateinit var adapter: ContactsAndSuggestionsListAdapter @@ -69,6 +67,8 @@ class StartConversationFragment : GenericAddressPickerFragment() { postponeEnterTransition() binding.lifecycleOwner = viewLifecycleOwner + + viewModel = ViewModelProvider(this)[StartConversationViewModel::class.java] binding.viewModel = viewModel binding.setBackClickListener { diff --git a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/StartConversationViewModel.kt b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/StartConversationViewModel.kt index cb247fafd..2c1453171 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/StartConversationViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/StartConversationViewModel.kt @@ -21,6 +21,7 @@ package org.linphone.ui.main.chat.viewmodel import androidx.annotation.UiThread import androidx.annotation.WorkerThread +import androidx.lifecycle.MediatorLiveData import androidx.lifecycle.MutableLiveData import kotlin.collections.ArrayList import org.linphone.LinphoneApplication.Companion.coreContext @@ -54,6 +55,10 @@ class StartConversationViewModel @UiThread constructor() : AddressSelectionViewM val hideGroupChatButton = MutableLiveData() + val subject = MutableLiveData() + + val groupChatRoomCreateButtonEnabled = MediatorLiveData() + val operationInProgress = MutableLiveData() val chatRoomCreationErrorEvent: MutableLiveData> by lazy { @@ -68,10 +73,10 @@ class StartConversationViewModel @UiThread constructor() : AddressSelectionViewM @WorkerThread override fun onStateChanged(chatRoom: ChatRoom, newState: ChatRoom.State?) { val state = chatRoom.state - Log.i("$TAG Chat room state changed: [$state]") + val id = LinphoneUtils.getChatRoomId(chatRoom) + Log.i("$TAG Chat room [$id] (${chatRoom.subject}) state changed: [$state]") if (state == ChatRoom.State.Created) { - val id = LinphoneUtils.getChatRoomId(chatRoom) Log.i("$TAG Chat room [$id] successfully created") chatRoom.removeListener(this) operationInProgress.postValue(false) @@ -84,7 +89,6 @@ class StartConversationViewModel @UiThread constructor() : AddressSelectionViewM ) ) } else if (state == ChatRoom.State.CreationFailed) { - val id = LinphoneUtils.getChatRoomId(chatRoom) Log.e("$TAG Chat room [$id] creation has failed!") chatRoom.removeListener(this) operationInProgress.postValue(false) @@ -121,6 +125,18 @@ class StartConversationViewModel @UiThread constructor() : AddressSelectionViewM } init { + groupChatRoomCreateButtonEnabled.postValue(false) + groupChatRoomCreateButtonEnabled.addSource(selection) { + groupChatRoomCreateButtonEnabled.postValue( + subject.value.orEmpty().isNotEmpty() && selection.value.orEmpty().isNotEmpty() + ) + } + groupChatRoomCreateButtonEnabled.addSource(subject) { + groupChatRoomCreateButtonEnabled.postValue( + subject.value.orEmpty().isNotEmpty() && selection.value.orEmpty().isNotEmpty() + ) + } + updateGroupChatButtonVisibility() coreContext.postOnCoreThread { core -> @@ -150,6 +166,79 @@ class StartConversationViewModel @UiThread constructor() : AddressSelectionViewM searchFilter.value = "" } + @UiThread + fun createGroupChatRoom() { + coreContext.postOnCoreThread { core -> + val account = core.defaultAccount + if (account == null) { + Log.e( + "$TAG No default account found, can't create group conversation!" + ) + return@postOnCoreThread + } + + operationInProgress.postValue(true) + + val groupChatRoomSubject = subject.value.orEmpty() + val params: ChatRoomParams = coreContext.core.createDefaultChatRoomParams() + params.isGroupEnabled = true + params.subject = groupChatRoomSubject + params.backend = ChatRoom.Backend.FlexisipChat + params.isEncryptionEnabled = true + + val participants = arrayListOf
() + for (participant in selection.value.orEmpty()) { + participants.add(participant.address) + } + val localAddress = account.params.identityAddress + + val participantsArray = arrayOf
() + val chatRoom = core.createChatRoom( + params, + localAddress, + participants.toArray(participantsArray) + ) + if (chatRoom != null) { + if (params.backend == ChatRoom.Backend.FlexisipChat) { + if (chatRoom.state == ChatRoom.State.Created) { + val id = LinphoneUtils.getChatRoomId(chatRoom) + Log.i("$TAG Group chat room [$id] ($groupChatRoomSubject) has been created") + operationInProgress.postValue(false) + chatRoomCreatedEvent.postValue( + Event( + Pair( + chatRoom.localAddress.asStringUriOnly(), + chatRoom.peerAddress.asStringUriOnly() + ) + ) + ) + } else { + Log.i( + "$TAG Chat room [$groupChatRoomSubject] isn't in Created state yet, wait for it" + ) + chatRoom.addListener(chatRoomListener) + } + } else { + val id = LinphoneUtils.getChatRoomId(chatRoom) + Log.i("$TAG Chat room successfully created [$id] ($groupChatRoomSubject)") + operationInProgress.postValue(false) + chatRoomCreatedEvent.postValue( + Event( + Pair( + chatRoom.localAddress.asStringUriOnly(), + chatRoom.peerAddress.asStringUriOnly() + ) + ) + ) + } + } else { + Log.e("$TAG Failed to create group chat room [$groupChatRoomSubject]!") + operationInProgress.postValue(false) + chatRoomCreationErrorEvent.postValue(Event("Error!")) // TODO FIXME: use translated string + } + } + } + @WorkerThread fun createOneToOneChatRoomWith(remote: Address) { val core = coreContext.core diff --git a/app/src/main/res/layout/start_chat_fragment.xml b/app/src/main/res/layout/start_chat_fragment.xml index dcd12a34a..67c12df77 100644 --- a/app/src/main/res/layout/start_chat_fragment.xml +++ b/app/src/main/res/layout/start_chat_fragment.xml @@ -22,6 +22,13 @@ android:layout_height="match_parent" android:background="@color/white"> + + @@ -69,25 +77,70 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/title" /> + + + + + + + app:layout_constraintTop_toBottomOf="@id/group_name" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 547cb346d..386b980e2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -46,6 +46,7 @@ or next Start + Required %s selected @@ -342,6 +343,7 @@ Search contact Create a group conversation No contact for the moment… + Name of the group Say something… %s is composing…