Merge branch 'main' into 1-issue#5829

This commit is contained in:
Nicolas Raoul 2025-01-11 08:47:44 +09:00 committed by GitHub
commit 045cfa24b3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 293 additions and 37 deletions

View file

@ -50,6 +50,8 @@ dependencies {
implementation "com.google.android.material:material:1.12.0"
implementation 'com.karumi:dexter:5.0.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.compose.ui:ui-tooling-preview'
androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
// Jetpack Compose
def composeBom = platform('androidx.compose:compose-bom:2024.11.00')
@ -87,6 +89,8 @@ dependencies {
// Dependency injector
implementation "com.google.dagger:dagger-android:$DAGGER_VERSION"
implementation "com.google.dagger:dagger-android-support:$DAGGER_VERSION"
debugImplementation 'androidx.compose.ui:ui-tooling'
debugImplementation 'androidx.compose.ui:ui-test-manifest'
kapt "com.google.dagger:dagger-android-processor:$DAGGER_VERSION"
kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
annotationProcessor "com.google.dagger:dagger-android-processor:$DAGGER_VERSION"

View file

@ -55,6 +55,10 @@
android:theme="@style/LightAppTheme"
tools:ignore="GoogleAppIndexingWarning"
tools:replace="android:appComponentFactory">
<activity
android:name=".activity.SingleWebViewActivity"
android:exported="false"
android:label="@string/title_activity_single_web_view" />
<activity
android:name=".nearby.WikidataFeedback"
android:exported="false" />

View file

@ -0,0 +1,181 @@
package fr.free.nrw.commons.activity
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.webkit.ConsoleMessage
import android.webkit.WebChromeClient
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView
import fr.free.nrw.commons.R
import timber.log.Timber
/**
* SingleWebViewActivity is a reusable activity webView based on a given url(initial url) and
* closes itself when a specified success URL is reached to success url.
*/
class SingleWebViewActivity : ComponentActivity() {
@OptIn(ExperimentalMaterial3Api::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val url = intent.getStringExtra(VANISH_ACCOUNT_URL)
val successUrl = intent.getStringExtra(VANISH_ACCOUNT_SUCCESS_URL)
if (url == null || successUrl == null) {
finish()
return
}
enableEdgeToEdge()
setContent {
Scaffold(
topBar = {
TopAppBar(
modifier = Modifier,
title = { Text(getString(R.string.vanish_account)) },
navigationIcon = {
IconButton(
onClick = {
// Close the WebView Activity if the user taps the back button
finish()
},
) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
// TODO("Add contentDescription)
contentDescription = ""
)
}
}
)
},
content = {
WebViewComponent(
url = url,
successUrl = successUrl,
onSuccess = {
// TODO Redirect the user to login screen like we do when the user logout's
finish()
},
modifier = Modifier
.fillMaxSize()
.padding(it)
)
}
)
}
}
/**
* @param url The initial URL which we are loading in the WebView.
* @param successUrl The URL that, when reached, triggers the `onSuccess` callback.
* @param onSuccess A callback that is invoked when the current url of webView is successUrl.
* This is used when we want to close when the webView once a success url is hit.
* @param modifier An optional [Modifier] to customize the layout or appearance of the WebView.
*/
@SuppressLint("SetJavaScriptEnabled")
@Composable
private fun WebViewComponent(
url: String,
successUrl: String,
onSuccess: () -> Unit,
modifier: Modifier = Modifier
) {
val webView = remember { mutableStateOf<WebView?>(null) }
AndroidView(
modifier = modifier,
factory = {
WebView(it).apply {
settings.apply {
javaScriptEnabled = true
domStorageEnabled = true
javaScriptCanOpenWindowsAutomatically = true
}
webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView?,
request: WebResourceRequest?
): Boolean {
request?.url?.let { url ->
Timber.d("URL Loading: $url")
if (url.toString() == successUrl) {
Timber.d("Success URL detected. Closing WebView.")
onSuccess() // Close the activity
return true
}
return false
}
return false
}
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
}
}
webChromeClient = object : WebChromeClient() {
override fun onConsoleMessage(message: ConsoleMessage): Boolean {
Timber.d("Console: ${message.message()} -- From line ${message.lineNumber()} of ${message.sourceId()}")
return true
}
}
loadUrl(url)
}
},
update = {
webView.value = it
}
)
}
companion object {
private const val VANISH_ACCOUNT_URL = "VanishAccountUrl"
private const val VANISH_ACCOUNT_SUCCESS_URL = "vanishAccountSuccessUrl"
/**
* Launch the WebViewActivity with the specified URL and success URL.
* @param context The context from which the activity is launched.
* @param url The initial URL to load in the WebView.
* @param successUrl The URL that triggers the WebView to close when matched.
*/
fun showWebView(
context: Context,
url: String,
successUrl: String
) {
val intent = Intent(
context,
SingleWebViewActivity::class.java
).apply {
putExtra(VANISH_ACCOUNT_URL, url)
putExtra(VANISH_ACCOUNT_SUCCESS_URL, successUrl)
}
context.startActivity(intent)
}
}
}

