diff --git a/app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.kt b/app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.kt index f1417d267..34a9a81be 100644 --- a/app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.kt +++ b/app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.kt @@ -48,4 +48,6 @@ class MediaDataExtractor @Inject constructor(private val mediaClient: MediaClien ) } + + fun getHtmlOfPage(title: String) = mediaClient.getPageHtml(title); } diff --git a/app/src/main/java/fr/free/nrw/commons/media/CaptionListViewAdapter.java b/app/src/main/java/fr/free/nrw/commons/media/CaptionListViewAdapter.java new file mode 100644 index 000000000..759eb2af7 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/media/CaptionListViewAdapter.java @@ -0,0 +1,67 @@ +package fr.free.nrw.commons.media; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.TextView; +import fr.free.nrw.commons.R; +import java.util.List; + +/** + * Adapter for Caption Listview + */ +public class CaptionListViewAdapter extends BaseAdapter { + + List captions; + + public CaptionListViewAdapter(final List captions) { + this.captions = captions; + } + + /** + * @return size of captions list + */ + @Override + public int getCount() { + return captions.size(); + } + + /** + * @return Object at position i + */ + @Override + public Object getItem(final int i) { + return null; + } + + /** + * @return id for current item + */ + @Override + public long getItemId(final int i) { + return 0; + } + + /** + * inflate the view and bind data with UI + */ + @Override + public View getView(final int i, final View view, final ViewGroup viewGroup) { + final TextView captionLanguageTextView; + final TextView captionTextView; + final View captionLayout = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.caption_item, null); + captionLanguageTextView = captionLayout.findViewById(R.id.caption_language_textview); + captionTextView = captionLayout.findViewById(R.id.caption_text); + if (captions.size() == 1 && captions.get(0).getValue().equals("No Caption")) { + captionLanguageTextView.setText(captions.get(i).getLanguage()); + captionTextView.setText(captions.get(i).getValue()); + } else { + captionLanguageTextView.setText(captions.get(i).getLanguage() + ":"); + captionTextView.setText(captions.get(i).getValue()); + } + + return captionLayout; + } + +} diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java index d9e11076d..1ed80696c 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java @@ -18,16 +18,20 @@ import android.os.Bundle; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; +import android.view.View.OnKeyListener; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; +import android.webkit.WebView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.FrameLayout; import android.widget.LinearLayout; +import android.widget.ListView; import android.widget.ProgressBar; import android.widget.ScrollView; import android.widget.SearchView; @@ -86,6 +90,7 @@ import java.util.concurrent.TimeUnit; import javax.inject.Inject; import javax.inject.Named; import org.apache.commons.lang3.StringUtils; +import org.wikipedia.language.AppLanguageLookUpTable; import org.wikipedia.util.DateUtil; import timber.log.Timber; @@ -140,7 +145,8 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements JsonKvStore applicationKvStore; private int initialListTop = 0; - + @BindView(R.id.description_webview) + WebView descriptionWebView; @BindView(R.id.mediaDetailFrameLayout) FrameLayout frameLayout; @BindView(R.id.mediaDetailImageView) @@ -203,6 +209,19 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements TextView existingCategories; @BindView(R.id.no_results_found) TextView noResultsFound; + @BindView(R.id.dummy_caption_description_container) + LinearLayout showCaptionAndDescriptionContainer; + @BindView(R.id.show_caption_description_textview) + TextView showCaptionDescriptionTextView; + @BindView(R.id.caption_listview) + ListView captionsListView; + @BindView(R.id.caption_label) + TextView captionLabel; + @BindView(R.id.description_label) + TextView descriptionLabel; + @BindView(R.id.pb_circular) + ProgressBar progressBar; + String descriptionHtmlCode; @BindView(R.id.progressBarDeletion) ProgressBar progressBarDeletion; @@ -302,6 +321,9 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements if(applicationKvStore.getBoolean("login_skipped")){ delete.setVisibility(GONE); } + + handleBackEvent(view); + /** * Gets the height of the frame layout as soon as the view is ready and updates aspect ratio * of the picture. @@ -317,14 +339,6 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements return view; } - @Override - public void onAttach(final Context context) { - super.onAttach(context); - if (getParentFragment() != null) { - callback = (Callback) getParentFragment(); - } - } - @OnClick(R.id.mediaDetailImageViewSpacer) public void launchZoomActivity(View view) { if (media.getImageUrl() != null) { @@ -769,6 +783,7 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements } public void displayHideCategorySearch() { + showCaptionAndDescriptionContainer.setVisibility(GONE); if (dummyCategoryEditContainer.getVisibility() != VISIBLE) { dummyCategoryEditContainer.setVisibility(VISIBLE); } else { @@ -1136,6 +1151,97 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements } } + @OnClick(R.id.show_caption_description_textview) + void showCaptionAndDescription() { + dummyCategoryEditContainer.setVisibility(GONE); + if (showCaptionAndDescriptionContainer.getVisibility() == GONE) { + showCaptionAndDescriptionContainer.setVisibility(VISIBLE); + setUpCaptionAndDescriptionLayout(); + } else { + showCaptionAndDescriptionContainer.setVisibility(GONE); + } + } + + /** + * setUp Caption And Description Layout + */ + private void setUpCaptionAndDescriptionLayout() { + List captions = getCaptions(); + + if (descriptionHtmlCode == null) { + progressBar.setVisibility(VISIBLE); + } + + getDescription(); + CaptionListViewAdapter adapter = new CaptionListViewAdapter(captions); + captionsListView.setAdapter(adapter); + } + + /** + * Generate the caption with language + */ + private List getCaptions() { + List captionList = new ArrayList<>(); + Map captions = media.getCaptions(); + AppLanguageLookUpTable appLanguageLookUpTable = new AppLanguageLookUpTable(getContext()); + for (Map.Entry map : captions.entrySet()) { + String language = appLanguageLookUpTable.getLocalizedName(map.getKey()); + String languageCaption = map.getValue(); + captionList.add(new Caption(language, languageCaption)); + } + + if (captionList.size() == 0) { + captionList.add(new Caption("", "No Caption")); + } + return captionList; + } + + private void getDescription() { + compositeDisposable.add(mediaDataExtractor.getHtmlOfPage(media.getFilename()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(this::extractDescription, Timber::e)); + } + + /** + * extract the description from html of imagepage + */ + private void extractDescription(String s) { + String descriptionClassName = ""; + int start = s.indexOf(descriptionClassName) + descriptionClassName.length(); + int end = s.indexOf("", start); + descriptionHtmlCode = ""; + for (int i = start; i < end; i++) { + descriptionHtmlCode = descriptionHtmlCode + s.toCharArray()[i]; + } + + descriptionWebView + .loadDataWithBaseURL(null, descriptionHtmlCode, "text/html", "utf-8", null); + progressBar.setVisibility(GONE); + } + + /** + * Handle back event when fragment when showCaptionAndDescriptionContainer is visible + */ + private void handleBackEvent(View view) { + view.setFocusableInTouchMode(true); + view.requestFocus(); + view.setOnKeyListener(new OnKeyListener() { + @Override + public boolean onKey(View view, int keycode, KeyEvent keyEvent) { + if (keycode == KeyEvent.KEYCODE_BACK) { + if (showCaptionAndDescriptionContainer.getVisibility() == VISIBLE) { + showCaptionAndDescriptionContainer.setVisibility(GONE); + return true; + } + } + return false; + } + }); + + } + + public interface Callback { void nominatingForDeletion(int index); } diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailInterface.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailInterface.java index ef9559c29..86be5c875 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailInterface.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailInterface.java @@ -3,6 +3,7 @@ package fr.free.nrw.commons.media; import io.reactivex.Observable; import io.reactivex.Single; import org.wikipedia.wikidata.Entities; +import retrofit2.Call; import retrofit2.http.GET; import retrofit2.http.Query; diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaInterface.java b/app/src/main/java/fr/free/nrw/commons/media/MediaInterface.java index 2ff346085..c354ba78b 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaInterface.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaInterface.java @@ -3,6 +3,7 @@ package fr.free.nrw.commons.media; import io.reactivex.Single; import java.util.Map; import org.wikipedia.dataclient.mwapi.MwQueryResponse; +import retrofit2.Call; import retrofit2.http.GET; import retrofit2.http.Query; import retrofit2.http.QueryMap; diff --git a/app/src/main/res/layout/caption_item.xml b/app/src/main/res/layout/caption_item.xml new file mode 100644 index 000000000..0e78d75cd --- /dev/null +++ b/app/src/main/res/layout/caption_item.xml @@ -0,0 +1,33 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_media_detail.xml b/app/src/main/res/layout/fragment_media_detail.xml index ef691c300..5fe88f920 100644 --- a/app/src/main/res/layout/fragment_media_detail.xml +++ b/app/src/main/res/layout/fragment_media_detail.xml @@ -23,6 +23,20 @@ layout="@layout/layout_edit_categories" /> + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-lb/strings.xml b/app/src/main/res/values-lb/strings.xml index 6d7feec72..9e388d6a9 100644 --- a/app/src/main/res/values-lb/strings.xml +++ b/app/src/main/res/values-lb/strings.xml @@ -348,5 +348,6 @@ Benotzt Limitéierte Verbindungsmodus Sprooch vum Interface vum Benotzer vun der App + In all languages Liest méi diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 3bdb8ddcc..5387ca117 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -48,6 +48,7 @@ + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3267ae344..9307a3a09 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -622,6 +622,7 @@ Upload your first media by tapping on the add button. App user interface language Removes a caption and description Read more + In all languages Choose a location Pan and zoom to adjust Exit location picker diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 63bca8146..308291dea 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -19,6 +19,7 @@ @color/button_blue_dark @color/white @color/white + @color/white @color/commons_app_blue_dark @color/sub_background_dark @@ -76,6 +77,7 @@ @color/button_blue @color/black @color/black + @color/black @color/commons_app_blue_light @color/sub_background_light @@ -206,6 +208,12 @@ bold + +