From 6594b8532ec9748202183b7bd58d67e5b81cee9a Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Wed, 3 Dec 2025 16:22:57 -0400 Subject: [PATCH] Call quality icons and config rotation. --- .../securesms/calls/quality/CallQuality.kt | 2 +- .../quality/CallQualityScreenViewModel.kt | 10 +++++++++ .../calls/quality/CallQualityScreens.kt | 21 ++++++++++++++----- .../app/internal/InternalSettingsFragment.kt | 11 ++++++---- .../app/internal/InternalSettingsState.kt | 1 - .../app/internal/InternalSettingsViewModel.kt | 6 ------ .../securesms/keyvalue/InternalValues.kt | 3 --- .../securesms/util/RemoteConfig.kt | 2 +- .../res/drawable/symbol_thumbs_down_24.xml | 9 ++++++++ .../main/res/drawable/symbol_thumbs_up_24.xml | 9 ++++++++ app/src/main/res/values/strings.xml | 4 ++++ 11 files changed, 57 insertions(+), 21 deletions(-) create mode 100644 app/src/main/res/drawable/symbol_thumbs_down_24.xml create mode 100644 app/src/main/res/drawable/symbol_thumbs_up_24.xml diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/quality/CallQuality.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/quality/CallQuality.kt index 7ed93bfee1..fa3dff2669 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/quality/CallQuality.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/quality/CallQuality.kt @@ -125,7 +125,7 @@ object CallQuality { } private fun isFeatureEnabled(): Boolean { - return (RemoteConfig.callQualitySurvey || SignalStore.internal.callQualitySurveys) && SignalStore.callQuality.isQualitySurveyEnabled + return RemoteConfig.callQualitySurvey && SignalStore.callQuality.isQualitySurveyEnabled } private enum class CallType(val code: String) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/quality/CallQualityScreenViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/quality/CallQualityScreenViewModel.kt index cf9a5ac450..ad7d39c538 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/quality/CallQualityScreenViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/quality/CallQualityScreenViewModel.kt @@ -9,6 +9,7 @@ import androidx.lifecycle.ViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.update +import org.signal.core.util.logging.Log import org.signal.storageservice.protos.calls.quality.SubmitCallQualitySurveyRequest import org.thoughtcrime.securesms.dependencies.AppDependencies import org.thoughtcrime.securesms.jobs.CallQualitySurveySubmissionJob @@ -17,6 +18,10 @@ class CallQualityScreenViewModel( val initialRequest: SubmitCallQualitySurveyRequest ) : ViewModel() { + companion object { + private val TAG = Log.tag(CallQualityScreenViewModel::class) + } + private val internalState = MutableStateFlow(CallQualitySheetState()) val state: StateFlow = internalState @@ -37,6 +42,11 @@ class CallQualityScreenViewModel( } fun submit() { + if (initialRequest.call_type.isEmpty()) { + Log.i(TAG, "Ignoring survey submission for blank call_type.") + return + } + val stateSnapshot = state.value val somethingElseDescription: String? = if (stateSnapshot.selectedQualityIssues.contains(CallQualityIssue.SOMETHING_ELSE)) { stateSnapshot.somethingElseDescription.takeIf { it.isNotEmpty() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/calls/quality/CallQualityScreens.kt b/app/src/main/java/org/thoughtcrime/securesms/calls/quality/CallQualityScreens.kt index 381a4d0a40..d51a57fcb9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/calls/quality/CallQualityScreens.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/calls/quality/CallQualityScreens.kt @@ -27,6 +27,7 @@ import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.ExperimentalMaterial3Api @@ -556,7 +557,9 @@ private fun HadIssuesButton( text = stringResource(R.string.CallQualitySheet__had_issues), containerColor = MaterialTheme.colorScheme.errorContainer, contentColor = MaterialTheme.colorScheme.error, - onClick = onClick + onClick = onClick, + contentDescription = stringResource(R.string.CallQualitySheet__had_issues_content_description), + imageVector = ImageVector.vectorResource(R.drawable.symbol_thumbs_down_24) ) } @@ -568,7 +571,9 @@ private fun GreatButton( text = stringResource(R.string.CallQualitySheet__great), containerColor = MaterialTheme.colorScheme.primaryContainer, contentColor = MaterialTheme.colorScheme.primary, - onClick = onClick + onClick = onClick, + contentDescription = stringResource(R.string.CallQualitySheet__great_content_description), + imageVector = ImageVector.vectorResource(R.drawable.symbol_thumbs_up_24) ) } @@ -577,8 +582,9 @@ private fun FeedbackButton( text: String, onClick: () -> Unit, containerColor: Color, - contentColor: Color - // imageVector icon + contentColor: Color, + imageVector: ImageVector, + contentDescription: String ) { Column( horizontalAlignment = Alignment.CenterHorizontally, @@ -591,7 +597,12 @@ private fun FeedbackButton( .clip(CircleShape) .background(color = containerColor) ) { - // TODO - icon with contentcolor tint + Icon( + imageVector = imageVector, + contentDescription = contentDescription, + tint = contentColor, + modifier = Modifier.size(36.dp) + ) } Text( diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt index 6278ff03c7..e9961f9885 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt @@ -23,6 +23,7 @@ import org.signal.core.util.readToList import org.signal.core.util.requireLong import org.signal.core.util.requireString import org.signal.ringrtc.CallManager +import org.signal.storageservice.protos.calls.quality.SubmitCallQualitySurveyRequest import org.thoughtcrime.securesms.BuildConfig import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.calls.quality.CallQualityBottomSheetFragment @@ -59,6 +60,7 @@ import org.thoughtcrime.securesms.payments.DataExportUtil import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.storage.StorageSyncHelper +import org.thoughtcrime.securesms.util.BottomSheetUtil import org.thoughtcrime.securesms.util.ConversationUtil import org.thoughtcrime.securesms.util.Util import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter @@ -580,11 +582,12 @@ class InternalSettingsFragment : DSLSettingsFragment(R.string.preferences__inter } ) - switchPref( - title = DSLSettingsText.from("Enable call quality surveys"), - isChecked = state.callQualitySurveys, + clickPref( + title = DSLSettingsText.from("Display call quality survey"), onClick = { - viewModel.setEnableCallQualitySurveys(!state.callQualitySurveys) + CallQualityBottomSheetFragment + .create(SubmitCallQualitySurveyRequest()) + .show(parentFragmentManager, BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG) } ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsState.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsState.kt index f577846f3c..138bcfc987 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsState.kt @@ -31,6 +31,5 @@ data class InternalSettingsState( val hasPendingOneTimeDonation: Boolean, val hevcEncoding: Boolean, val newCallingUi: Boolean, - val callQualitySurveys: Boolean, val forceSplitPane: Boolean ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsViewModel.kt index 2c2266a008..c8d6fbf639 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsViewModel.kt @@ -197,7 +197,6 @@ class InternalSettingsViewModel(private val repository: InternalSettingsReposito hasPendingOneTimeDonation = SignalStore.inAppPayments.getPendingOneTimeDonation() != null, hevcEncoding = SignalStore.internal.hevcEncoding, newCallingUi = SignalStore.internal.newCallingUi, - callQualitySurveys = SignalStore.internal.callQualitySurveys, forceSplitPane = SignalStore.internal.forceSplitPane ) @@ -214,11 +213,6 @@ class InternalSettingsViewModel(private val repository: InternalSettingsReposito refresh() } - fun setEnableCallQualitySurveys(enabled: Boolean) { - SignalStore.internal.callQualitySurveys = enabled - refresh() - } - fun setForceSplitPane(forceSplitPane: Boolean) { SignalStore.internal.forceSplitPane = forceSplitPane refresh() diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/InternalValues.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/InternalValues.kt index b37e460b6c..060994193f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/InternalValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/InternalValues.kt @@ -32,7 +32,6 @@ class InternalValues internal constructor(store: KeyValueStore) : SignalStoreVal const val WEB_SOCKET_SHADOWING_STATS: String = "internal.web_socket_shadowing_stats" const val ENCODE_HEVC: String = "internal.hevc_encoding" const val NEW_CALL_UI: String = "internal.new.call.ui" - const val CALL_QUALITY_SURVEYS: String = "internal.call_quality_surveys" const val FORCE_SPLIT_PANE_ON_COMPACT_LANDSCAPE: String = "internal.force.split.pane.on.compact.landscape.ui" const val SHOW_ARCHIVE_STATE_HINT: String = "internal.show_archive_state_hint" const val INCLUDE_DEBUGLOG_IN_BACKUP: String = "internal.include_debuglog_in_backup" @@ -171,8 +170,6 @@ class InternalValues internal constructor(store: KeyValueStore) : SignalStoreVal var newCallingUi: Boolean by booleanValue(NEW_CALL_UI, false).defaultForExternalUsers() - var callQualitySurveys: Boolean by booleanValue(CALL_QUALITY_SURVEYS, false).defaultForExternalUsers() - var lastScrollPosition: Int by integerValue(LAST_SCROLL_POSITION, 0).defaultForExternalUsers() var useConversationItemV2Media by booleanValue(CONVERSATION_ITEM_V2_MEDIA, false).defaultForExternalUsers() diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/RemoteConfig.kt b/app/src/main/java/org/thoughtcrime/securesms/util/RemoteConfig.kt index 1312e2abd1..dc9d7d41a5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/RemoteConfig.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/RemoteConfig.kt @@ -1233,7 +1233,7 @@ object RemoteConfig { @JvmStatic @get:JvmName("callQualitySurvey") val callQualitySurvey: Boolean by remoteBoolean( - key = "android.callQualitySurvey", + key = "android.callQualitySurvey.2", defaultValue = false, hotSwappable = true ) diff --git a/app/src/main/res/drawable/symbol_thumbs_down_24.xml b/app/src/main/res/drawable/symbol_thumbs_down_24.xml new file mode 100644 index 0000000000..a2165d097a --- /dev/null +++ b/app/src/main/res/drawable/symbol_thumbs_down_24.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/symbol_thumbs_up_24.xml b/app/src/main/res/drawable/symbol_thumbs_up_24.xml new file mode 100644 index 0000000000..c258149f6e --- /dev/null +++ b/app/src/main/res/drawable/symbol_thumbs_up_24.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 868d191679..bd90f481b5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -9025,6 +9025,10 @@ Submit Thanks for your feedback! + + I had issues with the call + + The call was great %1$s pinned a message