From e74d5671d5cce1531fcbde829b5d7511ba38362e Mon Sep 17 00:00:00 2001 From: Alexandre Ferris Date: Wed, 15 May 2024 12:24:12 -0300 Subject: [PATCH 1/2] feat: add toggle to opt-out analytics (WPB-8922) (#3008) Signed-off-by: alexandreferris --- .../wire/android/datastore/GlobalDataStore.kt | 8 + .../settings/privacy/PrivacySettingsScreen.kt | 12 ++ .../settings/privacy/PrivacySettingsState.kt | 1 + .../privacy/PrivacySettingsViewModel.kt | 15 +- app/src/main/res/values/strings.xml | 2 + .../privacy/PrivacySettingsViewModelTest.kt | 155 ++++++++++++++++++ 6 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 app/src/test/kotlin/com/wire/android/ui/home/settings/privacy/PrivacySettingsViewModelTest.kt diff --git a/app/src/main/kotlin/com/wire/android/datastore/GlobalDataStore.kt b/app/src/main/kotlin/com/wire/android/datastore/GlobalDataStore.kt index b9fa7463f57..56c5c70e651 100644 --- a/app/src/main/kotlin/com/wire/android/datastore/GlobalDataStore.kt +++ b/app/src/main/kotlin/com/wire/android/datastore/GlobalDataStore.kt @@ -60,6 +60,7 @@ class GlobalDataStore @Inject constructor(@ApplicationContext private val contex val APP_THEME_OPTION = stringPreferencesKey("app_theme_option") val RECORD_AUDIO_EFFECTS_CHECKBOX = booleanPreferencesKey("record_audio_effects_checkbox") + val ANONYMOUS_USAGE_DATA_STATUS = booleanPreferencesKey("anonymous_usage_data_status") private val Context.dataStore: DataStore by preferencesDataStore(name = PREFERENCES_NAME) @@ -104,6 +105,13 @@ class GlobalDataStore @Inject constructor(@ApplicationContext private val contex context.dataStore.edit { it[RECORD_AUDIO_EFFECTS_CHECKBOX] = enabled } } + fun isAnonymousUsageDataEnabled(): Flow = + getBooleanPreference(ANONYMOUS_USAGE_DATA_STATUS, true) + + suspend fun setAnonymousUsageDataEnabled(enabled: Boolean) { + context.dataStore.edit { it[ANONYMOUS_USAGE_DATA_STATUS] = enabled } + } + fun isEncryptedProteusStorageEnabled(): Flow = getBooleanPreference( IS_ENCRYPTED_PROTEUS_STORAGE_ENABLED, diff --git a/app/src/main/kotlin/com/wire/android/ui/home/settings/privacy/PrivacySettingsScreen.kt b/app/src/main/kotlin/com/wire/android/ui/home/settings/privacy/PrivacySettingsScreen.kt index 1d3bfc07a44..3d914ceeeba 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/settings/privacy/PrivacySettingsScreen.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/settings/privacy/PrivacySettingsScreen.kt @@ -46,12 +46,14 @@ fun PrivacySettingsConfigScreen( ) { with(viewModel) { PrivacySettingsScreenContent( + isAnonymousUsageDataEnabled = state.isAnonymousUsageDataEnabled, areReadReceiptsEnabled = state.areReadReceiptsEnabled, setReadReceiptsState = ::setReadReceiptsState, isTypingIndicatorEnabled = state.isTypingIndicatorEnabled, setTypingIndicatorState = ::setTypingIndicatorState, screenshotCensoringConfig = state.screenshotCensoringConfig, setScreenshotCensoringConfig = ::setScreenshotCensoringConfig, + setAnonymousUsageDataEnabled = ::setAnonymousUsageDataEnabled, onBackPressed = navigator::navigateBack, ) } @@ -59,12 +61,14 @@ fun PrivacySettingsConfigScreen( @Composable fun PrivacySettingsScreenContent( + isAnonymousUsageDataEnabled: Boolean, areReadReceiptsEnabled: Boolean, setReadReceiptsState: (Boolean) -> Unit, isTypingIndicatorEnabled: Boolean, setTypingIndicatorState: (Boolean) -> Unit, screenshotCensoringConfig: ScreenshotCensoringConfig, setScreenshotCensoringConfig: (Boolean) -> Unit, + setAnonymousUsageDataEnabled: (Boolean) -> Unit, onBackPressed: () -> Unit, ) { WireScaffold(topBar = { @@ -79,6 +83,12 @@ fun PrivacySettingsScreenContent( .fillMaxSize() .padding(internalPadding) ) { + GroupConversationOptionsItem( + title = stringResource(id = R.string.settings_send_anonymous_usage_data_title), + switchState = SwitchState.Enabled(value = isAnonymousUsageDataEnabled, onCheckedChange = setAnonymousUsageDataEnabled), + arrowType = ArrowType.NONE, + subtitle = stringResource(id = R.string.settings_send_anonymous_usage_data_description) + ) GroupConversationOptionsItem( title = stringResource(R.string.settings_send_read_receipts), switchState = SwitchState.Enabled(value = areReadReceiptsEnabled, onCheckedChange = setReadReceiptsState), @@ -119,12 +129,14 @@ fun PrivacySettingsScreenContent( @Preview fun PreviewSendReadReceipts() { PrivacySettingsScreenContent( + isAnonymousUsageDataEnabled = true, areReadReceiptsEnabled = true, setReadReceiptsState = {}, isTypingIndicatorEnabled = true, setTypingIndicatorState = {}, screenshotCensoringConfig = ScreenshotCensoringConfig.DISABLED, setScreenshotCensoringConfig = {}, + setAnonymousUsageDataEnabled = {}, onBackPressed = {}, ) } diff --git a/app/src/main/kotlin/com/wire/android/ui/home/settings/privacy/PrivacySettingsState.kt b/app/src/main/kotlin/com/wire/android/ui/home/settings/privacy/PrivacySettingsState.kt index 901883e05de..a82f62dc3ed 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/settings/privacy/PrivacySettingsState.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/settings/privacy/PrivacySettingsState.kt @@ -19,6 +19,7 @@ package com.wire.android.ui.home.settings.privacy data class PrivacySettingsState( + val isAnonymousUsageDataEnabled: Boolean = true, val areReadReceiptsEnabled: Boolean = true, val isTypingIndicatorEnabled: Boolean = true, val screenshotCensoringConfig: ScreenshotCensoringConfig = ScreenshotCensoringConfig.ENABLED_BY_USER, diff --git a/app/src/main/kotlin/com/wire/android/ui/home/settings/privacy/PrivacySettingsViewModel.kt b/app/src/main/kotlin/com/wire/android/ui/home/settings/privacy/PrivacySettingsViewModel.kt index 1f6c915d066..491d5cbc27f 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/settings/privacy/PrivacySettingsViewModel.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/settings/privacy/PrivacySettingsViewModel.kt @@ -24,6 +24,7 @@ import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.wire.android.appLogger +import com.wire.android.datastore.GlobalDataStore import com.wire.android.util.dispatchers.DispatcherProvider import com.wire.kalium.logic.feature.user.readReceipts.ObserveReadReceiptsEnabledUseCase import com.wire.kalium.logic.feature.user.readReceipts.PersistReadReceiptsStatusConfigUseCase @@ -50,6 +51,7 @@ class PrivacySettingsViewModel @Inject constructor( private val observeScreenshotCensoringConfig: ObserveScreenshotCensoringConfigUseCase, private val persistTypingIndicatorStatusConfig: PersistTypingIndicatorStatusConfigUseCase, private val observeTypingIndicatorEnabled: ObserveTypingIndicatorEnabledUseCase, + private val globalDataStore: GlobalDataStore ) : ViewModel() { var state by mutableStateOf(PrivacySettingsState()) @@ -61,8 +63,10 @@ class PrivacySettingsViewModel @Inject constructor( observeReadReceiptsEnabled(), observeTypingIndicatorEnabled(), observeScreenshotCensoringConfig(), - ) { readReceiptsEnabled, typingIndicatorEnabled, screenshotCensoringConfig -> + globalDataStore.isAnonymousUsageDataEnabled() + ) { readReceiptsEnabled, typingIndicatorEnabled, screenshotCensoringConfig, anonymousUsageDataEnabled -> PrivacySettingsState( + isAnonymousUsageDataEnabled = anonymousUsageDataEnabled, areReadReceiptsEnabled = readReceiptsEnabled, isTypingIndicatorEnabled = typingIndicatorEnabled, screenshotCensoringConfig = when (screenshotCensoringConfig) { @@ -127,4 +131,13 @@ class PrivacySettingsViewModel @Inject constructor( } } } + + fun setAnonymousUsageDataEnabled(enabled: Boolean) { + viewModelScope.launch { + globalDataStore.setAnonymousUsageDataEnabled(enabled) + } + state = state.copy( + isAnonymousUsageDataEnabled = enabled + ) + } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f08f06c6155..9a330bd167d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1000,6 +1000,8 @@ Typing indicator When this is off, you won\'t be able to see when other people are typing, and others won\'t see when you are typing. This setting applies to all conversations on this device. Lock with passcode + Send anonymous usage data + Usage data allow Wire to understand how the app is being used, and how it can be improved. The data is anonymous and doesn’t contains the content of your communications (such as messages, files, location, or calls) Set app lock passcode The app will lock itself after %1$s of inactivity. To unlock the app you need to enter this passcode or use biometric authentication.\n\nMake sure to remember this passcode as there is no way to recover it. diff --git a/app/src/test/kotlin/com/wire/android/ui/home/settings/privacy/PrivacySettingsViewModelTest.kt b/app/src/test/kotlin/com/wire/android/ui/home/settings/privacy/PrivacySettingsViewModelTest.kt new file mode 100644 index 00000000000..4de46648bc1 --- /dev/null +++ b/app/src/test/kotlin/com/wire/android/ui/home/settings/privacy/PrivacySettingsViewModelTest.kt @@ -0,0 +1,155 @@ +/* + * 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.home.settings.privacy + +import com.wire.android.config.CoroutineTestExtension +import com.wire.android.config.TestDispatcherProvider +import com.wire.android.datastore.GlobalDataStore +import com.wire.kalium.logic.feature.user.readReceipts.ObserveReadReceiptsEnabledUseCase +import com.wire.kalium.logic.feature.user.readReceipts.PersistReadReceiptsStatusConfigUseCase +import com.wire.kalium.logic.feature.user.readReceipts.ReadReceiptStatusConfigResult +import com.wire.kalium.logic.feature.user.screenshotCensoring.ObserveScreenshotCensoringConfigResult +import com.wire.kalium.logic.feature.user.screenshotCensoring.ObserveScreenshotCensoringConfigUseCase +import com.wire.kalium.logic.feature.user.screenshotCensoring.PersistScreenshotCensoringConfigResult +import com.wire.kalium.logic.feature.user.screenshotCensoring.PersistScreenshotCensoringConfigUseCase +import com.wire.kalium.logic.feature.user.typingIndicator.ObserveTypingIndicatorEnabledUseCase +import com.wire.kalium.logic.feature.user.typingIndicator.PersistTypingIndicatorStatusConfigUseCase +import com.wire.kalium.logic.feature.user.typingIndicator.TypingIndicatorConfigResult +import io.mockk.MockKAnnotations +import io.mockk.coEvery +import io.mockk.every +import io.mockk.mockk +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.runTest +import org.amshove.kluent.internal.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(CoroutineTestExtension::class) +class PrivacySettingsViewModelTest { + + @Test + fun `given user opens privacy settings screen, when viewing anonymous usage data, then its value is enabled`() = runTest { + // given + val (_, viewModel) = Arrangement() + .withEnabledAnonymousUsageData() + .arrange() + + // when + // then + assertEquals( + true, + viewModel.state.isAnonymousUsageDataEnabled + ) + } + + @Test + fun `given user opens privacy settings screen, when viewing anonymous usage data, then its value is not enabled`() = runTest { + // given + val (_, viewModel) = Arrangement() + .withDisabledAnonymousUsageData() + .arrange() + + // when + // then + assertEquals( + false, + viewModel.state.isAnonymousUsageDataEnabled + ) + } + + @Test + fun `given anonymous usage data is set to true, when setting to false, then correct value is propagated`() = runTest { + // given + val (_, viewModel) = Arrangement() + .withEnabledAnonymousUsageData() + .arrange() + + // when + viewModel.setAnonymousUsageDataEnabled(enabled = false) + + // then + assertEquals( + false, + viewModel.state.isAnonymousUsageDataEnabled + ) + } + + @Test + fun `given anonymous usage data is set to false, when setting to true, then correct value is propagated`() = runTest { + // given + val (_, viewModel) = Arrangement() + .withDisabledAnonymousUsageData() + .arrange() + + // when + viewModel.setAnonymousUsageDataEnabled(enabled = true) + + // then + assertEquals( + true, + viewModel.state.isAnonymousUsageDataEnabled + ) + } + + private class Arrangement { + val persistReadReceiptsStatusConfig = mockk() + val observeReadReceiptsEnabled = mockk() + val persistScreenshotCensoringConfig = mockk() + val observeScreenshotCensoringConfig = mockk() + val persistTypingIndicatorStatusConfig = mockk() + val observeTypingIndicatorEnabled = mockk() + val globalDataStore = mockk() + + val viewModel by lazy { + PrivacySettingsViewModel( + dispatchers = TestDispatcherProvider(), + persistReadReceiptsStatusConfig = persistReadReceiptsStatusConfig, + observeReadReceiptsEnabled = observeReadReceiptsEnabled, + persistScreenshotCensoringConfig = persistScreenshotCensoringConfig, + observeScreenshotCensoringConfig = observeScreenshotCensoringConfig, + persistTypingIndicatorStatusConfig = persistTypingIndicatorStatusConfig, + observeTypingIndicatorEnabled = observeTypingIndicatorEnabled, + globalDataStore = globalDataStore + ) + } + + init { + MockKAnnotations.init(this, relaxUnitFun = true) + + coEvery { persistReadReceiptsStatusConfig.invoke(true) } returns ReadReceiptStatusConfigResult.Success + coEvery { observeReadReceiptsEnabled() } returns flowOf(true) + coEvery { persistScreenshotCensoringConfig.invoke(true) } returns PersistScreenshotCensoringConfigResult.Success + coEvery { observeScreenshotCensoringConfig() } returns + flowOf(ObserveScreenshotCensoringConfigResult.Enabled.ChosenByUser) + coEvery { persistTypingIndicatorStatusConfig.invoke(true) } returns TypingIndicatorConfigResult.Success + coEvery { observeTypingIndicatorEnabled() } returns flowOf(true) + coEvery { globalDataStore.setAnonymousUsageDataEnabled(any()) } returns Unit + } + + fun withEnabledAnonymousUsageData() = apply { + every { globalDataStore.isAnonymousUsageDataEnabled() } returns flowOf(true) + } + + fun withDisabledAnonymousUsageData() = apply { + every { globalDataStore.isAnonymousUsageDataEnabled() } returns flowOf(false) + } + + fun arrange() = this to viewModel + } +} From 0cd5009404a4ad06c0ea1bcf782b476b4f5c7147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Saleniuk?= <30429749+saleniuk@users.noreply.github.com> Date: Wed, 15 May 2024 19:52:08 +0200 Subject: [PATCH 2/2] refactor: remove rememberRipple, unify calling icon buttons (#2998) --- .../ui/calling/controlbuttons/AcceptButton.kt | 43 ++++--- .../ui/calling/controlbuttons/CameraButton.kt | 71 +++++------ .../controlbuttons/CameraFlipButton.kt | 66 +++++----- .../calling/controlbuttons/DeclineButton.kt | 66 ---------- .../ui/calling/controlbuttons/HangUpButton.kt | 46 ++++--- .../ui/calling/controlbuttons/JoinButton.kt | 7 +- .../controlbuttons/MicrophoneButton.kt | 64 ++++------ .../calling/controlbuttons/SpeakerButton.kt | 64 ++++------ .../calling/controlbuttons/StartCallButton.kt | 3 +- .../controlbuttons/WireCallControlButton.kt | 32 +++-- .../ui/calling/incoming/IncomingCallScreen.kt | 6 +- .../ui/calling/ongoing/OngoingCallScreen.kt | 37 +++++- .../ui/calling/outgoing/OutgoingCallScreen.kt | 8 +- .../wire/android/ui/common/AppExtensions.kt | 6 +- .../android/ui/common/button/WireButton.kt | 30 ++--- .../ui/common/button/WireButtonDefaults.kt | 113 +++++++++--------- .../ui/common/button/WirePrimaryIconButton.kt | 4 +- .../common/button/WireTertiaryIconButton.kt | 4 +- .../wire/android/ui/theme/WireDimensions.kt | 12 +- 19 files changed, 303 insertions(+), 379 deletions(-) delete mode 100644 app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/DeclineButton.kt diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/AcceptButton.kt b/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/AcceptButton.kt index 0d067e117af..db4429db360 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/AcceptButton.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/AcceptButton.kt @@ -18,35 +18,40 @@ package com.wire.android.ui.calling.controlbuttons -import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.Icon import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.DpSize import com.wire.android.R -import com.wire.android.ui.common.button.WirePrimaryButton -import com.wire.android.ui.common.button.wirePrimaryButtonColors -import com.wire.android.ui.common.colorsScheme +import com.wire.android.ui.common.button.WireButtonState +import com.wire.android.ui.common.button.WirePrimaryIconButton import com.wire.android.ui.common.dimensions +import com.wire.android.ui.theme.WireTheme +import com.wire.android.util.ui.PreviewMultipleThemes @Composable fun AcceptButton( - modifier: Modifier = Modifier.size(dimensions().outgoingCallHangUpButtonSize), - buttonClicked: () -> Unit + buttonClicked: () -> Unit, + modifier: Modifier = Modifier, + size: Dp = dimensions().bigCallingControlsSize, + iconSize: Dp = dimensions().bigCallingAcceptButtonIconSize, ) { - WirePrimaryButton( + WirePrimaryIconButton( + iconResource = R.drawable.ic_call_accept, + contentDescription = R.string.content_description_calling_accept_call, + state = WireButtonState.Positive, shape = CircleShape, + minSize = DpSize(size, size), + minClickableSize = DpSize(size, size), + iconSize = iconSize, + onButtonClicked = buttonClicked, modifier = modifier, - colors = wirePrimaryButtonColors().copy(enabled = colorsScheme().callingAnswerButtonColor), - onClick = buttonClicked, - leadingIcon = { - Icon( - painter = painterResource(id = R.drawable.ic_call_accept), - contentDescription = stringResource(id = R.string.content_description_calling_accept_call), - tint = colorsScheme().onCallingAnswerButtonColor - ) - } ) } + +@PreviewMultipleThemes +@Composable +fun PreviewAcceptButton() = WireTheme { + AcceptButton(buttonClicked = { }) +} diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/CameraButton.kt b/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/CameraButton.kt index 472756b7e71..fc4055c4f65 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/CameraButton.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/CameraButton.kt @@ -18,31 +18,24 @@ package com.wire.android.ui.calling.controlbuttons -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.material.ripple -import androidx.compose.material3.Icon import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.Role -import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp import com.wire.android.R import com.wire.android.appLogger import com.wire.android.ui.common.dimensions +import com.wire.android.ui.theme.WireTheme import com.wire.android.util.permission.PermissionDenialType import com.wire.android.util.permission.rememberCallingCameraRequestFlow +import com.wire.android.util.ui.PreviewMultipleThemes @Composable fun CameraButton( - modifier: Modifier = Modifier.size(dimensions().defaultCallingControlsSize), isCameraOn: Boolean = false, onCameraButtonClicked: () -> Unit, - onPermissionPermanentlyDenied: (type: PermissionDenialType) -> Unit + onPermissionPermanentlyDenied: (type: PermissionDenialType) -> Unit, + size: Dp = dimensions().defaultCallingControlsSize, + modifier: Modifier = Modifier, ) { val cameraPermissionCheck = CameraPermissionCheckFlow( onPermissionGranted = onCameraButtonClicked, @@ -55,34 +48,18 @@ fun CameraButton( WireCallControlButton( isSelected = isCameraOn, - modifier = modifier - ) { iconColor -> - Icon( - modifier = Modifier - .wrapContentSize() - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = ripple( - bounded = false, - radius = dimensions().defaultCallingControlsSize / 2 - ), - role = Role.Button, - onClick = cameraPermissionCheck::launch, - ), - painter = painterResource( - id = if (isCameraOn) { - R.drawable.ic_camera_on - } else { - R.drawable.ic_camera_off - } - ), - contentDescription = stringResource( - id = if (isCameraOn) R.string.content_description_calling_turn_camera_off - else R.string.content_description_calling_turn_camera_on - ), - tint = iconColor - ) - } + iconResId = when (isCameraOn) { + true -> R.drawable.ic_camera_on + false -> R.drawable.ic_camera_off + }, + contentDescription = when (isCameraOn) { + true -> R.string.content_description_calling_turn_camera_off + false -> R.string.content_description_calling_turn_camera_on + }, + onClick = cameraPermissionCheck::launch, + size = size, + modifier = modifier, + ) } @Composable @@ -98,8 +75,14 @@ private fun CameraPermissionCheckFlow( onPermissionPermanentlyDenied = onPermanentPermissionDecline ) -@Preview +@PreviewMultipleThemes +@Composable +fun PreviewComposableCameraButtonOn() = WireTheme { + CameraButton(isCameraOn = true, onCameraButtonClicked = { }, onPermissionPermanentlyDenied = { }) +} + +@PreviewMultipleThemes @Composable -fun PreviewComposableCameraButton() { - CameraButton(onCameraButtonClicked = { }, onPermissionPermanentlyDenied = { }) +fun PreviewComposableCameraButtonOff() = WireTheme { + CameraButton(isCameraOn = false, onCameraButtonClicked = { }, onPermissionPermanentlyDenied = { }) } diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/CameraFlipButton.kt b/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/CameraFlipButton.kt index 5b8920776e1..4f99b9be4ee 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/CameraFlipButton.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/CameraFlipButton.kt @@ -18,57 +18,45 @@ package com.wire.android.ui.calling.controlbuttons -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.material.ripple -import androidx.compose.material3.Icon import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.Role -import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp import com.wire.android.R import com.wire.android.ui.common.dimensions +import com.wire.android.ui.theme.WireTheme +import com.wire.android.util.ui.PreviewMultipleThemes @Composable fun CameraFlipButton( isOnFrontCamera: Boolean = false, - onCameraFlipButtonClicked: () -> Unit + onCameraFlipButtonClicked: () -> Unit, + size: Dp = dimensions().defaultCallingControlsSize, + modifier: Modifier = Modifier, ) { WireCallControlButton( - isSelected = !isOnFrontCamera - ) { iconColor -> - Icon( - modifier = Modifier - .wrapContentSize() - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = ripple(bounded = false, radius = dimensions().defaultCallingControlsSize / 2), - role = Role.Button, - onClick = onCameraFlipButtonClicked + isSelected = !isOnFrontCamera, + iconResId = when (isOnFrontCamera) { + true -> R.drawable.ic_camera_flipped + false -> R.drawable.ic_camera_flip + }, + contentDescription = when (isOnFrontCamera) { + true -> R.string.content_description_calling_flip_camera_on + false -> R.string.content_description_calling_flip_camera_off + }, + onClick = onCameraFlipButtonClicked, + size = size, + modifier = modifier, + ) +} - ), - painter = painterResource( - id = if (isOnFrontCamera) { - R.drawable.ic_camera_flipped - } else { - R.drawable.ic_camera_flip - } - ), - tint = iconColor, - contentDescription = stringResource( - id = if (isOnFrontCamera) R.string.content_description_calling_flip_camera_on - else R.string.content_description_calling_flip_camera_off - ) - ) - } +@PreviewMultipleThemes +@Composable +fun PreviewCameraFlipButtonOn() = WireTheme { + CameraFlipButton(isOnFrontCamera = true, onCameraFlipButtonClicked = { }) } -@Preview +@PreviewMultipleThemes @Composable -fun PreviewCameraFlipButton() { - CameraFlipButton(onCameraFlipButtonClicked = { }) +fun PreviewCameraFlipButtonOff() = WireTheme { + CameraFlipButton(isOnFrontCamera = false, onCameraFlipButtonClicked = { }) } diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/DeclineButton.kt b/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/DeclineButton.kt deleted file mode 100644 index 696d3602633..00000000000 --- a/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/DeclineButton.kt +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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.calling.controlbuttons - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.size -import androidx.compose.material.ripple -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.Role -import androidx.compose.ui.tooling.preview.Preview -import com.wire.android.R -import com.wire.android.ui.common.dimensions - -@Composable -fun DeclineButton(buttonClicked: () -> Unit) { - IconButton( - modifier = Modifier.size(dimensions().outgoingCallHangUpButtonSize), - onClick = { } - ) { - Icon( - modifier = Modifier - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = ripple( - bounded = false, - radius = dimensions().outgoingCallHangUpButtonSize / 2 - ), - role = Role.Button, - onClick = { buttonClicked() } - ), - painter = painterResource(id = R.drawable.ic_decline), - contentDescription = stringResource(id = R.string.content_description_calling_decline_call), - tint = Color.Unspecified - ) - } -} - -@Preview -@Composable -fun PreviewComposableDeclineButton() { - DeclineButton(buttonClicked = { }) -} diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/HangUpButton.kt b/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/HangUpButton.kt index 5dd2986e095..c64e3cb7379 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/HangUpButton.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/HangUpButton.kt @@ -19,50 +19,48 @@ package com.wire.android.ui.calling.controlbuttons import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.DpSize import com.wire.android.R -import com.wire.android.ui.common.button.WirePrimaryButton -import com.wire.android.ui.common.button.wirePrimaryButtonColors -import com.wire.android.ui.common.colorsScheme +import com.wire.android.ui.common.button.WireButtonState +import com.wire.android.ui.common.button.WirePrimaryIconButton import com.wire.android.ui.common.dimensions +import com.wire.android.ui.theme.WireTheme import com.wire.android.ui.theme.wireDimensions +import com.wire.android.util.ui.PreviewMultipleThemes @Composable fun HangUpButton( - modifier: Modifier = Modifier.size(dimensions().defaultCallingHangUpButtonSize), - onHangUpButtonClicked: () -> Unit + onHangUpButtonClicked: () -> Unit, + modifier: Modifier = Modifier, + size: Dp = dimensions().bigCallingControlsSize, + iconSize: Dp = dimensions().bigCallingHangUpButtonIconSize, ) { - WirePrimaryButton( + WirePrimaryIconButton( + iconResource = R.drawable.ic_call_reject, + contentDescription = R.string.content_description_calling_hang_up_call, + state = WireButtonState.Error, shape = CircleShape, + minSize = DpSize(size, size), + minClickableSize = DpSize(size, size), + iconSize = iconSize, + onButtonClicked = onHangUpButtonClicked, modifier = modifier, - colors = wirePrimaryButtonColors().copy(enabled = colorsScheme().callingHangupButtonColor), - onClick = onHangUpButtonClicked, - leadingIcon = { - Icon( - painter = painterResource(id = R.drawable.ic_call_reject), - contentDescription = stringResource(id = R.string.content_description_calling_hang_up_call), - tint = colorsScheme().onCallingHangupButtonColor - ) - } ) } -@Preview +@PreviewMultipleThemes @Composable -fun PreviewComposableHangUpButton() { +fun PreviewComposableHangUpButton() = WireTheme { HangUpButton( modifier = Modifier - .width(MaterialTheme.wireDimensions.outgoingCallHangUpButtonSize) - .height(MaterialTheme.wireDimensions.outgoingCallHangUpButtonSize), + .width(MaterialTheme.wireDimensions.bigCallingControlsSize) + .height(MaterialTheme.wireDimensions.bigCallingControlsSize), onHangUpButtonClicked = { } ) } diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/JoinButton.kt b/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/JoinButton.kt index 01efc16c697..051d66ec259 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/JoinButton.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/JoinButton.kt @@ -25,7 +25,6 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.DpSize import com.wire.android.R @@ -33,10 +32,12 @@ import com.wire.android.appLogger import com.wire.android.ui.common.button.WireButtonState import com.wire.android.ui.common.button.WirePrimaryButton import com.wire.android.ui.common.dimensions +import com.wire.android.ui.theme.WireTheme import com.wire.android.ui.theme.wireDimensions import com.wire.android.ui.theme.wireTypography import com.wire.android.util.permission.PermissionDenialType import com.wire.android.util.permission.rememberCallingRecordAudioRequestFlow +import com.wire.android.util.ui.PreviewMultipleThemes @Composable fun JoinButton( @@ -87,9 +88,9 @@ private fun AudioPermissionCheckFlow( onAudioPermissionPermanentlyDenied = onPermanentPermissionDecline ) -@Preview +@PreviewMultipleThemes @Composable -fun PreviewJoinButton() { +fun PreviewJoinButton() = WireTheme { JoinButton( buttonClick = {}, onPermissionPermanentlyDenied = {} diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/MicrophoneButton.kt b/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/MicrophoneButton.kt index a19c42d80b1..74238480566 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/MicrophoneButton.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/MicrophoneButton.kt @@ -18,59 +18,45 @@ package com.wire.android.ui.calling.controlbuttons -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.material.ripple -import androidx.compose.material3.Icon import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.Role -import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp import com.wire.android.R import com.wire.android.ui.common.dimensions +import com.wire.android.ui.theme.WireTheme +import com.wire.android.util.ui.PreviewMultipleThemes @Composable fun MicrophoneButton( - modifier: Modifier = Modifier.size(dimensions().defaultCallingControlsSize), isMuted: Boolean, - onMicrophoneButtonClicked: () -> Unit + onMicrophoneButtonClicked: () -> Unit, + size: Dp = dimensions().defaultCallingControlsSize, + modifier: Modifier = Modifier, ) { WireCallControlButton( isSelected = !isMuted, + iconResId = when (isMuted) { + true -> R.drawable.ic_microphone_off + false -> R.drawable.ic_microphone_on + }, + contentDescription = when (isMuted) { + true -> R.string.content_description_calling_unmute_call + false -> R.string.content_description_calling_mute_call + }, + onClick = onMicrophoneButtonClicked, + size = size, modifier = modifier - ) { iconColor -> - Icon( - modifier = modifier - .wrapContentSize() - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = ripple(bounded = false, radius = dimensions().defaultCallingControlsSize / 2), - role = Role.Button, - onClick = { onMicrophoneButtonClicked() } - ), - painter = painterResource( - id = if (isMuted) { - R.drawable.ic_microphone_off - } else { - R.drawable.ic_microphone_on - } - ), - contentDescription = stringResource( - id = if (isMuted) R.string.content_description_calling_unmute_call - else R.string.content_description_calling_mute_call - ), - tint = iconColor - ) - } + ) } -@Preview +@PreviewMultipleThemes @Composable -fun PreviewComposableMicrophoneButton() { +fun PreviewComposableMicrophoneButtonOn() = WireTheme { MicrophoneButton(isMuted = true, onMicrophoneButtonClicked = { }) } + +@PreviewMultipleThemes +@Composable +fun PreviewComposableMicrophoneButtonOff() = WireTheme { + MicrophoneButton(isMuted = false, onMicrophoneButtonClicked = { }) +} diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/SpeakerButton.kt b/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/SpeakerButton.kt index 0771baf44cc..5c6faae8fa5 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/SpeakerButton.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/SpeakerButton.kt @@ -18,57 +18,45 @@ package com.wire.android.ui.calling.controlbuttons -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.material.ripple -import androidx.compose.material3.Icon import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.Role -import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp import com.wire.android.R import com.wire.android.ui.common.dimensions +import com.wire.android.ui.theme.WireTheme +import com.wire.android.util.ui.PreviewMultipleThemes @Composable fun SpeakerButton( - modifier: Modifier = Modifier.size(dimensions().defaultCallingControlsSize), isSpeakerOn: Boolean, - onSpeakerButtonClicked: () -> Unit + onSpeakerButtonClicked: () -> Unit, + size: Dp = dimensions().defaultCallingControlsSize, + modifier: Modifier = Modifier, ) { WireCallControlButton( isSelected = isSpeakerOn, - modifier = modifier - ) { iconColor -> - Icon( - modifier = modifier - .wrapContentSize() - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = ripple(bounded = false, radius = dimensions().defaultCallingControlsSize / 2), - role = Role.Button, - onClick = { onSpeakerButtonClicked() } - ), - painter = painterResource( - id = if (isSpeakerOn) - R.drawable.ic_speaker_on - else R.drawable.ic_speaker_off - ), - contentDescription = stringResource( - id = if (isSpeakerOn) R.string.content_description_calling_turn_speaker_off - else R.string.content_description_calling_turn_speaker_on - ), - tint = iconColor - ) - } + iconResId = when (isSpeakerOn) { + true -> R.drawable.ic_speaker_on + false -> R.drawable.ic_speaker_off + }, + contentDescription = when (isSpeakerOn) { + true -> R.string.content_description_calling_turn_speaker_off + false -> R.string.content_description_calling_turn_speaker_on + }, + onClick = onSpeakerButtonClicked, + size = size, + modifier = modifier, + ) } -@Preview +@PreviewMultipleThemes @Composable -fun PreviewSpeakerButton() { +fun PreviewSpeakerButtonOn() = WireTheme { SpeakerButton(isSpeakerOn = true, onSpeakerButtonClicked = { }) } + +@PreviewMultipleThemes +@Composable +fun PreviewSpeakerButtonOf() = WireTheme { + SpeakerButton(isSpeakerOn = false, onSpeakerButtonClicked = { }) +} diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/StartCallButton.kt b/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/StartCallButton.kt index 31c1d2ec828..79a7e61c2f3 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/StartCallButton.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/StartCallButton.kt @@ -32,6 +32,7 @@ import com.wire.android.model.ClickBlockParams import com.wire.android.ui.common.button.WireButtonState import com.wire.android.ui.common.button.WireSecondaryButton import com.wire.android.ui.common.dimensions +import com.wire.android.ui.theme.WireTheme import com.wire.android.ui.theme.wireDimensions import com.wire.android.util.permission.PermissionDenialType import com.wire.android.util.permission.rememberCallingRecordAudioRequestFlow @@ -88,7 +89,7 @@ private fun AudioPermissionCheckFlow( @PreviewMultipleThemes @Composable -fun PreviewStartCallButton() { +fun PreviewStartCallButton() = WireTheme { StartCallButton( onPhoneButtonClick = {}, onPermissionPermanentlyDenied = {}, diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/WireCallControlButton.kt b/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/WireCallControlButton.kt index 1c8d1f59fd4..54df2a3155e 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/WireCallControlButton.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/controlbuttons/WireCallControlButton.kt @@ -18,13 +18,16 @@ package com.wire.android.ui.calling.controlbuttons +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.DpSize import com.wire.android.ui.common.button.WireButtonState -import com.wire.android.ui.common.button.WireSecondaryButton +import com.wire.android.ui.common.button.WireSecondaryIconButton import com.wire.android.ui.common.button.wireSecondaryButtonColors import com.wire.android.ui.common.colorsScheme import com.wire.android.ui.common.dimensions @@ -32,25 +35,34 @@ import com.wire.android.ui.common.dimensions @Composable fun WireCallControlButton( isSelected: Boolean, + @DrawableRes iconResId: Int, + @StringRes contentDescription: Int, + onClick: () -> Unit, + size: Dp = dimensions().defaultCallingControlsSize, + iconSize: Dp = dimensions().defaultCallingControlsIconSize, modifier: Modifier = Modifier, - icon: @Composable (iconColor: Color) -> Unit, ) { - val iconColor = if (isSelected) colorsScheme().onCallingControlButtonActive else colorsScheme().onCallingControlButtonInactive - WireSecondaryButton( - modifier = modifier.size(dimensions().defaultCallingControlsSize), - onClick = {}, - leadingIcon = { icon(iconColor) }, + WireSecondaryIconButton( + onButtonClicked = onClick, + iconResource = iconResId, shape = CircleShape, colors = with(colorsScheme()) { wireSecondaryButtonColors().copy( selected = callingControlButtonActive, selectedOutline = callingControlButtonActiveOutline, onSelected = onCallingControlButtonActive, + selectedRipple = onCallingControlButtonActive, enabled = callingControlButtonInactive, enabledOutline = callingControlButtonInactiveOutline, - onEnabled = onCallingControlButtonInactive + onEnabled = onCallingControlButtonInactive, + enabledRipple = onCallingControlButtonInactive, ) }, - state = if (isSelected) WireButtonState.Selected else WireButtonState.Default + contentDescription = contentDescription, + state = if (isSelected) WireButtonState.Selected else WireButtonState.Default, + minSize = DpSize(size, size), + minClickableSize = DpSize(size, size), + iconSize = iconSize, + modifier = modifier.size(size), ) } diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/incoming/IncomingCallScreen.kt b/app/src/main/kotlin/com/wire/android/ui/calling/incoming/IncomingCallScreen.kt index d62a4a5c848..a78ad684177 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/incoming/IncomingCallScreen.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/incoming/IncomingCallScreen.kt @@ -24,7 +24,6 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text @@ -209,7 +208,8 @@ private fun IncomingCallContent( modifier = Modifier.align(alignment = Alignment.CenterStart) ) { HangUpButton( - modifier = Modifier.size(dimensions().outgoingCallHangUpButtonSize), + size = dimensions().bigCallingControlsSize, + iconSize = dimensions().bigCallingHangUpButtonIconSize, onHangUpButtonClicked = { declineCall() } ) Text( @@ -228,6 +228,8 @@ private fun IncomingCallContent( .align(alignment = Alignment.CenterEnd) ) { AcceptButton( + size = dimensions().bigCallingControlsSize, + iconSize = dimensions().bigCallingAcceptButtonIconSize, buttonClicked = acceptCall ) Text( diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/OngoingCallScreen.kt b/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/OngoingCallScreen.kt index 6cff25ed4b1..9e06147d6b2 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/OngoingCallScreen.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/ongoing/OngoingCallScreen.kt @@ -81,6 +81,7 @@ import com.wire.android.ui.common.topappbar.NavigationIconType import com.wire.android.ui.common.topappbar.WireCenterAlignedTopAppBar import com.wire.android.ui.common.visbility.rememberVisibilityState import com.wire.android.ui.home.conversations.PermissionPermanentlyDeniedDialogState +import com.wire.android.ui.theme.WireTheme import com.wire.android.ui.theme.wireColorScheme import com.wire.android.ui.theme.wireDimensions import com.wire.android.ui.theme.wireTypography @@ -429,7 +430,7 @@ private fun CallingControls( .fillMaxWidth() .height(dimensions().spacing56x) ) { - MicrophoneButton(isMuted = isMuted) { toggleMute() } + MicrophoneButton(isMuted = isMuted, onMicrophoneButtonClicked = toggleMute) CameraButton( isCameraOn = isCameraOn, onPermissionPermanentlyDenied = onPermissionPermanentlyDenied, @@ -446,7 +447,7 @@ private fun CallingControls( } HangUpButton( - modifier = Modifier.size(MaterialTheme.wireDimensions.defaultCallingHangUpButtonSize), + modifier = Modifier.size(MaterialTheme.wireDimensions.defaultCallingControlsSize), onHangUpButtonClicked = onHangUpCall ) } @@ -457,6 +458,36 @@ private fun CallingControls( @PreviewMultipleThemes @Composable -fun PreviewOngoingCallTopBar() { +fun PreviewOngoingCallScreen() = WireTheme { + OngoingCallContent( + conversationId = ConversationId("conversationId", "domain"), + conversationName = ConversationName.Known("Conversation Name"), + participants = emptyList(), + isMuted = false, + isCameraOn = false, + isOnFrontCamera = false, + isSpeakerOn = false, + isCbrEnabled = false, + shouldShowDoubleTapToast = false, + protocolInfo = null, + mlsVerificationStatus = null, + proteusVerificationStatus = null, + toggleSpeaker = {}, + toggleMute = {}, + hangUpCall = {}, + toggleVideo = {}, + flipCamera = {}, + setVideoPreview = {}, + clearVideoPreview = {}, + onCollapse = {}, + hideDoubleTapToast = {}, + onPermissionPermanentlyDenied = {}, + requestVideoStreams = {}, + ) +} + +@PreviewMultipleThemes +@Composable +fun PreviewOngoingCallTopBar() = WireTheme { OngoingCallTopBar("Default", true, null, null, null) { } } diff --git a/app/src/main/kotlin/com/wire/android/ui/calling/outgoing/OutgoingCallScreen.kt b/app/src/main/kotlin/com/wire/android/ui/calling/outgoing/OutgoingCallScreen.kt index cc5dc754814..4f8956fae00 100644 --- a/app/src/main/kotlin/com/wire/android/ui/calling/outgoing/OutgoingCallScreen.kt +++ b/app/src/main/kotlin/com/wire/android/ui/calling/outgoing/OutgoingCallScreen.kt @@ -26,9 +26,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.width import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.rememberBottomSheetScaffoldState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -51,7 +49,6 @@ import com.wire.android.ui.common.dialogs.PermissionPermanentlyDeniedDialog import com.wire.android.ui.common.dimensions import com.wire.android.ui.common.visbility.rememberVisibilityState import com.wire.android.ui.home.conversations.PermissionPermanentlyDeniedDialogState -import com.wire.android.ui.theme.wireDimensions import com.wire.android.util.permission.PermissionDenialType import com.wire.kalium.logic.data.id.ConversationId @@ -160,9 +157,8 @@ private fun OutgoingCallContent( .height(45.dp) ) HangUpButton( - modifier = Modifier - .width(MaterialTheme.wireDimensions.outgoingCallHangUpButtonSize) - .height(MaterialTheme.wireDimensions.outgoingCallHangUpButtonSize), + size = dimensions().bigCallingControlsSize, + iconSize = dimensions().bigCallingHangUpButtonIconSize, onHangUpButtonClicked = onHangUpCall ) } diff --git a/app/src/main/kotlin/com/wire/android/ui/common/AppExtensions.kt b/app/src/main/kotlin/com/wire/android/ui/common/AppExtensions.kt index 6272bc25548..c6bb16bfc7e 100644 --- a/app/src/main/kotlin/com/wire/android/ui/common/AppExtensions.kt +++ b/app/src/main/kotlin/com/wire/android/ui/common/AppExtensions.kt @@ -18,10 +18,8 @@ package com.wire.android.ui.common -import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.selection.selectable import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.ripple import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.State @@ -60,9 +58,7 @@ import kotlin.coroutines.EmptyCoroutineContext fun Modifier.selectableBackground(isSelected: Boolean, onClick: () -> Unit): Modifier = this.selectable( selected = isSelected, - onClick = { onClick() }, - interactionSource = remember { MutableInteractionSource() }, - indication = ripple(bounded = true, color = MaterialTheme.colorScheme.onBackground.copy(0.5f)), + onClick = onClick, role = Role.Tab ) diff --git a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireButton.kt b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireButton.kt index 6d4b0cd48ac..80e30222031 100644 --- a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireButton.kt +++ b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireButton.kt @@ -49,7 +49,6 @@ import androidx.compose.ui.graphics.Shape import androidx.compose.ui.layout.layout import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.platform.LocalViewConfiguration import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.DpSize @@ -90,17 +89,16 @@ fun WireButton( interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, modifier: Modifier = Modifier, ) { - val border = - if (borderWidth > 0.dp) BorderStroke( - width = borderWidth, - color = colors.outlineColor(state, interactionSource).value - ) - else null + val border = when { + borderWidth > 0.dp -> BorderStroke(width = borderWidth, color = colors.outlineColor(state).value) + else -> null + } val baseColors = ButtonDefaults.buttonColors( - containerColor = colors.containerColor(state, interactionSource).value, - contentColor = colors.rippleColor(), // actual content color is set directly for the children, here it's only used for the ripple - disabledContainerColor = colors.containerColor(state, interactionSource).value, - disabledContentColor = colors.rippleColor(), + containerColor = colors.containerColor(state).value, + // actual content color is set directly for the children, here it's only used for the ripple + contentColor = colors.rippleColor(state).value, + disabledContainerColor = colors.containerColor(state).value, + disabledContentColor = colors.rippleColor(state).value, ) val onClickWithSyncObserver = rememberClickBlockAction(clickBlockParams, onClick) CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) { @@ -141,7 +139,6 @@ fun WireButton( textStyle = textStyle, state = state, colors = colors, - interactionSource = interactionSource ) } } @@ -159,9 +156,8 @@ private fun InnerButtonBox( textStyle: TextStyle = MaterialTheme.wireTypography.button03, state: WireButtonState = WireButtonState.Default, colors: WireButtonColors = wirePrimaryButtonColors(), - interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, ) { - val contentColor = colors.contentColor(state, interactionSource).value + val contentColor = colors.contentColor(state).value val leadingItem: (@Composable () -> Unit) = { leadingIcon?.let { Tint(contentColor = contentColor, content = it) } } val trailingItem: (@Composable () -> Unit) = { Crossfade(targetState = trailingIcon to loading) { (trailingIcon, loading) -> @@ -213,10 +209,4 @@ private fun InnerButtonBox( } } -@Composable -fun getMinTouchMargins(minSize: DpSize) = PaddingValues( - horizontal = (LocalViewConfiguration.current.minimumTouchTargetSize.width - minSize.width) / 2, - vertical = (LocalViewConfiguration.current.minimumTouchTargetSize.height - minSize.height) / 2 -) - enum class IconAlignment { Border, Center } diff --git a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireButtonDefaults.kt b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireButtonDefaults.kt index 37d19da0b3c..4a9930cc1d9 100644 --- a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireButtonDefaults.kt +++ b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireButtonDefaults.kt @@ -19,7 +19,6 @@ package com.wire.android.ui.common.button import androidx.compose.animation.animateColorAsState -import androidx.compose.foundation.interaction.InteractionSource import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable @@ -32,19 +31,23 @@ fun wirePrimaryButtonColors() = wireButtonColors( enabled = MaterialTheme.wireColorScheme.primaryButtonEnabled, onEnabled = MaterialTheme.wireColorScheme.onPrimaryButtonEnabled, enabledOutline = MaterialTheme.wireColorScheme.primaryButtonEnabled, + enabledRipple = MaterialTheme.wireColorScheme.primaryButtonRipple, disabled = MaterialTheme.wireColorScheme.primaryButtonDisabled, onDisabled = MaterialTheme.wireColorScheme.onPrimaryButtonDisabled, disabledOutline = MaterialTheme.wireColorScheme.primaryButtonDisabled, + disabledRipple = MaterialTheme.wireColorScheme.primaryButtonRipple, selected = MaterialTheme.wireColorScheme.primaryButtonSelected, onSelected = MaterialTheme.wireColorScheme.onPrimaryButtonSelected, selectedOutline = MaterialTheme.wireColorScheme.primaryButtonSelected, + selectedRipple = MaterialTheme.wireColorScheme.primaryButtonRipple, error = MaterialTheme.wireColorScheme.error, onError = MaterialTheme.wireColorScheme.onError, errorOutline = MaterialTheme.wireColorScheme.error, + errorRipple = MaterialTheme.wireColorScheme.primaryButtonRipple, positive = MaterialTheme.wireColorScheme.positive, onPositive = MaterialTheme.wireColorScheme.onPositive, positiveOutline = MaterialTheme.wireColorScheme.positive, - ripple = MaterialTheme.wireColorScheme.primaryButtonRipple + positiveRipple = MaterialTheme.wireColorScheme.primaryButtonRipple, ) @Composable @@ -54,40 +57,27 @@ fun wireSendPrimaryButtonColors() = wirePrimaryButtonColors().copy( ) @Composable -fun wireSecondaryButtonColors( - enabled: Color = MaterialTheme.wireColorScheme.secondaryButtonEnabled, - onEnabled: Color = MaterialTheme.wireColorScheme.onSecondaryButtonEnabled, - enabledOutline: Color = MaterialTheme.wireColorScheme.secondaryButtonEnabledOutline, - disabled: Color = MaterialTheme.wireColorScheme.secondaryButtonDisabled, - onDisabled: Color = MaterialTheme.wireColorScheme.onSecondaryButtonDisabled, - disabledOutline: Color = MaterialTheme.wireColorScheme.secondaryButtonDisabledOutline, - selected: Color = MaterialTheme.wireColorScheme.secondaryButtonSelected, - onSelected: Color = MaterialTheme.wireColorScheme.onSecondaryButtonSelected, - selectedOutline: Color = MaterialTheme.wireColorScheme.secondaryButtonSelectedOutline, - error: Color = MaterialTheme.wireColorScheme.secondaryButtonEnabled, - onError: Color = MaterialTheme.wireColorScheme.error, - errorOutline: Color = MaterialTheme.wireColorScheme.secondaryButtonEnabledOutline, - positive: Color = MaterialTheme.wireColorScheme.secondaryButtonEnabled, - onPositive: Color = MaterialTheme.wireColorScheme.positive, - positiveOutline: Color = MaterialTheme.wireColorScheme.secondaryButtonEnabledOutline, - ripple: Color = MaterialTheme.wireColorScheme.secondaryButtonRipple -) = wireButtonColors( - enabled = enabled, - onEnabled = onEnabled, - enabledOutline = enabledOutline, - disabled = disabled, - onDisabled = onDisabled, - disabledOutline = disabledOutline, - selected = selected, - onSelected = onSelected, - selectedOutline = selectedOutline, - error = error, - onError = onError, - errorOutline = errorOutline, - positive = positive, - onPositive = onPositive, - positiveOutline = positiveOutline, - ripple = ripple +fun wireSecondaryButtonColors() = wireButtonColors( + enabled = MaterialTheme.wireColorScheme.secondaryButtonEnabled, + onEnabled = MaterialTheme.wireColorScheme.onSecondaryButtonEnabled, + enabledOutline = MaterialTheme.wireColorScheme.secondaryButtonEnabledOutline, + enabledRipple = MaterialTheme.wireColorScheme.secondaryButtonRipple, + disabled = MaterialTheme.wireColorScheme.secondaryButtonDisabled, + onDisabled = MaterialTheme.wireColorScheme.onSecondaryButtonDisabled, + disabledOutline = MaterialTheme.wireColorScheme.secondaryButtonDisabledOutline, + disabledRipple = MaterialTheme.wireColorScheme.secondaryButtonRipple, + selected = MaterialTheme.wireColorScheme.secondaryButtonSelected, + onSelected = MaterialTheme.wireColorScheme.onSecondaryButtonSelected, + selectedOutline = MaterialTheme.wireColorScheme.secondaryButtonSelectedOutline, + selectedRipple = MaterialTheme.wireColorScheme.secondaryButtonRipple, + error = MaterialTheme.wireColorScheme.secondaryButtonEnabled, + onError = MaterialTheme.wireColorScheme.error, + errorOutline = MaterialTheme.wireColorScheme.secondaryButtonEnabledOutline, + errorRipple = MaterialTheme.wireColorScheme.secondaryButtonRipple, + positive = MaterialTheme.wireColorScheme.secondaryButtonEnabled, + onPositive = MaterialTheme.wireColorScheme.positive, + positiveOutline = MaterialTheme.wireColorScheme.secondaryButtonEnabledOutline, + positiveRipple = MaterialTheme.wireColorScheme.secondaryButtonRipple, ) @Composable @@ -95,36 +85,39 @@ fun wireTertiaryButtonColors() = wireButtonColors( enabled = MaterialTheme.wireColorScheme.tertiaryButtonEnabled, onEnabled = MaterialTheme.wireColorScheme.onTertiaryButtonEnabled, enabledOutline = MaterialTheme.wireColorScheme.tertiaryButtonEnabled, + enabledRipple = MaterialTheme.wireColorScheme.tertiaryButtonRipple, disabled = MaterialTheme.wireColorScheme.tertiaryButtonDisabled, onDisabled = MaterialTheme.wireColorScheme.onTertiaryButtonDisabled, disabledOutline = MaterialTheme.wireColorScheme.tertiaryButtonDisabled, + disabledRipple = MaterialTheme.wireColorScheme.tertiaryButtonRipple, selected = MaterialTheme.wireColorScheme.tertiaryButtonSelected, onSelected = MaterialTheme.wireColorScheme.onTertiaryButtonSelected, selectedOutline = MaterialTheme.wireColorScheme.tertiaryButtonSelectedOutline, + selectedRipple = MaterialTheme.wireColorScheme.tertiaryButtonRipple, error = MaterialTheme.wireColorScheme.tertiaryButtonEnabled, onError = MaterialTheme.wireColorScheme.error, errorOutline = MaterialTheme.wireColorScheme.tertiaryButtonEnabled, + errorRipple = MaterialTheme.wireColorScheme.tertiaryButtonRipple, positive = MaterialTheme.wireColorScheme.tertiaryButtonEnabled, onPositive = MaterialTheme.wireColorScheme.positive, positiveOutline = MaterialTheme.wireColorScheme.tertiaryButtonEnabled, - ripple = MaterialTheme.wireColorScheme.tertiaryButtonRipple + positiveRipple = MaterialTheme.wireColorScheme.tertiaryButtonRipple, ) +@Suppress("ParameterListWrapping") @Composable private fun wireButtonColors( - enabled: Color, onEnabled: Color, enabledOutline: Color, - disabled: Color, onDisabled: Color, disabledOutline: Color, - selected: Color, onSelected: Color, selectedOutline: Color, - error: Color, onError: Color, errorOutline: Color, - positive: Color, onPositive: Color, positiveOutline: Color, - ripple: Color + enabled: Color, onEnabled: Color, enabledOutline: Color, enabledRipple: Color, + disabled: Color, onDisabled: Color, disabledOutline: Color, disabledRipple: Color, + selected: Color, onSelected: Color, selectedOutline: Color, selectedRipple: Color, + error: Color, onError: Color, errorOutline: Color, errorRipple: Color, + positive: Color, onPositive: Color, positiveOutline: Color, positiveRipple: Color, ) = WireButtonColors( - enabled, onEnabled, enabledOutline, - disabled, onDisabled, disabledOutline, - selected, onSelected, selectedOutline, - error, onError, errorOutline, - positive, onPositive, positiveOutline, - ripple + enabled, onEnabled, enabledOutline, enabledRipple, + disabled, onDisabled, disabledOutline, disabledRipple, + selected, onSelected, selectedOutline, selectedRipple, + error, onError, errorOutline, errorRipple, + positive, onPositive, positiveOutline, positiveRipple, ) @Stable @@ -132,23 +125,27 @@ data class WireButtonColors( val enabled: Color, val onEnabled: Color, val enabledOutline: Color, + val enabledRipple: Color, val disabled: Color, val onDisabled: Color, val disabledOutline: Color, + val disabledRipple: Color, val selected: Color, val onSelected: Color, val selectedOutline: Color, + val selectedRipple: Color, val error: Color, val onError: Color, val errorOutline: Color, + val errorRipple: Color, val positive: Color, val onPositive: Color, val positiveOutline: Color, - val ripple: Color + val positiveRipple: Color, ) { @Composable - fun containerColor(state: WireButtonState, interactionSource: InteractionSource): State = animateColorAsState( + fun containerColor(state: WireButtonState): State = animateColorAsState( when (state) { WireButtonState.Default -> enabled WireButtonState.Disabled -> disabled @@ -159,7 +156,7 @@ data class WireButtonColors( ) @Composable - fun outlineColor(state: WireButtonState, interactionSource: InteractionSource): State = animateColorAsState( + fun outlineColor(state: WireButtonState): State = animateColorAsState( when (state) { WireButtonState.Default -> enabledOutline WireButtonState.Disabled -> disabledOutline @@ -170,7 +167,7 @@ data class WireButtonColors( ) @Composable - fun contentColor(state: WireButtonState, interactionSource: InteractionSource): State = animateColorAsState( + fun contentColor(state: WireButtonState): State = animateColorAsState( when (state) { WireButtonState.Default -> onEnabled WireButtonState.Disabled -> onDisabled @@ -181,7 +178,15 @@ data class WireButtonColors( ) @Composable - fun rippleColor(): Color = ripple + fun rippleColor(state: WireButtonState): State = animateColorAsState( + when (state) { + WireButtonState.Default -> enabledRipple + WireButtonState.Disabled -> disabledRipple + WireButtonState.Selected -> selectedRipple + WireButtonState.Error -> errorRipple + WireButtonState.Positive -> positiveRipple + } + ) } sealed class WireButtonState { diff --git a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WirePrimaryIconButton.kt b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WirePrimaryIconButton.kt index 911c3734876..3a21581b9c1 100644 --- a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WirePrimaryIconButton.kt +++ b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WirePrimaryIconButton.kt @@ -32,6 +32,7 @@ import androidx.compose.ui.graphics.Shape import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.dp import com.wire.android.model.ClickBlockParams @@ -47,6 +48,7 @@ fun WirePrimaryIconButton( shape: Shape = RoundedCornerShape(MaterialTheme.wireDimensions.buttonCornerSize), minSize: DpSize = MaterialTheme.wireDimensions.buttonSmallMinSize, minClickableSize: DpSize = MaterialTheme.wireDimensions.buttonMinClickableSize, + iconSize: Dp = dimensions().wireIconButtonSize, state: WireButtonState = WireButtonState.Default, colors: WireButtonColors = wirePrimaryButtonColors(), clickBlockParams: ClickBlockParams = ClickBlockParams(), @@ -59,7 +61,7 @@ fun WirePrimaryIconButton( Icon( painter = painterResource(id = iconResource), contentDescription = stringResource(contentDescription), - modifier = Modifier.size(dimensions().wireIconButtonSize) + modifier = Modifier.size(iconSize) ) }, shape = shape, diff --git a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireTertiaryIconButton.kt b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireTertiaryIconButton.kt index b86fa89d497..19498bcd898 100644 --- a/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireTertiaryIconButton.kt +++ b/core/ui-common/src/main/kotlin/com/wire/android/ui/common/button/WireTertiaryIconButton.kt @@ -32,6 +32,7 @@ import androidx.compose.ui.graphics.Shape import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.dp import com.wire.android.model.ClickBlockParams @@ -47,6 +48,7 @@ fun WireTertiaryIconButton( shape: Shape = RoundedCornerShape(MaterialTheme.wireDimensions.buttonCornerSize), minSize: DpSize = MaterialTheme.wireDimensions.buttonSmallMinSize, minClickableSize: DpSize = MaterialTheme.wireDimensions.buttonMinClickableSize, + iconSize: Dp = dimensions().wireIconButtonSize, state: WireButtonState = WireButtonState.Default, colors: WireButtonColors = wireTertiaryButtonColors(), clickBlockParams: ClickBlockParams = ClickBlockParams(), @@ -59,7 +61,7 @@ fun WireTertiaryIconButton( Icon( painter = painterResource(id = iconResource), contentDescription = stringResource(contentDescription), - modifier = Modifier.size(dimensions().wireIconButtonSize) + modifier = Modifier.size(iconSize) ) }, shape = shape, diff --git a/core/ui-common/src/main/kotlin/com/wire/android/ui/theme/WireDimensions.kt b/core/ui-common/src/main/kotlin/com/wire/android/ui/theme/WireDimensions.kt index 35cc799c451..ed4b93454a6 100644 --- a/core/ui-common/src/main/kotlin/com/wire/android/ui/theme/WireDimensions.kt +++ b/core/ui-common/src/main/kotlin/com/wire/android/ui/theme/WireDimensions.kt @@ -174,7 +174,10 @@ data class WireDimensions( val groupButtonHeight: Dp, // Calling val defaultCallingControlsSize: Dp, - val defaultCallingHangUpButtonSize: Dp, + val defaultCallingControlsIconSize: Dp, + val bigCallingControlsSize: Dp, + val bigCallingHangUpButtonIconSize: Dp, + val bigCallingAcceptButtonIconSize: Dp, val defaultSheetPeekHeight: Dp, val defaultOutgoingCallSheetPeekHeight: Dp, val onGoingCallUserAvatarSize: Dp, @@ -183,7 +186,6 @@ data class WireDimensions( val outgoingCallUserAvatarSize: Dp, val defaultIncomingCallSheetPeekHeight: Dp, val callingIncomingUserAvatarSize: Dp, - val outgoingCallHangUpButtonSize: Dp, val ongoingCallLabelHeight: Dp, // Message item val messageItemBottomPadding: Dp, @@ -322,7 +324,10 @@ private val DefaultPhonePortraitWireDimensions: WireDimensions = WireDimensions( systemMessageIconLargeSize = 18.dp, groupButtonHeight = 82.dp, defaultCallingControlsSize = 56.dp, - defaultCallingHangUpButtonSize = 56.dp, + defaultCallingControlsIconSize = 20.dp, + bigCallingControlsSize = 72.dp, + bigCallingHangUpButtonIconSize = 32.dp, + bigCallingAcceptButtonIconSize = 24.dp, defaultSheetPeekHeight = 100.dp, defaultOutgoingCallSheetPeekHeight = 281.dp, onGoingCallUserAvatarSize = 90.dp, @@ -331,7 +336,6 @@ private val DefaultPhonePortraitWireDimensions: WireDimensions = WireDimensions( outgoingCallUserAvatarSize = 128.dp, defaultIncomingCallSheetPeekHeight = 280.dp, callingIncomingUserAvatarSize = 128.dp, - outgoingCallHangUpButtonSize = 72.dp, messageItemBottomPadding = 6.dp, messageItemHorizontalPadding = 12.dp, conversationOptionsItemMinHeight = 57.dp,