Skip to content

Commit

Permalink
feat: add and remove conversation favorite [WPB-11639] (#3653)
Browse files Browse the repository at this point in the history
  • Loading branch information
Garzas authored Nov 25, 2024
1 parent c911271 commit 955306a
Show file tree
Hide file tree
Showing 27 changed files with 397 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -327,4 +327,14 @@ class ConversationModule {
@Provides
fun provideGetFavoriteFolderUseCase(conversationScope: ConversationScope) =
conversationScope.getFavoriteFolder

@ViewModelScoped
@Provides
fun provideAddConversationToFavoritesUseCase(conversationScope: ConversationScope) =
conversationScope.addConversationToFavorites

@ViewModelScoped
@Provides
fun provideRemoveConversationFromFavoritesUseCase(conversationScope: ConversationScope) =
conversationScope.removeConversationFromFavorites
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ fun ConversationDetailsWithEvents.toConversationItem(
proteusVerificationStatus = conversationDetails.conversation.proteusVerificationStatus,
hasNewActivitiesToShow = hasNewActivitiesToShow,
searchQuery = searchQuery,
isFavorite = conversationDetails.isFavorite
)
}

Expand Down Expand Up @@ -101,6 +102,7 @@ fun ConversationDetailsWithEvents.toConversationItem(
proteusVerificationStatus = conversationDetails.conversation.proteusVerificationStatus,
hasNewActivitiesToShow = hasNewActivitiesToShow,
searchQuery = searchQuery,
isFavorite = conversationDetails.isFavorite
)
}

Expand Down
7 changes: 7 additions & 0 deletions app/src/main/kotlin/com/wire/android/model/SnackBarMessage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,10 @@ interface SnackBarMessage {
val uiText: UIText
val actionLabel: UIText? get() = null
}

data class DefaultSnackBarMessage(
override val uiText: UIText,
override val actionLabel: UIText? = null
) : SnackBarMessage

