mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Ability to show captions and descriptions in all entered languages (#4355)
* implement Ability to show captions and descriptions in all entered languages *Add Javadoc * handle Back event of fragment(mediaDetailFragment) * fix minor bugs * add internationalization * revert previous changes * fix visibility bug * resolve conflict
This commit is contained in:
parent
808f21a1f2
commit
b202f553f0
12 changed files with 308 additions and 9 deletions
|
|
@ -48,4 +48,6 @@ class MediaDataExtractor @Inject constructor(private val mediaClient: MediaClien
|
|||
)
|
||||
|
||||
}
|
||||
|
||||
fun getHtmlOfPage(title: String) = mediaClient.getPageHtml(title);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Caption> captions;
|
||||
|
||||
public CaptionListViewAdapter(final List<Caption> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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<Caption> captions = getCaptions();
|
||||
|
||||
if (descriptionHtmlCode == null) {
|
||||
progressBar.setVisibility(VISIBLE);
|
||||
}
|
||||
|
||||
getDescription();
|
||||
CaptionListViewAdapter adapter = new CaptionListViewAdapter(captions);
|
||||
captionsListView.setAdapter(adapter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the caption with language
|
||||
*/
|
||||
private List<Caption> getCaptions() {
|
||||
List<Caption> captionList = new ArrayList<>();
|
||||
Map<String, String> captions = media.getCaptions();
|
||||
AppLanguageLookUpTable appLanguageLookUpTable = new AppLanguageLookUpTable(getContext());
|
||||
for (Map.Entry<String, String> 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 = "<td class=\"description\">";
|
||||
int start = s.indexOf(descriptionClassName) + descriptionClassName.length();
|
||||
int end = s.indexOf("</td>", 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
33
app/src/main/res/layout/caption_item.xml
Normal file
33
app/src/main/res/layout/caption_item.xml
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/mainBackground"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/caption_language_textview"
|
||||
style="@style/CaptionTextLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textMultiLine"
|
||||
android:text="Caption"
|
||||
android:textColor="?attr/caption_description_text_color"
|
||||
android:textSize="16dp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/caption_text"
|
||||
style="@style/CaptionTextLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textMultiLine"
|
||||
android:textColor="?attr/caption_description_text_color"
|
||||
android:textStyle="normal" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
|
@ -23,6 +23,20 @@
|
|||
layout="@layout/layout_edit_categories" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/dummy_caption_description_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="bottom"
|
||||
android:elevation="35dp"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
android:weightSum="10">
|
||||
|
||||
<include
|
||||
layout="@layout/show_captions_descriptions" />
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/mediaDetailImageFailed"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
@ -190,6 +204,15 @@
|
|||
tools:text="Description of the media goes here. This can potentially be fairly long, and will need to wrap across multiple lines. We hope it looks nice though." />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/show_caption_description_textview"
|
||||
style="@style/MediaDetailTextLabelGeneric"
|
||||
android:layout_width="match_parent"
|
||||
android:gravity="center"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/dimen_10"
|
||||
android:text="@string/media_detail_in_all_languages" />
|
||||
|
||||
<View
|
||||
android:background="?attr/mediaDetailSpacerColor"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
|||
55
app/src/main/res/layout/show_captions_descriptions.xml
Normal file
55
app/src/main/res/layout/show_captions_descriptions.xml
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/dimen_20"
|
||||
android:background="?attr/mainBackground"
|
||||
android:elevation="30dp"
|
||||
android:padding="@dimen/dimen_10">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/caption_label"
|
||||
style="@style/MediaDetailTextLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Captions"
|
||||
android:textColor="?attr/caption_description_text_color" />
|
||||
|
||||
<ListView
|
||||
android:id="@+id/caption_listview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/caption_label" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/description_label"
|
||||
style="@style/MediaDetailTextLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/caption_listview"
|
||||
android:layout_marginTop="@dimen/dimen_10"
|
||||
android:text="Descriptions"
|
||||
android:textColor="?attr/caption_description_text_color" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/pb_circular"
|
||||
style="?android:attr/progressBarStyleSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:background="?attr/mainBackground"
|
||||
android:indeterminate="true"
|
||||
android:indeterminateOnly="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
<WebView
|
||||
android:id="@+id/description_webview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/description_label"
|
||||
android:layout_marginTop="@dimen/dimen_10"
|
||||
android:layout_marginBottom="@dimen/dimen_20"
|
||||
android:background="?attr/mainBackground"
|
||||
tools:ignore="WebViewLayout" />
|
||||
</RelativeLayout>
|
||||
|
|
@ -348,5 +348,6 @@
|
|||
<string name="leaderboard_used">Benotzt</string>
|
||||
<string name="limited_connection_mode">Limitéierte Verbindungsmodus</string>
|
||||
<string name="app_ui_language">Sprooch vum Interface vum Benotzer vun der App</string>
|
||||
<string name="media_detail_in_all_languages">In all languages</string>
|
||||
<string name="read_help_link">Liest méi</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
<attr name="contributionsListTextPrimary" format="reference"/>
|
||||
<attr name="menu_item_tint" format="reference"/>
|
||||
<attr name="search_icon" format="reference"/>
|
||||
<attr name="caption_description_text_color" format="reference" />
|
||||
|
||||
<declare-styleable name="Badge">
|
||||
<attr name="boundary" format="color"/>
|
||||
|
|
|
|||
|
|
@ -622,6 +622,7 @@ Upload your first media by tapping on the add button.</string>
|
|||
<string name="app_ui_language">App user interface language</string>
|
||||
<string name="remove">Removes a caption and description</string>
|
||||
<string name="read_help_link">Read more</string>
|
||||
<string name="media_detail_in_all_languages">In all languages</string>
|
||||
<string name="choose_a_location">Choose a location</string>
|
||||
<string name="pan_and_zoom_to_adjust">Pan and zoom to adjust</string>
|
||||
<string name="exit_location_picker">Exit location picker</string>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
<item name="rowButtonColor">@color/button_blue_dark</item>
|
||||
<item name="reviewHeading">@color/white</item>
|
||||
<item name="aboutIconsColor">@color/white</item>
|
||||
<item name="caption_description_text_color">@color/white</item>
|
||||
|
||||
<item name="semitransparentText">@color/commons_app_blue_dark</item>
|
||||
<item name="subBackground">@color/sub_background_dark</item>
|
||||
|
|
@ -76,6 +77,7 @@
|
|||
<item name="rowButtonColor">@color/button_blue</item>
|
||||
<item name="reviewHeading">@color/black</item>
|
||||
<item name="aboutIconsColor">@color/black</item>
|
||||
<item name="caption_description_text_color">@color/black</item>
|
||||
|
||||
<item name="semitransparentText">@color/commons_app_blue_light</item>
|
||||
<item name="subBackground">@color/sub_background_light</item>
|
||||
|
|
@ -206,6 +208,12 @@
|
|||
<item name="android:textStyle">bold</item>
|
||||
</style>
|
||||
|
||||
<style name="CaptionTextLabel">
|
||||
<item name="android:paddingTop">@dimen/dimen_6</item>
|
||||
<item name="android:paddingLeft">@dimen/tiny_gap</item>
|
||||
<item name="android:textSize">@dimen/normal_text</item>
|
||||
</style>
|
||||
|
||||
<style name="MediaDetailTextLabelTitle" parent="@style/MediaDetailTextLabel">
|
||||
<item name="android:textColor">@android:color/white</item>
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue