Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import com.wire.kalium.logic.feature.conversation.LeaveConversationUseCase
import com.wire.kalium.logic.feature.conversation.ObserveEligibleMembersForConversationAdminRoleUseCase
import com.wire.kalium.logic.feature.conversation.PromoteAdminAndLeaveConversationUseCase
import com.wire.kalium.logic.feature.conversation.NotifyConversationIsOpenUseCase
import com.wire.kalium.logic.feature.conversation.ObserveSelfUserHasViewerAccessOnConversationUseCase
import com.wire.kalium.logic.feature.conversation.ObserveArchivedUnreadConversationsCountUseCase
import com.wire.kalium.logic.feature.conversation.ObserveConversationDetailsUseCase
import com.wire.kalium.logic.feature.conversation.ObserveConversationInteractionAvailabilityUseCase
Expand Down Expand Up @@ -419,4 +420,11 @@ class ConversationModule {
conversationScope: ConversationScope
): ChangeAccessForAppsInConversationUseCase =
conversationScope.changeAccessForAppsInConversation

@ViewModelScoped
@Provides
fun provideObserveSelfUserHasViewerAccessUseCase(
conversationScope: ConversationScope
): ObserveSelfUserHasViewerAccessOnConversationUseCase =
conversationScope.observeSelfUserHasViewerAccess
}
33 changes: 28 additions & 5 deletions app/src/main/kotlin/com/wire/android/ui/common/AttachmentButton.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,42 @@ import com.wire.android.ui.theme.wireDimensions
import com.wire.android.ui.theme.wireTypography

