mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-19 16:19:33 +01:00
Add the call quality diagnostics fragment.
This commit is contained in:
@@ -76,6 +76,12 @@ class CallQualityBottomSheetFragment : ComposeBottomSheetDialogFragment() {
|
||||
)
|
||||
}
|
||||
|
||||
override fun viewDiagnostics() {
|
||||
CallQualityDiagnosticsFragment.create(
|
||||
viewModel.getRequestSnapshot()
|
||||
).show(parentFragmentManager, null)
|
||||
}
|
||||
|
||||
override fun onUserSatisfiedWithCall(isUserSatisfiedWithCall: Boolean) {
|
||||
viewModel.setUserSatisfiedWithCall(isUserSatisfiedWithCall)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2026 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.calls.quality
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.core.os.bundleOf
|
||||
import org.signal.storageservice.protos.calls.quality.SubmitCallQualitySurveyRequest
|
||||
import org.thoughtcrime.securesms.compose.ComposeFullScreenDialogFragment
|
||||
|
||||
class CallQualityDiagnosticsFragment : ComposeFullScreenDialogFragment() {
|
||||
|
||||
companion object {
|
||||
private const val REQUEST_KEY = "CallQualityDiagnosticsRequestKey"
|
||||
|
||||
fun create(request: SubmitCallQualitySurveyRequest): CallQualityDiagnosticsFragment {
|
||||
return CallQualityDiagnosticsFragment().apply {
|
||||
arguments = bundleOf(REQUEST_KEY to request.encode())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val callQualitySurveyRequest: SubmitCallQualitySurveyRequest by lazy {
|
||||
val bytes = requireArguments().getByteArray(REQUEST_KEY)!!
|
||||
SubmitCallQualitySurveyRequest.ADAPTER.decode(bytes)
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun DialogContent() {
|
||||
CallQualityDiagnosticsScreen(
|
||||
callQualitySurveyRequest = callQualitySurveyRequest,
|
||||
onNavigationClick = { requireActivity().onBackPressedDispatcher.onBackPressed() }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2026 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.calls.quality
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.signal.core.ui.compose.Buttons
|
||||
import org.signal.core.ui.compose.DayNightPreviews
|
||||
import org.signal.core.ui.compose.Previews
|
||||
import org.signal.core.ui.compose.Scaffolds
|
||||
import org.signal.core.ui.compose.horizontalGutters
|
||||
import org.signal.storageservice.protos.calls.quality.SubmitCallQualitySurveyRequest
|
||||
import org.thoughtcrime.securesms.R
|
||||
|
||||
@Composable
|
||||
fun CallQualityDiagnosticsScreen(
|
||||
callQualitySurveyRequest: SubmitCallQualitySurveyRequest,
|
||||
onNavigationClick: () -> Unit = {}
|
||||
) {
|
||||
Scaffolds.Settings(
|
||||
title = stringResource(R.string.CallQualityDiagnosticsScreen__diagnostic_information),
|
||||
navigationIcon = ImageVector.vectorResource(R.drawable.symbol_arrow_start_24),
|
||||
navigationContentDescription = stringResource(R.string.CallQualityDiagnosticsScreen__close),
|
||||
onNavigationClick = onNavigationClick
|
||||
) {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
.padding(it)
|
||||
.fillMaxSize()
|
||||
.horizontalGutters()
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
Text(
|
||||
text = callQualitySurveyRequest.toString().substringAfter(SubmitCallQualitySurveyRequest::class.simpleName ?: "")
|
||||
)
|
||||
}
|
||||
|
||||
Buttons.LargeTonal(
|
||||
onClick = onNavigationClick,
|
||||
modifier = Modifier
|
||||
.padding(top = 10.dp, bottom = 24.dp)
|
||||
.widthIn(min = 256.dp)
|
||||
) {
|
||||
Text(text = stringResource(R.string.CallQualityDiagnosticsScreen__close))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DayNightPreviews
|
||||
@Composable
|
||||
private fun CallQualityDiagnosticsScreenPreview() {
|
||||
Previews.Preview {
|
||||
CallQualityDiagnosticsScreen(
|
||||
callQualitySurveyRequest = SubmitCallQualitySurveyRequest()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -58,6 +58,10 @@ class CallQualityScreenViewModel(
|
||||
return
|
||||
}
|
||||
|
||||
AppDependencies.jobManager.add(CallQualitySurveySubmissionJob(getRequestSnapshot(), state.value.isShareDebugLogSelected))
|
||||
}
|
||||
|
||||
fun getRequestSnapshot(): SubmitCallQualitySurveyRequest {
|
||||
val stateSnapshot = state.value
|
||||
val somethingElseDescription: String? = if (stateSnapshot.selectedQualityIssues.contains(CallQualityIssue.SOMETHING_ELSE)) {
|
||||
stateSnapshot.somethingElseDescription.takeIf { it.isNotEmpty() }
|
||||
@@ -65,12 +69,10 @@ class CallQualityScreenViewModel(
|
||||
null
|
||||
}
|
||||
|
||||
val requestToSubmitToJob = initialRequest.newBuilder()
|
||||
return initialRequest.newBuilder()
|
||||
.user_satisfied(stateSnapshot.isUserSatisfiedWithCall)
|
||||
.call_quality_issues(stateSnapshot.selectedQualityIssues.map { it.code })
|
||||
.additional_issues_description(somethingElseDescription)
|
||||
.build()
|
||||
|
||||
AppDependencies.jobManager.add(CallQualitySurveySubmissionJob(requestToSubmitToJob, stateSnapshot.isShareDebugLogSelected))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,6 +141,7 @@ fun CallQualitySheet(
|
||||
CallQualitySheetNavEntry.HelpUsImprove -> HelpUsImprove(
|
||||
isShareDebugLogSelected = state.isShareDebugLogSelected,
|
||||
onViewDebugLogClick = callback::viewDebugLog,
|
||||
onViewDiagnosticsClick = callback::viewDiagnostics,
|
||||
onCancelClick = callback::dismiss,
|
||||
onShareDebugLogChanged = callback::onShareDebugLogChanged,
|
||||
onSubmitClick = callback::submit
|
||||
@@ -431,6 +432,7 @@ private fun IssueChip(
|
||||
private fun HelpUsImprove(
|
||||
isShareDebugLogSelected: Boolean,
|
||||
onShareDebugLogChanged: (Boolean) -> Unit,
|
||||
onViewDiagnosticsClick: () -> Unit,
|
||||
onViewDebugLogClick: () -> Unit,
|
||||
onCancelClick: () -> Unit,
|
||||
onSubmitClick: () -> Unit
|
||||
@@ -443,12 +445,12 @@ private fun HelpUsImprove(
|
||||
|
||||
withLink(
|
||||
link = LinkAnnotation.Clickable(
|
||||
"view-your-debug-log",
|
||||
linkInteractionListener = { onViewDebugLogClick() },
|
||||
"view-diagnostics",
|
||||
linkInteractionListener = { onViewDiagnosticsClick() },
|
||||
styles = TextLinkStyles(style = SpanStyle(color = MaterialTheme.colorScheme.primary))
|
||||
)
|
||||
) {
|
||||
append(stringResource(R.string.CallQualitySheet__view_your_debug_log))
|
||||
append(stringResource(R.string.CallQualitySheet__diagnostic_information_about_your_call))
|
||||
}
|
||||
|
||||
append(" ")
|
||||
@@ -463,7 +465,20 @@ private fun HelpUsImprove(
|
||||
)
|
||||
|
||||
Text(
|
||||
text = stringResource(R.string.CallQualitySheet__debug_log_privacy_notice),
|
||||
text = buildAnnotatedString {
|
||||
append(stringResource(R.string.CallQualitySheet__information_shared_with_us))
|
||||
append(" ")
|
||||
|
||||
withLink(
|
||||
link = LinkAnnotation.Clickable(
|
||||
"view-debug-log",
|
||||
linkInteractionListener = { onViewDebugLogClick() },
|
||||
styles = TextLinkStyles(style = SpanStyle(color = MaterialTheme.colorScheme.primary))
|
||||
)
|
||||
) {
|
||||
append(stringResource(R.string.CallQualitySheet__view_debug_log))
|
||||
}
|
||||
},
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier
|
||||
@@ -688,6 +703,7 @@ private fun HelpUsImprovePreview() {
|
||||
Column {
|
||||
HelpUsImprove(
|
||||
isShareDebugLogSelected = true,
|
||||
onViewDiagnosticsClick = {},
|
||||
onViewDebugLogClick = {},
|
||||
onCancelClick = {},
|
||||
onShareDebugLogChanged = {},
|
||||
@@ -728,6 +744,7 @@ data class CallQualitySheetState(
|
||||
interface CallQualitySheetCallback {
|
||||
fun dismiss()
|
||||
fun viewDebugLog()
|
||||
fun viewDiagnostics()
|
||||
fun onUserSatisfiedWithCall(isUserSatisfiedWithCall: Boolean)
|
||||
fun describeYourIssue()
|
||||
fun onCallQualityIssueSelectionChanged(selection: Set<CallQualityIssue>)
|
||||
@@ -738,6 +755,7 @@ interface CallQualitySheetCallback {
|
||||
object Empty : CallQualitySheetCallback {
|
||||
override fun dismiss() = Unit
|
||||
override fun viewDebugLog() = Unit
|
||||
override fun viewDiagnostics() = Unit
|
||||
override fun onUserSatisfiedWithCall(isUserSatisfiedWithCall: Boolean) = Unit
|
||||
override fun describeYourIssue() = Unit
|
||||
override fun onCallQualityIssueSelectionChanged(selection: Set<CallQualityIssue>) = Unit
|
||||
|
||||
Reference in New Issue
Block a user