mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-29 13:53:54 +01:00
* #3468 Switch from RvRenderer to AdapterDelegates - replace SearchDepictionsRenderer * #3468 Switch from RvRenderer to AdapterDelegates - replace UploadCategoryDepictionsRenderer * #3468 Switch from RvRenderer to AdapterDelegates - update BaseAdapter to be easier to use * #3468 Switch from RvRenderer to AdapterDelegates - replace SearchImagesRenderer * #3468 Switch from RvRenderer to AdapterDelegates - replace SearchCategoriesRenderer * #3468 Switch from RvRenderer to AdapterDelegates - replace NotificationRenderer * #3468 Switch from RvRenderer to AdapterDelegates - replace UploadDepictsRenderer * #3468 Switch from RvRenderer to AdapterDelegates - replace PlaceRenderer * #3756 Convert SearchDepictionsFragment to use Pagination - convert SearchDepictionsFragment * #3756 Convert SearchDepictionsFragment to use Pagination - fix presenter unit tests now that view is not nullable - fix Category prefix imports * #3756 Convert SearchDepictionsFragment to use Pagination - test DataSource related classes * #3756 Convert SearchDepictionsFragment to use Pagination - reset rx scheduler - ignore failing test * #3760 Convert SearchCategoriesFragment to use Pagination - extract functionality of pagination to base classes - add category pagination * #3772 Convert SearchImagesFragment to use Pagination - convert SearchImagesFragment - tidy up showing the empty view - make search fragments show snackbar with appropriate text * #3772 Convert SearchImagesFragment to use Pagination - allow viewpager to load more data * #3760 remove test that got re-added by merge * #3760 remove duplicate dependency * #3772 fix compilation * #3780 Create media using a combination of Entities & MwQueryResult - construct media with an entity - move fields from media down to contribution - move dynamic fields outside of media - remove unused constructors - remove all unnecessary fetching of captions/descriptions - bump database version * #3808 Construct media objects that depict an item id correctly - use generator to construct media for DepictedImages * #3780 Create media using a combination of Entities & MwQueryResult - update wikicode to align with expected behaviour * #3780 Create media using a combination of Entities & MwQueryResult - replace old site of thumbnail title with most relevant caption
This commit is contained in:
parent
bf4b7e2efc
commit
4b22583b60
46 changed files with 803 additions and 1532 deletions
|
|
@ -1,17 +1,18 @@
|
|||
package fr.free.nrw.commons.contributions;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.room.Entity;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.auth.SessionManager;
|
||||
import fr.free.nrw.commons.upload.UploadMediaDetail;
|
||||
import fr.free.nrw.commons.upload.UploadItem;
|
||||
import fr.free.nrw.commons.upload.UploadMediaDetail;
|
||||
import fr.free.nrw.commons.upload.WikidataPlace;
|
||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity(tableName = "contribution")
|
||||
|
|
@ -34,24 +35,23 @@ public class Contribution extends Media {
|
|||
*/
|
||||
private List<DepictedItem> depictedItems = new ArrayList<>();
|
||||
private String mimeType;
|
||||
/**
|
||||
* This hasmap stores the list of multilingual captions, where key of the HashMap is the language
|
||||
* and value is the caption in the corresponding language Ex: key = "en", value: "<caption in
|
||||
* short in English>" key = "de" , value: "<caption in german>"
|
||||
*/
|
||||
private HashMap<String, String> captions = new HashMap<>();
|
||||
@Nullable
|
||||
private Uri localUri;
|
||||
private long dataLength;
|
||||
private Date dateCreated;
|
||||
|
||||
public Contribution() {
|
||||
}
|
||||
|
||||
public Contribution(final UploadItem item, final SessionManager sessionManager,
|
||||
final List<DepictedItem> depictedItems, final List<String> categories) {
|
||||
super(item.getMediaUri(),
|
||||
super(
|
||||
item.getFileName(),
|
||||
UploadMediaDetail.formatList(item.getUploadMediaDetails()),
|
||||
UploadMediaDetail.formatCaptions(item.getUploadMediaDetails()),
|
||||
UploadMediaDetail.formatDescriptions(item.getUploadMediaDetails()),
|
||||
sessionManager.getAuthorName(),
|
||||
categories);
|
||||
captions = new HashMap<>(UploadMediaDetail.formatCaptions(item.getUploadMediaDetails()));
|
||||
localUri = item.getMediaUri();
|
||||
decimalCoords = item.getGpsCoords().getDecimalCoords();
|
||||
dateCreatedSource = "";
|
||||
this.depictedItems = depictedItems;
|
||||
|
|
@ -117,24 +117,6 @@ public class Contribution extends Media {
|
|||
this.mimeType = mimeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Captions are a feature part of Structured data. They are meant to store short, multilingual
|
||||
* descriptions about files This is a replacement of the previously used titles for images (titles
|
||||
* were not multilingual) Also now captions replace the previous convention of using title for
|
||||
* filename
|
||||
* <p>
|
||||
* key of the HashMap is the language and value is the caption in the corresponding language
|
||||
* <p>
|
||||
* returns list of captions stored in hashmap
|
||||
*/
|
||||
public HashMap<String, String> getCaptions() {
|
||||
return captions;
|
||||
}
|
||||
|
||||
public void setCaptions(HashMap<String, String> captions) {
|
||||
this.captions = captions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
|
|
@ -147,7 +129,6 @@ public class Contribution extends Media {
|
|||
dest.writeLong(transferred);
|
||||
dest.writeString(decimalCoords);
|
||||
dest.writeString(dateCreatedSource);
|
||||
dest.writeSerializable(captions);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -156,13 +137,7 @@ public class Contribution extends Media {
|
|||
* @param state
|
||||
*/
|
||||
public Contribution(Media media, int state) {
|
||||
super(media.getPageId(),
|
||||
media.getLocalUri(), media.getThumbUrl(), media.getImageUrl(), media.getFilename(),
|
||||
media.getDescription(),
|
||||
media.getDiscussion(),
|
||||
media.getDataLength(), media.getDateCreated(), media.getDateUploaded(),
|
||||
media.getLicense(), media.getLicenseUrl(), media.getCreator(), media.getCategories(),
|
||||
media.isRequestedDeletion(), media.getCoordinates());
|
||||
super(media);
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
|
|
@ -172,7 +147,6 @@ public class Contribution extends Media {
|
|||
transferred = in.readLong();
|
||||
decimalCoords = in.readString();
|
||||
dateCreatedSource = in.readString();
|
||||
captions = (HashMap<String, String>) in.readSerializable();
|
||||
}
|
||||
|
||||
public static final Creator<Contribution> CREATOR = new Creator<Contribution>() {
|
||||
|
|
@ -187,34 +161,60 @@ public class Contribution extends Media {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Equals implementation of Contributions that compares all parameters for checking equality
|
||||
*/
|
||||
@Nullable
|
||||
public Uri getLocalUri() {
|
||||
return localUri;
|
||||
}
|
||||
|
||||
public void setLocalUri(@Nullable Uri localUri) {
|
||||
this.localUri = localUri;
|
||||
}
|
||||
|
||||
public long getDataLength() {
|
||||
return dataLength;
|
||||
}
|
||||
|
||||
public void setDataLength(long dataLength) {
|
||||
this.dataLength = dataLength;
|
||||
}
|
||||
|
||||
public Date getDateCreated() {
|
||||
return dateCreated;
|
||||
}
|
||||
|
||||
public void setDateCreated(Date dateCreated) {
|
||||
this.dateCreated = dateCreated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof Contribution)) {
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
if (!super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
final Contribution that = (Contribution) o;
|
||||
return getState() == that.getState() && getTransferred() == that.getTransferred() && Objects
|
||||
.equals(getDecimalCoords(), that.getDecimalCoords()) && Objects
|
||||
.equals(getDateCreatedSource(), that.getDateCreatedSource()) && Objects
|
||||
.equals(getWikidataPlace(), that.getWikidataPlace()) && Objects
|
||||
.equals(getDepictedItems(), that.getDepictedItems()) && Objects
|
||||
.equals(getMimeType(), that.getMimeType()) && Objects
|
||||
.equals(getCaptions(), that.getCaptions());
|
||||
return state == that.state &&
|
||||
transferred == that.transferred &&
|
||||
dataLength == that.dataLength &&
|
||||
Objects.equals(decimalCoords, that.decimalCoords) &&
|
||||
Objects.equals(dateCreatedSource, that.dateCreatedSource) &&
|
||||
Objects.equals(wikidataPlace, that.wikidataPlace) &&
|
||||
Objects.equals(depictedItems, that.depictedItems) &&
|
||||
Objects.equals(mimeType, that.mimeType) &&
|
||||
Objects.equals(localUri, that.localUri) &&
|
||||
Objects.equals(dateCreated, that.dateCreated);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash code implementation of contributions that considers all parameters for calculating hash.
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects
|
||||
.hash(getState(), getTransferred(), getDecimalCoords(), getDateCreatedSource(),
|
||||
getWikidataPlace(), getDepictedItems(), getMimeType(), getCaptions());
|
||||
.hash(super.hashCode(), state, transferred, decimalCoords, dateCreatedSource,
|
||||
wikidataPlace,
|
||||
depictedItems, mimeType, localUri, dataLength, dateCreated);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,9 +62,7 @@ class ContributionBoundaryCallback @Inject constructor(
|
|||
}
|
||||
}
|
||||
.subscribeOn(ioThreadScheduler)
|
||||
.subscribe(
|
||||
::saveContributionsToDB
|
||||
) { error: Throwable ->
|
||||
.subscribe(::saveContributionsToDB) { error: Throwable ->
|
||||
Timber.e(
|
||||
"Failed to fetch contributions: %s",
|
||||
error.message
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
package fr.free.nrw.commons.contributions;
|
||||
|
||||
import static fr.free.nrw.commons.depictions.Media.DepictedImagesFragment.PAGE_ID_PREFIX;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
|
@ -24,8 +21,6 @@ import fr.free.nrw.commons.media.MediaClient;
|
|||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import org.wikipedia.dataclient.WikiSite;
|
||||
import timber.log.Timber;
|
||||
|
||||
public class ContributionViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
|
|
@ -65,8 +60,8 @@ public class ContributionViewHolder extends RecyclerView.ViewHolder {
|
|||
|
||||
public void init(final int position, final Contribution contribution) {
|
||||
this.contribution = contribution;
|
||||
fetchAndDisplayCaption(contribution);
|
||||
this.position = position;
|
||||
titleView.setText(contribution.getMostRelevantCaption());
|
||||
final String imageSource = chooseImageSource(contribution.getThumbUrl(),
|
||||
contribution.getLocalUri());
|
||||
if (!TextUtils.isEmpty(imageSource)) {
|
||||
|
|
@ -116,37 +111,6 @@ public class ContributionViewHolder extends RecyclerView.ViewHolder {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* In contributions first we show the title for the image stored in cache, then we fetch captions
|
||||
* associated with the image and replace title on the thumbnail with caption
|
||||
*
|
||||
* @param contribution
|
||||
*/
|
||||
private void fetchAndDisplayCaption(final Contribution contribution) {
|
||||
if ((contribution.getState() != Contribution.STATE_COMPLETED)) {
|
||||
titleView.setText(contribution.getDisplayTitle());
|
||||
} else {
|
||||
final String pageId = contribution.getPageId();
|
||||
if (pageId != null) {
|
||||
Timber.d("Fetching caption for %s", contribution.getFilename());
|
||||
final String wikibaseMediaId = PAGE_ID_PREFIX
|
||||
+ pageId; // Create Wikibase media id from the page id. Example media id: M80618155 for https://commons.wikimedia.org/wiki/File:Tantanmen.jpeg with has the pageid 80618155
|
||||
compositeDisposable.add(mediaClient.getCaptionByWikibaseIdentifier(wikibaseMediaId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(subscriber -> {
|
||||
if (!subscriber.trim().equals(MediaClient.NO_CAPTION)) {
|
||||
titleView.setText(subscriber);
|
||||
} else {
|
||||
titleView.setText(contribution.getDisplayTitle());
|
||||
}
|
||||
}));
|
||||
} else {
|
||||
titleView.setText(contribution.getDisplayTitle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a media exists on the corresponding Wikipedia article Currently the check is made for
|
||||
* the device's current language Wikipedia
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
package fr.free.nrw.commons.contributions;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import fr.free.nrw.commons.BasePresenter;
|
||||
import fr.free.nrw.commons.Media;
|
||||
|
||||
/**
|
||||
* The contract for Contributions View & Presenter
|
||||
|
|
@ -21,8 +18,5 @@ public class ContributionsContract {
|
|||
|
||||
void deleteUpload(Contribution contribution);
|
||||
|
||||
void updateContribution(Contribution contribution);
|
||||
|
||||
void fetchMediaDetails(Contribution contribution);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,9 +46,8 @@ public class ContributionsListAdapter extends
|
|||
* Initializes the view holder with contribution data
|
||||
*/
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final ContributionViewHolder holder, final int position) {
|
||||
final Contribution contribution = getItem(position);
|
||||
holder.init(position, contribution);
|
||||
public void onBindViewHolder(@NonNull ContributionViewHolder holder, int position) {
|
||||
holder.init(position, getItem(position));
|
||||
}
|
||||
|
||||
Contribution getContributionForPosition(final int position) {
|
||||
|
|
|
|||
|
|
@ -1,30 +1,10 @@
|
|||
package fr.free.nrw.commons.contributions;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import fr.free.nrw.commons.CommonsApplication;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.MediaDataExtractor;
|
||||
import fr.free.nrw.commons.auth.SessionManager;
|
||||
import fr.free.nrw.commons.MediaDataExtractor;
|
||||
import fr.free.nrw.commons.contributions.ContributionsContract.UserActionListener;
|
||||
import fr.free.nrw.commons.di.CommonsApplicationModule;
|
||||
import fr.free.nrw.commons.mwapi.UserClient;
|
||||
import fr.free.nrw.commons.utils.NetworkUtils;
|
||||
import io.reactivex.Scheduler;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import timber.log.Timber;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
|
|
@ -77,24 +57,4 @@ public class ContributionsPresenter implements UserActionListener {
|
|||
.subscribeOn(ioThreadScheduler)
|
||||
.subscribe());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateContribution(Contribution contribution) {
|
||||
compositeDisposable.add(repository
|
||||
.updateContribution(contribution)
|
||||
.subscribeOn(ioThreadScheduler)
|
||||
.subscribe());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fetchMediaDetails(Contribution contribution) {
|
||||
compositeDisposable.add(mediaDataExtractor
|
||||
.getMediaFromFileName(contribution.getFilename())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(media -> {
|
||||
contribution.setThumbUrl(media.getThumbUrl());
|
||||
updateContribution(contribution);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue