mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 12:23:58 +01:00
With option for associating image with wikipedia article (#3783)
This commit is contained in:
parent
a4379fde02
commit
e4190f3f7d
28 changed files with 979 additions and 479 deletions
|
|
@ -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.
|
||||
* </p>
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public class Contribution extends Media {
|
|||
* 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 Map<String, String> captions = new HashMap<>();
|
||||
private HashMap<String, String> 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 {
|
|||
* <p>
|
||||
* returns list of captions stored in hashmap
|
||||
*/
|
||||
public Map<String, String> getCaptions() {
|
||||
public HashMap<String, String> getCaptions() {
|
||||
return captions;
|
||||
}
|
||||
|
||||
public void setCaptions(Map<String, String> captions) {
|
||||
public void setCaptions(HashMap<String, String> 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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -53,6 +53,9 @@ public abstract class ContributionDao {
|
|||
@Query("SELECT * from contribution WHERE filename=:fileName")
|
||||
public abstract List<Contribution> 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<Integer> updateStates(int state, int[] toUpdateStates);
|
||||
|
||||
|
|
|
|||
|
|
@ -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,6 +24,7 @@ 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 {
|
||||
|
|
@ -29,11 +32,22 @@ 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;
|
||||
@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;
|
||||
|
|
@ -53,7 +67,8 @@ public class ContributionViewHolder extends RecyclerView.ViewHolder {
|
|||
this.contribution = contribution;
|
||||
fetchAndDisplayCaption(contribution);
|
||||
this.position = position;
|
||||
final String imageSource = chooseImageSource(contribution.getThumbUrl(), contribution.getLocalUri());
|
||||
final String imageSource = chooseImageSource(contribution.getThumbUrl(),
|
||||
contribution.getLocalUri());
|
||||
if (!TextUtils.isEmpty(imageSource)) {
|
||||
final ImageRequest imageRequest =
|
||||
ImageRequestBuilder.newBuilderWithSource(Uri.parse(imageSource))
|
||||
|
|
@ -65,23 +80,25 @@ public class ContributionViewHolder extends RecyclerView.ViewHolder {
|
|||
seqNumView.setText(String.valueOf(position + 1));
|
||||
seqNumView.setVisibility(View.VISIBLE);
|
||||
|
||||
addToWikipediaButton.setVisibility(View.GONE);
|
||||
switch (contribution.getState()) {
|
||||
case Contribution.STATE_COMPLETED:
|
||||
stateView.setVisibility(View.GONE);
|
||||
progressView.setVisibility(View.GONE);
|
||||
failedImageOptions.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);
|
||||
failedImageOptions.setVisibility(View.GONE);
|
||||
imageOptions.setVisibility(View.GONE);
|
||||
break;
|
||||
case Contribution.STATE_IN_PROGRESS:
|
||||
stateView.setVisibility(View.GONE);
|
||||
progressView.setVisibility(View.VISIBLE);
|
||||
failedImageOptions.setVisibility(View.GONE);
|
||||
imageOptions.setVisibility(View.GONE);
|
||||
final long total = contribution.getDataLength();
|
||||
final long transferred = contribution.getTransferred();
|
||||
if (transferred == 0 || transferred >= total) {
|
||||
|
|
@ -94,14 +111,14 @@ public class ContributionViewHolder extends RecyclerView.ViewHolder {
|
|||
stateView.setVisibility(View.VISIBLE);
|
||||
stateView.setText(R.string.contribution_state_failed);
|
||||
progressView.setVisibility(View.GONE);
|
||||
failedImageOptions.setVisibility(View.VISIBLE);
|
||||
imageOptions.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
|
||||
* 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
|
||||
*/
|
||||
|
|
@ -130,6 +147,42 @@ public class ContributionViewHolder extends RecyclerView.ViewHolder {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
@ -165,4 +218,9 @@ public class ContributionViewHolder extends RecyclerView.ViewHolder {
|
|||
public void imageClicked() {
|
||||
callback.openMediaDetail(position);
|
||||
}
|
||||
|
||||
@OnClick(R.id.wikipediaButton)
|
||||
public void wikipediaButtonClicked() {
|
||||
callback.addImageToWikipedia(contribution);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ 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
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<List<Long>> saveContributions(List<Contribution> contributions) {
|
||||
return contributionDao.save(contributions);
|
||||
List<Contribution> 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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<String,String> objectList) {
|
||||
public static String mapObjectToString(HashMap<String,String> objectList) {
|
||||
return writeObjectToString(objectList);
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
public static Map<String,String> stringToMap(String objectList) {
|
||||
return readObjectWithTypeToken(objectList, new TypeToken<Map<String,String>>(){});
|
||||
public static HashMap<String,String> stringToMap(String objectList) {
|
||||
return readObjectWithTypeToken(objectList, new TypeToken<HashMap<String,String>>(){});
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import fr.free.nrw.commons.explore.depictions.DepictsClient;
|
|||
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||
import fr.free.nrw.commons.media.MediaDetailInterface;
|
||||
import fr.free.nrw.commons.media.MediaInterface;
|
||||
import fr.free.nrw.commons.media.PageMediaInterface;
|
||||
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
|
||||
import fr.free.nrw.commons.mwapi.UserInterface;
|
||||
import fr.free.nrw.commons.review.ReviewInterface;
|
||||
|
|
@ -21,6 +22,7 @@ import fr.free.nrw.commons.upload.WikiBaseInterface;
|
|||
import fr.free.nrw.commons.upload.depicts.DepictsInterface;
|
||||
import fr.free.nrw.commons.wikidata.WikidataInterface;
|
||||
import java.io.File;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
|
@ -49,6 +51,9 @@ public class NetworkingModule {
|
|||
|
||||
public static final String NAMED_COMMONS_WIKI_SITE = "commons-wikisite";
|
||||
private static final String NAMED_WIKI_DATA_WIKI_SITE = "wikidata-wikisite";
|
||||
private static final String NAMED_WIKI_PEDIA_WIKI_SITE = "wikipedia-wikisite";
|
||||
|
||||
public static final String NAMED_LANGUAGE_WIKI_PEDIA_WIKI_SITE = "language-wikipedia-wikisite";
|
||||
|
||||
public static final String NAMED_COMMONS_CSRF = "commons-csrf";
|
||||
|
||||
|
|
@ -234,4 +239,21 @@ public class NetworkingModule {
|
|||
public WikidataInterface provideWikidataInterface(@Named(NAMED_WIKI_DATA_WIKI_SITE) WikiSite wikiDataWikiSite) {
|
||||
return ServiceFactory.get(wikiDataWikiSite, BuildConfig.WIKIDATA_URL, WikidataInterface.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add provider for PageMediaInterface
|
||||
* It creates a retrofit service for the wiki site using device's current language
|
||||
*/
|
||||
@Provides
|
||||
@Singleton
|
||||
public PageMediaInterface providePageMediaInterface(@Named(NAMED_LANGUAGE_WIKI_PEDIA_WIKI_SITE) WikiSite wikiSite) {
|
||||
return ServiceFactory.get(wikiSite, wikiSite.url(), PageMediaInterface.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named(NAMED_LANGUAGE_WIKI_PEDIA_WIKI_SITE)
|
||||
public WikiSite provideLanguageWikipediaSite() {
|
||||
return WikiSite.forLanguageCode(Locale.getDefault().getLanguage());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import timber.log.Timber;
|
|||
public class MediaClient {
|
||||
|
||||
private final MediaInterface mediaInterface;
|
||||
private final PageMediaInterface pageMediaInterface;
|
||||
private final MediaDetailInterface mediaDetailInterface;
|
||||
|
||||
//OkHttpJsonApiClient used JsonKvStore for this. I don't know why.
|
||||
|
|
@ -37,8 +38,11 @@ public class MediaClient {
|
|||
private static final String NO_DEPICTION = "No depiction";
|
||||
|
||||
@Inject
|
||||
public MediaClient(MediaInterface mediaInterface, MediaDetailInterface mediaDetailInterface) {
|
||||
public MediaClient(MediaInterface mediaInterface,
|
||||
PageMediaInterface pageMediaInterface,
|
||||
MediaDetailInterface mediaDetailInterface) {
|
||||
this.mediaInterface = mediaInterface;
|
||||
this.pageMediaInterface = pageMediaInterface;
|
||||
this.mediaDetailInterface = mediaDetailInterface;
|
||||
this.continuationStore = new HashMap<>();
|
||||
this.continuationExists = new HashMap<>();
|
||||
|
|
@ -222,6 +226,13 @@ public class MediaClient {
|
|||
.singleOrError();
|
||||
}
|
||||
|
||||
public Single<Boolean> doesPageContainMedia(String title) {
|
||||
return pageMediaInterface.getMediaList(title)
|
||||
.map(pageMediaListResponse -> {
|
||||
return pageMediaListResponse.getItems().size() > 0;
|
||||
}).singleOrError();
|
||||
}
|
||||
|
||||
private boolean isSuccess(Entities response) {
|
||||
return response != null && response.getSuccess() == 1 && response.entities() != null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
package fr.free.nrw.commons.media
|
||||
|
||||
import fr.free.nrw.commons.media.model.PageMediaListResponse
|
||||
import io.reactivex.Observable
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Path
|
||||
|
||||
/**
|
||||
* Interface for MediaWiki Page REST APIs
|
||||
*/
|
||||
interface PageMediaInterface {
|
||||
/**
|
||||
* Get a list of media used on a page
|
||||
*
|
||||
* @param title the title of the page
|
||||
*/
|
||||
@GET("api/rest_v1/page/media-list/{title}")
|
||||
fun getMediaList(@Path("title") title: String?): Observable<PageMediaListResponse?>?
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package fr.free.nrw.commons.media.model
|
||||
|
||||
data class PageMediaListResponse(
|
||||
val revision: String,
|
||||
val tid: String,
|
||||
val items: List<PageMediaListItem>
|
||||
)
|
||||
|
||||
data class PageMediaListItem(val title: String)
|
||||
|
|
@ -125,7 +125,6 @@ public class Place implements Parcelable {
|
|||
}
|
||||
|
||||
String wikiDataLink = siteLinks.getWikidataLink().toString();
|
||||
Timber.d("Wikidata entity is %s", wikiDataLink);
|
||||
return wikiDataLink.replace("http://www.wikidata.org/entity/", "");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1419,14 +1419,17 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
|||
if (fabGallery.isShown()) {
|
||||
Timber.d("Gallery button tapped. Place: %s", selectedPlace.toString());
|
||||
storeSharedPrefs(selectedPlace);
|
||||
|
||||
controller.initiateGalleryPick(getActivity(), false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void storeSharedPrefs(final Place selectedPlace) {
|
||||
Timber.d("Store place object %s", selectedPlace.toString());
|
||||
applicationKvStore.putJson(PLACE_OBJECT, selectedPlace);
|
||||
Place place = applicationKvStore.getJson(PLACE_OBJECT, Place.class);
|
||||
|
||||
Timber.d("Stored place object %s", place.toString());
|
||||
}
|
||||
|
||||
private void updateBookmarkButtonImage(final Place place) {
|
||||
|
|
|
|||
|
|
@ -51,17 +51,22 @@ public class UploadService extends CommonsDaggerService {
|
|||
|
||||
public static final String ACTION_START_SERVICE = EXTRA_PREFIX + ".upload";
|
||||
public static final String EXTRA_FILES = EXTRA_PREFIX + ".files";
|
||||
@Inject WikidataEditService wikidataEditService;
|
||||
@Inject SessionManager sessionManager;
|
||||
@Inject
|
||||
WikidataEditService wikidataEditService;
|
||||
@Inject
|
||||
SessionManager sessionManager;
|
||||
@Inject
|
||||
ContributionDao contributionDao;
|
||||
@Inject UploadClient uploadClient;
|
||||
@Inject MediaClient mediaClient;
|
||||
@Inject
|
||||
UploadClient uploadClient;
|
||||
@Inject
|
||||
MediaClient mediaClient;
|
||||
@Inject
|
||||
@Named(CommonsApplicationModule.MAIN_THREAD)
|
||||
Scheduler mainThreadScheduler;
|
||||
@Inject
|
||||
@Named(CommonsApplicationModule.IO_THREAD) Scheduler ioThreadScheduler;
|
||||
@Named(CommonsApplicationModule.IO_THREAD)
|
||||
Scheduler ioThreadScheduler;
|
||||
|
||||
private NotificationManagerCompat notificationManager;
|
||||
private NotificationCompat.Builder curNotification;
|
||||
|
|
@ -88,7 +93,8 @@ public class UploadService extends CommonsDaggerService {
|
|||
String notificationProgressTitle;
|
||||
String notificationFinishingTitle;
|
||||
|
||||
NotificationUpdateProgressListener(String notificationTag, String notificationProgressTitle, String notificationFinishingTitle, Contribution contribution) {
|
||||
NotificationUpdateProgressListener(String notificationTag, String notificationProgressTitle,
|
||||
String notificationFinishingTitle, Contribution contribution) {
|
||||
this.notificationTag = notificationTag;
|
||||
this.notificationProgressTitle = notificationProgressTitle;
|
||||
this.notificationFinishingTitle = notificationFinishingTitle;
|
||||
|
|
@ -107,9 +113,11 @@ public class UploadService extends CommonsDaggerService {
|
|||
.setTicker(notificationFinishingTitle)
|
||||
.setProgress(0, 100, true);
|
||||
} else {
|
||||
curNotification.setProgress(100, (int) (((double) transferred / (double) total) * 100), false);
|
||||
curNotification
|
||||
.setProgress(100, (int) (((double) transferred / (double) total) * 100), false);
|
||||
}
|
||||
notificationManager.notify(notificationTag, NOTIFICATION_UPLOAD_IN_PROGRESS, curNotification.build());
|
||||
notificationManager
|
||||
.notify(notificationTag, NOTIFICATION_UPLOAD_IN_PROGRESS, curNotification.build());
|
||||
|
||||
contribution.setTransferred(transferred);
|
||||
|
||||
|
|
@ -128,6 +136,7 @@ public class UploadService extends CommonsDaggerService {
|
|||
}
|
||||
|
||||
public class UploadServiceLocalBinder extends Binder {
|
||||
|
||||
public UploadService getService() {
|
||||
return UploadService.this;
|
||||
}
|
||||
|
|
@ -158,9 +167,12 @@ public class UploadService extends CommonsDaggerService {
|
|||
contribution.setTransferred(0);
|
||||
toUpload++;
|
||||
if (curNotification != null && toUpload != 1) {
|
||||
curNotification.setContentText(getResources().getQuantityString(R.plurals.uploads_pending_notification_indicator, toUpload, toUpload));
|
||||
curNotification.setContentText(getResources()
|
||||
.getQuantityString(R.plurals.uploads_pending_notification_indicator, toUpload, toUpload));
|
||||
Timber.d("%d uploads left", toUpload);
|
||||
notificationManager.notify(contribution.getLocalUri().toString(), NOTIFICATION_UPLOAD_IN_PROGRESS, curNotification.build());
|
||||
notificationManager
|
||||
.notify(contribution.getLocalUri().toString(), NOTIFICATION_UPLOAD_IN_PROGRESS,
|
||||
curNotification.build());
|
||||
}
|
||||
|
||||
compositeDisposable.add(contributionDao
|
||||
|
|
@ -178,7 +190,8 @@ public class UploadService extends CommonsDaggerService {
|
|||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if (ACTION_START_SERVICE.equals(intent.getAction()) && freshStart) {
|
||||
compositeDisposable.add(contributionDao.updateStates(Contribution.STATE_FAILED, new int[]{Contribution.STATE_QUEUED, Contribution.STATE_IN_PROGRESS})
|
||||
compositeDisposable.add(contributionDao.updateStates(Contribution.STATE_FAILED,
|
||||
new int[]{Contribution.STATE_QUEUED, Contribution.STATE_IN_PROGRESS})
|
||||
.observeOn(mainThreadScheduler)
|
||||
.subscribeOn(ioThreadScheduler)
|
||||
.subscribe());
|
||||
|
|
@ -196,7 +209,8 @@ public class UploadService extends CommonsDaggerService {
|
|||
.setOnlyAlertOnce(true)
|
||||
.setProgress(100, 0, true)
|
||||
.setOngoing(true)
|
||||
.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0));
|
||||
.setContentIntent(
|
||||
PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0));
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
|
|
@ -210,18 +224,25 @@ public class UploadService extends CommonsDaggerService {
|
|||
File localFile = new File(localUri.getPath());
|
||||
|
||||
Timber.d("Before execution!");
|
||||
curNotification.setContentTitle(getString(R.string.upload_progress_notification_title_start, contribution.getDisplayTitle()))
|
||||
.setContentText(getResources().getQuantityString(R.plurals.uploads_pending_notification_indicator, toUpload, toUpload))
|
||||
.setTicker(getString(R.string.upload_progress_notification_title_in_progress, contribution.getDisplayTitle()))
|
||||
curNotification.setContentTitle(getString(R.string.upload_progress_notification_title_start,
|
||||
contribution.getDisplayTitle()))
|
||||
.setContentText(getResources()
|
||||
.getQuantityString(R.plurals.uploads_pending_notification_indicator, toUpload,
|
||||
toUpload))
|
||||
.setTicker(getString(R.string.upload_progress_notification_title_in_progress,
|
||||
contribution.getDisplayTitle()))
|
||||
.setOngoing(true);
|
||||
notificationManager
|
||||
.notify(notificationTag, NOTIFICATION_UPLOAD_IN_PROGRESS, curNotification.build());
|
||||
|
||||
String filename = contribution.getFilename();
|
||||
|
||||
NotificationUpdateProgressListener notificationUpdater = new NotificationUpdateProgressListener(notificationTag,
|
||||
getString(R.string.upload_progress_notification_title_in_progress, contribution.getDisplayTitle()),
|
||||
getString(R.string.upload_progress_notification_title_finishing, contribution.getDisplayTitle()),
|
||||
NotificationUpdateProgressListener notificationUpdater = new NotificationUpdateProgressListener(
|
||||
notificationTag,
|
||||
getString(R.string.upload_progress_notification_title_in_progress,
|
||||
contribution.getDisplayTitle()),
|
||||
getString(R.string.upload_progress_notification_title_finishing,
|
||||
contribution.getDisplayTitle()),
|
||||
contribution
|
||||
);
|
||||
|
||||
|
|
@ -238,7 +259,9 @@ public class UploadService extends CommonsDaggerService {
|
|||
toUpload--;
|
||||
if (toUpload == 0) {
|
||||
// Sync modifications right after all uploads are processed
|
||||
ContentResolver.requestSync(sessionManager.getCurrentAccount(), BuildConfig.MODIFICATION_AUTHORITY, new Bundle());
|
||||
ContentResolver
|
||||
.requestSync(sessionManager.getCurrentAccount(), BuildConfig.MODIFICATION_AUTHORITY,
|
||||
new Bundle());
|
||||
stopForeground(true);
|
||||
}
|
||||
})
|
||||
|
|
@ -289,6 +312,7 @@ public class UploadService extends CommonsDaggerService {
|
|||
compositeDisposable
|
||||
.add(wikidataEditService.addDepictionsAndCaptions(uploadResult, contribution));
|
||||
WikidataPlace wikidataPlace = contribution.getWikidataPlace();
|
||||
Timber.d("Wikidata place %s", wikidataPlace.toString());
|
||||
if (wikidataPlace != null && wikidataPlace.getImageValue() == null) {
|
||||
wikidataEditService.createImageClaim(wikidataPlace, uploadResult);
|
||||
}
|
||||
|
|
@ -297,20 +321,30 @@ public class UploadService extends CommonsDaggerService {
|
|||
|
||||
private void saveCompletedContribution(Contribution contribution, UploadResult uploadResult) {
|
||||
compositeDisposable.add(mediaClient.getMedia("File:" + uploadResult.getFilename())
|
||||
.map(media -> new Contribution(media, Contribution.STATE_COMPLETED))
|
||||
.flatMapCompletable(newContribution -> contributionDao.saveAndDelete(contribution, newContribution))
|
||||
.map(media -> {
|
||||
Contribution newContribution = new Contribution(media, Contribution.STATE_COMPLETED);
|
||||
if (contribution.getWikidataPlace() != null) {
|
||||
newContribution.setWikidataPlace(contribution.getWikidataPlace());
|
||||
}
|
||||
return newContribution;
|
||||
})
|
||||
.flatMapCompletable(
|
||||
newContribution -> contributionDao.saveAndDelete(contribution, newContribution))
|
||||
.subscribe());
|
||||
}
|
||||
|
||||
@SuppressLint("StringFormatInvalid")
|
||||
@SuppressWarnings("deprecation")
|
||||
private void showFailedNotification(Contribution contribution) {
|
||||
curNotification.setTicker(getString(R.string.upload_failed_notification_title, contribution.getDisplayTitle()))
|
||||
.setContentTitle(getString(R.string.upload_failed_notification_title, contribution.getDisplayTitle()))
|
||||
curNotification.setTicker(
|
||||
getString(R.string.upload_failed_notification_title, contribution.getDisplayTitle()))
|
||||
.setContentTitle(
|
||||
getString(R.string.upload_failed_notification_title, contribution.getDisplayTitle()))
|
||||
.setContentText(getString(R.string.upload_failed_notification_subtitle))
|
||||
.setProgress(0, 0, false)
|
||||
.setOngoing(false);
|
||||
notificationManager.notify(contribution.getLocalUri().toString(), NOTIFICATION_UPLOAD_FAILED, curNotification.build());
|
||||
notificationManager.notify(contribution.getLocalUri().toString(), NOTIFICATION_UPLOAD_FAILED,
|
||||
curNotification.build());
|
||||
|
||||
contribution.setState(Contribution.STATE_FAILED);
|
||||
|
||||
|
|
@ -336,7 +370,8 @@ public class UploadService extends CommonsDaggerService {
|
|||
sequenceFileName = regexMatcher.replaceAll("$1 " + sequenceNumber + "$2");
|
||||
}
|
||||
}
|
||||
if (!mediaClient.checkPageExistsUsingTitle(String.format("File:%s",sequenceFileName)).blockingGet()
|
||||
if (!mediaClient.checkPageExistsUsingTitle(String.format("File:%s", sequenceFileName))
|
||||
.blockingGet()
|
||||
&& !unfinishedUploads.contains(sequenceFileName)) {
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,19 @@ import fr.free.nrw.commons.nearby.Place
|
|||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
@Parcelize
|
||||
internal data class WikidataPlace(override val id: String, override val name: String, val imageValue: String?) :
|
||||
internal data class WikidataPlace(
|
||||
override val id: String,
|
||||
override val name: String,
|
||||
val imageValue: String?,
|
||||
val wikipediaArticle: String?
|
||||
) :
|
||||
WikidataItem, Parcelable {
|
||||
constructor(place: Place) : this(
|
||||
place.wikiDataEntityId!!,
|
||||
place.name,
|
||||
place.pic.takeIf { it.isNotBlank() })
|
||||
place.pic.takeIf { it.isNotBlank() },
|
||||
if (place.siteLinks.wikipediaLink == null) "" else place.siteLinks.wikipediaLink.toString()
|
||||
)
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
|
|
@ -18,4 +25,12 @@ internal data class WikidataPlace(override val id: String, override val name: St
|
|||
return place?.let { WikidataPlace(it) }
|
||||
}
|
||||
}
|
||||
|
||||
fun getWikipediaPageTitle(): String? {
|
||||
if (wikipediaArticle == null) {
|
||||
return null
|
||||
}
|
||||
val split: Array<String> = wikipediaArticle.split("/".toRegex()).toTypedArray()
|
||||
return split[split.size - 1]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
BIN
app/src/main/res/drawable-hdpi/ic_wikipedia.png
Normal file
BIN
app/src/main/res/drawable-hdpi/ic_wikipedia.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 647 B |
BIN
app/src/main/res/drawable-mdpi/ic_wikipedia.png
Normal file
BIN
app/src/main/res/drawable-mdpi/ic_wikipedia.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 420 B |
BIN
app/src/main/res/drawable-xhdpi/ic_wikipedia.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_wikipedia.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 895 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_wikipedia.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/ic_wikipedia.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/ic_wikipedia.png
Normal file
BIN
app/src/main/res/drawable-xxxhdpi/ic_wikipedia.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
110
app/src/main/res/layout/dialog_add_to_wikipedia_instructions.xml
Normal file
110
app/src/main/res/layout/dialog_add_to_wikipedia_instructions.xml
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/dimen_10"
|
||||
android:padding="@dimen/dimen_10"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/instructions_title"
|
||||
android:layout_marginBottom="@dimen/dimen_20"
|
||||
android:textSize="@dimen/heading_text_size" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/dimen_10"
|
||||
android:text="@string/wikipedia_instructions_step_1" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/tv_wikicode"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="#00000000"
|
||||
android:textSize="@dimen/description_text_size"
|
||||
android:layout_marginBottom="@dimen/dimen_10"
|
||||
tools:text="[File:Hello.jpg|Hello]"
|
||||
android:inputType="text" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/dimen_6"
|
||||
android:text="@string/wikipedia_instructions_step_2" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/dimen_6"
|
||||
android:text="@string/wikipedia_instructions_step_3" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/dimen_6"
|
||||
android:text="@string/wikipedia_instructions_step_4" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/dimen_6"
|
||||
android:text="@string/wikipedia_instructions_step_5" />
|
||||
|
||||
<fr.free.nrw.commons.ui.widget.HtmlTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/dimen_6"
|
||||
android:text="@string/wikipedia_instructions_step_6" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/dimen_6"
|
||||
android:text="@string/wikipedia_instructions_step_7" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/checkbox_copy_wikicode"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dimen_6"
|
||||
android:layout_marginBottom="@dimen/dimen_6"
|
||||
android:checked="true"
|
||||
android:text="@string/copy_wikicode_to_clipboard"/>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="2"
|
||||
android:layout_height="wrap_content">
|
||||
<Button
|
||||
android:id="@+id/instructions_cancel"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/cancel"
|
||||
android:textColor="@color/button_blue"
|
||||
android:padding="@dimen/dimen_10"
|
||||
android:backgroundTint="@color/white"
|
||||
android:layout_weight="1"
|
||||
android:layout_margin="@dimen/dimen_6"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/instructions_confirm"
|
||||
android:layout_width="wrap_content"
|
||||
android:text="@string/confirm"
|
||||
android:textColor="@color/white"
|
||||
android:padding="@dimen/dimen_10"
|
||||
android:layout_weight="1"
|
||||
android:layout_margin="@dimen/dimen_6"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
|
@ -74,14 +74,16 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/failed_image_options"
|
||||
<RelativeLayout
|
||||
android:id="@+id/image_options"
|
||||
android:layout_width="@dimen/dimen_0"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_weight="2"
|
||||
android:visibility="gone"
|
||||
android:padding="@dimen/small_gap"
|
||||
android:layout_weight="2.6"
|
||||
android:visibility="visible"
|
||||
android:layout_gravity="right"
|
||||
android:gravity="right"
|
||||
android:padding="@dimen/tiny_gap"
|
||||
>
|
||||
|
||||
<ImageButton
|
||||
|
|
@ -92,7 +94,8 @@
|
|||
android:text="@string/menu_cancel_upload"
|
||||
android:background="@android:color/transparent"
|
||||
android:padding="@dimen/activity_margin_horizontal"
|
||||
android:layout_marginRight="@dimen/tiny_padding"
|
||||
android:layout_toStartOf="@id/retryButton"
|
||||
android:layout_marginEnd="@dimen/tiny_padding"
|
||||
/>
|
||||
|
||||
<ImageButton
|
||||
|
|
@ -103,9 +106,24 @@
|
|||
android:text="@string/menu_retry_upload"
|
||||
android:background="@android:color/transparent"
|
||||
android:padding="@dimen/activity_margin_horizontal"
|
||||
android:layout_toStartOf="@id/wikipediaButton"
|
||||
android:layout_marginEnd="@dimen/tiny_padding"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
<ImageButton
|
||||
android:id="@+id/wikipediaButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_wikipedia"
|
||||
android:text="@string/menu_cancel_upload"
|
||||
android:background="@android:color/transparent"
|
||||
android:visibility="visible"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:padding="@dimen/activity_margin_horizontal"
|
||||
android:layout_marginEnd="@dimen/tiny_padding"
|
||||
/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,35 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<plurals name="uploads_pending_notification_indicator">
|
||||
<item quantity="one">%1$d file uploading</item>
|
||||
<item quantity="other">%1$d files uploading</item>
|
||||
</plurals>
|
||||
<plurals name="contributions_subtitle">
|
||||
<!--zero is not used in english. Category mentioned here for easy reference in future-->
|
||||
<item quantity="zero">@string/contributions_subtitle_zero</item>
|
||||
<item quantity="one">(%1$d)</item>
|
||||
<item quantity="other">(%1$d)</item>
|
||||
</plurals>
|
||||
<plurals name="starting_multiple_uploads">
|
||||
<item quantity="one">Starting %1$d upload</item>
|
||||
<item quantity="other">Starting %1$d uploads</item>
|
||||
</plurals>
|
||||
<plurals name="multiple_uploads_title">
|
||||
<item quantity="one">%1$d upload</item>
|
||||
<item quantity="other">%1$d uploads</item>
|
||||
</plurals>
|
||||
<plurals name="share_license_summary">
|
||||
<item quantity="one">This image will be licensed under %1$s</item>
|
||||
<item quantity="other">These images will be licensed under %1$s</item>
|
||||
</plurals>
|
||||
<plurals name="upload_count_title">
|
||||
<item quantity="one">%1$d Upload</item>
|
||||
<item quantity="other">%1$d Uploads</item>
|
||||
</plurals>
|
||||
<plurals name="receiving_shared_content">
|
||||
<item quantity="one">Receiving shared content. Processing the image might take some time depending on the size of the image and your device</item>
|
||||
<item quantity="other">Receiving shared content. Processing the images might take some time depending on the size of the images and your device</item>
|
||||
</plurals>
|
||||
<string name="title_activity_explore">Explore</string>
|
||||
<string name="navigation_item_explore">Explore</string>
|
||||
<string name="preference_category_appearance">Appearance</string>
|
||||
|
|
@ -31,10 +61,6 @@
|
|||
<string name="upload_progress_notification_title_finishing">Finishing uploading %1$s</string>
|
||||
<string name="upload_failed_notification_title">Uploading %1$s failed</string>
|
||||
<string name="upload_failed_notification_subtitle">Tap to view</string>
|
||||
<plurals name="uploads_pending_notification_indicator">
|
||||
<item quantity="one">%1$d file uploading</item>
|
||||
<item quantity="other">%1$d files uploading</item>
|
||||
</plurals>
|
||||
<string name="title_activity_contributions">My Recent Uploads</string>
|
||||
<string name="contribution_state_queued">Queued</string>
|
||||
<string name="contribution_state_failed">Failed</string>
|
||||
|
|
@ -69,20 +95,6 @@
|
|||
<string name="gps_disabled">GPS is disabled in your device. Would you like to enable it?</string>
|
||||
<string name="enable_gps">Enable GPS</string>
|
||||
<string name="contributions_subtitle_zero">No uploads yet</string>
|
||||
<plurals name="contributions_subtitle">
|
||||
<!--zero is not used in english. Category mentioned here for easy reference in future-->
|
||||
<item quantity="zero">@string/contributions_subtitle_zero</item>
|
||||
<item quantity="one">(%1$d)</item>
|
||||
<item quantity="other">(%1$d)</item>
|
||||
</plurals>
|
||||
<plurals name="starting_multiple_uploads">
|
||||
<item quantity="one">Starting %1$d upload</item>
|
||||
<item quantity="other">Starting %1$d uploads</item>
|
||||
</plurals>
|
||||
<plurals name="multiple_uploads_title">
|
||||
<item quantity="one">%1$d upload</item>
|
||||
<item quantity="other">%1$d uploads</item>
|
||||
</plurals>
|
||||
<string name="categories_not_found">No categories matching %1$s found</string>
|
||||
<string name="depictions_not_found">No Wikidata items matching %1$s found</string>
|
||||
<string name="no_child_classes">%1$s has no child classes</string>
|
||||
|
|
@ -110,10 +122,6 @@
|
|||
<string name="no_uploads_yet">You have not yet uploaded any photos.</string>
|
||||
<string name="menu_retry_upload">Retry</string>
|
||||
<string name="menu_cancel_upload">Cancel</string>
|
||||
<plurals name="share_license_summary">
|
||||
<item quantity="one">This image will be licensed under %1$s</item>
|
||||
<item quantity="other">These images will be licensed under %1$s</item>
|
||||
</plurals>
|
||||
<string name="media_upload_policy">By submitting this picture, I declare that this is my own work, that it does not contain copyrighted material or selfies, and otherwise adheres to <a href=\"https://commons.wikimedia.org/wiki/Commons:Policies_and_guidelines\">Wikimedia Commons policies</a>.</string>
|
||||
<string name="menu_download">Download</string>
|
||||
<string name="preference_license">Default License</string>
|
||||
|
|
@ -254,9 +262,9 @@
|
|||
<string name="title_info">A unique descriptive title for the file, which will serve as a filename. You may use plain language with spaces. Do not include the file extension</string>
|
||||
<string name="description_info">Please describe the media as much as possible: Where was it taken? What does it show? What is the context? Please describe the objects or persons. Reveal information that can not be easily guessed, for instance the time of day if it is a landscape. If the media shows something unusual, please explain what makes it unusual.</string>
|
||||
<string name="caption_info">Please write a brief description of the image. (Limit to 255 characters)</string>
|
||||
|
||||
<string name="upload_image_too_dark">This picture is too dark, are you sure you want to upload it? Wikimedia Commons is only for pictures with encyclopedic value.</string>
|
||||
<string name="upload_image_blurry">This picture is blurry, are you sure you want to upload it? Wikimedia Commons is only for pictures with encyclopedic value.</string>
|
||||
|
||||
<string name="upload_problem_exist">Potential problems with this image:</string>
|
||||
<string name="upload_problem_image_dark">Image is too dark.</string>
|
||||
<string name="upload_problem_image_blurry">Image is blurry.</string>
|
||||
|
|
@ -264,10 +272,10 @@
|
|||
<string name="upload_problem_different_geolocation">This picture was taken at a different location.</string>
|
||||
<string name="upload_problem_fbmd">Please only upload pictures that you have taken by yourself. Don\'t upload pictures that you have found on other people\'s Facebook accounts.</string>
|
||||
<string name="upload_problem_do_you_continue">Do you still want to upload this picture?</string>
|
||||
|
||||
|
||||
<string name="upload_problem_image">Problems found in image</string>
|
||||
<string name="internet_downloaded">Please only upload pictures that you have taken by yourself. Don\'t upload pictures that you have downloaded from the Internet.</string>
|
||||
|
||||
|
||||
<string name="give_permission">Give permission</string>
|
||||
<string name="use_external_storage">Use external storage</string>
|
||||
<string name="use_external_storage_summary">Save pictures taken with the in-app camera on your device</string>
|
||||
|
|
@ -287,15 +295,15 @@
|
|||
<string name="skip_login_title">Do you really want to skip login?</string>
|
||||
<string name="skip_login_message">You would have to log in to upload pictures in the future.</string>
|
||||
<string name="login_alert_message">Please log in to use this feature</string>
|
||||
|
||||
<string name="copy_wikicode">Copy the wikitext to the clipboard</string>
|
||||
<string name="wikicode_copied">The wikitext was copied to the clipboard</string>
|
||||
|
||||
<string name="nearby_location_has_not_changed">Location has not changed.</string>
|
||||
<string name="nearby_location_not_available">Nearby might not work properly, Location not available.</string>
|
||||
<string name="location_permission_rationale_nearby">Permission required to display a list of nearby places</string>
|
||||
|
||||
<string name="get_directions">Get directions</string>
|
||||
<string name="read_article">Read article</string>
|
||||
|
||||
<string formatted="false" name="notifications_welcome">Welcome to Wikimedia Commons, %1$s! We\'re glad you\'re here.</string>
|
||||
<string name="notifications_talk_page_message">%1$s left a message on your talk page</string>
|
||||
<string name="notifications_thank_you_edit">Thank you for making an edit</string>
|
||||
|
|
@ -318,18 +326,18 @@
|
|||
<string name="about_translate_title">Languages</string>
|
||||
<string name="about_translate_message">Select the language that you would like to submit translations for</string>
|
||||
<string name="about_translate_proceed">Proceed</string>
|
||||
|
||||
<string name="about_translate_cancel">Cancel</string>
|
||||
<string name="retry">Retry</string>
|
||||
|
||||
<string name="showcase_view_got_it_button">Got it!</string>
|
||||
<string name="showcase_view_whole_nearby_activity">These are the places near you that need pictures to illustrate their Wikipedia articles.\n\nClicking on \'SEARCH THIS AREA\' locks the map and launches a nearby search around that location.</string>
|
||||
|
||||
<string name="showcase_view_list_icon">Tapping this button brings up a list of these places</string>
|
||||
<string name="showcase_view_plus_fab">You can upload a picture for any place from your gallery or camera</string>
|
||||
|
||||
<string name="no_images_found">No images found!</string>
|
||||
|
||||
<string name="error_loading_images">Error occurred while loading images.</string>
|
||||
<string name="image_uploaded_by">Uploaded by: %1$s</string>
|
||||
|
||||
<string name="block_notification_title">Blocked</string>
|
||||
<string name="block_notification">You are blocked from editing Commons</string>
|
||||
<string name="appwidget_img">Pic of the Day</string>
|
||||
|
|
@ -346,9 +354,9 @@
|
|||
<string name="search_tab_title_media">Media</string>
|
||||
<string name="search_tab_title_categories">Categories</string>
|
||||
<string name="search_tab_title_depictions">Items</string>
|
||||
|
||||
<string name="explore_tab_title_featured">Featured</string>
|
||||
<string name="explore_tab_title_mobile">Uploaded via mobile</string>
|
||||
|
||||
<string name="successful_wikidata_edit">Image added to %1$s on Wikidata!</string>
|
||||
<string name="wikidata_edit_failure">Failed to update corresponding Wikidata entity!</string>
|
||||
<string name="menu_set_wallpaper">Set as wallpaper</string>
|
||||
|
|
@ -375,16 +383,16 @@
|
|||
<string name="quiz_screenshot_question">Is this screenshot OK to upload?</string>
|
||||
<string name="share_app_title">Share App</string>
|
||||
<string name="share_coordinates_not_present">Coordinates were not specified during image selection</string>
|
||||
|
||||
<string name="error_fetching_nearby_places">Error fetching nearby places.</string>
|
||||
<string name="add_description">+ Add description</string>
|
||||
|
||||
<string name="no_recent_searches">No recent searches</string>
|
||||
<string name="delete_recent_searches_dialog">Are you sure you want to clear your search history?</string>
|
||||
<string name="delete_search_dialog">Do you want to delete this search?</string>
|
||||
<string name="search_history_deleted">Search history deleted</string>
|
||||
|
||||
<string name="nominate_delete">Nominate For Deletion</string>
|
||||
<string name="delete">Delete</string>
|
||||
|
||||
<string name="Achievements">Achievements</string>
|
||||
<string name="statistics">Statistics</string>
|
||||
<string name="statistics_thanks">Thanks Received</string>
|
||||
|
|
@ -398,12 +406,12 @@
|
|||
<string name="achievements_info_message">Your level increases as you meet these requirements. Items in the "statistics" section do not count towards your level.</string>
|
||||
<string name="achievements_revert_limit_message">minimum required: </string>
|
||||
<string name="images_uploaded_explanation">The number of images you have uploaded to Commons, via any upload software</string>
|
||||
|
||||
<string name="images_reverted_explanation">The percentage of images you have uploaded to Commons that were not deleted</string>
|
||||
<string name="images_used_explanation">The number of images you have uploaded to Commons that were used in Wikimedia articles</string>
|
||||
|
||||
<string name="error_occurred">Error occurred!</string>
|
||||
<string name="notifications_channel_name_all">Commons Notification</string>
|
||||
|
||||
<string name="preference_author_name_toggle">Use custom author name</string>
|
||||
<string name="preference_author_name_toggle_summary">Use a custom author name instead of your username while uploading photos</string>
|
||||
<string name="preference_author_name">Custom author name</string>
|
||||
|
|
@ -413,24 +421,20 @@
|
|||
<string name="read_notifications">Notifications (read)</string>
|
||||
<string name="display_nearby_notification">Display nearby notification</string>
|
||||
<string name="display_nearby_notification_summary">Tap here to see the nearest place that needs pictures</string>
|
||||
|
||||
<string name="no_close_nearby">No nearby places found close to you</string>
|
||||
<string name="list_sheet">List</string>
|
||||
|
||||
<string name="storage_permission">Storage Permission</string>
|
||||
|
||||
<string name="write_storage_permission_rationale_for_image_share">We need your permission to access the external storage of your device in order to upload images.</string>
|
||||
<string name="nearby_notification_dismiss_message">You won\'t see the nearest place that needs pictures anymore. However, you can re-enable this notification in Settings if you wish.</string>
|
||||
|
||||
<string name="step_count">Step %1$d of %2$d</string>
|
||||
<string name="image_in_set_label">Image %1$d in set</string>
|
||||
<string name="next">Next</string>
|
||||
<string name="previous">Previous</string>
|
||||
<string name="submit">Submit</string>
|
||||
<string name="upload_title_duplicate" formatted="true">A file with the file name %1$s exists. Are you sure you want to proceed?</string>
|
||||
<string formatted="true" name="upload_title_duplicate">A file with the file name %1$s exists. Are you sure you want to proceed?</string>
|
||||
<string name="map_application_missing">No compatible map application could be found on your device. Please install a map application to use this feature.</string>
|
||||
<plurals name="upload_count_title">
|
||||
<item quantity="one">%1$d Upload</item>
|
||||
<item quantity="other">%1$d Uploads</item>
|
||||
</plurals>
|
||||
<string name="navigation_item_bookmarks">Bookmarks</string>
|
||||
<string name="title_activity_bookmarks">Bookmarks</string>
|
||||
<string name="title_page_bookmarks_pictures">Pictures</string>
|
||||
|
|
@ -439,32 +443,32 @@
|
|||
<string name="provider_bookmarks">Bookmarks</string>
|
||||
<string name="bookmark_empty">You haven\'t added any bookmarks</string>
|
||||
<string name="provider_bookmarks_location">Bookmarks</string>
|
||||
<string name="log_collection_started">Log collection started. Please RESTART the app, perform action that you wish to log, and then tap \'Send log file\' again</string>
|
||||
|
||||
<string name="log_collection_started">Log collection started. Please RESTART the app, perform action that you wish to log, and then tap \'Send log file\' again</string>
|
||||
<string name="deletion_reason_uploaded_by_mistake">I uploaded it by mistake</string>
|
||||
<string name="deletion_reason_publicly_visible">I did not know it would be publicly visible</string>
|
||||
<string name="deletion_reason_bad_for_my_privacy">I realized it is bad for my privacy</string>
|
||||
<string name="deletion_reason_no_longer_want_public">I changed my mind, I don\'t want it to be publicly visible anymore</string>
|
||||
<string name="deletion_reason_not_interesting">Sorry this picture is not interesting for an encyclopedia</string>
|
||||
|
||||
<string name="uploaded_by_myself">Uploaded by myself on %1$s, used in %2$d article(s).</string>
|
||||
|
||||
<string name="no_uploads">Welcome to Commons!\n
|
||||
Upload your first media by tapping on the add button.</string>
|
||||
|
||||
<string name="desc_language_Worldwide">Worldwide</string>
|
||||
<string name="desc_language_America">America</string>
|
||||
<string name="desc_language_Europe">Europe</string>
|
||||
<string name="desc_language_Middle_East">Middle East</string>
|
||||
<string name="desc_language_Africa">Africa</string>
|
||||
<string name="desc_language_Asia">Asia</string>
|
||||
|
||||
<string name="desc_language_Pacific">Pacific</string>
|
||||
|
||||
<string name="no_categories_selected">No Categories Selected</string>
|
||||
|
||||
<string name="no_categories_selected_warning_desc">Images without categories are rarely usable. Are you sure you want to continue without selecting categories?</string>
|
||||
|
||||
<string name="no_depictions_selected">No Depictions Selected</string>
|
||||
<string name="no_depictions_selected_warning_desc">Images with depictions are more easily found and more likely to be used. Are you sure you want to continue without selecting depictions?</string>
|
||||
|
||||
<string name="no_depictions_selected_warning_desc">Images with depictions are more easily found and more likely to be used. Are you sure you want to continue without selecting depictions?</string>
|
||||
<string name="upload_flow_all_images_in_set">(For all images in set)</string>
|
||||
<string name="search_this_area">Search this area</string>
|
||||
<string name="nearby_card_permission_title">Permission Request</string>
|
||||
|
|
@ -478,8 +482,8 @@ Upload your first media by tapping on the add button.</string>
|
|||
<string name="ends_on">Ends on:</string>
|
||||
<string name="display_campaigns">Display campaigns</string>
|
||||
<string name="display_campaigns_explanation">See the ongoing campaigns</string>
|
||||
<string name="nearby_campaign_dismiss_message">You won\'t see the campaigns anymore. However, you can re-enable this notification in Settings if you wish.</string>
|
||||
|
||||
<string name="nearby_campaign_dismiss_message">You won\'t see the campaigns anymore. However, you can re-enable this notification in Settings if you wish.</string>
|
||||
<string name="this_function_needs_network_connection">This function requires network connection, please check your connection settings.</string>
|
||||
<string name="bad_token_error_proposed_solution">Upload failed due to issues with edit token. Please try logging out and in again. </string>
|
||||
<string name="error_processing_image">Error occurred while processing the image. Please try again!</string>
|
||||
|
|
@ -504,8 +508,8 @@ Upload your first media by tapping on the add button.</string>
|
|||
<string name="send_thank_failure_title">Sending Thanks: Failure</string>
|
||||
<string name="send_thank_send">Sending thanks</string>
|
||||
<string name="send_thank_notification_title">Sending thanks</string>
|
||||
<string name="send_thank_toast">Sending Thanks for %1$s</string>
|
||||
|
||||
<string name="send_thank_toast">Sending Thanks for %1$s</string>
|
||||
<string name="review_copyright">Does this follow the rules of copyright?</string>
|
||||
<string name="review_category">Is this correctly categorized?</string>
|
||||
<string name="review_spam">Is this in-scope?</string>
|
||||
|
|
@ -526,12 +530,8 @@ Upload your first media by tapping on the add button.</string>
|
|||
<string name="review_thanks_yes_button_text">Yes, why not</string>
|
||||
<string name="review_thanks_no_button_text">Next image</string>
|
||||
<string name="skip_image_explanation">Clicking this button will give you another recently uploaded image from Wikimedia Commons</string>
|
||||
<string name="review_image_explanation">You can review images and improve the quality of Wikimedia Commons.\n The four parameters of review are: \n - Is this image in-scope? \n - Does this image follow the rules of copyright? \n - Is this image correctly categorized? \n - If all goes well you can also thank the contributor.</string>
|
||||
|
||||
<plurals name="receiving_shared_content">
|
||||
<item quantity="one">Receiving shared content. Processing the image might take some time depending on the size of the image and your device</item>
|
||||
<item quantity="other">Receiving shared content. Processing the images might take some time depending on the size of the images and your device</item>
|
||||
</plurals>
|
||||
<string name="review_image_explanation">You can review images and improve the quality of Wikimedia Commons.\n The four parameters of review are: \n - Is this image in-scope? \n - Does this image follow the rules of copyright? \n - Is this image correctly categorized? \n - If all goes well you can also thank the contributor.</string>
|
||||
|
||||
<string name="no_image">No images used</string>
|
||||
<string name="no_image_reverted">No images reverted</string>
|
||||
|
|
@ -630,4 +630,20 @@ Upload your first media by tapping on the add button.</string>
|
|||
<string name="use_location_from_similar_image">Did you shoot these two pictures at the same place? Do you want to use the latitude/longitude of the picture on the right?</string>
|
||||
<string name="load_more">Load More</string>
|
||||
<string name="nearby_no_results">No places found, try changing your search criteria.</string>
|
||||
|
||||
<string name="add_picture_to_wikipedia_article_title">Add image to Wikipedia</string>
|
||||
<string name="add_picture_to_wikipedia_article_desc">Do you want to add this picture to the %1$s language Wikipedia article?</string>
|
||||
|
||||
<string name="add_picture_to_wikipedia_instructions_title">Instructions</string>
|
||||
<string name="add_picture_to_wikipedia_instructions_desc">Take care to follow editing guidelines!</string>
|
||||
<string name="confirm">Confirm</string>
|
||||
<string name="instructions_title">Instructions</string>
|
||||
<string name="wikipedia_instructions_step_1">1. Use the following wikitext:</string>
|
||||
<string name="wikipedia_instructions_step_2">2. Clicking on Confirm will open the Wikipedia article</string>
|
||||
<string name="wikipedia_instructions_step_3">3. Find an appropriate section in the article for your image</string>
|
||||
<string name="wikipedia_instructions_step_4">4. Click on the Edit icon (the one like a pencil) for that section.</string>
|
||||
<string name="wikipedia_instructions_step_5">5. Paste the wikitext in the appropriate place.</string>
|
||||
<string name="wikipedia_instructions_step_6">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>.</string>
|
||||
<string name="wikipedia_instructions_step_7">7. Publish the article</string>
|
||||
<string name="copy_wikicode_to_clipboard">Copy wikicode to clipboard</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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<PageMediaListItem>(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<PageMediaListItem>())
|
||||
`when`(pageMediaInterface!!.getMediaList(ArgumentMatchers.anyString()))
|
||||
.thenReturn(Observable.just(mock))
|
||||
|
||||
mediaClient!!.doesPageContainMedia("Test").test().assertValue(false)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getPageHtmlTestNull() {
|
||||
val mockResponse = MwParseResponse()
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue