diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/AdjustableMessageHolderInterface.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/AdjustableMessageHolderInterface.kt new file mode 100644 index 000000000..12bbd1e06 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/AdjustableMessageHolderInterface.kt @@ -0,0 +1,51 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2024 Christian Reiner + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.adapters.messages + +import android.widget.RelativeLayout +import androidx.viewbinding.ViewBinding +import com.nextcloud.talk.databinding.ItemCustomOutcomingDeckCardMessageBinding +import com.nextcloud.talk.databinding.ItemCustomOutcomingLinkPreviewMessageBinding +import com.nextcloud.talk.databinding.ItemCustomOutcomingLocationMessageBinding +import com.nextcloud.talk.databinding.ItemCustomOutcomingPollMessageBinding +import com.nextcloud.talk.databinding.ItemCustomOutcomingTextMessageBinding +import com.nextcloud.talk.databinding.ItemCustomOutcomingVoiceMessageBinding +import com.nextcloud.talk.models.domain.ConversationModel +import com.nextcloud.talk.models.json.conversations.ConversationEnums.ConversationType + +interface AdjustableMessageHolderInterface { + + val binding: ViewBinding + + fun adjustIfNoteToSelf(viewHolder: AdjustableMessageHolderInterface, currentConversation: ConversationModel?) { + if (currentConversation?.type == ConversationType.NOTE_TO_SELF) { + when (viewHolder.binding.javaClass) { + ItemCustomOutcomingTextMessageBinding::class.java -> + (viewHolder.binding as ItemCustomOutcomingTextMessageBinding).bubble + ItemCustomOutcomingDeckCardMessageBinding::class.java -> + (viewHolder.binding as ItemCustomOutcomingDeckCardMessageBinding).bubble + ItemCustomOutcomingLinkPreviewMessageBinding::class.java -> + (viewHolder.binding as ItemCustomOutcomingLinkPreviewMessageBinding).bubble + ItemCustomOutcomingPollMessageBinding::class.java -> + (viewHolder.binding as ItemCustomOutcomingPollMessageBinding).bubble + ItemCustomOutcomingVoiceMessageBinding::class.java -> + (viewHolder.binding as ItemCustomOutcomingVoiceMessageBinding).bubble + ItemCustomOutcomingLocationMessageBinding::class.java -> + (viewHolder.binding as ItemCustomOutcomingLocationMessageBinding).bubble + else -> null + }?.let { + RelativeLayout.LayoutParams(binding.root.layoutParams).apply { + marginStart = 0 + marginEnd = 0 + }.run { + it.layoutParams = this + } + } + } + } +} diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingDeckCardViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingDeckCardViewHolder.kt index 49e649e26..7c053f170 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingDeckCardViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingDeckCardViewHolder.kt @@ -1,6 +1,7 @@ /* * Nextcloud Talk - Android Client * + * SPDX-FileCopyrightText: 2024 Christian Reiner * SPDX-FileCopyrightText: 2024 Sowjanya Kota * SPDX-License-Identifier: GPL-3.0-or-later */ @@ -43,9 +44,10 @@ import javax.inject.Inject @AutoInjector(NextcloudTalkApplication::class) class OutcomingDeckCardViewHolder( outcomingView: View -) : MessageHolders.OutcomingTextMessageViewHolder(outcomingView) { +) : MessageHolders.OutcomingTextMessageViewHolder(outcomingView), + AdjustableMessageHolderInterface { - private val binding: ItemCustomOutcomingDeckCardMessageBinding = ItemCustomOutcomingDeckCardMessageBinding.bind( + override val binding: ItemCustomOutcomingDeckCardMessageBinding = ItemCustomOutcomingDeckCardMessageBinding.bind( itemView ) diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLinkPreviewMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLinkPreviewMessageViewHolder.kt index e557a98cb..c22f16dbb 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLinkPreviewMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLinkPreviewMessageViewHolder.kt @@ -1,6 +1,7 @@ /* * Nextcloud Talk - Android Client * + * SPDX-FileCopyrightText: 2024 Christian Reiner * SPDX-FileCopyrightText: 2022 Marcel Hibbe * SPDX-FileCopyrightText: 2017-2019 Mario Danic * SPDX-License-Identifier: GPL-3.0-or-later @@ -38,9 +39,10 @@ import javax.inject.Inject @AutoInjector(NextcloudTalkApplication::class) class OutcomingLinkPreviewMessageViewHolder(outcomingView: View, payload: Any) : - MessageHolders.OutcomingTextMessageViewHolder(outcomingView, payload) { + MessageHolders.OutcomingTextMessageViewHolder(outcomingView, payload), + AdjustableMessageHolderInterface { - private val binding: ItemCustomOutcomingLinkPreviewMessageBinding = + override val binding: ItemCustomOutcomingLinkPreviewMessageBinding = ItemCustomOutcomingLinkPreviewMessageBinding.bind(itemView) @Inject diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLocationMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLocationMessageViewHolder.kt index ada48c130..7ae85a5c6 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLocationMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingLocationMessageViewHolder.kt @@ -1,6 +1,7 @@ /* * Nextcloud Talk - Android Client * + * SPDX-FileCopyrightText: 2024 Christian Reiner * SPDX-FileCopyrightText: 2021 Marcel Hibbe * SPDX-FileCopyrightText: 2017-2018 Mario Danic * SPDX-License-Identifier: GPL-3.0-or-later @@ -47,8 +48,10 @@ import kotlin.math.roundToInt @AutoInjector(NextcloudTalkApplication::class) class OutcomingLocationMessageViewHolder(incomingView: View) : - MessageHolders.OutcomingTextMessageViewHolder(incomingView) { - private val binding: ItemCustomOutcomingLocationMessageBinding = + MessageHolders.OutcomingTextMessageViewHolder(incomingView), + AdjustableMessageHolderInterface { + + override val binding: ItemCustomOutcomingLocationMessageBinding = ItemCustomOutcomingLocationMessageBinding.bind(itemView) private val realView: View = itemView diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingTextMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingTextMessageViewHolder.kt index ba0b4fe1a..68e2c515d 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingTextMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingTextMessageViewHolder.kt @@ -1,6 +1,7 @@ /* * Nextcloud Talk - Android Client * + * SPDX-FileCopyrightText: 2024 Christian Reiner * SPDX-FileCopyrightText: 2021 Andy Scherzinger * SPDX-FileCopyrightText: 2021 Marcel Hibbe * SPDX-FileCopyrightText: 2017-2018 Mario Danic @@ -38,8 +39,11 @@ import kotlinx.coroutines.withContext import javax.inject.Inject @AutoInjector(NextcloudTalkApplication::class) -class OutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessageViewHolder(itemView) { - private val binding: ItemCustomOutcomingTextMessageBinding = ItemCustomOutcomingTextMessageBinding.bind(itemView) +class OutcomingTextMessageViewHolder(itemView: View) : + OutcomingTextMessageViewHolder(itemView), + AdjustableMessageHolderInterface { + + override val binding: ItemCustomOutcomingTextMessageBinding = ItemCustomOutcomingTextMessageBinding.bind(itemView) private val realView: View = itemView @Inject diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingVoiceMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingVoiceMessageViewHolder.kt index 45b9e8ec7..4f3f57a24 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingVoiceMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/OutcomingVoiceMessageViewHolder.kt @@ -1,6 +1,7 @@ /* * Nextcloud Talk - Android Client * + * SPDX-FileCopyrightText: 2024 Christian Reiner * SPDX-FileCopyrightText: 2023 Andy Scherzinger * SPDX-FileCopyrightText: 2023 Julius Linus * SPDX-FileCopyrightText: 2021 Marcel Hibbe @@ -45,9 +46,10 @@ import javax.inject.Inject @AutoInjector(NextcloudTalkApplication::class) class OutcomingVoiceMessageViewHolder(outcomingView: View) : - MessageHolders.OutcomingTextMessageViewHolder(outcomingView) { + MessageHolders.OutcomingTextMessageViewHolder(outcomingView), + AdjustableMessageHolderInterface { - private val binding: ItemCustomOutcomingVoiceMessageBinding = ItemCustomOutcomingVoiceMessageBinding.bind(itemView) + override val binding: ItemCustomOutcomingVoiceMessageBinding = ItemCustomOutcomingVoiceMessageBinding.bind(itemView) @JvmField @Inject diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/TalkMessagesListAdapter.java b/app/src/main/java/com/nextcloud/talk/adapters/messages/TalkMessagesListAdapter.java index 10f669306..d331f1d61 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/TalkMessagesListAdapter.java +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/TalkMessagesListAdapter.java @@ -1,6 +1,7 @@ /* * Nextcloud Talk - Android Client * + * SPDX-FileCopyrightText: 2024 Christian Reiner * SPDX-FileCopyrightText: 2020 Tobias Kaminsky * SPDX-License-Identifier: GPL-3.0-or-later */ @@ -34,43 +35,50 @@ public class TalkMessagesListAdapter extends MessagesListAda @Override public void onBindViewHolder(ViewHolder holder, int position) { + if (holder instanceof IncomingTextMessageViewHolder holderInstance) { + holderInstance.assignCommonMessageInterface(chatActivity); + } else if (holder instanceof OutcomingTextMessageViewHolder holderInstance) { + holderInstance.assignCommonMessageInterface(chatActivity); + holderInstance.adjustIfNoteToSelf(holderInstance, chatActivity.getCurrentConversation()); - if (holder instanceof IncomingTextMessageViewHolder) { - ((IncomingTextMessageViewHolder) holder).assignCommonMessageInterface(chatActivity); - } else if (holder instanceof OutcomingTextMessageViewHolder) { - ((OutcomingTextMessageViewHolder) holder).assignCommonMessageInterface(chatActivity); + } else if (holder instanceof IncomingLocationMessageViewHolder holderInstance) { + holderInstance.assignCommonMessageInterface(chatActivity); + } else if (holder instanceof OutcomingLocationMessageViewHolder holderInstance) { + holderInstance.assignCommonMessageInterface(chatActivity); + holderInstance.adjustIfNoteToSelf(holderInstance, chatActivity.getCurrentConversation()); - } else if (holder instanceof IncomingLocationMessageViewHolder) { - ((IncomingLocationMessageViewHolder) holder).assignCommonMessageInterface(chatActivity); - } else if (holder instanceof OutcomingLocationMessageViewHolder) { - ((OutcomingLocationMessageViewHolder) holder).assignCommonMessageInterface(chatActivity); + } else if (holder instanceof IncomingLinkPreviewMessageViewHolder holderInstance) { + holderInstance.assignCommonMessageInterface(chatActivity); + } else if (holder instanceof OutcomingLinkPreviewMessageViewHolder holderInstance) { + holderInstance.assignCommonMessageInterface(chatActivity); + holderInstance.adjustIfNoteToSelf(holderInstance, chatActivity.getCurrentConversation()); - } else if (holder instanceof IncomingLinkPreviewMessageViewHolder) { - ((IncomingLinkPreviewMessageViewHolder) holder).assignCommonMessageInterface(chatActivity); - } else if (holder instanceof OutcomingLinkPreviewMessageViewHolder) { - ((OutcomingLinkPreviewMessageViewHolder) holder).assignCommonMessageInterface(chatActivity); + } else if (holder instanceof IncomingVoiceMessageViewHolder holderInstance) { + holderInstance.assignVoiceMessageInterface(chatActivity); + holderInstance.assignCommonMessageInterface(chatActivity); + } else if (holder instanceof OutcomingVoiceMessageViewHolder holderInstance) { + holderInstance.assignVoiceMessageInterface(chatActivity); + holderInstance.assignCommonMessageInterface(chatActivity); + holderInstance.adjustIfNoteToSelf(holderInstance, chatActivity.getCurrentConversation()); - } else if (holder instanceof IncomingVoiceMessageViewHolder) { - ((IncomingVoiceMessageViewHolder) holder).assignVoiceMessageInterface(chatActivity); - ((IncomingVoiceMessageViewHolder) holder).assignCommonMessageInterface(chatActivity); - } else if (holder instanceof OutcomingVoiceMessageViewHolder) { - ((OutcomingVoiceMessageViewHolder) holder).assignVoiceMessageInterface(chatActivity); - ((OutcomingVoiceMessageViewHolder) holder).assignCommonMessageInterface(chatActivity); + } else if (holder instanceof PreviewMessageViewHolder holderInstance) { + holderInstance.assignPreviewMessageInterface(chatActivity); + holderInstance.assignCommonMessageInterface(chatActivity); - } else if (holder instanceof PreviewMessageViewHolder) { - ((PreviewMessageViewHolder) holder).assignPreviewMessageInterface(chatActivity); - ((PreviewMessageViewHolder) holder).assignCommonMessageInterface(chatActivity); + } else if (holder instanceof SystemMessageViewHolder holderInstance) { + holderInstance.assignSystemMessageInterface(chatActivity); - } else if (holder instanceof SystemMessageViewHolder) { - ((SystemMessageViewHolder) holder).assignSystemMessageInterface(chatActivity); - } else if (holder instanceof CallStartedViewHolder) { - ((CallStartedViewHolder) holder).assignCallStartedMessageInterface(chatActivity); - } else if (holder instanceof TemporaryMessageViewHolder) { - ((TemporaryMessageViewHolder) holder).assignTemporaryMessageInterface(chatActivity); - }else if (holder instanceof IncomingDeckCardViewHolder){ - ((IncomingDeckCardViewHolder) holder).assignCommonMessageInterface(chatActivity); - } else if(holder instanceof OutcomingDeckCardViewHolder){ - ((OutcomingDeckCardViewHolder) holder).assignCommonMessageInterface(chatActivity); + } else if (holder instanceof CallStartedViewHolder holderInstance) { + holderInstance.assignCallStartedMessageInterface(chatActivity); + + } else if (holder instanceof TemporaryMessageViewHolder holderInstance) { + holderInstance.assignTemporaryMessageInterface(chatActivity); + + } else if (holder instanceof IncomingDeckCardViewHolder holderInstance) { + holderInstance.assignCommonMessageInterface(chatActivity); + } else if (holder instanceof OutcomingDeckCardViewHolder holderInstance) { + holderInstance.assignCommonMessageInterface(chatActivity); + holderInstance.adjustIfNoteToSelf(holderInstance, chatActivity.getCurrentConversation()); } super.onBindViewHolder(holder, position); diff --git a/app/src/main/java/com/nextcloud/talk/call/CallParticipantList.java b/app/src/main/java/com/nextcloud/talk/call/CallParticipantList.java index 4a1c7370b..4b3727aa4 100644 --- a/app/src/main/java/com/nextcloud/talk/call/CallParticipantList.java +++ b/app/src/main/java/com/nextcloud/talk/call/CallParticipantList.java @@ -86,8 +86,8 @@ public class CallParticipantList { callParticipants.remove(callParticipant.getSessionId()); // No need to copy it, as it will be no longer used. callParticipant.setInCall(Participant.InCallFlags.DISCONNECTED); - left.add(callParticipant); } + left.addAll(knownCallParticipantsNotFound); if (!joined.isEmpty() || !updated.isEmpty() || !left.isEmpty()) { callParticipantListNotifier.notifyChanged(joined, updated, left, unchanged); diff --git a/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt b/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt index 39a09bdcb..6b80b3d91 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt @@ -141,12 +141,12 @@ class ChatViewModel @Inject constructor( val getReminderExistState: LiveData get() = _getReminderExistState - object NoteToSelfNotAvaliableState : ViewState - open class NoteToSelfAvaliableState(val roomToken: String) : ViewState + object NoteToSelfNotAvailableState : ViewState + open class NoteToSelfAvailableState(val roomToken: String) : ViewState - private val _getNoteToSelfAvaliability: MutableLiveData = MutableLiveData(NoteToSelfNotAvaliableState) - val getNoteToSelfAvaliability: LiveData - get() = _getNoteToSelfAvaliability + private val _getNoteToSelfAvailability: MutableLiveData = MutableLiveData(NoteToSelfNotAvailableState) + val getNoteToSelfAvailability: LiveData + get() = _getNoteToSelfAvailability object GetRoomStartState : ViewState object GetRoomErrorState : ViewState @@ -732,9 +732,9 @@ class ChatViewModel @Inject constructor( val model = ConversationModel.mapToConversationModel(it, userProvider.currentUser.blockingGet()) ConversationUtils.isNoteToSelfConversation(model) } - _getNoteToSelfAvaliability.value = NoteToSelfAvaliableState(noteToSelf.token!!) + _getNoteToSelfAvailability.value = NoteToSelfAvailableState(noteToSelf.token!!) } catch (e: NoSuchElementException) { - _getNoteToSelfAvaliability.value = NoteToSelfNotAvaliableState + _getNoteToSelfAvailability.value = NoteToSelfNotAvailableState Log.e(TAG, "Note to self not found $e") } } diff --git a/app/src/main/java/com/nextcloud/talk/presenters/MentionAutocompletePresenter.java b/app/src/main/java/com/nextcloud/talk/presenters/MentionAutocompletePresenter.java index 9ec1f67e3..5d5f20699 100644 --- a/app/src/main/java/com/nextcloud/talk/presenters/MentionAutocompletePresenter.java +++ b/app/src/main/java/com/nextcloud/talk/presenters/MentionAutocompletePresenter.java @@ -126,28 +126,33 @@ public class MentionAutocompletePresenter extends RecyclerViewPresenter @Override public void onNext(@NonNull MentionOverall mentionOverall) { - List mentionsList = mentionOverall.getOcs().getData(); + if (mentionOverall.getOcs() != null) { + List mentionsList = mentionOverall.getOcs().getData(); - if (mentionsList.size() == 0) { - adapter.clear(); - } else { - List internalAbstractFlexibleItemList = - new ArrayList<>(mentionsList.size()); - for (Mention mention : mentionsList) { - internalAbstractFlexibleItemList.add( - new MentionAutocompleteItem( - mention, - currentUser, - context, - roomToken, - viewThemeUtils)); + if (mentionsList != null) { + + if (mentionsList.isEmpty()) { + adapter.clear(); + } else { + List internalAbstractFlexibleItemList = + new ArrayList<>(mentionsList.size()); + for (Mention mention : mentionsList) { + internalAbstractFlexibleItemList.add( + new MentionAutocompleteItem( + mention, + currentUser, + context, + roomToken, + viewThemeUtils)); + } + + if (adapter.getItemCount() != 0) { + adapter.clear(); + } + + adapter.updateDataSet(internalAbstractFlexibleItemList); + } } - - if (adapter.getItemCount() != 0) { - adapter.clear(); - } - - adapter.updateDataSet(internalAbstractFlexibleItemList); } } diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/ChooseAccountDialogFragment.java b/app/src/main/java/com/nextcloud/talk/ui/dialog/ChooseAccountDialogFragment.java index 8e5382147..729fa5181 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/ChooseAccountDialogFragment.java +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/ChooseAccountDialogFragment.java @@ -109,7 +109,7 @@ public class ChooseAccountDialogFragment extends DialogFragment { themeViews(); setupCurrentUser(user); - setupListeners(user); + setupListeners(); setupAdapter(); prepareViews(); } @@ -220,7 +220,7 @@ public class ChooseAccountDialogFragment extends DialogFragment { adapter.updateDataSet(userItems, false); } - private void setupListeners(User user) { + private void setupListeners() { // Creating listeners for quick-actions binding.currentAccount.getRoot().setOnClickListener(v -> dismiss()); @@ -240,7 +240,7 @@ public class ChooseAccountDialogFragment extends DialogFragment { binding.setStatus.setOnClickListener(v -> { dismiss(); - if (status != null) { + if (status != null && getActivity() != null) { SetStatusDialogFragment setStatusDialog = SetStatusDialogFragment.newInstance(status); setStatusDialog.show(getActivity().getSupportFragmentManager(), "fragment_set_status"); } else { diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt index 88a84fcf9..0a4445ca2 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt @@ -120,9 +120,9 @@ class MessageActionsDialog( ), false ) - chatActivity.chatViewModel.getNoteToSelfAvaliability.observe(this) { state -> + chatActivity.chatViewModel.getNoteToSelfAvailability.observe(this) { state -> when (state) { - is ChatViewModel.NoteToSelfAvaliableState -> { + is ChatViewModel.NoteToSelfAvailableState -> { initMenuAddToNote( !message.isDeleted && !ConversationUtils.isNoteToSelfConversation(currentConversation), state.roomToken diff --git a/detekt.yml b/detekt.yml index 63e05ff12..449cb490d 100644 --- a/detekt.yml +++ b/detekt.yml @@ -1,7 +1,7 @@ # SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors # SPDX-License-Identifier: GPL-3.0-or-later build: - maxIssues: 178 + maxIssues: 179 weights: # complexity: 2 # LongParameterList: 1