diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c74f95fb4..a5a67d209 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -347,6 +347,7 @@ dependencies { // Kotlin + coroutines implementation(libs.androidx.work.runtime.ktx) implementation(libs.androidx.work.runtime) + implementation(libs.kotlinx.coroutines.rx2) testImplementation(libs.androidx.work.testing) //Glide diff --git a/app/src/main/java/fr/free/nrw/commons/delete/ReasonBuilder.kt b/app/src/main/java/fr/free/nrw/commons/delete/ReasonBuilder.kt index e9e590e73..63845b7ba 100644 --- a/app/src/main/java/fr/free/nrw/commons/delete/ReasonBuilder.kt +++ b/app/src/main/java/fr/free/nrw/commons/delete/ReasonBuilder.kt @@ -2,22 +2,19 @@ package fr.free.nrw.commons.delete import android.annotation.SuppressLint import android.content.Context -import android.util.Log - -import fr.free.nrw.commons.utils.DateUtil -import java.util.Locale - -import javax.inject.Inject -import javax.inject.Singleton - import fr.free.nrw.commons.Media import fr.free.nrw.commons.R -import fr.free.nrw.commons.profile.achievements.FeedbackResponse import fr.free.nrw.commons.auth.SessionManager import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient +import fr.free.nrw.commons.utils.DateUtil import fr.free.nrw.commons.utils.ViewUtilWrapper import io.reactivex.Single +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.rx2.rxSingle import timber.log.Timber +import java.util.Locale +import javax.inject.Inject +import javax.inject.Singleton /** * This class handles the reason for deleting a Media object @@ -30,6 +27,8 @@ class ReasonBuilder @Inject constructor( private val viewUtilWrapper: ViewUtilWrapper ) { + private val defaultFileUsagePageSize = 10 + /** * To process the reason and append the media's upload date and uploaded_by_me string * @param media @@ -41,7 +40,7 @@ class ReasonBuilder @Inject constructor( return Single.just("Not known") } Timber.d("Fetching article number") - return fetchArticleNumber(media, reason) + return getAndAppendFileUsage(media, reason) } /** @@ -56,31 +55,36 @@ class ReasonBuilder @Inject constructor( } } - private fun fetchArticleNumber(media: Media, reason: String): Single { - return if (checkAccount()) { - Timber.d("Fetching achievements for ${sessionManager.userName}") - okHttpJsonApiClient - .getAchievements(sessionManager.userName) - .map { feedbackResponse -> - Timber.d("Feedback Response: $feedbackResponse") - appendArticlesUsed(feedbackResponse, media, reason) - } - } else { - Single.just("") + private fun getAndAppendFileUsage(media: Media, reason: String): Single { + return rxSingle(context = Dispatchers.IO) { + if (!checkAccount()) return@rxSingle "" + + try { + val globalFileUsage = okHttpJsonApiClient.getGlobalFileUsages( + fileName = media.filename, + pageSize = defaultFileUsagePageSize + ) + val globalUsages = globalFileUsage?.query?.pages?.sumOf { it.fileUsage.size } ?: 0 + + appendArticlesUsed(globalUsages, media, reason) + } catch (e: Exception) { + Timber.e(e, "Error fetching file usage") + throw e + } } } /** - * Takes the uploaded_by_me string, the upload date, name of articles using images + * Takes the uploaded_by_me string, the upload date, no. of articles using images * and appends it to the received reason - * @param feedBack object + * @param fileUsages No. of files/articles using this image * @param media whose upload data is to be fetched - * @param reason + * @param reason string to be appended */ @SuppressLint("StringFormatInvalid") - private fun appendArticlesUsed(feedBack: FeedbackResponse, media: Media, reason: String): String { + private fun appendArticlesUsed(fileUsages: Int, media: Media, reason: String): String { val reason1Template = context.getString(R.string.uploaded_by_myself) - return reason + String.format(Locale.getDefault(), reason1Template, prettyUploadedDate(media), feedBack.articlesUsingImages) + return reason + String.format(Locale.getDefault(), reason1Template, prettyUploadedDate(media), fileUsages) .also { Timber.i("New Reason %s", it) } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 65ffda846..c9a2d16c8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -431,7 +431,7 @@ I changed my mind, I don\'t want it to be publicly visible anymore Sorry this picture is not interesting for an encyclopedia - Uploaded by myself on %1$s, used in %2$d article(s). + Uploaded by myself on %1$s, used in %2$d article(s) at least. Welcome to Commons!\n Upload your first media by tapping on the add button. diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index afb3615d2..d1fa89e42 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -16,6 +16,7 @@ constraintlayout = "1.1.3" coordinates2country = "1.8" dexcount = "4.0.0" githubTripletPlay = "2.7.2" +kotlinxCoroutinesRx2 = "1.8.0" osmdroidAndroid = "6.1.17" testCore = "1.4.0" coreKtx = "1.9.0" @@ -127,6 +128,7 @@ dagger-compiler = { module = "com.google.dagger:dagger-compiler", version.ref = facebook-fresco = { module = "com.facebook.fresco:fresco", version.ref = "frescoVersion" } glide-compiler = { module = "com.github.bumptech.glide:compiler", version.ref = "glide" } glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" } +kotlinx-coroutines-rx2 = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-rx2", version.ref = "kotlinxCoroutinesRx2" } photoview = { module = "com.github.chrisbanes:PhotoView", version.ref = "photoviewVersion" } # RxJava and Reactive Programming