mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Merge branch 'main' into 1-issue#5829
This commit is contained in:
commit
045cfa24b3
25 changed files with 293 additions and 37 deletions
|
|
@ -50,6 +50,8 @@ dependencies {
|
||||||
implementation "com.google.android.material:material:1.12.0"
|
implementation "com.google.android.material:material:1.12.0"
|
||||||
implementation 'com.karumi:dexter:5.0.0'
|
implementation 'com.karumi:dexter:5.0.0'
|
||||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.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
|
// Jetpack Compose
|
||||||
def composeBom = platform('androidx.compose:compose-bom:2024.11.00')
|
def composeBom = platform('androidx.compose:compose-bom:2024.11.00')
|
||||||
|
|
@ -87,6 +89,8 @@ dependencies {
|
||||||
// Dependency injector
|
// Dependency injector
|
||||||
implementation "com.google.dagger:dagger-android:$DAGGER_VERSION"
|
implementation "com.google.dagger:dagger-android:$DAGGER_VERSION"
|
||||||
implementation "com.google.dagger:dagger-android-support:$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-android-processor:$DAGGER_VERSION"
|
||||||
kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
|
kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
|
||||||
annotationProcessor "com.google.dagger:dagger-android-processor:$DAGGER_VERSION"
|
annotationProcessor "com.google.dagger:dagger-android-processor:$DAGGER_VERSION"
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,10 @@
|
||||||
android:theme="@style/LightAppTheme"
|
android:theme="@style/LightAppTheme"
|
||||||
tools:ignore="GoogleAppIndexingWarning"
|
tools:ignore="GoogleAppIndexingWarning"
|
||||||
tools:replace="android:appComponentFactory">
|
tools:replace="android:appComponentFactory">
|
||||||
|
<activity
|
||||||
|
android:name=".activity.SingleWebViewActivity"
|
||||||
|
android:exported="false"
|
||||||
|
android:label="@string/title_activity_single_web_view" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".nearby.WikidataFeedback"
|
android:name=".nearby.WikidataFeedback"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -61,16 +61,16 @@ class CoordinateEditHelper @Inject constructor(
|
||||||
/**
|
/**
|
||||||
* Replaces new coordinates
|
* Replaces new coordinates
|
||||||
* @param media to be added
|
* @param media to be added
|
||||||
* @param Latitude to be added
|
* @param latitude to be added
|
||||||
* @param Longitude to be added
|
* @param longitude to be added
|
||||||
* @param Accuracy to be added
|
* @param accuracy to be added
|
||||||
* @return Observable<Boolean>
|
* @return Observable<Boolean>
|
||||||
*/
|
*/
|
||||||
private fun addCoordinates(
|
private fun addCoordinates(
|
||||||
media: Media,
|
media: Media,
|
||||||
Latitude: String,
|
latitude: String,
|
||||||
Longitude: String,
|
longitude: String,
|
||||||
Accuracy: String
|
accuracy: String
|
||||||
): Observable<Boolean>? {
|
): Observable<Boolean>? {
|
||||||
Timber.d("thread is coordinates adding %s", Thread.currentThread().getName())
|
Timber.d("thread is coordinates adding %s", Thread.currentThread().getName())
|
||||||
val summary = "Adding Coordinates"
|
val summary = "Adding Coordinates"
|
||||||
|
|
@ -83,9 +83,9 @@ class CoordinateEditHelper @Inject constructor(
|
||||||
.blockingGet()
|
.blockingGet()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Latitude != null) {
|
if (latitude != null) {
|
||||||
buffer.append("\n{{Location|").append(Latitude).append("|").append(Longitude)
|
buffer.append("\n{{Location|").append(latitude).append("|").append(longitude)
|
||||||
.append("|").append(Accuracy).append("}}")
|
.append("|").append(accuracy).append("}}")
|
||||||
}
|
}
|
||||||
|
|
||||||
val editedLocation = buffer.toString()
|
val editedLocation = buffer.toString()
|
||||||
|
|
@ -141,7 +141,7 @@ class CoordinateEditHelper @Inject constructor(
|
||||||
* @param media to be added
|
* @param media to be added
|
||||||
* @param latitude to be added
|
* @param latitude to be added
|
||||||
* @param longitude to be added
|
* @param longitude to be added
|
||||||
* @param Accuracy to be added
|
* @param accuracy to be added
|
||||||
* @param result to be added
|
* @param result to be added
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
|
|
@ -150,7 +150,7 @@ class CoordinateEditHelper @Inject constructor(
|
||||||
media: Media,
|
media: Media,
|
||||||
latitude: String,
|
latitude: String,
|
||||||
longitude: String,
|
longitude: String,
|
||||||
Accuracy: String,
|
accuracy: String,
|
||||||
result: Boolean
|
result: Boolean
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val message: String
|
val message: String
|
||||||
|
|
@ -160,7 +160,7 @@ class CoordinateEditHelper @Inject constructor(
|
||||||
media.coordinates = fr.free.nrw.commons.location.LatLng(
|
media.coordinates = fr.free.nrw.commons.location.LatLng(
|
||||||
latitude.toDouble(),
|
latitude.toDouble(),
|
||||||
longitude.toDouble(),
|
longitude.toDouble(),
|
||||||
Accuracy.toFloat()
|
accuracy.toFloat()
|
||||||
)
|
)
|
||||||
title += ": " + context.getString(R.string.coordinates_edit_helper_show_edit_title_success)
|
title += ": " + context.getString(R.string.coordinates_edit_helper_show_edit_title_success)
|
||||||
val coordinatesInMessage = StringBuilder()
|
val coordinatesInMessage = StringBuilder()
|
||||||
|
|
|
||||||
|
|
@ -271,7 +271,7 @@ class CustomSelectorActivity :
|
||||||
dialog.setCancelable(false)
|
dialog.setCancelable(false)
|
||||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||||
dialog.setContentView(R.layout.custom_selector_info_dialog)
|
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()
|
dialog.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -687,8 +687,8 @@ class CustomSelectorActivity :
|
||||||
dialog.setCancelable(false)
|
dialog.setCancelable(false)
|
||||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||||
dialog.setContentView(R.layout.custom_selector_limit_dialog)
|
dialog.setContentView(R.layout.custom_selector_limit_dialog)
|
||||||
(dialog.findViewById(R.id.btn_dismiss_limit_warning) as Button).setOnClickListener { dialog.dismiss() }
|
(dialog.findViewById<Button>(R.id.btn_dismiss_limit_warning))?.setOnClickListener { dialog.dismiss() }
|
||||||
(dialog.findViewById(R.id.upload_limit_warning) as TextView).text =
|
(dialog.findViewById<TextView>(R.id.upload_limit_warning))?.text =
|
||||||
resources.getString(
|
resources.getString(
|
||||||
R.string.custom_selector_over_limit_warning,
|
R.string.custom_selector_over_limit_warning,
|
||||||
uploadLimit,
|
uploadLimit,
|
||||||
|
|
|
||||||
|
|
@ -40,10 +40,10 @@ class QuizChecker @Inject constructor(
|
||||||
|
|
||||||
private val compositeDisposable = CompositeDisposable()
|
private val compositeDisposable = CompositeDisposable()
|
||||||
|
|
||||||
private val UPLOAD_COUNT_THRESHOLD = 5
|
private val uploadCountThreshold = 5
|
||||||
private val REVERT_PERCENTAGE_FOR_MESSAGE = "50%"
|
private val revertPercentageForMessage = "50%"
|
||||||
private val REVERT_SHARED_PREFERENCE = "revertCount"
|
private val revertSharedPreference = "revertCount"
|
||||||
private val UPLOAD_SHARED_PREFERENCE = "uploadCount"
|
private val uploadSharedPreference = "uploadCount"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes quiz check by calculating revert parameters and showing quiz if necessary
|
* 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) {
|
private fun setTotalUploadCount(uploadCount: Int) {
|
||||||
totalUploadCount = uploadCount - revertKvStore.getInt(
|
totalUploadCount = uploadCount - revertKvStore.getInt(
|
||||||
UPLOAD_SHARED_PREFERENCE,
|
uploadSharedPreference,
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
if (totalUploadCount < 0) {
|
if (totalUploadCount < 0) {
|
||||||
totalUploadCount = 0
|
totalUploadCount = 0
|
||||||
revertKvStore.putInt(UPLOAD_SHARED_PREFERENCE, 0)
|
revertKvStore.putInt(uploadSharedPreference, 0)
|
||||||
}
|
}
|
||||||
isUploadCountFetched = true
|
isUploadCountFetched = true
|
||||||
}
|
}
|
||||||
|
|
@ -112,10 +112,10 @@ class QuizChecker @Inject constructor(
|
||||||
* @param revertCountFetched Count of deleted uploads
|
* @param revertCountFetched Count of deleted uploads
|
||||||
*/
|
*/
|
||||||
private fun setRevertParameter(revertCountFetched: Int) {
|
private fun setRevertParameter(revertCountFetched: Int) {
|
||||||
revertCount = revertCountFetched - revertKvStore.getInt(REVERT_SHARED_PREFERENCE, 0)
|
revertCount = revertCountFetched - revertKvStore.getInt(revertSharedPreference, 0)
|
||||||
if (revertCount < 0) {
|
if (revertCount < 0) {
|
||||||
revertCount = 0
|
revertCount = 0
|
||||||
revertKvStore.putInt(REVERT_SHARED_PREFERENCE, 0)
|
revertKvStore.putInt(revertSharedPreference, 0)
|
||||||
}
|
}
|
||||||
isRevertCountFetched = true
|
isRevertCountFetched = true
|
||||||
}
|
}
|
||||||
|
|
@ -128,13 +128,13 @@ class QuizChecker @Inject constructor(
|
||||||
setRevertCount()
|
setRevertCount()
|
||||||
|
|
||||||
if (revertCount < 0 || totalUploadCount < 0) {
|
if (revertCount < 0 || totalUploadCount < 0) {
|
||||||
revertKvStore.putInt(REVERT_SHARED_PREFERENCE, 0)
|
revertKvStore.putInt(revertSharedPreference, 0)
|
||||||
revertKvStore.putInt(UPLOAD_SHARED_PREFERENCE, 0)
|
revertKvStore.putInt(uploadSharedPreference, 0)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isRevertCountFetched && isUploadCountFetched &&
|
if (isRevertCountFetched && isUploadCountFetched &&
|
||||||
totalUploadCount >= UPLOAD_COUNT_THRESHOLD &&
|
totalUploadCount >= uploadCountThreshold &&
|
||||||
(revertCount * 100) / totalUploadCount >= 50
|
(revertCount * 100) / totalUploadCount >= 50
|
||||||
) {
|
) {
|
||||||
callQuiz(activity)
|
callQuiz(activity)
|
||||||
|
|
@ -149,7 +149,7 @@ class QuizChecker @Inject constructor(
|
||||||
DialogUtil.showAlertDialog(
|
DialogUtil.showAlertDialog(
|
||||||
activity,
|
activity,
|
||||||
activity.getString(R.string.quiz),
|
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(R.string.about_translate_proceed),
|
||||||
activity.getString(android.R.string.cancel),
|
activity.getString(android.R.string.cancel),
|
||||||
{ startQuizActivity(activity) },
|
{ startQuizActivity(activity) },
|
||||||
|
|
@ -161,11 +161,11 @@ class QuizChecker @Inject constructor(
|
||||||
* Starts the quiz activity and updates preferences for revert and upload counts
|
* Starts the quiz activity and updates preferences for revert and upload counts
|
||||||
*/
|
*/
|
||||||
private fun startQuizActivity(activity: Activity) {
|
private fun startQuizActivity(activity: Activity) {
|
||||||
val newRevertSharedPrefs = revertCount + revertKvStore.getInt(REVERT_SHARED_PREFERENCE, 0)
|
val newRevertSharedPrefs = revertCount + revertKvStore.getInt(revertSharedPreference, 0)
|
||||||
revertKvStore.putInt(REVERT_SHARED_PREFERENCE, newRevertSharedPrefs)
|
revertKvStore.putInt(revertSharedPreference, newRevertSharedPrefs)
|
||||||
|
|
||||||
val newUploadCount = totalUploadCount + revertKvStore.getInt(UPLOAD_SHARED_PREFERENCE, 0)
|
val newUploadCount = totalUploadCount + revertKvStore.getInt(uploadSharedPreference, 0)
|
||||||
revertKvStore.putInt(UPLOAD_SHARED_PREFERENCE, newUploadCount)
|
revertKvStore.putInt(uploadSharedPreference, newUploadCount)
|
||||||
|
|
||||||
val intent = Intent(activity, WelcomeActivity::class.java).apply {
|
val intent = Intent(activity, WelcomeActivity::class.java).apply {
|
||||||
putExtra("isQuiz", true)
|
putExtra("isQuiz", true)
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,8 @@ import fr.free.nrw.commons.contributions.MainActivity
|
||||||
class QuizResultActivity : AppCompatActivity() {
|
class QuizResultActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private var binding: ActivityQuizResultBinding? = null
|
private var binding: ActivityQuizResultBinding? = null
|
||||||
private val NUMBER_OF_QUESTIONS = 5
|
private val numberOfQuestions = 5
|
||||||
private val MULTIPLIER_TO_GET_PERCENTAGE = 20
|
private val multiplierToGetPercentage = 20
|
||||||
|
|
||||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
@ -67,9 +67,9 @@ class QuizResultActivity : AppCompatActivity() {
|
||||||
*/
|
*/
|
||||||
@SuppressLint("StringFormatInvalid", "SetTextI18n")
|
@SuppressLint("StringFormatInvalid", "SetTextI18n")
|
||||||
fun setScore(score: Int) {
|
fun setScore(score: Int) {
|
||||||
val scorePercent = score * MULTIPLIER_TO_GET_PERCENTAGE
|
val scorePercent = score * multiplierToGetPercentage
|
||||||
binding?.resultProgressBar?.progress = scorePercent
|
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%")
|
val message = resources.getString(R.string.congratulatory_message_quiz, "$scorePercent%")
|
||||||
binding?.congratulatoryMessage?.text = message
|
binding?.congratulatoryMessage?.text = message
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package fr.free.nrw.commons.settings
|
||||||
object Prefs {
|
object Prefs {
|
||||||
const val DEFAULT_LICENSE = "defaultLicense"
|
const val DEFAULT_LICENSE = "defaultLicense"
|
||||||
const val MANAGED_EXIF_TAGS = "managed_exif_tags"
|
const val MANAGED_EXIF_TAGS = "managed_exif_tags"
|
||||||
|
const val VANISHED_ACCOUNT = "vanishAccount"
|
||||||
const val DESCRIPTION_LANGUAGE = "languageDescription"
|
const val DESCRIPTION_LANGUAGE = "languageDescription"
|
||||||
const val APP_UI_LANGUAGE = "appUiLanguage"
|
const val APP_UI_LANGUAGE = "appUiLanguage"
|
||||||
const val KEY_THEME_VALUE = "appThemePref"
|
const val KEY_THEME_VALUE = "appThemePref"
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import android.widget.TextView
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions
|
import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions
|
||||||
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
|
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.preference.ListPreference
|
import androidx.preference.ListPreference
|
||||||
import androidx.preference.MultiSelectListPreference
|
import androidx.preference.MultiSelectListPreference
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
|
|
@ -34,6 +35,7 @@ import com.karumi.dexter.listener.PermissionRequest
|
||||||
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
|
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
|
||||||
import fr.free.nrw.commons.R
|
import fr.free.nrw.commons.R
|
||||||
import fr.free.nrw.commons.Utils
|
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.campaigns.CampaignView
|
||||||
import fr.free.nrw.commons.contributions.ContributionController
|
import fr.free.nrw.commons.contributions.ContributionController
|
||||||
import fr.free.nrw.commons.contributions.MainActivity
|
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.upload.LanguagesAdapter
|
||||||
import fr.free.nrw.commons.utils.DialogUtil
|
import fr.free.nrw.commons.utils.DialogUtil
|
||||||
import fr.free.nrw.commons.utils.PermissionUtils
|
import fr.free.nrw.commons.utils.PermissionUtils
|
||||||
|
import fr.free.nrw.commons.utils.StringUtil
|
||||||
import fr.free.nrw.commons.utils.ViewUtil
|
import fr.free.nrw.commons.utils.ViewUtil
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
@ -71,6 +74,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var locationManager: LocationServiceManager
|
lateinit var locationManager: LocationServiceManager
|
||||||
|
|
||||||
|
private var vanishAccountPreference: Preference? = null
|
||||||
private var themeListPreference: ListPreference? = null
|
private var themeListPreference: ListPreference? = null
|
||||||
private var descriptionLanguageListPreference: Preference? = null
|
private var descriptionLanguageListPreference: Preference? = null
|
||||||
private var appUiLanguageListPreference: Preference? = null
|
private var appUiLanguageListPreference: Preference? = null
|
||||||
|
|
@ -79,6 +83,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
private var recentLanguagesTextView: TextView? = null
|
private var recentLanguagesTextView: TextView? = null
|
||||||
private var separator: View? = null
|
private var separator: View? = null
|
||||||
private var languageHistoryListView: ListView? = null
|
private var languageHistoryListView: ListView? = null
|
||||||
|
|
||||||
private lateinit var inAppCameraLocationPermissionLauncher: ActivityResultLauncher<Array<String>>
|
private lateinit var inAppCameraLocationPermissionLauncher: ActivityResultLauncher<Array<String>>
|
||||||
private val GET_CONTENT_PICKER_HELP_URL = "https://commons-app.github.io/docs.html#get-content"
|
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)
|
themeListPreference = findPreference(Prefs.KEY_THEME_VALUE)
|
||||||
prepareTheme()
|
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(
|
val multiSelectListPref: MultiSelectListPreference? = findPreference(
|
||||||
Prefs.MANAGED_EXIF_TAGS
|
Prefs.MANAGED_EXIF_TAGS
|
||||||
)
|
)
|
||||||
|
|
@ -484,7 +509,10 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
editor.apply()
|
editor.apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("LongLine")
|
||||||
companion object {
|
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
|
* Create Locale based on different types of language codes
|
||||||
* @param languageCode
|
* @param languageCode
|
||||||
|
|
|
||||||
|
|
@ -875,4 +875,6 @@
|
||||||
<string name="usages_on_commons_heading">كومنز</string>
|
<string name="usages_on_commons_heading">كومنز</string>
|
||||||
<string name="usages_on_other_wikis_heading">مواقع ويكي أخرى</string>
|
<string name="usages_on_other_wikis_heading">مواقع ويكي أخرى</string>
|
||||||
<string name="file_usages_container_heading">حالات استخدام الملف</string>
|
<string name="file_usages_container_heading">حالات استخدام الملف</string>
|
||||||
|
<string name="caption">الشرح</string>
|
||||||
|
<string name="caption_copied_to_clipboard">تم نسخ التسمية التوضيحية إلى الحافظة</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -529,4 +529,6 @@
|
||||||
<string name="uploads">আপলোড</string>
|
<string name="uploads">আপলোড</string>
|
||||||
<string name="pending">অমীমাংসিত</string>
|
<string name="pending">অমীমাংসিত</string>
|
||||||
<string name="failed">ব্যর্থ হয়েছে</string>
|
<string name="failed">ব্যর্থ হয়েছে</string>
|
||||||
|
<string name="caption">ক্যাপশন</string>
|
||||||
|
<string name="caption_copied_to_clipboard">ক্যাপশন ক্লিপবোর্ডে অনুলিপি করা হয়েছে</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -814,4 +814,6 @@
|
||||||
<string name="usages_on_other_wikis_heading">Andre wikier</string>
|
<string name="usages_on_other_wikis_heading">Andre wikier</string>
|
||||||
<string name="bullet_point">•</string>
|
<string name="bullet_point">•</string>
|
||||||
<string name="file_usages_container_heading">Filanvendelser</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>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
* Orikrin1998
|
* Orikrin1998
|
||||||
* Paraboule
|
* Paraboule
|
||||||
* Patrick Star
|
* Patrick Star
|
||||||
|
* Pols12
|
||||||
* Robins7
|
* Robins7
|
||||||
* Sherbrooke
|
* Sherbrooke
|
||||||
* SleaY
|
* SleaY
|
||||||
|
|
@ -852,4 +853,6 @@
|
||||||
<string name="usages_on_other_wikis_heading">Autres wikis</string>
|
<string name="usages_on_other_wikis_heading">Autres wikis</string>
|
||||||
<string name="bullet_point">•</string>
|
<string name="bullet_point">•</string>
|
||||||
<string name="file_usages_container_heading">Utilisations du fichier</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>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -358,4 +358,5 @@
|
||||||
<string name="custom_selector_delete_folder">फ़ोल्डर हटाएँ</string>
|
<string name="custom_selector_delete_folder">फ़ोल्डर हटाएँ</string>
|
||||||
<string name="custom_selector_delete">हटाएँ</string>
|
<string name="custom_selector_delete">हटाएँ</string>
|
||||||
<string name="custom_selector_cancel">रद्द करें</string>
|
<string name="custom_selector_cancel">रद्द करें</string>
|
||||||
|
<string name="caption">कैप्शन</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -773,4 +773,6 @@
|
||||||
<string name="usages_on_commons_heading">Commons</string>
|
<string name="usages_on_commons_heading">Commons</string>
|
||||||
<string name="usages_on_other_wikis_heading">Altri wiki</string>
|
<string name="usages_on_other_wikis_heading">Altri wiki</string>
|
||||||
<string name="file_usages_container_heading">Utilizzi del file</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>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Authors:
|
<!-- Authors:
|
||||||
|
* GilPe
|
||||||
* Les Meloures
|
* Les Meloures
|
||||||
* Robby
|
* Robby
|
||||||
* Soued031
|
* Soued031
|
||||||
|
|
@ -532,4 +533,6 @@
|
||||||
<string name="error_while_loading">Feeler beim Lueden</string>
|
<string name="error_while_loading">Feeler beim Lueden</string>
|
||||||
<string name="usages_on_commons_heading">Commons</string>
|
<string name="usages_on_commons_heading">Commons</string>
|
||||||
<string name="usages_on_other_wikis_heading">Aner Wikien</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>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -810,4 +810,6 @@
|
||||||
<string name="usages_on_other_wikis_heading">Други викија</string>
|
<string name="usages_on_other_wikis_heading">Други викија</string>
|
||||||
<string name="bullet_point">•</string>
|
<string name="bullet_point">•</string>
|
||||||
<string name="file_usages_container_heading">Употреби на податотеката</string>
|
<string name="file_usages_container_heading">Употреби на податотеката</string>
|
||||||
|
<string name="caption">Толкување</string>
|
||||||
|
<string name="caption_copied_to_clipboard">Толкувањето е ставено во меѓускладот</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@
|
||||||
<string name="navigation_item_upload">ਚੜ੍ਹਾਉ</string>
|
<string name="navigation_item_upload">ਚੜ੍ਹਾਉ</string>
|
||||||
<string name="navigation_item_nearby">ਨੇੜੇ-ਤੇੜੇ</string>
|
<string name="navigation_item_nearby">ਨੇੜੇ-ਤੇੜੇ</string>
|
||||||
<string name="navigation_item_about">ਬਾਰੇ</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_feedback">ਸੁਝਾਅ</string>
|
||||||
<string name="navigation_item_logout">ਬਾਹਰ ਆਉ</string>
|
<string name="navigation_item_logout">ਬਾਹਰ ਆਉ</string>
|
||||||
<string name="navigation_item_info">ਸਿਖਲਾਈ</string>
|
<string name="navigation_item_info">ਸਿਖਲਾਈ</string>
|
||||||
|
|
|
||||||
|
|
@ -806,4 +806,6 @@
|
||||||
<string name="usages_on_other_wikis_heading">Àutre wiki</string>
|
<string name="usages_on_other_wikis_heading">Àutre wiki</string>
|
||||||
<string name="bullet_point">•</string>
|
<string name="bullet_point">•</string>
|
||||||
<string name="file_usages_container_heading">Usagi dl\'archivi</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>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -217,6 +217,7 @@
|
||||||
<string name="next">Čuovvovaš</string>
|
<string name="next">Čuovvovaš</string>
|
||||||
<string name="title_page_bookmarks_pictures">Govat</string>
|
<string name="title_page_bookmarks_pictures">Govat</string>
|
||||||
<string name="title_page_bookmarks_locations">Sajit</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">Girjemearkkat</string>
|
||||||
<string name="provider_bookmarks_location">Girjemearkkat</string>
|
<string name="provider_bookmarks_location">Girjemearkkat</string>
|
||||||
<string name="no_categories_selected">Ii oktage kategoriija leat válljejuvvon</string>
|
<string name="no_categories_selected">Ii oktage kategoriija leat válljejuvvon</string>
|
||||||
|
|
|
||||||
|
|
@ -277,4 +277,5 @@
|
||||||
<string name="custom_selector_delete">مٹاؤ</string>
|
<string name="custom_selector_delete">مٹاؤ</string>
|
||||||
<string name="custom_selector_cancel">منسوخ</string>
|
<string name="custom_selector_cancel">منسوخ</string>
|
||||||
<string name="usages_on_commons_heading">کامنز</string>
|
<string name="usages_on_commons_heading">کامنز</string>
|
||||||
|
<string name="caption">عنوان</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -743,4 +743,6 @@
|
||||||
<string name="failed">Није успело</string>
|
<string name="failed">Није успело</string>
|
||||||
<string name="green_pin">Ово место већ има слику</string>
|
<string name="green_pin">Ово место већ има слику</string>
|
||||||
<string name="grey_pin">Проверавање да ли ово место има слику.</string>
|
<string name="grey_pin">Проверавање да ли ово место има слику.</string>
|
||||||
|
<string name="caption">Поднапис</string>
|
||||||
|
<string name="caption_copied_to_clipboard">Поднапис копиран</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -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="usages_on_other_wikis_heading">Other wikis</string>
|
||||||
<string name="bullet_point">•</string>
|
<string name="bullet_point">•</string>
|
||||||
<string name="file_usages_container_heading">File usages</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">Caption</string>
|
||||||
<string name="caption_copied_to_clipboard">Caption copied to clipboard</string>
|
<string name="caption_copied_to_clipboard">Caption copied to clipboard</string>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -129,4 +129,14 @@
|
||||||
android:title="@string/send_log_file" />
|
android:title="@string/send_log_file" />
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<PreferenceCategory
|
||||||
|
android:title="@string/account">
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="vanishAccount"
|
||||||
|
app:singleLineTitle="false"
|
||||||
|
android:title="@string/vanish_account"/>
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ KOTLIN_VERSION=1.9.22
|
||||||
LEAK_CANARY_VERSION=2.10
|
LEAK_CANARY_VERSION=2.10
|
||||||
DAGGER_VERSION=2.23
|
DAGGER_VERSION=2.23
|
||||||
ROOM_VERSION=2.6.1
|
ROOM_VERSION=2.6.1
|
||||||
PREFERENCE_VERSION=1.1.0
|
PREFERENCE_VERSION=1.2.1
|
||||||
CORE_KTX_VERSION=1.9.0
|
CORE_KTX_VERSION=1.9.0
|
||||||
ADAPTER_DELEGATES_VERSION=4.3.0
|
ADAPTER_DELEGATES_VERSION=4.3.0
|
||||||
PAGING_VERSION=2.1.2
|
PAGING_VERSION=2.1.2
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue