diff --git a/app/src/main/java/fr/free/nrw/commons/Media.java b/app/src/main/java/fr/free/nrw/commons/Media.java
index 214660334..b3e18fe11 100644
--- a/app/src/main/java/fr/free/nrw/commons/Media.java
+++ b/app/src/main/java/fr/free/nrw/commons/Media.java
@@ -518,6 +518,14 @@ public class Media implements Parcelable {
this.coordinates = coordinates;
}
+ /**
+ * Returns wikicode to use the media file on a MediaWiki site
+ * @return
+ */
+ public String getWikiCode() {
+ return String.format("[[%s|thumb|%s]]", filename, thumbnailTitle);
+ }
+
/**
* Sets the categories the file falls under.
*
diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.java b/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.java
index 5461ccfca..4b969be03 100644
--- a/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.java
+++ b/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.java
@@ -39,7 +39,7 @@ public class Contribution extends Media {
* and value is the caption in the corresponding language Ex: key = "en", value: "
" key = "de" , value: "
"
*/
- private Map captions = new HashMap<>();
+ private HashMap captions = new HashMap<>();
public Contribution() {
}
@@ -51,7 +51,7 @@ public class Contribution extends Media {
UploadMediaDetail.formatList(item.getUploadMediaDetails()),
sessionManager.getAuthorName(),
categories);
- captions = UploadMediaDetail.formatCaptions(item.getUploadMediaDetails());
+ captions = new HashMap<>(UploadMediaDetail.formatCaptions(item.getUploadMediaDetails()));
decimalCoords = item.getGpsCoords().getDecimalCoords();
dateCreatedSource = "";
this.depictedItems = depictedItems;
@@ -127,11 +127,11 @@ public class Contribution extends Media {
*
* returns list of captions stored in hashmap
*/
- public Map getCaptions() {
+ public HashMap getCaptions() {
return captions;
}
- public void setCaptions(Map captions) {
+ public void setCaptions(HashMap captions) {
this.captions = captions;
}
@@ -147,7 +147,7 @@ public class Contribution extends Media {
dest.writeLong(transferred);
dest.writeString(decimalCoords);
dest.writeString(dateCreatedSource);
- dest.writeSerializable((HashMap) captions);
+ dest.writeSerializable(captions);
}
/**
diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionDao.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionDao.java
index e288a84af..20de34eb9 100644
--- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionDao.java
+++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionDao.java
@@ -53,6 +53,9 @@ public abstract class ContributionDao {
@Query("SELECT * from contribution WHERE filename=:fileName")
public abstract List getContributionWithTitle(String fileName);
+ @Query("SELECT * from contribution WHERE pageId=:pageId")
+ public abstract Contribution getContribution(String pageId);
+
@Query("UPDATE contribution SET state=:state WHERE state in (:toUpdateStates)")
public abstract Single updateStates(int state, int[] toUpdateStates);
diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionViewHolder.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionViewHolder.java
index a5de53bb1..1064d86ca 100644
--- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionViewHolder.java
+++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionViewHolder.java
@@ -5,8 +5,10 @@ import static fr.free.nrw.commons.depictions.Media.DepictedImagesFragment.PAGE_I
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;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
@@ -22,147 +24,203 @@ 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 {
- private final Callback callback;
- @BindView(R.id.contributionImage)
- SimpleDraweeView imageView;
- @BindView(R.id.contributionTitle) TextView titleView;
- @BindView(R.id.contributionState) TextView stateView;
- @BindView(R.id.contributionSequenceNumber) TextView seqNumView;
- @BindView(R.id.contributionProgress) ProgressBar progressView;
- @BindView(R.id.failed_image_options) LinearLayout failedImageOptions;
+ private final Callback callback;
+ @BindView(R.id.contributionImage)
+ SimpleDraweeView imageView;
+ @BindView(R.id.contributionTitle)
+ TextView titleView;
+ @BindView(R.id.contributionState)
+ TextView stateView;
+ @BindView(R.id.contributionSequenceNumber)
+ TextView seqNumView;
+ @BindView(R.id.contributionProgress)
+ ProgressBar progressView;
+ @BindView(R.id.image_options)
+ RelativeLayout imageOptions;
+ @BindView(R.id.wikipediaButton)
+ ImageButton addToWikipediaButton;
+ @BindView(R.id.retryButton)
+ ImageButton retryButton;
+ @BindView(R.id.cancelButton)
+ ImageButton cancelButton;
- private int position;
- private Contribution contribution;
- private final CompositeDisposable compositeDisposable = new CompositeDisposable();
- private final MediaClient mediaClient;
+ private int position;
+ private Contribution contribution;
+ private final CompositeDisposable compositeDisposable = new CompositeDisposable();
+ private final MediaClient mediaClient;
- ContributionViewHolder(final View parent, final Callback callback,
- final MediaClient mediaClient) {
- super(parent);
- this.mediaClient = mediaClient;
- ButterKnife.bind(this, parent);
- this.callback=callback;
+ ContributionViewHolder(final View parent, final Callback callback,
+ final MediaClient mediaClient) {
+ super(parent);
+ this.mediaClient = mediaClient;
+ ButterKnife.bind(this, parent);
+ this.callback = callback;
+ }
+
+ public void init(final int position, final Contribution contribution) {
+ this.contribution = contribution;
+ fetchAndDisplayCaption(contribution);
+ this.position = position;
+ final String imageSource = chooseImageSource(contribution.getThumbUrl(),
+ contribution.getLocalUri());
+ if (!TextUtils.isEmpty(imageSource)) {
+ final ImageRequest imageRequest =
+ ImageRequestBuilder.newBuilderWithSource(Uri.parse(imageSource))
+ .setProgressiveRenderingEnabled(true)
+ .build();
+ imageView.setImageRequest(imageRequest);
}
- public void init(final int position, final Contribution contribution) {
- this.contribution = contribution;
- fetchAndDisplayCaption(contribution);
- this.position = position;
- final String imageSource = chooseImageSource(contribution.getThumbUrl(), contribution.getLocalUri());
- if (!TextUtils.isEmpty(imageSource)) {
- final ImageRequest imageRequest =
- ImageRequestBuilder.newBuilderWithSource(Uri.parse(imageSource))
- .setProgressiveRenderingEnabled(true)
- .build();
- imageView.setImageRequest(imageRequest);
- }
+ seqNumView.setText(String.valueOf(position + 1));
+ seqNumView.setVisibility(View.VISIBLE);
- seqNumView.setText(String.valueOf(position + 1));
- seqNumView.setVisibility(View.VISIBLE);
-
- switch (contribution.getState()) {
- case Contribution.STATE_COMPLETED:
- stateView.setVisibility(View.GONE);
- progressView.setVisibility(View.GONE);
- failedImageOptions.setVisibility(View.GONE);
- stateView.setText("");
- break;
- case Contribution.STATE_QUEUED:
- stateView.setVisibility(View.VISIBLE);
- progressView.setVisibility(View.GONE);
- stateView.setText(R.string.contribution_state_queued);
- failedImageOptions.setVisibility(View.GONE);
- break;
- case Contribution.STATE_IN_PROGRESS:
- stateView.setVisibility(View.GONE);
- progressView.setVisibility(View.VISIBLE);
- failedImageOptions.setVisibility(View.GONE);
- final long total = contribution.getDataLength();
- final long transferred = contribution.getTransferred();
- if (transferred == 0 || transferred >= total) {
- progressView.setIndeterminate(true);
- } else {
- progressView.setProgress((int)(((double)transferred / (double)total) * 100));
- }
- break;
- case Contribution.STATE_FAILED:
- stateView.setVisibility(View.VISIBLE);
- stateView.setText(R.string.contribution_state_failed);
- progressView.setVisibility(View.GONE);
- failedImageOptions.setVisibility(View.VISIBLE);
- break;
- }
- }
-
- /**
- * 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());
+ addToWikipediaButton.setVisibility(View.GONE);
+ switch (contribution.getState()) {
+ case Contribution.STATE_COMPLETED:
+ stateView.setVisibility(View.GONE);
+ progressView.setVisibility(View.GONE);
+ imageOptions.setVisibility(View.GONE);
+ stateView.setText("");
+ checkIfMediaExistsOnWikipediaPage(contribution);
+ break;
+ case Contribution.STATE_QUEUED:
+ stateView.setVisibility(View.VISIBLE);
+ progressView.setVisibility(View.GONE);
+ stateView.setText(R.string.contribution_state_queued);
+ imageOptions.setVisibility(View.GONE);
+ break;
+ case Contribution.STATE_IN_PROGRESS:
+ stateView.setVisibility(View.GONE);
+ progressView.setVisibility(View.VISIBLE);
+ imageOptions.setVisibility(View.GONE);
+ final long total = contribution.getDataLength();
+ final long transferred = contribution.getTransferred();
+ if (transferred == 0 || transferred >= total) {
+ progressView.setIndeterminate(true);
} 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());
- }
+ progressView.setProgress((int) (((double) transferred / (double) total) * 100));
}
+ break;
+ case Contribution.STATE_FAILED:
+ stateView.setVisibility(View.VISIBLE);
+ stateView.setText(R.string.contribution_state_failed);
+ progressView.setVisibility(View.GONE);
+ imageOptions.setVisibility(View.VISIBLE);
+ break;
}
+ }
- /**
- * Returns the image source for the image view, first preference is given to thumbUrl if that is
- * null, moves to local uri and if both are null return null
- *
- * @param thumbUrl
- * @param localUri
- * @return
- */
- @Nullable
- private String chooseImageSource(final String thumbUrl, final Uri localUri) {
- return !TextUtils.isEmpty(thumbUrl) ? thumbUrl :
- localUri != null ? localUri.toString() :
- null;
+ /**
+ * 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());
+ }
}
+ }
- /**
- * Retry upload when it is failed
- */
- @OnClick(R.id.retryButton)
- public void retryUpload() {
- callback.retryUpload(contribution);
+ /**
+ * Checks if a media exists on the corresponding Wikipedia article Currently the check is made for
+ * the device's current language Wikipedia
+ *
+ * @param contribution
+ */
+ private void checkIfMediaExistsOnWikipediaPage(final Contribution contribution) {
+ if (contribution.getWikidataPlace() == null
+ || contribution.getWikidataPlace().getWikipediaArticle() == null) {
+ return;
}
+ final String wikipediaArticle = contribution.getWikidataPlace().getWikipediaPageTitle();
+ compositeDisposable.add(mediaClient.doesPageContainMedia(wikipediaArticle)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(mediaExists -> {
+ displayWikipediaButton(mediaExists);
+ }));
+ }
- /**
- * Delete a failed upload attempt
- */
- @OnClick(R.id.cancelButton)
- public void deleteUpload() {
- callback.deleteUpload(contribution);
+ /**
+ * Handle action buttons visibility if the corresponding wikipedia page doesn't contain any media.
+ * This method needs to control the state of just the scenario where media does not exists as
+ * other scenarios are already handled in the init method.
+ *
+ * @param mediaExists
+ */
+ private void displayWikipediaButton(Boolean mediaExists) {
+ if (!mediaExists) {
+ addToWikipediaButton.setVisibility(View.VISIBLE);
+ cancelButton.setVisibility(View.GONE);
+ retryButton.setVisibility(View.GONE);
+ imageOptions.setVisibility(View.VISIBLE);
}
+ }
- @OnClick(R.id.contributionImage)
- public void imageClicked(){
- callback.openMediaDetail(position);
- }
+ /**
+ * Returns the image source for the image view, first preference is given to thumbUrl if that is
+ * null, moves to local uri and if both are null return null
+ *
+ * @param thumbUrl
+ * @param localUri
+ * @return
+ */
+ @Nullable
+ private String chooseImageSource(final String thumbUrl, final Uri localUri) {
+ return !TextUtils.isEmpty(thumbUrl) ? thumbUrl :
+ localUri != null ? localUri.toString() :
+ null;
+ }
+
+ /**
+ * Retry upload when it is failed
+ */
+ @OnClick(R.id.retryButton)
+ public void retryUpload() {
+ callback.retryUpload(contribution);
+ }
+
+ /**
+ * Delete a failed upload attempt
+ */
+ @OnClick(R.id.cancelButton)
+ public void deleteUpload() {
+ callback.deleteUpload(contribution);
+ }
+
+ @OnClick(R.id.contributionImage)
+ public void imageClicked() {
+ callback.openMediaDetail(position);
+ }
+
+ @OnClick(R.id.wikipediaButton)
+ public void wikipediaButtonClicked() {
+ callback.addImageToWikipedia(contribution);
+ }
}
diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListAdapter.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListAdapter.java
index a0c8e1088..0b2556f0e 100644
--- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListAdapter.java
+++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListAdapter.java
@@ -7,8 +7,9 @@ import androidx.paging.PagedListAdapter;
import androidx.recyclerview.widget.DiffUtil;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.media.MediaClient;
+import org.wikipedia.dataclient.WikiSite;
-/**
+ /**
* Represents The View Adapter for the List of Contributions
*/
public class ContributionsListAdapter extends
@@ -64,7 +65,8 @@ public class ContributionsListAdapter extends
final int viewType) {
final ContributionViewHolder viewHolder = new ContributionViewHolder(
LayoutInflater.from(parent.getContext())
- .inflate(R.layout.layout_contribution, parent, false), callback, mediaClient);
+ .inflate(R.layout.layout_contribution, parent, false),
+ callback, mediaClient);
return viewHolder;
}
@@ -75,5 +77,7 @@ public class ContributionsListAdapter extends
void deleteUpload(Contribution contribution);
void openMediaDetail(int contribution);
+
+ void addImageToWikipedia(Contribution contribution);
}
}
diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java
index ad859fd36..e1bb1968e 100644
--- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java
+++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java
@@ -2,9 +2,11 @@ package fr.free.nrw.commons.contributions;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
+import static fr.free.nrw.commons.di.NetworkingModule.NAMED_LANGUAGE_WIKI_PEDIA_WIKI_SITE;
import android.content.Context;
import android.content.res.Configuration;
+import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.view.LayoutInflater;
@@ -17,25 +19,29 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.RecyclerView.LayoutManager;
import butterknife.BindView;
import butterknife.ButterKnife;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.R;
+import fr.free.nrw.commons.Utils;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.media.MediaClient;
-import fr.free.nrw.commons.media.MediaDetailPagerFragment;
+import fr.free.nrw.commons.utils.DialogUtil;
+import java.util.Locale;
import javax.inject.Inject;
+import javax.inject.Named;
+import org.wikipedia.dataclient.WikiSite;
/**
* Created by root on 01.06.2018.
*/
public class ContributionsListFragment extends CommonsDaggerSupportFragment implements
- ContributionsListContract.View, ContributionsListAdapter.Callback {
+ ContributionsListContract.View, ContributionsListAdapter.Callback, WikipediaInstructionsDialogFragment.Callback {
private static final String RV_STATE = "rv_scroll_state";
@@ -59,6 +65,10 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
@Inject
MediaClient mediaClient;
+ @Named(NAMED_LANGUAGE_WIKI_PEDIA_WIKI_SITE)
+ @Inject
+ WikiSite languageWikipediaSite;
+
@Inject
ContributionsListPresenter contributionsListPresenter;
@@ -200,7 +210,8 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
- final GridLayoutManager layoutManager = (GridLayoutManager) rvContributionsList.getLayoutManager();
+ final GridLayoutManager layoutManager = (GridLayoutManager) rvContributionsList
+ .getLayoutManager();
outState.putParcelable(RV_STATE, layoutManager.onSaveInstanceState());
}
@@ -232,6 +243,39 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
}
}
+ /**
+ * Handle callback for wikipedia icon clicked
+ *
+ * @param contribution
+ */
+ @Override
+ public void addImageToWikipedia(Contribution contribution) {
+ DialogUtil.showAlertDialog(getActivity(),
+ getString(R.string.add_picture_to_wikipedia_article_title),
+ String.format(getString(R.string.add_picture_to_wikipedia_article_desc),
+ Locale.getDefault().getDisplayLanguage()),
+ () -> {
+ showAddImageToWikipediaInstructions(contribution);
+ }, () -> {
+ // do nothing
+ });
+ }
+
+ /**
+ * Display confirmation dialog with instructions when the user tries to add image to wikipedia
+ *
+ * @param contribution
+ */
+ private void showAddImageToWikipediaInstructions(Contribution contribution) {
+ FragmentManager fragmentManager = getFragmentManager();
+ WikipediaInstructionsDialogFragment fragment = WikipediaInstructionsDialogFragment
+ .newInstance(contribution);
+ fragment.setCallback(this::onConfirmClicked);
+ fragment.show(fragmentManager, "WikimediaFragment");
+ }
+
+
+
public Media getMediaAtPosition(final int i) {
return adapter.getContributionForPosition(i);
}
@@ -240,6 +284,23 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
return adapter.getItemCount();
}
+ /**
+ * Open the editor for the language Wikipedia
+ *
+ * @param contribution
+ */
+ @Override
+ public void onConfirmClicked(@Nullable Contribution contribution, boolean copyWikicode) {
+ if(copyWikicode) {
+ String wikicode = contribution.getWikiCode();
+ Utils.copy("wikicode", wikicode, getContext());
+ }
+
+ final String url = languageWikipediaSite.mobileUrl() + "/wiki/" + contribution.getWikidataPlace()
+ .getWikipediaPageTitle();
+ Utils.handleWebUrl(getContext(), Uri.parse(url));
+ }
+
public interface Callback {
void retryUpload(Contribution contribution);
diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsLocalDataSource.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsLocalDataSource.java
index 3b94d0fa7..5e21940b5 100644
--- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsLocalDataSource.java
+++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsLocalDataSource.java
@@ -2,6 +2,7 @@ package fr.free.nrw.commons.contributions;
import androidx.paging.DataSource.Factory;
import io.reactivex.Completable;
+import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
@@ -67,7 +68,15 @@ class ContributionsLocalDataSource {
}
public Single> saveContributions(List contributions) {
- return contributionDao.save(contributions);
+ List contributionList = new ArrayList<>();
+ for(Contribution contribution: contributions) {
+ Contribution oldContribution = contributionDao.getContribution(contribution.getPageId());
+ if(oldContribution != null) {
+ contribution.setWikidataPlace(oldContribution.getWikidataPlace());
+ }
+ contributionList.add(contribution);
+ }
+ return contributionDao.save(contributionList);
}
public void set(String key, long value) {
diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/WikipediaInstructionsDialogFragment.kt b/app/src/main/java/fr/free/nrw/commons/contributions/WikipediaInstructionsDialogFragment.kt
new file mode 100644
index 000000000..3032f718e
--- /dev/null
+++ b/app/src/main/java/fr/free/nrw/commons/contributions/WikipediaInstructionsDialogFragment.kt
@@ -0,0 +1,67 @@
+package fr.free.nrw.commons.contributions
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.WindowManager
+import androidx.fragment.app.DialogFragment
+import fr.free.nrw.commons.R
+import kotlinx.android.synthetic.main.dialog_add_to_wikipedia_instructions.*
+
+/**
+ * Dialog fragment for displaying instructions for editing wikipedia
+ */
+class WikipediaInstructionsDialogFragment : DialogFragment() {
+
+ var contribution: Contribution? = null
+ var callback: Callback? = null
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ return inflater.inflate(R.layout.dialog_add_to_wikipedia_instructions, container)
+ }
+
+ override fun onViewCreated(
+ view: View,
+ savedInstanceState: Bundle?
+ ) {
+ super.onViewCreated(view, savedInstanceState)
+ contribution = arguments!!.getParcelable(ARG_CONTRIBUTION)
+ tv_wikicode.setText(contribution?.wikiCode)
+ instructions_cancel.setOnClickListener {
+ dismiss()
+ }
+
+ instructions_confirm.setOnClickListener {
+ callback?.onConfirmClicked(contribution, checkbox_copy_wikicode.isChecked)
+ }
+
+ dialog!!.window.setSoftInputMode(
+ WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
+ )
+ }
+
+ /**
+ * Callback for handling confirm button clicked
+ */
+ interface Callback {
+ fun onConfirmClicked(contribution: Contribution?, copyWikicode: Boolean)
+ }
+
+ companion object {
+
+ val ARG_CONTRIBUTION = "contribution"
+
+ @JvmStatic
+ fun newInstance(contribution: Contribution): WikipediaInstructionsDialogFragment {
+ val frag = WikipediaInstructionsDialogFragment()
+ val args = Bundle()
+ args.putParcelable(ARG_CONTRIBUTION, contribution)
+ frag.arguments = args
+ return frag
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/fr/free/nrw/commons/db/Converters.java b/app/src/main/java/fr/free/nrw/commons/db/Converters.java
index 94311c67c..b5326f777 100644
--- a/app/src/main/java/fr/free/nrw/commons/db/Converters.java
+++ b/app/src/main/java/fr/free/nrw/commons/db/Converters.java
@@ -11,6 +11,7 @@ import fr.free.nrw.commons.media.Depictions;
import fr.free.nrw.commons.upload.WikidataPlace;
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
import java.util.Date;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -54,13 +55,13 @@ public class Converters {
}
@TypeConverter
- public static String mapObjectToString(Map objectList) {
+ public static String mapObjectToString(HashMap objectList) {
return writeObjectToString(objectList);
}
@TypeConverter
- public static Map stringToMap(String objectList) {
- return readObjectWithTypeToken(objectList, new TypeTokenDid you shoot these two pictures at the same place? Do you want to use the latitude/longitude of the picture on the right?Load MoreNo places found, try changing your search criteria.
+
+ Add image to Wikipedia
+ Do you want to add this picture to the %1$s language Wikipedia article?
+
+ Instructions
+ Take care to follow editing guidelines!
+ Confirm
+ Instructions
+ 1. Use the following wikitext:
+ 2. Clicking on Confirm will open the Wikipedia article
+ 3. Find an appropriate section in the article for your image
+ 4. Click on the Edit icon (the one like a pencil) for that section.
+ 5. Paste the wikitext in the appropriate place.
+ 6. Edit the wikitext for appropriate positioning, if necessary. For more information, see <a href="https://en.wikipedia.org/wiki/Wikipedia:Manual_of_Style/Images#How_to_place_an_image">here</a>.
+ 7. Publish the article
+ Copy wikicode to clipboard
diff --git a/app/src/test/kotlin/fr/free/nrw/commons/contributions/ContributionsRepositoryTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/contributions/ContributionsRepositoryTest.kt
index 0b11c4bb4..b90b4420c 100644
--- a/app/src/test/kotlin/fr/free/nrw/commons/contributions/ContributionsRepositoryTest.kt
+++ b/app/src/test/kotlin/fr/free/nrw/commons/contributions/ContributionsRepositoryTest.kt
@@ -6,11 +6,9 @@ import com.nhaarman.mockitokotlin2.whenever
import fr.free.nrw.commons.utils.createMockDataSourceFactory
import io.reactivex.Scheduler
import io.reactivex.Single
-import junit.framework.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.mockito.*
-import org.mockito.Mockito.any
import org.mockito.Mockito.mock
/**
diff --git a/app/src/test/kotlin/fr/free/nrw/commons/media/MediaClientTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/media/MediaClientTest.kt
index d594e722b..1fe48fb8d 100644
--- a/app/src/test/kotlin/fr/free/nrw/commons/media/MediaClientTest.kt
+++ b/app/src/test/kotlin/fr/free/nrw/commons/media/MediaClientTest.kt
@@ -2,6 +2,8 @@ package fr.free.nrw.commons.media
import com.nhaarman.mockitokotlin2.whenever
import fr.free.nrw.commons.Media
+import fr.free.nrw.commons.media.model.PageMediaListItem
+import fr.free.nrw.commons.media.model.PageMediaListResponse
import fr.free.nrw.commons.utils.CommonsDateUtil
import io.reactivex.Observable
import junit.framework.Assert.*
@@ -25,6 +27,9 @@ class MediaClientTest {
@Mock
internal var mediaInterface: MediaInterface? = null
+ @Mock
+ internal var pageMediaInterface: PageMediaInterface? = null
+
@InjectMocks
var mediaClient: MediaClient? = null
@@ -250,6 +255,26 @@ class MediaClientTest {
assertEquals("Test", mediaClient!!.getPageHtml("abcde").blockingGet())
}
+ @Test
+ fun doesPageContainMedia() {
+ val mock = mock(PageMediaListResponse::class.java)
+ whenever(mock.items).thenReturn(listOf(mock(PageMediaListItem::class.java)))
+ `when`(pageMediaInterface!!.getMediaList(ArgumentMatchers.anyString()))
+ .thenReturn(Observable.just(mock))
+
+ mediaClient!!.doesPageContainMedia("Test").test().assertValue(true)
+ }
+
+ @Test
+ fun doesPageContainMediaWithNoMedia() {
+ val mock = mock(PageMediaListResponse::class.java)
+ whenever(mock.items).thenReturn(listOf())
+ `when`(pageMediaInterface!!.getMediaList(ArgumentMatchers.anyString()))
+ .thenReturn(Observable.just(mock))
+
+ mediaClient!!.doesPageContainMedia("Test").test().assertValue(false)
+ }
+
@Test
fun getPageHtmlTestNull() {
val mockResponse = MwParseResponse()
diff --git a/data-client/src/main/java/org/wikipedia/dataclient/WikiSite.java b/data-client/src/main/java/org/wikipedia/dataclient/WikiSite.java
index cac1f681c..37f603e60 100644
--- a/data-client/src/main/java/org/wikipedia/dataclient/WikiSite.java
+++ b/data-client/src/main/java/org/wikipedia/dataclient/WikiSite.java
@@ -138,6 +138,15 @@ public class WikiSite implements Parcelable {
return authorityToMobile(authority());
}
+ /**
+ * Get wiki's mobile URL
+ * Eg. https://en.m.wikipedia.org
+ * @return
+ */
+ public String mobileUrl() {
+ return String.format("%1$s://%2$s", scheme(), mobileAuthority());
+ }
+
/**
* @return The canonical "desktop" form of the authority. For example, if the authority
* is in a "mobile" form, e.g. en.m.wikipedia.org, this will become en.wikipedia.org.