From fb402ac4ebfc1549b21fae5ff9b78b81bfbbe452 Mon Sep 17 00:00:00 2001 From: Dmitry Brant Date: Wed, 21 Feb 2024 12:20:58 -0500 Subject: [PATCH] Underpinnings for Revert Risk instead of ORES scores. --- .../dataclient/mwapi/MwQueryResult.kt | 11 +++--- .../diff/ArticleEditDetailsFragment.kt | 36 ++++++++----------- ...SuggestedEditsRecentEditsFilterActivity.kt | 5 +-- .../SuggestedEditsRecentEditsFilterTypes.kt | 13 ++----- .../SuggestedEditsRecentEditsViewModel.kt | 17 ++++----- .../layout/fragment_article_edit_details.xml | 15 ++------ app/src/main/res/values-qq/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 8 files changed, 33 insertions(+), 66 deletions(-) diff --git a/app/src/main/java/org/wikipedia/dataclient/mwapi/MwQueryResult.kt b/app/src/main/java/org/wikipedia/dataclient/mwapi/MwQueryResult.kt index 46324ed268e..bac310c8b8d 100644 --- a/app/src/main/java/org/wikipedia/dataclient/mwapi/MwQueryResult.kt +++ b/app/src/main/java/org/wikipedia/dataclient/mwapi/MwQueryResult.kt @@ -227,15 +227,12 @@ class MwQueryResult { @Serializable class OresResult { - private val damaging: OresItem? = null - private val goodfaith: OresItem? = null - + private val revertrisklanguageagnostic: OresItem? = null // TODO: articlequality // TODO: draftquality - val damagingProb: Float - get() = damaging?.trueProb ?: 0f - val goodfaithProb: Float - get() = goodfaith?.trueProb ?: 0f + + val revertRisk: Float + get() = revertrisklanguageagnostic?.trueProb ?: 0f } @Serializable diff --git a/app/src/main/java/org/wikipedia/diff/ArticleEditDetailsFragment.kt b/app/src/main/java/org/wikipedia/diff/ArticleEditDetailsFragment.kt index 6d614b431b5..c33024b165a 100644 --- a/app/src/main/java/org/wikipedia/diff/ArticleEditDetailsFragment.kt +++ b/app/src/main/java/org/wikipedia/diff/ArticleEditDetailsFragment.kt @@ -110,14 +110,13 @@ class ArticleEditDetailsFragment : Fragment(), WatchlistExpiryDialog.Callback, M } } - private val sequentialTooltipRunnable = Runnable { + private val revertRiskTooltipRunnable = Runnable { if (!isAdded) { return@Runnable } sendPatrollerExperienceEvent("impression", "pt_tooltip") - val balloon = FeedbackUtil.getTooltip(requireContext(), getString(R.string.patroller_diff_tooltip_one), autoDismiss = true, showDismissButton = true, dismissButtonText = R.string.image_recommendation_tooltip_next, countNum = 1, countTotal = 2) - balloon.showAlignBottom(binding.oresDamagingButton) - balloon.relayShowAlignBottom(FeedbackUtil.getTooltip(requireContext(), getString(R.string.patroller_diff_tooltip_two), autoDismiss = true, showDismissButton = true, countNum = 2, countTotal = 2), binding.oresGoodFaithButton) + FeedbackUtil.getTooltip(requireContext(), getString(R.string.patroller_diff_tooltip_one), autoDismiss = true, showDismissButton = true) + .showAlignBottom(binding.revertRiskButton) } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { @@ -263,7 +262,7 @@ class ArticleEditDetailsFragment : Fragment(), WatchlistExpiryDialog.Callback, M override fun onDestroyView() { binding.appBarLayout.removeOnOffsetChangedListener(actionBarOffsetChangedListener) - binding.root.removeCallbacks(sequentialTooltipRunnable) + binding.root.removeCallbacks(revertRiskTooltipRunnable) _binding = null super.onDestroyView() } @@ -412,11 +411,11 @@ class ArticleEditDetailsFragment : Fragment(), WatchlistExpiryDialog.Callback, M private fun maybeShowOneTimeSequentialRecentEditsTooltips() { if (Prefs.showOneTimeSequentialRecentEditsDiffTooltip && viewModel.fromRecentEdits && - binding.oresDamagingButton.isVisible && binding.oresGoodFaithButton.isVisible && + binding.revertRiskButton.isVisible && parentFragment == FragmentUtil.getAncestor(this, SuggestedEditsCardsFragment::class.java)?.topBaseChild()) { Prefs.showOneTimeSequentialRecentEditsDiffTooltip = false - binding.root.removeCallbacks(sequentialTooltipRunnable) - binding.root.postDelayed(sequentialTooltipRunnable, 500) + binding.root.removeCallbacks(revertRiskTooltipRunnable) + binding.root.postDelayed(revertRiskTooltipRunnable, 500) } } @@ -471,8 +470,7 @@ class ArticleEditDetailsFragment : Fragment(), WatchlistExpiryDialog.Callback, M } binding.overlayRevisionFromTimestamp.text = binding.revisionFromTimestamp.text - binding.oresDamagingButton.isVisible = false - binding.oresGoodFaithButton.isVisible = false + binding.revertRiskButton.isVisible = false viewModel.revisionTo?.let { binding.usernameToButton.text = it.user @@ -480,13 +478,10 @@ class ArticleEditDetailsFragment : Fragment(), WatchlistExpiryDialog.Callback, M binding.overlayRevisionToTimestamp.text = binding.revisionToTimestamp.text binding.revisionToEditComment.text = StringUtil.fromHtml(it.parsedcomment.trim()) - if (it.ores != null && viewModel.fromRecentEdits) { - binding.oresDamagingButton.isVisible = true - binding.oresDamagingButton.text = getString(R.string.edit_damage, ((it.ores?.damagingProb ?: 0f) * 100f).toInt().toString().plus("%")) - binding.oresDamagingButton.setOnClickListener(openQualityAndIntentFiltersPage) - binding.oresGoodFaithButton.isVisible = true - binding.oresGoodFaithButton.text = getString(R.string.edit_intent, ((it.ores?.goodfaithProb ?: 0f) * 100f).toInt().toString().plus("%")) - binding.oresGoodFaithButton.setOnClickListener(openQualityAndIntentFiltersPage) + if (it.ores != null) { + binding.revertRiskButton.isVisible = true + binding.revertRiskButton.text = getString(R.string.edit_revert_risk, ((it.ores?.revertRisk ?: 0f) * 100f).toInt().toString().plus("%")) + binding.revertRiskButton.setOnClickListener(openQualityAndIntentFiltersPage) maybeShowOneTimeSequentialRecentEditsTooltips() } @@ -506,11 +501,8 @@ class ArticleEditDetailsFragment : Fragment(), WatchlistExpiryDialog.Callback, M } private val openQualityAndIntentFiltersPage = View.OnClickListener { view -> - if (view.id == R.id.oresDamagingButton) { - sendPatrollerExperienceEvent("quality_click", "pt_edit") - } else { - sendPatrollerExperienceEvent("intent_click", "pt_edit") - } + sendPatrollerExperienceEvent("revert_risk_click", "pt_edit") + // TODO: correct url: UriUtil.visitInExternalBrowser(requireContext(), Uri.parse(getString(R.string.quality_and_intent_filters_url))) } diff --git a/app/src/main/java/org/wikipedia/suggestededits/SuggestedEditsRecentEditsFilterActivity.kt b/app/src/main/java/org/wikipedia/suggestededits/SuggestedEditsRecentEditsFilterActivity.kt index d1e87b26238..1e65ea07dfc 100644 --- a/app/src/main/java/org/wikipedia/suggestededits/SuggestedEditsRecentEditsFilterActivity.kt +++ b/app/src/main/java/org/wikipedia/suggestededits/SuggestedEditsRecentEditsFilterActivity.kt @@ -109,14 +109,11 @@ class SuggestedEditsRecentEditsFilterActivity : BaseActivity() { SuggestedEditsRecentEditsFilterTypes.BOT_EDITS_GROUP.forEach { filterListWithHeaders.add(Filter(FILTER_TYPE_CATEGORY, it.id)) } + // TODO: rename to "revert risk": filterListWithHeaders.add(getString(R.string.patroller_tasks_filters_contribution_quality_header)) SuggestedEditsRecentEditsFilterTypes.DAMAGING_GROUP.forEach { filterListWithHeaders.add(Filter(FILTER_TYPE_CATEGORY, it.id, true)) } - filterListWithHeaders.add(getString(R.string.patroller_tasks_filters_user_intent_header)) - SuggestedEditsRecentEditsFilterTypes.GOODFAITH_GROUP.forEach { - filterListWithHeaders.add(Filter(FILTER_TYPE_CATEGORY, it.id, true)) - } filterListWithHeaders.add(getString(R.string.patroller_tasks_filters_significance_header)) SuggestedEditsRecentEditsFilterTypes.MINOR_EDITS_GROUP.forEach { filterListWithHeaders.add(Filter(FILTER_TYPE_CATEGORY, it.id)) diff --git a/app/src/main/java/org/wikipedia/suggestededits/SuggestedEditsRecentEditsFilterTypes.kt b/app/src/main/java/org/wikipedia/suggestededits/SuggestedEditsRecentEditsFilterTypes.kt index 61615d7f146..63fec2e8ba7 100644 --- a/app/src/main/java/org/wikipedia/suggestededits/SuggestedEditsRecentEditsFilterTypes.kt +++ b/app/src/main/java/org/wikipedia/suggestededits/SuggestedEditsRecentEditsFilterTypes.kt @@ -45,16 +45,7 @@ enum class SuggestedEditsRecentEditsFilterTypes constructor(val id: String, DAMAGING_LIKELY_PROBLEMS("damagingLikelyProblems", "0.629|0.944", R.string.patroller_tasks_filters_contribution_quality_likely_problems, R.string.patroller_tasks_filters_contribution_quality_likely_problems_desc), DAMAGING_VERY_LIKELY_PROBLEMS("damagingBad", "0.944|1", - R.string.patroller_tasks_filters_contribution_quality_bad, R.string.patroller_tasks_filters_contribution_quality_bad_desc), - // Only check the goodfaith: { true } score - GOODFAITH_GOOD("goodfaithGood", "0.75|1", - R.string.patroller_tasks_filters_user_intent_good, R.string.patroller_tasks_filters_user_intent_good_desc), - GOODFAITH_MAY_PROBLEMS("goodfaithMayProblems", "0.647|0.75", - R.string.patroller_tasks_filters_user_intent_may_problems, R.string.patroller_tasks_filters_user_intent_may_problems_desc), - GOODFAITH_LIKELY_PROBLEMS("goodfaithLikelyProblems", "0.25|0.647", - R.string.patroller_tasks_filters_user_intent_likely_problems, R.string.patroller_tasks_filters_user_intent_likely_problems_desc), - GOODFAITH_VERY_LIKELY_PROBLEMS("goodfaithBad", "0|0.25", - R.string.patroller_tasks_filters_user_intent_bad, R.string.patroller_tasks_filters_user_intent_bad_desc); + R.string.patroller_tasks_filters_contribution_quality_bad, R.string.patroller_tasks_filters_contribution_quality_bad_desc); override fun code(): Int { // This enumeration is not marshalled so tying declaration order to presentation order is @@ -68,8 +59,8 @@ enum class SuggestedEditsRecentEditsFilterTypes constructor(val id: String, val LATEST_REVISIONS_GROUP = listOf(LATEST_REVISION, NOT_LATEST_REVISION) val USER_REGISTRATION_GROUP = listOf(UNREGISTERED, REGISTERED) val USER_EXPERIENCE_GROUP = listOf(NEWCOMERS, LEARNERS, EXPERIENCED_USERS) + // TODO: rename to "revert risk"? val DAMAGING_GROUP = listOf(DAMAGING_GOOD, DAMAGING_MAY_PROBLEMS, DAMAGING_LIKELY_PROBLEMS, DAMAGING_VERY_LIKELY_PROBLEMS) - val GOODFAITH_GROUP = listOf(GOODFAITH_GOOD, GOODFAITH_MAY_PROBLEMS, GOODFAITH_LIKELY_PROBLEMS, GOODFAITH_VERY_LIKELY_PROBLEMS) // Multiple choice val DEFAULT_FILTER_USER_STATUS = setOf(UNREGISTERED, NEWCOMERS) diff --git a/app/src/main/java/org/wikipedia/suggestededits/SuggestedEditsRecentEditsViewModel.kt b/app/src/main/java/org/wikipedia/suggestededits/SuggestedEditsRecentEditsViewModel.kt index 53d4701028d..8c9e810d1b0 100644 --- a/app/src/main/java/org/wikipedia/suggestededits/SuggestedEditsRecentEditsViewModel.kt +++ b/app/src/main/java/org/wikipedia/suggestededits/SuggestedEditsRecentEditsViewModel.kt @@ -118,8 +118,8 @@ class SuggestedEditsRecentEditsViewModel : ViewModel() { val allRecentChanges = response.query?.recentChanges.orEmpty() - // Filtering Ores damaging and goodfaith - val recentChanges = filterOresScores(filterOresScores(allRecentChanges, true), false) + // Filtering by revert risk + val recentChanges = filterOresScores(allRecentChanges) // Get usernames val usernames = recentChanges.filter { !it.anon }.map { it.user }.distinct().filter { @@ -152,8 +152,7 @@ class SuggestedEditsRecentEditsViewModel : ViewModel() { // Ores related: default is empty val findSelectedOres = Prefs.recentEditsIncludedTypeCodes.subtract(findSelectedUserStatus.toSet()) .filter { code -> - SuggestedEditsRecentEditsFilterTypes.GOODFAITH_GROUP.map { it.id }.contains(code) || - SuggestedEditsRecentEditsFilterTypes.DAMAGING_GROUP.map { it.id }.contains(code) + SuggestedEditsRecentEditsFilterTypes.DAMAGING_GROUP.map { it.id }.contains(code) } // Find the remaining selected filters @@ -195,8 +194,7 @@ class SuggestedEditsRecentEditsViewModel : ViewModel() { } if (includedTypesCodes.any { code -> - SuggestedEditsRecentEditsFilterTypes.GOODFAITH_GROUP.map { it.id }.contains(code) || - SuggestedEditsRecentEditsFilterTypes.DAMAGING_GROUP.map { it.id }.contains(code) }) { + SuggestedEditsRecentEditsFilterTypes.DAMAGING_GROUP.map { it.id }.contains(code) }) { list.add("oresreview") } @@ -266,9 +264,8 @@ class SuggestedEditsRecentEditsViewModel : ViewModel() { return recentChanges } - private fun filterOresScores(recentChanges: List, isDamagingGroup: Boolean): List { - val filterGroupSet = if (isDamagingGroup) SuggestedEditsRecentEditsFilterTypes.DAMAGING_GROUP.map { it.id } - else SuggestedEditsRecentEditsFilterTypes.GOODFAITH_GROUP.map { it.id } + private fun filterOresScores(recentChanges: List): List { + val filterGroupSet = SuggestedEditsRecentEditsFilterTypes.DAMAGING_GROUP.map { it.id } if (Prefs.recentEditsIncludedTypeCodes.any { code -> filterGroupSet.contains(code) }) { val findOresFilters = Prefs.recentEditsIncludedTypeCodes @@ -280,7 +277,7 @@ class SuggestedEditsRecentEditsViewModel : ViewModel() { return recentChanges.filter { it.ores != null }.filter { val scoreRanges = findOresFilters.map { type -> type.value } - val oresScore = if (isDamagingGroup) it.ores?.damagingProb ?: 0f else it.ores?.goodfaithProb ?: 0f + val oresScore = it.ores?.revertRisk ?: 0f scoreRanges.forEach { range -> val scoreRangeArray = range.split("|") val inScoreRange = oresScore >= scoreRangeArray.first().toFloat() && oresScore <= scoreRangeArray.last().toFloat() diff --git a/app/src/main/res/layout/fragment_article_edit_details.xml b/app/src/main/res/layout/fragment_article_edit_details.xml index e211c2e323c..eca5487b046 100644 --- a/app/src/main/res/layout/fragment_article_edit_details.xml +++ b/app/src/main/res/layout/fragment_article_edit_details.xml @@ -251,7 +251,7 @@ android:layout_marginStart="16dp" android:layout_marginTop="6dp" android:layout_marginBottom="8dp" - app:constraint_referenced_ids="oresDamagingButton,oresGoodFaithButton,diffCharacterCountView" + app:constraint_referenced_ids="revertRiskButton,diffCharacterCountView" app:flow_horizontalBias="0" app:flow_horizontalGap="8dp" app:flow_horizontalStyle="packed" @@ -263,22 +263,13 @@ app:layout_constraintTop_toBottomOf="@id/thanksDivider" /> - - + tools:text="Revert risk: 50%"/> Title of the screen of publishing a warn message to a user talk page. Label of the edit damage in the article edit detail page. %s will be replaced by the percentage of edit damage. Label of the edit intent in the article edit detail page. %s will be replaced by the percentage of edit intent. + Label that displays the calculated revert risk of a certain revision. %s will be replaced by the percentage of revert risk. Text for the revisions difference in bytes. %s will be replaced by the positive one or negative one. Text for the revisions difference in bytes. %s will be replaced by the number of bytes. diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c0935d106ff..8f5abda74d2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -268,6 +268,7 @@ Warn Damage %s Intent %s + Revert risk: %s %s byte %s bytes