Improve credit line in image list (#6295)
Some checks are pending
Android CI / Run tests and generate APK (push) Waiting to run

- When author is not uploader, show both.
- When failing to parse author from HTML, use structured data.
This commit is contained in:
Yusuke Matsubara 2025-04-23 23:23:09 +09:00 committed by GitHub
parent 30762971db
commit 329a68216e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 363 additions and 81 deletions

View file

@ -8,23 +8,29 @@ import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.RecyclerView
import com.facebook.imagepipeline.request.ImageRequest
import com.facebook.imagepipeline.request.ImageRequestBuilder
import fr.free.nrw.commons.Media
import fr.free.nrw.commons.utils.MediaAttributionUtil
import fr.free.nrw.commons.MediaDataExtractor
import fr.free.nrw.commons.R
import fr.free.nrw.commons.databinding.LayoutContributionBinding
import fr.free.nrw.commons.media.MediaClient
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import timber.log.Timber
import java.io.File
class ContributionViewHolder internal constructor(
private val parent: View, private val callback: ContributionsListAdapter.Callback,
private val mediaClient: MediaClient
parent: View,
private val callback: ContributionsListAdapter.Callback,
private val compositeDisposable: CompositeDisposable,
private val mediaClient: MediaClient,
private val mediaDataExtractor: MediaDataExtractor
) : RecyclerView.ViewHolder(parent) {
var binding: LayoutContributionBinding = LayoutContributionBinding.bind(parent)
private var position = 0
private var contribution: Contribution? = null
private val compositeDisposable = CompositeDisposable()
private var isWikipediaButtonDisplayed = false
private val pausingPopUp: AlertDialog
var imageRequest: ImageRequest? = null
@ -54,7 +60,7 @@ an upload might take a dozen seconds. */
this.contribution = contribution
this.position = position
binding.contributionTitle.text = contribution.media.mostRelevantCaption
binding.authorView.text = contribution.media.getAuthorOrUser()
setAuthorText(contribution.media)
//Removes flicker of loading image.
binding.contributionImage.hierarchy.fadeDuration = 0
@ -93,6 +99,30 @@ an upload might take a dozen seconds. */
checkIfMediaExistsOnWikipediaPage(contribution)
}
fun updateAttribution() {
if (contribution != null) {
val media = contribution!!.media
if (!media.getAttributedAuthor().isNullOrEmpty()) {
return
}
compositeDisposable.addAll(
mediaDataExtractor.fetchCreatorIdsAndLabels(media)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ idAndLabels ->
media.creatorName = MediaAttributionUtil.getCreatorName(idAndLabels)
setAuthorText(media)
},
{ t: Throwable? -> Timber.e(t) })
)
}
}
private fun setAuthorText(media: Media) {
binding.authorView.text = MediaAttributionUtil.getTagLine(media, itemView.context)
}
/**
* Checks if a media exists on the corresponding Wikipedia article Currently the check is made
* for the device's current language Wikipedia

View file

@ -4,21 +4,26 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.paging.PagedListAdapter
import androidx.recyclerview.widget.DiffUtil
import fr.free.nrw.commons.MediaDataExtractor
import fr.free.nrw.commons.R
import fr.free.nrw.commons.media.MediaClient
import io.reactivex.disposables.CompositeDisposable
/**
* Represents The View Adapter for the List of Contributions
*/
class ContributionsListAdapter internal constructor(
private val callback: Callback,
private val mediaClient: MediaClient
private val mediaClient: MediaClient,
private val mediaDataExtractor: MediaDataExtractor,
private val compositeDisposable: CompositeDisposable
) : PagedListAdapter<Contribution, ContributionViewHolder>(DIFF_CALLBACK) {
/**
* Initializes the view holder with contribution data
*/
override fun onBindViewHolder(holder: ContributionViewHolder, position: Int) {
holder.init(position, getItem(position))
holder.updateAttribution()
}
fun getContributionForPosition(position: Int): Contribution? {
@ -36,7 +41,7 @@ class ContributionsListAdapter internal constructor(
val viewHolder = ContributionViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.layout_contribution, parent, false),
callback, mediaClient
callback, compositeDisposable, mediaClient, mediaDataExtractor
)
return viewHolder
}

View file

@ -27,6 +27,7 @@ import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver
import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener
import androidx.recyclerview.widget.SimpleItemAnimator
import fr.free.nrw.commons.Media
import fr.free.nrw.commons.MediaDataExtractor
import fr.free.nrw.commons.R
import fr.free.nrw.commons.Utils
import fr.free.nrw.commons.auth.SessionManager
@ -63,6 +64,10 @@ class ContributionsListFragment : CommonsDaggerSupportFragment(), ContributionsL
@Inject
var mediaClient: MediaClient? = null
@JvmField
@Inject
var mediaDataExtractor: MediaDataExtractor? = null
@JvmField
@Named(NetworkingModule.NAMED_LANGUAGE_WIKI_PEDIA_WIKI_SITE)
@Inject
@ -231,7 +236,7 @@ class ContributionsListFragment : CommonsDaggerSupportFragment(), ContributionsL
}
private fun initAdapter() {
adapter = ContributionsListAdapter(this, mediaClient!!)
adapter = ContributionsListAdapter(this, mediaClient!!, mediaDataExtractor!!, compositeDisposable)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {