@@ -60,6 +60,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedA
6060import com.nextcloud.talk.callbacks.MentionAutocompleteCallback
6161import com.nextcloud.talk.chat.data.model.ChatMessage
6262import com.nextcloud.talk.chat.viewmodels.ChatViewModel
63+ import com.nextcloud.talk.chat.viewmodels.MessageInputViewModel
6364import com.nextcloud.talk.data.network.NetworkMonitor
6465import com.nextcloud.talk.databinding.FragmentMessageInputBinding
6566import com.nextcloud.talk.jobs.UploadAndShareFilesWorker
@@ -74,6 +75,7 @@ import com.nextcloud.talk.users.UserManager
7475import com.nextcloud.talk.utils.ApiUtils
7576import com.nextcloud.talk.utils.CapabilitiesUtil
7677import com.nextcloud.talk.utils.CharPolicy
78+ import com.nextcloud.talk.utils.EmojiTextInputEditText
7779import com.nextcloud.talk.utils.ImageEmojiEditText
7880import com.nextcloud.talk.utils.SpreedFeatures
7981import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
@@ -172,6 +174,14 @@ class MessageInputFragment : Fragment() {
172174 override fun onViewCreated (view : View , savedInstanceState : Bundle ? ) {
173175 super .onViewCreated(view, savedInstanceState)
174176 initObservers()
177+
178+ binding.fragmentCreateThreadView.createThreadView.findViewById<EmojiTextInputEditText >(
179+ R .id
180+ .createThread
181+ ).doAfterTextChanged { text ->
182+ val threadTitle = text.toString()
183+ chatActivity.chatViewModel.messageDraft.threadTitle = threadTitle
184+ }
175185 }
176186
177187 private fun initObservers () {
@@ -194,6 +204,24 @@ class MessageInputFragment : Fragment() {
194204 message?.let { setEditUI(it as ChatMessage ) }
195205 }
196206
207+ chatActivity.messageInputViewModel.createThreadViewState.observe(viewLifecycleOwner) { state ->
208+ when (state) {
209+ is MessageInputViewModel .CreateThreadStartState ->
210+ binding.fragmentCreateThreadView.createThreadView.visibility = View .GONE
211+
212+ is MessageInputViewModel .CreateThreadEditState -> {
213+ binding.fragmentCreateThreadView.createThreadView.visibility = View .VISIBLE
214+ binding.fragmentCreateThreadView.createThreadView
215+ .findViewById<EmojiTextInputEditText >(R .id.createThread)?.setText(
216+ chatActivity.chatViewModel.messageDraft.threadTitle
217+ )
218+ }
219+
220+ else -> {}
221+ }
222+ initVoiceRecordButton()
223+ }
224+
197225 chatActivity.chatViewModel.leaveRoomViewState.observe(viewLifecycleOwner) { state ->
198226 when (state) {
199227 is ChatViewModel .LeaveRoomSuccessState -> sendStopTypingMessage()
@@ -310,6 +338,11 @@ class MessageInputFragment : Fragment() {
310338 val draft = chatActivity.chatViewModel.messageDraft
311339 binding.fragmentMessageInputView.messageInput.setText(draft.messageText)
312340 binding.fragmentMessageInputView.messageInput.setSelection(draft.messageCursor)
341+
342+ if (draft.threadTitle?.isNotEmpty() == true ) {
343+ chatActivity.messageInputViewModel.startThreadCreation()
344+ }
345+
313346 if (draft.messageText != " " ) {
314347 binding.fragmentMessageInputView.messageInput.requestFocus()
315348 }
@@ -444,6 +477,9 @@ class MessageInputFragment : Fragment() {
444477 binding.fragmentEditView.clearEdit.setOnClickListener {
445478 clearEditUI()
446479 }
480+ binding.fragmentCreateThreadView.abortCreateThread.setOnClickListener {
481+ cancelCreateThread()
482+ }
447483
448484 if (CapabilitiesUtil .hasSpreedFeatureCapability(chatActivity.spreedCapabilities, SpreedFeatures .SILENT_SEND )) {
449485 binding.fragmentMessageInputView.button?.setOnLongClickListener {
@@ -489,31 +525,10 @@ class MessageInputFragment : Fragment() {
489525
490526 @Suppress(" ClickableViewAccessibility" , " CyclomaticComplexMethod" , " LongMethod" )
491527 private fun initVoiceRecordButton () {
492- if (binding.fragmentMessageInputView.messageInput.text.isNullOrBlank()) {
493- binding.fragmentMessageInputView.messageSendButton.visibility = View .GONE
494- binding.fragmentMessageInputView.recordAudioButton.visibility = View .VISIBLE
495- } else {
496- binding.fragmentMessageInputView.messageSendButton.visibility = View .VISIBLE
497- binding.fragmentMessageInputView.recordAudioButton.visibility = View .GONE
498- }
499- binding.fragmentMessageInputView.inputEditText.doAfterTextChanged {
500- binding.fragmentMessageInputView.recordAudioButton.visibility =
501- if (binding.fragmentMessageInputView.inputEditText.text.isEmpty() &&
502- chatActivity.messageInputViewModel.getEditChatMessage.value == null
503- ) {
504- View .VISIBLE
505- } else {
506- View .GONE
507- }
528+ handleButtonsVisibility()
508529
509- binding.fragmentMessageInputView.messageSendButton.visibility =
510- if (binding.fragmentMessageInputView.inputEditText.text.isEmpty() ||
511- binding.fragmentEditView.editMessageView.isVisible
512- ) {
513- View .GONE
514- } else {
515- View .VISIBLE
516- }
530+ binding.fragmentMessageInputView.inputEditText.doAfterTextChanged {
531+ handleButtonsVisibility()
517532 }
518533
519534 var prevDx = 0f
@@ -628,6 +643,33 @@ class MessageInputFragment : Fragment() {
628643 }
629644 }
630645
646+ private fun handleButtonsVisibility () {
647+ fun View.setVisible (isVisible : Boolean ) {
648+ visibility = if (isVisible) View .VISIBLE else View .GONE
649+ }
650+
651+ val isEditModeActive = binding.fragmentEditView.editMessageView.isVisible
652+ val isThreadCreateModeActive = binding.fragmentCreateThreadView.createThreadView.isVisible
653+ val inputContainsText = binding.fragmentMessageInputView.messageInput.text.isNotEmpty()
654+
655+ binding.fragmentMessageInputView.apply {
656+ when {
657+ isEditModeActive -> {
658+ messageSendButton.setVisible(false )
659+ recordAudioButton.setVisible(false )
660+ }
661+ inputContainsText || isThreadCreateModeActive -> {
662+ messageSendButton.setVisible(true )
663+ recordAudioButton.setVisible(false )
664+ }
665+ else -> {
666+ messageSendButton.setVisible(false )
667+ recordAudioButton.setVisible(true )
668+ }
669+ }
670+ }
671+ }
672+
631673 private fun resetSlider () {
632674 binding.fragmentMessageInputView.audioRecordDuration.stop()
633675 binding.fragmentMessageInputView.audioRecordDuration.clearAnimation()
@@ -837,27 +879,28 @@ class MessageInputFragment : Fragment() {
837879 replaceMentionChipSpans(editable)
838880 binding.fragmentMessageInputView.inputEditText?.setText(" " )
839881 sendStopTypingMessage()
840-
841882 sendMessage(
842883 editable.toString(),
843884 sendWithoutNotification
844885 )
845886 cancelReply()
887+ cancelCreateThread()
846888 }
847889 }
848890
849891 private fun sendMessage (message : String , sendWithoutNotification : Boolean ) {
850892 chatActivity.messageInputViewModel.sendChatMessage(
851- chatActivity.conversationUser!! .getCredentials(),
852- ApiUtils .getUrlForChat(
893+ credentials = chatActivity.conversationUser!! .getCredentials(),
894+ url = ApiUtils .getUrlForChat(
853895 chatActivity.chatApiVersion,
854896 chatActivity.conversationUser!! .baseUrl!! ,
855897 chatActivity.roomToken
856898 ),
857- message,
858- chatActivity.conversationUser!! .displayName ? : " " ,
859- chatActivity.getReplyToMessageId(),
860- sendWithoutNotification
899+ message = message,
900+ displayName = chatActivity.conversationUser!! .displayName ? : " " ,
901+ replyTo = chatActivity.getReplyToMessageId(),
902+ sendWithoutNotification = sendWithoutNotification,
903+ threadTitle = chatActivity.chatViewModel.messageDraft.threadTitle
861904 )
862905 }
863906
@@ -952,6 +995,7 @@ class MessageInputFragment : Fragment() {
952995 binding.fragmentEditView.editMessageView.visibility = View .GONE
953996 binding.fragmentMessageInputView.attachmentButton.visibility = View .VISIBLE
954997 chatActivity.messageInputViewModel.edit(null )
998+ handleButtonsVisibility()
955999 }
9561000
9571001 private fun themeMessageInputView () {
@@ -994,6 +1038,9 @@ class MessageInputFragment : Fragment() {
9941038 binding.fragmentEditView.clearEdit.let {
9951039 viewThemeUtils.platform.colorImageView(it, ColorRole .PRIMARY )
9961040 }
1041+ binding.fragmentCreateThreadView.abortCreateThread.let {
1042+ viewThemeUtils.platform.colorImageView(it, ColorRole .PRIMARY )
1043+ }
9971044
9981045 binding.fragmentCallStarted.callStartedBackground.apply {
9991046 viewThemeUtils.talk.themeOutgoingMessageBubble(this , grouped = true , false )
@@ -1012,6 +1059,12 @@ class MessageInputFragment : Fragment() {
10121059 }
10131060 }
10141061
1062+ private fun cancelCreateThread () {
1063+ chatActivity.cancelCreateThread()
1064+ chatActivity.messageInputViewModel.stopThreadCreation()
1065+ binding.fragmentCreateThreadView.createThreadView.visibility = View .GONE
1066+ }
1067+
10151068 private fun cancelReply () {
10161069 chatActivity.cancelReply()
10171070 clearReplyUi()
0 commit comments