View file

@ -61,16 +61,16 @@ class CoordinateEditHelper @Inject constructor(
/**
* Replaces new coordinates
* @param media to be added
* @param Latitude to be added
* @param Longitude to be added
* @param Accuracy to be added
* @param latitude to be added
* @param longitude to be added
* @param accuracy to be added
* @return Observable<Boolean>
*/
private fun addCoordinates(
media: Media,
Latitude: String,
Longitude: String,
Accuracy: String
latitude: String,
longitude: String,
accuracy: String
): Observable<Boolean>? {
Timber.d("thread is coordinates adding %s", Thread.currentThread().getName())
val summary = "Adding Coordinates"
@ -83,9 +83,9 @@ class CoordinateEditHelper @Inject constructor(
.blockingGet()
}
if (Latitude != null) {
buffer.append("\n{{Location|").append(Latitude).append("|").append(Longitude)
.append("|").append(Accuracy).append("}}")
if (latitude != null) {
buffer.append("\n{{Location|").append(latitude).append("|").append(longitude)
.append("|").append(accuracy).append("}}")
}
val editedLocation = buffer.toString()
@ -141,7 +141,7 @@ class CoordinateEditHelper @Inject constructor(
* @param media to be added
* @param latitude to be added
* @param longitude to be added
* @param Accuracy to be added
* @param accuracy to be added
* @param result to be added
* @return boolean
*/
@ -150,7 +150,7 @@ class CoordinateEditHelper @Inject constructor(
media: Media,
latitude: String,
longitude: String,
Accuracy: String,
accuracy: String,
result: Boolean
): Boolean {
val message: String
@ -160,7 +160,7 @@ class CoordinateEditHelper @Inject constructor(
media.coordinates = fr.free.nrw.commons.location.LatLng(
latitude.toDouble(),
longitude.toDouble(),
Accuracy.toFloat()
accuracy.toFloat()
)
title += ": " + context.getString(R.string.coordinates_edit_helper_show_edit_title_success)
val coordinatesInMessage = StringBuilder()

View file

@ -271,7 +271,7 @@ class CustomSelectorActivity :
dialog.setCancelable(false)
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
dialog.setContentView(R.layout.custom_selector_info_dialog)
(dialog.findViewById(R.id.btn_ok) as Button).setOnClickListener { dialog.dismiss() }
(dialog.findViewById<Button>(R.id.btn_ok))?.setOnClickListener { dialog.dismiss() }
dialog.show()
}
@ -687,8 +687,8 @@ class CustomSelectorActivity :
dialog.setCancelable(false)
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
dialog.setContentView(R.layout.custom_selector_limit_dialog)
(dialog.findViewById(R.id.btn_dismiss_limit_warning) as Button).setOnClickListener { dialog.dismiss() }
(dialog.findViewById(R.id.upload_limit_warning) as TextView).text =
(dialog.findViewById<Button>(R.id.btn_dismiss_limit_warning))?.setOnClickListener { dialog.dismiss() }
(dialog.findViewById<TextView>(R.id.upload_limit_warning))?.text =
resources.getString(
R.string.custom_selector_over_limit_warning,
uploadLimit,

View file

@ -40,10 +40,10 @@ class QuizChecker @Inject constructor(
private val compositeDisposable = CompositeDisposable()
private val UPLOAD_COUNT_THRESHOLD = 5
private val REVERT_PERCENTAGE_FOR_MESSAGE = "50%"
private val REVERT_SHARED_PREFERENCE = "revertCount"
private val UPLOAD_SHARED_PREFERENCE = "uploadCount"
private val uploadCountThreshold = 5
private val revertPercentageForMessage = "50%"
private val revertSharedPreference = "revertCount"
private val uploadSharedPreference = "uploadCount"
/**
* Initializes quiz check by calculating revert parameters and showing quiz if necessary
@ -80,12 +80,12 @@ class QuizChecker @Inject constructor(
*/
private fun setTotalUploadCount(uploadCount: Int) {
totalUploadCount = uploadCount - revertKvStore.getInt(
UPLOAD_SHARED_PREFERENCE,
uploadSharedPreference,
0
)
if (totalUploadCount < 0) {
totalUploadCount = 0
revertKvStore.putInt(UPLOAD_SHARED_PREFERENCE, 0)
revertKvStore.putInt(uploadSharedPreference, 0)
}
isUploadCountFetched = true
}
@ -112,10 +112,10 @@ class QuizChecker @Inject constructor(
* @param revertCountFetched Count of deleted uploads
*/
private fun setRevertParameter(revertCountFetched: Int) {
revertCount = revertCountFetched - revertKvStore.getInt(REVERT_SHARED_PREFERENCE, 0)
revertCount = revertCountFetched - revertKvStore.getInt(revertSharedPreference, 0)
if (revertCount < 0) {
revertCount = 0
revertKvStore.putInt(REVERT_SHARED_PREFERENCE, 0)
revertKvStore.putInt(revertSharedPreference, 0)
}
isRevertCountFetched = true
}
@ -128,13 +128,13 @@ class QuizChecker @Inject constructor(
setRevertCount()
if (revertCount < 0 || totalUploadCount < 0) {
revertKvStore.putInt(REVERT_SHARED_PREFERENCE, 0)
revertKvStore.putInt(UPLOAD_SHARED_PREFERENCE, 0)
revertKvStore.putInt(revertSharedPreference, 0)
revertKvStore.putInt(uploadSharedPreference, 0)
return
}
if (isRevertCountFetched && isUploadCountFetched &&
totalUploadCount >= UPLOAD_COUNT_THRESHOLD &&
totalUploadCount >= uploadCountThreshold &&
(revertCount * 100) / totalUploadCount >= 50
) {
callQuiz(activity)
@ -149,7 +149,7 @@ class QuizChecker @Inject constructor(
DialogUtil.showAlertDialog(
activity,
activity.getString(R.string.quiz),
activity.getString(R.string.quiz_alert_message, REVERT_PERCENTAGE_FOR_MESSAGE),
activity.getString(R.string.quiz_alert_message, revertPercentageForMessage),
activity.getString(R.string.about_translate_proceed),
activity.getString(android.R.string.cancel),
{ startQuizActivity(activity) },
@ -161,11 +161,11 @@ class QuizChecker @Inject constructor(
* Starts the quiz activity and updates preferences for revert and upload counts
*/
private fun startQuizActivity(activity: Activity) {
val newRevertSharedPrefs = revertCount + revertKvStore.getInt(REVERT_SHARED_PREFERENCE, 0)
revertKvStore.putInt(REVERT_SHARED_PREFERENCE, newRevertSharedPrefs)
val newRevertSharedPrefs = revertCount + revertKvStore.getInt(revertSharedPreference, 0)
revertKvStore.putInt(revertSharedPreference, newRevertSharedPrefs)
val newUploadCount = totalUploadCount + revertKvStore.getInt(UPLOAD_SHARED_PREFERENCE, 0)
revertKvStore.putInt(UPLOAD_SHARED_PREFERENCE, newUploadCount)
val newUploadCount = totalUploadCount + revertKvStore.getInt(uploadSharedPreference, 0)
revertKvStore.putInt(uploadSharedPreference, newUploadCount)
val intent = Intent(activity, WelcomeActivity::class.java).apply {
putExtra("isQuiz", true)

View file

@ -30,8 +30,8 @@ import fr.free.nrw.commons.contributions.MainActivity
class QuizResultActivity : AppCompatActivity() {
private var binding: ActivityQuizResultBinding? = null
private val NUMBER_OF_QUESTIONS = 5
private val MULTIPLIER_TO_GET_PERCENTAGE = 20
private val numberOfQuestions = 5
private val multiplierToGetPercentage = 20
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -67,9 +67,9 @@ class QuizResultActivity : AppCompatActivity() {
*/
@SuppressLint("StringFormatInvalid", "SetTextI18n")
fun setScore(score: Int) {
val scorePercent = score * MULTIPLIER_TO_GET_PERCENTAGE
val scorePercent = score * multiplierToGetPercentage
binding?.resultProgressBar?.progress = scorePercent
binding?.tvResultProgress?.text = "$score / $NUMBER_OF_QUESTIONS"
binding?.tvResultProgress?.text = "$score / $numberOfQuestions"
val message = resources.getString(R.string.congratulatory_message_quiz, "$scorePercent%")
binding?.congratulatoryMessage?.text = message
}

View file

@ -3,6 +3,7 @@ package fr.free.nrw.commons.settings
object Prefs {
const val DEFAULT_LICENSE = "defaultLicense"
const val MANAGED_EXIF_TAGS = "managed_exif_tags"
const val VANISHED_ACCOUNT = "vanishAccount"
const val DESCRIPTION_LANGUAGE = "languageDescription"
const val APP_UI_LANGUAGE = "appUiLanguage"
const val KEY_THEME_VALUE = "appThemePref"

View file

@ -19,6 +19,7 @@ import android.widget.TextView
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
import androidx.appcompat.app.AlertDialog
import androidx.preference.ListPreference
import androidx.preference.MultiSelectListPreference
import androidx.preference.Preference
@ -34,6 +35,7 @@ import com.karumi.dexter.listener.PermissionRequest
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
import fr.free.nrw.commons.R
import fr.free.nrw.commons.Utils
import fr.free.nrw.commons.activity.SingleWebViewActivity
import fr.free.nrw.commons.campaigns.CampaignView
import fr.free.nrw.commons.contributions.ContributionController
import fr.free.nrw.commons.contributions.MainActivity
@ -48,6 +50,7 @@ import fr.free.nrw.commons.recentlanguages.RecentLanguagesDao
import fr.free.nrw.commons.upload.LanguagesAdapter
import fr.free.nrw.commons.utils.DialogUtil
import fr.free.nrw.commons.utils.PermissionUtils
import fr.free.nrw.commons.utils.StringUtil
import fr.free.nrw.commons.utils.ViewUtil
import java.util.Locale
import javax.inject.Inject
@ -71,6 +74,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
@Inject
lateinit var locationManager: LocationServiceManager
private var vanishAccountPreference: Preference? = null
private var themeListPreference: ListPreference? = null
private var descriptionLanguageListPreference: Preference? = null
private var appUiLanguageListPreference: Preference? = null
@ -79,6 +83,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
private var recentLanguagesTextView: TextView? = null
private var separator: View? = null
private var languageHistoryListView: ListView? = null
private lateinit var inAppCameraLocationPermissionLauncher: ActivityResultLauncher<Array<String>>
private val GET_CONTENT_PICKER_HELP_URL = "https://commons-app.github.io/docs.html#get-content"
@ -114,6 +119,26 @@ class SettingsFragment : PreferenceFragmentCompat() {
themeListPreference = findPreference(Prefs.KEY_THEME_VALUE)
prepareTheme()
vanishAccountPreference = findPreference(Prefs.VANISHED_ACCOUNT)
vanishAccountPreference?.setOnPreferenceClickListener {
AlertDialog.Builder(requireContext())
.setTitle(R.string.account_vanish_request_confirm_title)
.setMessage(StringUtil.fromHtml(getString(R.string.account_vanish_request_confirm)))
.setNegativeButton(R.string.cancel){ dialog,_ ->
dialog.dismiss()
}
.setPositiveButton(R.string.vanish_account) { dialog, _ ->
SingleWebViewActivity.showWebView(
context = requireActivity(),
url = VANISH_ACCOUNT_URL,
successUrl = VANISH_ACCOUNT_SUCCESS_URL
)
dialog.dismiss()
}
.show()
true
}
val multiSelectListPref: MultiSelectListPreference? = findPreference(
Prefs.MANAGED_EXIF_TAGS
)
@ -484,7 +509,10 @@ class SettingsFragment : PreferenceFragmentCompat() {
editor.apply()
}
@Suppress("LongLine")
companion object {
private const val VANISH_ACCOUNT_URL = "https://meta.m.wikimedia.org/wiki/Special:Contact/accountvanishapps"
private const val VANISH_ACCOUNT_SUCCESS_URL = "https://meta.m.wikimedia.org/wiki/Special:GlobalVanishRequest/vanished"
/**
* Create Locale based on different types of language codes
* @param languageCode

View file

@ -875,4 +875,6 @@
<string name="usages_on_commons_heading">كومنز</string>
<string name="usages_on_other_wikis_heading">مواقع ويكي أخرى</string>
<string name="file_usages_container_heading">حالات استخدام الملف</string>
<string name="caption">الشرح</string>
<string name="caption_copied_to_clipboard">تم نسخ التسمية التوضيحية إلى الحافظة</string>
</resources>

View file

@ -529,4 +529,6 @@
<string name="uploads">আপলোড</string>
<string name="pending">অমীমাংসিত</string>
<string name="failed">ব্যর্থ হয়েছে</string>
<string name="caption">ক্যাপশন</string>
<string name="caption_copied_to_clipboard">ক্যাপশন ক্লিপবোর্ডে অনুলিপি করা হয়েছে</string>
</resources>

View file

@ -814,4 +814,6 @@
<string name="usages_on_other_wikis_heading">Andre wikier</string>
<string name="bullet_point"></string>
<string name="file_usages_container_heading">Filanvendelser</string>
<string name="caption">Billedtekst</string>
<string name="caption_copied_to_clipboard">Billedtekst kopieret til udklipsholder</string>
</resources>

View file

@ -32,6 +32,7 @@
* Orikrin1998
* Paraboule
* Patrick Star
* Pols12
* Robins7
* Sherbrooke
* SleaY
@ -852,4 +853,6 @@
<string name="usages_on_other_wikis_heading">Autres wikis</string>
<string name="bullet_point"></string>
<string name="file_usages_container_heading">Utilisations du fichier</string>
<string name="caption">Légende</string>
<string name="caption_copied_to_clipboard">Légende copiée dans le presse-papier</string>
</resources>

View file

@ -358,4 +358,5 @@
<string name="custom_selector_delete_folder">फ़ोल्डर हटाएँ</string>
<string name="custom_selector_delete">हटाएँ</string>
<string name="custom_selector_cancel">रद्द करें</string>
<string name="caption">कैप्शन</string>
</resources>

View file

@ -773,4 +773,6 @@
<string name="usages_on_commons_heading">Commons</string>
<string name="usages_on_other_wikis_heading">Altri wiki</string>
<string name="file_usages_container_heading">Utilizzi del file</string>
<string name="caption">Didascalia</string>
<string name="caption_copied_to_clipboard">Didascalia copiata negli appunti</string>
</resources>

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Authors:
* GilPe
* Les Meloures
* Robby
* Soued031
@ -532,4 +533,6 @@
<string name="error_while_loading">Feeler beim Lueden</string>
<string name="usages_on_commons_heading">Commons</string>
<string name="usages_on_other_wikis_heading">Aner Wikien</string>
<string name="caption">Beschrëftung</string>
<string name="caption_copied_to_clipboard">Text an den Tëschespäicher kopéiert</string>
</resources>

View file

@ -810,4 +810,6 @@
<string name="usages_on_other_wikis_heading">Други викија</string>
<string name="bullet_point"></string>
<string name="file_usages_container_heading">Употреби на податотеката</string>
<string name="caption">Толкување</string>
<string name="caption_copied_to_clipboard">Толкувањето е ставено во меѓускладот</string>
</resources>

View file

@ -160,7 +160,7 @@
<string name="navigation_item_upload">ਚੜ੍ਹਾਉ</string>
<string name="navigation_item_nearby">ਨੇੜੇ-ਤੇੜੇ</string>
<string name="navigation_item_about">ਬਾਰੇ</string>
<string name="navigation_item_settings">ਸੈਟਿੰਗਾਂ</string>
<string name="navigation_item_settings">ਤਰਜੀਹਾਂ</string>
<string name="navigation_item_feedback">ਸੁਝਾਅ</string>
<string name="navigation_item_logout">ਬਾਹਰ ਆਉ</string>
<string name="navigation_item_info">ਸਿਖਲਾਈ</string>

View file

@ -806,4 +806,6 @@
<string name="usages_on_other_wikis_heading">Àutre wiki</string>
<string name="bullet_point"></string>
<string name="file_usages_container_heading">Usagi dl\'archivi</string>
<string name="caption">Legenda</string>
<string name="caption_copied_to_clipboard">Legenda copià an sla taulëtta</string>
</resources>

View file

@ -217,6 +217,7 @@
<string name="next">Čuovvovaš</string>
<string name="title_page_bookmarks_pictures">Govat</string>
<string name="title_page_bookmarks_locations">Sajit</string>
<string name="title_page_bookmarks_categories">Kategoriijat</string>
<string name="provider_bookmarks">Girjemearkkat</string>
<string name="provider_bookmarks_location">Girjemearkkat</string>
<string name="no_categories_selected">Ii oktage kategoriija leat válljejuvvon</string>

View file

@ -277,4 +277,5 @@
<string name="custom_selector_delete">مٹاؤ</string>
<string name="custom_selector_cancel">منسوخ</string>
<string name="usages_on_commons_heading">کامنز</string>
<string name="caption">عنوان</string>
</resources>

View file

@ -743,4 +743,6 @@
<string name="failed">Није успело</string>
<string name="green_pin">Ово место већ има слику</string>
<string name="grey_pin">Проверавање да ли ово место има слику.</string>
<string name="caption">Поднапис</string>
<string name="caption_copied_to_clipboard">Поднапис копиран</string>
</resources>

View file

@ -860,6 +860,11 @@ Upload your first media by tapping on the add button.</string>
<string name="usages_on_other_wikis_heading">Other wikis</string>
<string name="bullet_point"></string>
<string name="file_usages_container_heading">File usages</string>
<string name="title_activity_single_web_view">SingleWebViewActivity</string>
<string name="account">Account</string>
<string name="vanish_account">Vanish Account</string>
<string name="account_vanish_request_confirm_title">Vanish account warning</string>
<string name="account_vanish_request_confirm"><![CDATA[Vanishing is a <b>last resort</b> and should <b>only be used when you wish to stop editing forever</b> and also to hide as many of your past associations as possible.<br/><br/>Account deletion on Wikimedia Commons is done by changing your account name to make it so others cannot recognize your contributions in a process called account vanishing. <b>Vanishing does not guarantee complete anonymity or remove contributions to the projects</b>.]]></string>
<string name="caption">Caption</string>
<string name="caption_copied_to_clipboard">Caption copied to clipboard</string>

View file

@ -129,4 +129,14 @@
android:title="@string/send_log_file" />
</PreferenceCategory>
<PreferenceCategory
android:title="@string/account">
<Preference
android:key="vanishAccount"
app:singleLineTitle="false"
android:title="@string/vanish_account"/>
</PreferenceCategory>
</PreferenceScreen>

View file

@ -21,7 +21,7 @@ KOTLIN_VERSION=1.9.22
LEAK_CANARY_VERSION=2.10
DAGGER_VERSION=2.23
ROOM_VERSION=2.6.1
PREFERENCE_VERSION=1.1.0
PREFERENCE_VERSION=1.2.1
CORE_KTX_VERSION=1.9.0
ADAPTER_DELEGATES_VERSION=4.3.0
PAGING_VERSION=2.1.2