Bug 1840338 - Add review quality info card to review product analysis.

fenix/118.0
Noah Bond 10 months ago committed by mergify[bot]
parent 08431e4a8b
commit ee4f30518f

@ -12,10 +12,10 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.sp
import org.mozilla.fenix.theme.FirefoxTheme
/**
@ -32,6 +32,7 @@ import org.mozilla.fenix.theme.FirefoxTheme
@Composable
fun ClickableSubstringLink(
text: String,
textStyle: TextStyle = FirefoxTheme.typography.caption,
textColor: Color = FirefoxTheme.colors.textPrimary,
linkTextColor: Color = FirefoxTheme.colors.textAccent,
linkTextDecoration: TextDecoration? = null,
@ -63,12 +64,6 @@ fun ClickableSubstringLink(
end = text.length,
)
addStyle(
SpanStyle(fontSize = 12.sp),
start = 0,
end = clickableEndIndex,
)
addStringAnnotation(
tag = "link",
annotation = "",
@ -79,6 +74,7 @@ fun ClickableSubstringLink(
ClickableText(
text = annotatedText,
style = textStyle,
onClick = {
annotatedText
.getStringAnnotations("link", it, it)

@ -34,6 +34,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import org.mozilla.fenix.R
import org.mozilla.fenix.compose.ClickableSubstringLink
import org.mozilla.fenix.compose.SwitchWithLabel
import org.mozilla.fenix.compose.annotation.LightDarkPreview
import org.mozilla.fenix.compose.button.SecondaryButton
@ -51,6 +52,7 @@ import org.mozilla.fenix.theme.FirefoxTheme
* @param onOptOutClick Invoked when the user opts out of the review quality check feature.
* @param onProductRecommendationsEnabledStateChange Invoked when the user changes the product
* recommendations toggle state.
* @param onReviewGradeLearnMoreClick Invoked when the user clicks to learn more about review grades.
* @param modifier The modifier to be applied to the Composable.
*/
@Composable
@ -59,6 +61,7 @@ fun ProductAnalysis(
productAnalysis: AnalysisPresent,
onOptOutClick: () -> Unit,
onProductRecommendationsEnabledStateChange: (Boolean) -> Unit,
onReviewGradeLearnMoreClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Column(
@ -93,6 +96,16 @@ fun ProductAnalysis(
)
}
ReviewQualityCheckExpandableCard(
title = stringResource(id = R.string.review_quality_check_info_title),
modifier = Modifier.fillMaxWidth(),
) {
ReviewQualityInfo(
modifier = Modifier.fillMaxWidth(),
onLearnMoreClick = onReviewGradeLearnMoreClick,
)
}
SettingsCard(
modifier = Modifier.fillMaxWidth(),
productRecommendationsEnabled = productRecommendationsEnabled,
@ -307,6 +320,95 @@ private fun SettingsCard(
}
}
@Composable
private fun ReviewQualityInfo(
modifier: Modifier = Modifier,
onLearnMoreClick: () -> Unit,
) {
Column(
modifier = modifier,
verticalArrangement = Arrangement.spacedBy(24.dp),
) {
// Any and all text formatting (bullets, inline substring bolding, etc.) will be handled as
// follow-up when the copy is finalized.
// Bug 1848219
Text(
text = stringResource(id = R.string.review_quality_check_info_overview),
color = FirefoxTheme.colors.textPrimary,
style = FirefoxTheme.typography.body2,
)
val link = stringResource(R.string.review_quality_check_info_learn_more_link)
val text = stringResource(R.string.review_quality_check_info_learn_more, link)
val linkStartIndex = text.indexOf(link)
val linkEndIndex = linkStartIndex + link.length
ClickableSubstringLink(
text = text,
textStyle = FirefoxTheme.typography.body2,
clickableStartIndex = linkStartIndex,
clickableEndIndex = linkEndIndex,
onClick = onLearnMoreClick,
)
Text(
text = stringResource(id = R.string.review_quality_check_info_review_grade_header),
color = FirefoxTheme.colors.textPrimary,
style = FirefoxTheme.typography.body2,
)
ReviewGradingScaleInfo(
reviewGrades = listOf(
ReviewQualityCheckState.Grade.A,
ReviewQualityCheckState.Grade.B,
),
info = stringResource(id = R.string.review_quality_check_info_grade_info_AB),
modifier = Modifier.fillMaxWidth(),
)
ReviewGradingScaleInfo(
reviewGrades = listOf(ReviewQualityCheckState.Grade.C),
info = stringResource(id = R.string.review_quality_check_info_grade_info_C),
modifier = Modifier.fillMaxWidth(),
)
ReviewGradingScaleInfo(
reviewGrades = listOf(
ReviewQualityCheckState.Grade.D,
ReviewQualityCheckState.Grade.F,
),
info = stringResource(id = R.string.review_quality_check_info_grade_info_DF),
modifier = Modifier.fillMaxWidth(),
)
}
}
@Composable
private fun ReviewGradingScaleInfo(
reviewGrades: List<ReviewQualityCheckState.Grade>,
info: String,
modifier: Modifier = Modifier,
) {
Row(
modifier = modifier.semantics(mergeDescendants = true) {},
verticalAlignment = Alignment.Top,
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
reviewGrades.forEach { grade ->
ReviewGradeCompact(grade = grade)
}
if (reviewGrades.size == 1) {
Spacer(modifier = Modifier.width(24.dp))
}
Text(
text = info,
color = FirefoxTheme.colors.textPrimary,
style = FirefoxTheme.typography.body2,
)
}
}
private fun HighlightType.toHighlight() =
when (this) {
HighlightType.QUALITY -> Highlight.QUALITY
@ -392,6 +494,25 @@ private fun ProductAnalysisPreview() {
onProductRecommendationsEnabledStateChange = {
productRecommendationsEnabled.value = it
},
onReviewGradeLearnMoreClick = {},
)
}
}
}
@Composable
@LightDarkPreview
private fun ReviewQualityInfoPreview() {
FirefoxTheme {
Box(
modifier = Modifier
.fillMaxWidth()
.background(color = FirefoxTheme.colors.layer1)
.padding(all = 16.dp),
) {
ReviewQualityInfo(
modifier = Modifier.fillMaxWidth(),
onLearnMoreClick = {},
)
}
}

@ -54,6 +54,9 @@ fun ReviewQualityCheckBottomSheet(
onProductRecommendationsEnabledStateChange = {
store.dispatch(ReviewQualityCheckAction.ToggleProductRecommendation)
},
onReviewGradeLearnMoreClick = {
// Bug 1847740
},
)
}
@ -67,6 +70,7 @@ private fun ProductReview(
state: ReviewQualityCheckState.OptedIn,
onOptOutClick: () -> Unit,
onProductRecommendationsEnabledStateChange: (Boolean) -> Unit,
onReviewGradeLearnMoreClick: () -> Unit,
) {
Crossfade(
targetState = state.productReviewState,
@ -79,6 +83,7 @@ private fun ProductReview(
productAnalysis = productReviewState,
onOptOutClick = onOptOutClick,
onProductRecommendationsEnabledStateChange = onProductRecommendationsEnabledStateChange,
onReviewGradeLearnMoreClick = onReviewGradeLearnMoreClick,
)
}

@ -139,4 +139,20 @@
<string name="review_quality_check_highlights_type_shipping" translatable="false">Shipping</string>
<string name="review_quality_check_highlights_type_packaging_appearance" translatable="false">Packaging and appearance</string>
<string name="review_quality_check_highlights_type_competitiveness" translatable="false">Competitiveness</string>
<string name="review_quality_check_info_title" translatable="false">How reliable are the reviews?</string>
<string name="review_quality_check_info_overview" translatable="false">Firefox uses AI technology from Fakespot to analyze the quality and reliability of product reviews. This is only provided to help you assess review quality, not product quality.\n
\n
We assign each products reviews a letter grade from A to F.\n
\n
A higher grade means we believe the reviews are likely from real customers who left honest, unbiased reviews. \n
A lower grade means we believe the reviews are likely from paid or biased reviewers.
\n\nThe adjusted rating is based on review quality, with unreliable reviews removed.
\n\nHelpful snippets are pulled from recent Amazon reviews (from the last 80 days), that we believe to be reliable.</string>
<string name="review_quality_check_info_learn_more" translatable="false">Learn more about %s</string>
<string name="review_quality_check_info_learn_more_link" translatable="false">how Fakespot determines review quality.</string>
<string name="review_quality_check_info_review_grade_header" translatable="false">Review grading scale:</string>
<string name="review_quality_check_info_grade_info_AB" translatable="false">We believe the reviews to be reliable</string>
<string name="review_quality_check_info_grade_info_C" translatable="false">We believe theres a mix of reliable and unreliable reviews</string>
<string name="review_quality_check_info_grade_info_DF" translatable="false">We believe the reviews are unreliable</string>
</resources>

Loading…
Cancel
Save