fun UIText.asSnackBarMessage(actionLabel: UIText? = null): SnackBarMessage = DefaultSnackBarMessage(this, actionLabel)
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import com.wire.kalium.logic.data.user.UserId
fun ConversationSheetContent(
conversationSheetState: ConversationSheetState,
onMutingConversationStatusChange: () -> Unit,
addConversationToFavourites: () -> Unit,
changeFavoriteState: (GroupDialogState, addToFavorite: Boolean) -> Unit,
moveConversationToFolder: () -> Unit,
updateConversationArchiveStatus: (DialogState) -> Unit,
clearConversationContent: (DialogState) -> Unit,
Expand All @@ -54,9 +54,8 @@ fun ConversationSheetContent(
ConversationOptionNavigation.Home -> {
ConversationMainSheetContent(
conversationSheetContent = conversationSheetState.conversationSheetContent!!,
changeFavoriteState = changeFavoriteState,
// TODO(profile): enable when implemented
//
// addConversationToFavourites = addConversationToFavourites,
// moveConversationToFolder = moveConversationToFolder,
updateConversationArchiveStatus = updateConversationArchiveStatus,
clearConversationContent = clearConversationContent,
Expand Down Expand Up @@ -125,6 +124,7 @@ data class ConversationSheetContent(
val mlsVerificationStatus: Conversation.VerificationStatus,
val proteusVerificationStatus: Conversation.VerificationStatus,
val isUnderLegalHold: Boolean,
val isFavorite: Boolean?
) {

private val isSelfUserMember: Boolean get() = selfRole != null
Expand All @@ -147,9 +147,9 @@ data class ConversationSheetContent(
fun canUnblockUser(): Boolean =
conversationTypeDetail is ConversationTypeDetail.Private && conversationTypeDetail.blockingState == BlockingState.BLOCKED

fun canAddToFavourite(): Boolean =
(conversationTypeDetail is ConversationTypeDetail.Private && conversationTypeDetail.blockingState != BlockingState.BLOCKED)
|| conversationTypeDetail is ConversationTypeDetail.Group
fun canAddToFavourite(): Boolean = isFavorite != null &&
((conversationTypeDetail is ConversationTypeDetail.Private && conversationTypeDetail.blockingState != BlockingState.BLOCKED)
|| conversationTypeDetail is ConversationTypeDetail.Group)

fun isAbandonedOneOnOneConversation(participantsCount: Int): Boolean = title.isEmpty() && participantsCount == 1
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ fun rememberConversationSheetState(
protocol = Conversation.ProtocolInfo.Proteus,
mlsVerificationStatus = Conversation.VerificationStatus.VERIFIED,
proteusVerificationStatus = Conversation.VerificationStatus.VERIFIED,
isUnderLegalHold = showLegalHoldIndicator
isUnderLegalHold = showLegalHoldIndicator,
isFavorite = isFavorite
)
}
}
Expand All @@ -102,7 +103,8 @@ fun rememberConversationSheetState(
protocol = Conversation.ProtocolInfo.Proteus,
mlsVerificationStatus = Conversation.VerificationStatus.VERIFIED,
proteusVerificationStatus = Conversation.VerificationStatus.VERIFIED,
isUnderLegalHold = showLegalHoldIndicator
isUnderLegalHold = showLegalHoldIndicator,
isFavorite = isFavorite
)
}
}
Expand All @@ -122,7 +124,8 @@ fun rememberConversationSheetState(
protocol = Conversation.ProtocolInfo.Proteus,
mlsVerificationStatus = Conversation.VerificationStatus.VERIFIED,
proteusVerificationStatus = Conversation.VerificationStatus.VERIFIED,
isUnderLegalHold = showLegalHoldIndicator
isUnderLegalHold = showLegalHoldIndicator,
isFavorite = null
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,14 @@ import com.wire.android.ui.theme.wireTypography
import com.wire.kalium.logic.data.conversation.MutedConversationStatus
import com.wire.kalium.logic.data.user.ConnectionState

// items cannot be simplified
@Suppress("CyclomaticComplexMethod")
@Composable
internal fun ConversationMainSheetContent(
conversationSheetContent: ConversationSheetContent,
// TODO(profile): enable when implemented
// addConversationToFavourites: () -> Unit,
// moveConversationToFolder: () -> Unit,
changeFavoriteState: (dialogState: GroupDialogState, addToFavorite: Boolean) -> Unit,
// TODO(profile): enable when implemented
// moveConversationToFolder: () -> Unit,
updateConversationArchiveStatus: (DialogState) -> Unit,
clearConversationContent: (DialogState) -> Unit,
blockUserClick: (BlockUserDialogState) -> Unit,
Expand Down Expand Up @@ -108,21 +110,38 @@ internal fun ConversationMainSheetContent(
)
}
}

if (conversationSheetContent.canAddToFavourite() && !conversationSheetContent.isArchived) {
conversationSheetContent.isFavorite?.let { isFavorite ->
add {
MenuBottomSheetItem(
title = stringResource(
if (isFavorite) {
R.string.label_remove_from_favourites
} else {
R.string.label_add_to_favourites
}
),
leading = {
MenuItemIcon(
id = R.drawable.ic_favourite,
contentDescription = null
)
},
onItemClick = {
changeFavoriteState(
GroupDialogState(
conversationSheetContent.conversationId,
conversationSheetContent.title
),
!isFavorite
)
}
)
}
}
}
// TODO(profile): enable when implemented
//
// if (conversationSheetContent.canAddToFavourite())
// add {
// MenuBottomSheetItem(
// title = stringResource(R.string.label_add_to_favourites),
// icon = {
// MenuItemIcon(
// id = R.drawable.ic_favourite,
// contentDescription = stringResource(R.string.content_description_add_to_favourite),
// )
// },
// onItemClick = addConversationToFavourites
// )
// }
// add {
// MenuBottomSheetItem(
// icon = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Wire
* Copyright (C) 2024 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.wire.android.ui.common.bottomsheet.folder

import com.wire.android.di.ScopedArgs
import kotlinx.serialization.Serializable

@Serializable
object ChangeConversationFavoriteStateArgs : ScopedArgs {
override val key = "ConnectionActionButtonArgsKey"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Wire
* Copyright (C) 2024 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/

package com.wire.android.ui.common.bottomsheet.folder

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.wire.android.R
import com.wire.android.di.ViewModelScopedPreview
import com.wire.android.model.SnackBarMessage
import com.wire.android.model.asSnackBarMessage
import com.wire.android.ui.home.conversationslist.model.GroupDialogState
import com.wire.android.util.ui.UIText
import com.wire.kalium.logic.feature.conversation.folder.AddConversationToFavoritesUseCase
import com.wire.kalium.logic.feature.conversation.folder.RemoveConversationFromFavoritesUseCase
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.launch
import javax.inject.Inject

@ViewModelScopedPreview
interface ChangeConversationFavoriteVM {
val infoMessage: SharedFlow<SnackBarMessage>
get() = MutableSharedFlow()

fun changeFavoriteState(dialogState: GroupDialogState, addToFavorite: Boolean) {}
}

@HiltViewModel
class ChangeConversationFavoriteVMImpl @Inject constructor(
private val addConversationToFavorites: AddConversationToFavoritesUseCase,
private val removeConversationFromFavorites: RemoveConversationFromFavoritesUseCase,
) : ChangeConversationFavoriteVM, ViewModel() {

private val _infoMessage = MutableSharedFlow<SnackBarMessage>()
override val infoMessage = _infoMessage.asSharedFlow()

override fun changeFavoriteState(dialogState: GroupDialogState, addToFavorite: Boolean) {
viewModelScope.launch {
val messageResource = if (addToFavorite) {
when (addConversationToFavorites(dialogState.conversationId)) {
is AddConversationToFavoritesUseCase.Result.Failure -> R.string.error_adding_to_favorite
AddConversationToFavoritesUseCase.Result.Success -> R.string.success_adding_to_favorite
}
} else {
when (removeConversationFromFavorites(dialogState.conversationId)) {
is RemoveConversationFromFavoritesUseCase.Result.Failure -> R.string.error_removing_from_favorite
RemoveConversationFromFavoritesUseCase.Result.Success -> R.string.success_removing_from_favorite
}
}
_infoMessage.emit(UIText.StringResource(messageResource, dialogState.conversationName).asSnackBarMessage())
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import com.ramcosta.composedestinations.result.ResultBackNavigator
import com.ramcosta.composedestinations.result.ResultRecipient
import com.wire.android.R
import com.wire.android.appLogger
import com.wire.android.di.hiltViewModelScoped
import com.wire.android.navigation.NavigationCommand
import com.wire.android.navigation.Navigator
import com.wire.android.navigation.WireDestination
Expand All @@ -78,6 +79,9 @@ import com.wire.android.ui.common.bottomsheet.WireModalSheetLayout
import com.wire.android.ui.common.bottomsheet.conversation.ConversationSheetContent
import com.wire.android.ui.common.bottomsheet.conversation.ConversationTypeDetail
import com.wire.android.ui.common.bottomsheet.conversation.rememberConversationSheetState
import com.wire.android.ui.common.bottomsheet.folder.ChangeConversationFavoriteStateArgs
import com.wire.android.ui.common.bottomsheet.folder.ChangeConversationFavoriteVM
import com.wire.android.ui.common.bottomsheet.folder.ChangeConversationFavoriteVMImpl
import com.wire.android.ui.common.bottomsheet.rememberWireModalSheetState
import com.wire.android.ui.common.bottomsheet.show
import com.wire.android.ui.common.button.WirePrimaryButton
Expand Down Expand Up @@ -285,7 +289,11 @@ private fun GroupConversationDetailsContent(
isLoading: Boolean,
isAbandonedOneOnOneConversation: Boolean,
onSearchConversationMessagesClick: () -> Unit,
onConversationMediaClick: () -> Unit
onConversationMediaClick: () -> Unit,
changeConversationFavoriteStateViewModel: ChangeConversationFavoriteVM =
hiltViewModelScoped<ChangeConversationFavoriteVMImpl, ChangeConversationFavoriteVM, ChangeConversationFavoriteStateArgs>(
ChangeConversationFavoriteStateArgs
),
) {
val scope = rememberCoroutineScope()
val resources = LocalContext.current.resources
Expand Down Expand Up @@ -461,7 +469,7 @@ private fun GroupConversationDetailsContent(
)
}
},
addConversationToFavourites = bottomSheetEventsHandler::onAddConversationToFavourites,
changeFavoriteState = changeConversationFavoriteStateViewModel::changeFavoriteState,
moveConversationToFolder = bottomSheetEventsHandler::onMoveConversationToFolder,
updateConversationArchiveStatus = {
// Only show the confirmation dialog if the conversation is not archived
Expand Down Expand Up @@ -597,7 +605,8 @@ fun PreviewGroupConversationDetails() {
),
mlsVerificationStatus = Conversation.VerificationStatus.VERIFIED,
isUnderLegalHold = false,
proteusVerificationStatus = Conversation.VerificationStatus.VERIFIED
proteusVerificationStatus = Conversation.VerificationStatus.VERIFIED,
isFavorite = false
),
bottomSheetEventsHandler = GroupConversationDetailsBottomSheetEventsHandler.PREVIEW,
onBackPressed = {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ class GroupConversationDetailsViewModel @Inject constructor(
mlsVerificationStatus = groupDetails.conversation.mlsVerificationStatus,
proteusVerificationStatus = groupDetails.conversation.proteusVerificationStatus,
isUnderLegalHold = groupDetails.conversation.legalHoldStatus.showLegalHoldIndicator(),
isFavorite = groupDetails.isFavorite
)

updateState(
Expand Down Expand Up @@ -374,10 +375,6 @@ class GroupConversationDetailsViewModel @Inject constructor(
}
}

@Suppress("EmptyFunctionBlock")
override fun onAddConversationToFavourites(conversationId: ConversationId?) {
}

@Suppress("EmptyFunctionBlock")
override fun onMoveConversationToFolder(conversationId: ConversationId?) {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import com.wire.kalium.util.DateTimeUtil
@Suppress("TooManyFunctions")
interface GroupConversationDetailsBottomSheetEventsHandler {
fun onMutingConversationStatusChange(conversationId: ConversationId?, status: MutedConversationStatus, onMessage: (UIText) -> Unit)
fun onAddConversationToFavourites(conversationId: ConversationId? = null)
fun onMoveConversationToFolder(conversationId: ConversationId? = null)
fun updateConversationArchiveStatus(
dialogState: DialogState,
Expand All @@ -47,7 +46,6 @@ interface GroupConversationDetailsBottomSheetEventsHandler {
) {
}

override fun onAddConversationToFavourites(conversationId: ConversationId?) {}
override fun onMoveConversationToFolder(conversationId: ConversationId?) {}
override fun updateConversationArchiveStatus(
dialogState: DialogState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ interface ConversationListViewModel {
fun leaveGroup(leaveGroupState: GroupDialogState) {}
fun clearConversationContent(dialogState: DialogState) {}
fun muteConversation(conversationId: ConversationId?, mutedConversationStatus: MutedConversationStatus) {}
fun addConversationToFavourites() {}
fun moveConversationToFolder() {}
fun searchQueryChanged(searchQuery: String) {}
}
Expand Down Expand Up @@ -367,11 +366,6 @@ class ConversationListViewModelImpl @AssistedInject constructor(
}
}

// TODO: needs to be implemented
@Suppress("EmptyFunctionBlock")
override fun addConversationToFavourites() {
}

// TODO: needs to be implemented
@Suppress("EmptyFunctionBlock")
override fun moveConversationToFolder() {
Expand Down
Loading

0 comments on commit 955306a

Please sign in to comment.