@Composable
fun AttachmentButton(@DrawableRes icon: Int, labelStyle: TextStyle, modifier: Modifier = Modifier, text: String = "", onClick: () -> Unit) {
fun AttachmentButton(
@DrawableRes icon: Int,
labelStyle: TextStyle,
modifier: Modifier = Modifier,
text: String = "",
enabled: Boolean = true,
onClick: () -> Unit,
) {
val buttonBackgroundColor = if (enabled) {
MaterialTheme.wireColorScheme.primaryButtonEnabled
} else {
MaterialTheme.wireColorScheme.primaryButtonDisabled
}
val buttonContentColor = if (enabled) {
MaterialTheme.wireColorScheme.onPrimaryButtonEnabled
} else {
MaterialTheme.wireColorScheme.onPrimaryButtonDisabled
}
val labelColor = if (enabled) {
MaterialTheme.wireColorScheme.onBackground
} else {
MaterialTheme.wireColorScheme.secondaryText
}

Column(
modifier = modifier
.padding(dimensions().spacing4x)
.clip(RoundedCornerShape(size = MaterialTheme.wireDimensions.buttonSmallCornerSize))
.clickable { onClick() }
.clickable(enabled = enabled) { onClick() }
.padding(dimensions().spacing8x),
horizontalAlignment = Alignment.CenterHorizontally
) {
Box(
modifier = Modifier
.size(dimensions().attachmentButtonSize)
.background(MaterialTheme.wireColorScheme.primaryButtonEnabled, CircleShape)
.background(buttonBackgroundColor, CircleShape)
.padding(dimensions().spacing2x)
) {
Image(
Expand All @@ -70,7 +93,7 @@ fun AttachmentButton(@DrawableRes icon: Int, labelStyle: TextStyle, modifier: Mo
modifier = Modifier
.padding(dimensions().spacing8x)
.align(Alignment.Center),
colorFilter = ColorFilter.tint(MaterialTheme.wireColorScheme.onPrimaryButtonEnabled)
colorFilter = ColorFilter.tint(buttonContentColor)
)
}
VerticalSpace.x4()
Expand All @@ -80,7 +103,7 @@ fun AttachmentButton(@DrawableRes icon: Int, labelStyle: TextStyle, modifier: Mo
maxLines = 2,
textAlign = TextAlign.Center,
style = labelStyle,
color = MaterialTheme.wireColorScheme.onBackground,
color = labelColor,
)
Spacer(modifier = Modifier.weight(1F))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ import com.wire.kalium.logic.feature.conversation.ObserveConversationDetailsUseC
import com.wire.kalium.logic.feature.conversation.ObserveConversationInteractionAvailabilityUseCase
import com.wire.kalium.logic.feature.conversation.ObserveConversationUnderLegalHoldNotifiedUseCase
import com.wire.kalium.logic.feature.conversation.ObserveDegradedConversationNotifiedUseCase
import com.wire.kalium.logic.feature.conversation.ObserveSelfUserHasViewerAccessOnConversationUseCase
import com.wire.kalium.logic.feature.conversation.SendTypingEventUseCase
import com.wire.kalium.logic.feature.conversation.SetNotifiedAboutConversationUnderLegalHoldUseCase
import com.wire.kalium.logic.feature.conversation.SetUserInformedAboutVerificationUseCase
Expand Down Expand Up @@ -192,6 +193,7 @@ class ConversationCoreViewModelFactory @Inject constructor(
private val onlineEditor: OnlineEditor,
private val featureFlags: KaliumConfigs,
private val getWireCellsConfig: GetWireCellConfigurationUseCase,
private val observeSelfUserHasViewerAccess: ObserveSelfUserHasViewerAccessOnConversationUseCase,
private val networkStateObserver: NetworkStateObserver,
@CurrentAccount private val selfUserId: UserId,
) {
Expand Down Expand Up @@ -234,6 +236,7 @@ class ConversationCoreViewModelFactory @Inject constructor(
currentSessionFlowUseCase = currentSessionFlowUseCase,
observeEstablishedCalls = observeEstablishedCalls,
globalDataStore = globalDataStore,
observeSelfUserHasViewerAccess = observeSelfUserHasViewerAccess
)

fun sendMessageViewModel(savedStateHandle: SavedStateHandle) = SendMessageViewModel(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import com.wire.kalium.logic.data.id.MessageId

data class MessageComposerViewState(
val isFileSharingEnabled: Boolean = true,
val areAttachmentOptionsEnabled: Boolean = true,
val interactionAvailability: InteractionAvailability = InteractionAvailability.ENABLED,
val mentionSearchResult: List<Contact> = listOf(),
val mentionSearchQuery: String = String.EMPTY,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ import androidx.compose.runtime.setValue
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.ramcosta.composedestinations.generated.app.navArgs
import com.wire.android.datastore.GlobalDataStore
import com.wire.android.mapper.ContactMapper
import com.wire.android.ui.home.conversations.ConversationNavArgs
import com.wire.android.ui.home.conversations.InvalidLinkDialogState
import com.wire.android.ui.home.conversations.MessageComposerViewState
import com.wire.android.ui.home.conversations.VisitLinkDialogState
import com.wire.android.ui.home.conversations.model.UIMessage
import com.ramcosta.composedestinations.generated.app.navArgs
import com.wire.android.util.EMPTY
import com.wire.android.util.FileManager
import com.wire.android.util.dispatchers.DispatcherProvider
Expand All @@ -45,9 +45,10 @@ import com.wire.kalium.logic.data.message.SelfDeletionTimer
import com.wire.kalium.logic.data.user.OtherUser
import com.wire.kalium.logic.feature.call.usecase.ObserveEstablishedCallsUseCase
import com.wire.kalium.logic.feature.conversation.IsInteractionAvailableResult
import com.wire.kalium.logic.feature.conversation.MarkConversationAsReadLocallyUseCase
import com.wire.kalium.logic.feature.conversation.MembersToMentionUseCase
import com.wire.kalium.logic.feature.conversation.ObserveSelfUserHasViewerAccessOnConversationUseCase
import com.wire.kalium.logic.feature.conversation.ObserveConversationInteractionAvailabilityUseCase
import com.wire.kalium.logic.feature.conversation.MarkConversationAsReadLocallyUseCase
import com.wire.kalium.logic.feature.conversation.SendTypingEventUseCase
import com.wire.kalium.logic.feature.conversation.UpdateConversationReadDateUseCase
import com.wire.kalium.logic.feature.message.ephemeral.EnqueueMessageSelfDeletionUseCase
Expand Down Expand Up @@ -84,6 +85,7 @@ class MessageComposerViewModel(
private val currentSessionFlowUseCase: CurrentSessionFlowUseCase,
private val observeEstablishedCalls: ObserveEstablishedCallsUseCase,
private val globalDataStore: GlobalDataStore,
private val observeSelfUserHasViewerAccess: ObserveSelfUserHasViewerAccessOnConversationUseCase,
) : ViewModel() {

var messageComposerViewState = mutableStateOf(MessageComposerViewState())
Expand Down Expand Up @@ -113,6 +115,7 @@ class MessageComposerViewModel(
initTempWritableImageUri()
observeIsTypingAvailable()
setFileSharingStatus()
observeAttachmentOptionsAvailability()
getEnterToSendState()
observeCallState()
}
Expand Down Expand Up @@ -196,6 +199,18 @@ class MessageComposerViewModel(
}
}

private fun observeAttachmentOptionsAvailability() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not aware of this "Viewers profile" feature but it seems like this does not allow uploading to user from other team. This is a clear business logic and must be placed into kalium use case.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we disable attachment options, should we also disable sharing files into this conversation from other apps?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it will be next, we will restrict download, copy, move, screenshoots... step by step

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it will be better to to add a real restriction on the logic level to make sure we do not depend on the enabled/disabled button states.
Enable/disable buttons will only visualize the restriction.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This real restriction backend must enforce it

viewModelScope.launch {
observeSelfUserHasViewerAccess(conversationId)
.collectLatest { areAttachmentOptionsEnabled ->
messageComposerViewState.value = messageComposerViewState.value.copy(
areAttachmentOptionsEnabled = areAttachmentOptionsEnabled
)
}
}
}


fun updateConversationReadDate(utcISO: String) {
val instant = Instant.parse(utcISO)
lastReadInstant = instant
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ fun AdditionalOptionsMenu(
isEditing: Boolean,
isMentionActive: Boolean,
isFileSharingEnabled: Boolean,
areAttachmentOptionsEnabled: Boolean,
onAdditionalOptionsMenuClicked: () -> Unit,
onMentionButtonClicked: (() -> Unit),
onPingOptionClicked: () -> Unit,
Expand Down Expand Up @@ -75,7 +76,8 @@ fun AdditionalOptionsMenu(
onRichEditingButtonClicked = onRichEditingButtonClicked,
onPingClicked = onPingOptionClicked,
onDrawingModeClicked = onDrawingModeClicked,
isFileSharingEnabled = isFileSharingEnabled
isFileSharingEnabled = isFileSharingEnabled,
areAttachmentOptionsEnabled = areAttachmentOptionsEnabled,
)
}

Expand All @@ -94,6 +96,7 @@ fun AdditionalOptionsMenu(
@Composable
fun AdditionalOptionSubMenu(
isFileSharingEnabled: Boolean,
areAttachmentOptionsEnabled: Boolean,
optionsVisible: Boolean,
onPermissionPermanentlyDenied: (type: ConversationActionPermissionType) -> Unit,
onLocationPickerClicked: () -> Unit,
Expand All @@ -115,6 +118,7 @@ fun AdditionalOptionSubMenu(
tempWritableImageUri = tempWritableImageUri,
tempWritableVideoUri = tempWritableVideoUri,
isFileSharingEnabled = isFileSharingEnabled,
areAttachmentOptionsEnabled = areAttachmentOptionsEnabled,
onRecordAudioMessageClicked = onRecordAudioMessageClicked,
onLocationPickerClicked = onLocationPickerClicked,
onPermissionPermanentlyDenied = onPermissionPermanentlyDenied,
Expand All @@ -139,6 +143,7 @@ fun AttachmentAndAdditionalOptionsMenuItems(
attachmentsVisible: Boolean,
isMentionActive: Boolean,
isFileSharingEnabled: Boolean,
areAttachmentOptionsEnabled: Boolean,
onMentionButtonClicked: () -> Unit,
onSelfDeletionOptionButtonClicked: (SelfDeletionTimer) -> Unit,
modifier: Modifier = Modifier,
Expand All @@ -163,7 +168,8 @@ fun AttachmentAndAdditionalOptionsMenuItems(
onGifButtonClicked = onGifButtonClicked,
onRichEditingButtonClicked = onRichEditingButtonClicked,
onDrawingModeClicked = onDrawingModeClicked,
isFileSharingEnabled = isFileSharingEnabled
isFileSharingEnabled = isFileSharingEnabled,
areAttachmentOptionsEnabled = areAttachmentOptionsEnabled,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ fun AttachmentOptionsComponent(
tempWritableImageUri: Uri?,
tempWritableVideoUri: Uri?,
isFileSharingEnabled: Boolean,
areAttachmentOptionsEnabled: Boolean,
onLocationPickerClicked: () -> Unit,
onPermissionPermanentlyDenied: (type: ConversationActionPermissionType) -> Unit,
modifier: Modifier = Modifier,
Expand All @@ -80,6 +81,7 @@ fun AttachmentOptionsComponent(

val attachmentOptions = buildAttachmentOptionItems(
isFileSharingEnabled = isFileSharingEnabled,
areAttachmentOptionsEnabled = areAttachmentOptionsEnabled,
tempWritableImageUri = tempWritableImageUri,
tempWritableVideoUri = tempWritableVideoUri,
onImagesPicked = onImagesPicked,
Expand Down Expand Up @@ -163,7 +165,8 @@ fun AttachmentOptionsComponent(
icon = option.icon,
labelStyle = labelStyle,
modifier = Modifier.scale(animatedScale),
text = stringResource(option.text)
text = stringResource(option.text),
enabled = option.isEnabled,
) { option.onClick() }
}
}
Expand Down Expand Up @@ -278,6 +281,7 @@ private fun rememberCaptureVideoFlow(
@Composable
private fun buildAttachmentOptionItems(
isFileSharingEnabled: Boolean,
areAttachmentOptionsEnabled: Boolean,
tempWritableImageUri: Uri?,
tempWritableVideoUri: Uri?,
onImagesPicked: (List<Uri>) -> Unit,
Expand Down Expand Up @@ -311,39 +315,44 @@ private fun buildAttachmentOptionItems(
with(localFeatureVisibilityFlags) {
add(
AttachmentOptionItem(
isFileSharingEnabled,
R.string.attachment_share_file,
R.drawable.ic_attach_file
shouldShow = isFileSharingEnabled,
isEnabled = areAttachmentOptionsEnabled,
text = R.string.attachment_share_file,
icon = R.drawable.ic_attach_file,
) { fileFlow.launch() }
)
add(
AttachmentOptionItem(
isFileSharingEnabled,
R.string.attachment_share_image,
R.drawable.ic_gallery
shouldShow = isFileSharingEnabled,
isEnabled = areAttachmentOptionsEnabled,
text = R.string.attachment_share_image,
icon = R.drawable.ic_gallery,
) { galleryFlow.launch() }
)
add(
AttachmentOptionItem(
isFileSharingEnabled,
R.string.attachment_take_photo,
R.drawable.ic_camera
shouldShow = isFileSharingEnabled,
isEnabled = areAttachmentOptionsEnabled,
text = R.string.attachment_take_photo,
icon = R.drawable.ic_camera,
) { takePictureFlow?.launch() }
)
add(
AttachmentOptionItem(
isFileSharingEnabled,
R.string.attachment_record_video,
R.drawable.ic_video
shouldShow = isFileSharingEnabled,
isEnabled = areAttachmentOptionsEnabled,
text = R.string.attachment_record_video,
icon = R.drawable.ic_video,
) { captureVideoFlow?.launch() }
)
if (AudioMessagesIcon) {
add(
AttachmentOptionItem(
isFileSharingEnabled,
R.string.attachment_voice_message,
R.drawable.ic_mic_on,
onRecordAudioMessageClicked
shouldShow = isFileSharingEnabled,
isEnabled = areAttachmentOptionsEnabled,
text = R.string.attachment_voice_message,
icon = R.drawable.ic_mic_on,
onClick = onRecordAudioMessageClicked,
)
)
}
Expand All @@ -363,6 +372,7 @@ private fun buildAttachmentOptionItems(

private data class AttachmentOptionItem(
val shouldShow: Boolean = true,
val isEnabled: Boolean = true,
@StringRes val text: Int,
@DrawableRes val icon: Int,
val onClick: () -> Unit
Expand All @@ -377,6 +387,7 @@ fun PreviewAttachmentComponents() {
onImagesPicked = {},
onAttachmentPicked = {},
isFileSharingEnabled = true,
areAttachmentOptionsEnabled = true,
tempWritableImageUri = null,
tempWritableVideoUri = null,
onRecordAudioMessageClicked = {},
Expand All @@ -398,6 +409,7 @@ fun PreviewAttachmentOptionsComponentSmallScreen() {
onAttachmentPicked = {},
onImagesPicked = {},
isFileSharingEnabled = true,
areAttachmentOptionsEnabled = true,
tempWritableImageUri = null,
tempWritableVideoUri = null,
onRecordAudioMessageClicked = {},
Expand All @@ -420,6 +432,7 @@ fun PreviewAttachmentOptionsComponentNormalScreen() {
onAttachmentPicked = {},
onImagesPicked = {},
isFileSharingEnabled = true,
areAttachmentOptionsEnabled = true,
tempWritableImageUri = null,
tempWritableVideoUri = null,
onRecordAudioMessageClicked = {},
Expand All @@ -442,6 +455,7 @@ fun PreviewAttachmentOptionsComponentTabledScreen() {
onAttachmentPicked = {},
onImagesPicked = {},
isFileSharingEnabled = true,
areAttachmentOptionsEnabled = true,
tempWritableImageUri = null,
tempWritableVideoUri = null,
onRecordAudioMessageClicked = {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -388,8 +388,13 @@ fun EnabledMessageComposer(
additionalOptionStateHolder.toRichTextEditing()
},
onCloseRichEditingButtonClicked = additionalOptionStateHolder::toAttachmentAndAdditionalOptionsMenu,
onDrawingModeClicked = openDrawingCanvas,
isFileSharingEnabled = messageComposerViewState.value.isFileSharingEnabled
onDrawingModeClicked = {
if (messageComposerViewState.value.areAttachmentOptionsEnabled) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for an extra condition here since the button will be disabled when areAttachmentOptionsEnabled == false

openDrawingCanvas()
}
},
isFileSharingEnabled = messageComposerViewState.value.isFileSharingEnabled,
areAttachmentOptionsEnabled = messageComposerViewState.value.areAttachmentOptionsEnabled,
)
}
}
Expand Down Expand Up @@ -453,6 +458,7 @@ fun EnabledMessageComposer(
AdditionalOptionSubMenu(
optionsVisible = inputStateHolder.optionsVisible,
isFileSharingEnabled = messageComposerViewState.value.isFileSharingEnabled,
areAttachmentOptionsEnabled = messageComposerViewState.value.areAttachmentOptionsEnabled,
additionalOptionsState = additionalOptionStateHolder.additionalOptionsSubMenuState,
onRecordAudioMessageClicked = {
if (!messageComposerViewState.value.isCallOngoing) {
Expand Down
Loading
Loading