Skip to content

Commit 2302fca

Browse files
ujjwalagrawal17maskaravivek
authored andcommitted
Fix #2881 (Change Media Details UI) (#2954)
* Media Details UI changed - XML file * Onclicks added, design updated * Removed bookmark item from media detail menu * Update in XML
1 parent 7a70eb5 commit 2302fca

25 files changed

+483
-380
lines changed

app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,24 @@
22

33
import android.annotation.SuppressLint;
44
import android.app.AlertDialog;
5+
import android.app.DownloadManager;
56
import android.content.Intent;
67
import android.database.DataSetObserver;
78
import android.net.Uri;
89
import android.os.Bundle;
10+
import android.os.Environment;
911
import android.text.Editable;
1012
import android.text.TextWatcher;
1113
import android.util.TypedValue;
1214
import android.view.LayoutInflater;
15+
import android.view.MenuItem;
1316
import android.view.View;
1417
import android.view.ViewGroup;
1518
import android.view.ViewTreeObserver;
1619
import android.widget.ArrayAdapter;
1720
import android.widget.Button;
1821
import android.widget.EditText;
22+
import android.widget.ImageView;
1923
import android.widget.LinearLayout;
2024
import android.widget.ScrollView;
2125
import android.widget.Spinner;
@@ -44,13 +48,19 @@
4448
import fr.free.nrw.commons.MediaDataExtractor;
4549
import fr.free.nrw.commons.R;
4650
import fr.free.nrw.commons.Utils;
51+
import fr.free.nrw.commons.bookmarks.Bookmark;
52+
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesContentProvider;
53+
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesDao;
4754
import fr.free.nrw.commons.category.CategoryDetailsActivity;
4855
import fr.free.nrw.commons.contributions.ContributionsFragment;
4956
import fr.free.nrw.commons.delete.DeleteHelper;
5057
import fr.free.nrw.commons.delete.ReasonBuilder;
5158
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
5259
import fr.free.nrw.commons.ui.widget.CompatTextView;
5360
import fr.free.nrw.commons.ui.widget.HtmlTextView;
61+
import fr.free.nrw.commons.utils.NetworkUtils;
62+
import fr.free.nrw.commons.utils.PermissionUtils;
63+
import fr.free.nrw.commons.utils.ViewUtil;
5464
import fr.free.nrw.commons.utils.ViewUtilWrapper;
5565
import io.reactivex.Single;
5666
import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -61,6 +71,8 @@
6171
import org.wikipedia.util.StringUtil;
6272
import timber.log.Timber;
6373

74+
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
75+
import static android.content.Context.DOWNLOAD_SERVICE;
6476
import static android.view.View.GONE;
6577
import static android.view.View.VISIBLE;
6678

@@ -97,8 +109,12 @@ public static MediaDetailFragment forMedia(int index, boolean editable, boolean
97109
DeleteHelper deleteHelper;
98110
@Inject
99111
ViewUtilWrapper viewUtil;
112+
@Inject
113+
BookmarkPicturesDao bookmarkDao;
114+
100115

101116
private int initialListTop = 0;
117+
private Bookmark bookmark;
102118

103119
@BindView(R.id.mediaDetailImage)
104120
SimpleDraweeView image;
@@ -130,6 +146,8 @@ public static MediaDetailFragment forMedia(int index, boolean editable, boolean
130146
Button delete;
131147
@BindView(R.id.mediaDetailScrollView)
132148
ScrollView scrollView;
149+
@BindView(R.id.iv_bookmark_icon)
150+
ImageView ivBookmarkIcon;
133151

134152
private ArrayList<String> categoryNames;
135153
private boolean categoriesLoaded = false;
@@ -276,6 +294,15 @@ private void displayMediaDetails() {
276294
.observeOn(AndroidSchedulers.mainThread())
277295
.subscribe(this::setTextFields);
278296
compositeDisposable.add(disposable);
297+
298+
// Initialize bookmark object
299+
bookmark = new Bookmark(
300+
media.getFilename(),
301+
media.getCreator(),
302+
BookmarkPicturesContentProvider.uriForName(media.getFilename())
303+
);
304+
updateBookmarkState();
305+
279306
}
280307

281308
/**
@@ -445,6 +472,82 @@ private void onDeleteClicked(Spinner spinner) {
445472

446473
}
447474

475+
@OnClick(R.id.ll_bookmark)
476+
public void onBookMarkClick(){
477+
bookmarkDao.updateBookmark(bookmark);
478+
updateBookmarkState();
479+
}
480+
481+
private void updateBookmarkState() {
482+
boolean isBookmarked = bookmarkDao.findBookmark(bookmark);
483+
int icon = isBookmarked ? R.drawable.ic_star_filled_primary_dark_24dp : R.drawable.ic_star_border_primary_dark_24dp;
484+
ivBookmarkIcon.setImageResource(icon);
485+
}
486+
487+
@OnClick(R.id.ll_share)
488+
public void onShareClick(){
489+
Intent shareIntent = new Intent(Intent.ACTION_SEND);
490+
shareIntent.setType("text/plain");
491+
shareIntent.putExtra(Intent.EXTRA_TEXT, media.getDisplayTitle() + " \n" + media.getPageTitle().getCanonicalUri());
492+
startActivity(Intent.createChooser(shareIntent, "Share image via..."));
493+
}
494+
495+
@OnClick(R.id.ll_download)
496+
public void onDownloadClick(){
497+
if (!NetworkUtils.isInternetConnectionEstablished(getActivity())) {
498+
ViewUtil.showShortSnackbar(getView(), R.string.no_internet);
499+
return;
500+
}
501+
downloadMedia(media);
502+
}
503+
504+
/**
505+
* Start the media file downloading to the local SD card/storage.
506+
* The file can then be opened in Gallery or other apps.
507+
*
508+
* @param m Media file to download
509+
*/
510+
private void downloadMedia(Media m) {
511+
String imageUrl = m.getImageUrl(), fileName = m.getFilename();
512+
513+
if (imageUrl == null
514+
|| fileName == null
515+
|| getContext() == null
516+
|| getActivity() == null) {
517+
Timber.d("Skipping download media as either imageUrl %s or filename %s activity is null", imageUrl, fileName);
518+
return;
519+
}
520+
521+
// Strip 'File:' from beginning of filename, we really shouldn't store it
522+
fileName = fileName.replaceFirst("^File:", "");
523+
524+
Uri imageUri = Uri.parse(imageUrl);
525+
526+
DownloadManager.Request req = new DownloadManager.Request(imageUri);
527+
//These are not the image title and description fields, they are download descs for notifications
528+
req.setDescription(getString(R.string.app_name));
529+
req.setTitle(m.getDisplayTitle());
530+
req.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
531+
532+
// Modern Android updates the gallery automatically. Yay!
533+
req.allowScanningByMediaScanner();
534+
req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
535+
PermissionUtils.checkPermissionsAndPerformAction(getActivity(), WRITE_EXTERNAL_STORAGE,
536+
() -> enqueueRequest(req), () -> Toast.makeText(getContext(),
537+
R.string.download_failed_we_cannot_download_the_file_without_storage_permission,
538+
Toast.LENGTH_SHORT).show(), R.string.storage_permission,
539+
R.string.write_storage_permission_rationale);
540+
541+
}
542+
543+
private void enqueueRequest(DownloadManager.Request req) {
544+
DownloadManager systemService =
545+
(DownloadManager) getActivity().getSystemService(DOWNLOAD_SERVICE);
546+
if (systemService != null) {
547+
systemService.enqueue(req);
548+
}
549+
}
550+
448551
@OnClick(R.id.seeMore)
449552
public void onSeeMoreClicked(){
450553
if (nominatedForDeletion.getVisibility() == VISIBLE && getActivity() != null) {

app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java

Lines changed: 0 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -41,27 +41,20 @@
4141
import fr.free.nrw.commons.kvstore.JsonKvStore;
4242
import fr.free.nrw.commons.mwapi.MediaWikiApi;
4343
import fr.free.nrw.commons.utils.ImageUtils;
44-
import fr.free.nrw.commons.utils.NetworkUtils;
45-
import fr.free.nrw.commons.utils.PermissionUtils;
46-
import fr.free.nrw.commons.utils.ViewUtil;
4744
import timber.log.Timber;
4845

49-
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
50-
import static android.content.Context.DOWNLOAD_SERVICE;
5146
import static fr.free.nrw.commons.Utils.handleWebUrl;
5247

5348
public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment implements ViewPager.OnPageChangeListener {
5449

5550
@Inject MediaWikiApi mwApi;
5651
@Inject SessionManager sessionManager;
5752
@Inject @Named("default_preferences") JsonKvStore store;
58-
@Inject BookmarkPicturesDao bookmarkDao;
5953

6054
@BindView(R.id.mediaDetailsPager) ViewPager pager;
6155
private Boolean editable;
6256
private boolean isFeaturedImage;
6357
MediaDetailAdapter adapter;
64-
private Bookmark bookmark;
6558
private MediaDetailProvider provider;
6659

6760
public MediaDetailPagerFragment() {
@@ -157,28 +150,10 @@ public boolean onOptionsItemSelected(MenuItem item) {
157150

158151
Media m = provider.getMediaAtPosition(pager.getCurrentItem());
159152
switch (item.getItemId()) {
160-
case R.id.menu_bookmark_current_image:
161-
bookmarkDao.updateBookmark(bookmark);
162-
updateBookmarkState(item);
163-
return true;
164-
case R.id.menu_share_current_image:
165-
Intent shareIntent = new Intent(Intent.ACTION_SEND);
166-
shareIntent.setType("text/plain");
167-
shareIntent.putExtra(Intent.EXTRA_TEXT, m.getDisplayTitle() + " \n" + m.getPageTitle().getCanonicalUri());
168-
startActivity(Intent.createChooser(shareIntent, "Share image via..."));
169-
return true;
170153
case R.id.menu_browser_current_image:
171154
// View in browser
172155
handleWebUrl(requireContext(), Uri.parse(m.getPageTitle().getMobileUri()));
173156
return true;
174-
case R.id.menu_download_current_image:
175-
// Download
176-
if (!NetworkUtils.isInternetConnectionEstablished(getActivity())) {
177-
ViewUtil.showShortSnackbar(getView(), R.string.no_internet);
178-
return false;
179-
}
180-
downloadMedia(m);
181-
return true;
182157
case R.id.menu_set_as_wallpaper:
183158
// Set wallpaper
184159
setWallpaper(m);
@@ -201,52 +176,6 @@ private void setWallpaper(Media media) {
201176
ImageUtils.setWallpaperFromImageUrl(getActivity(), Uri.parse(media.getImageUrl()));
202177
}
203178

204-
/**
205-
* Start the media file downloading to the local SD card/storage.
206-
* The file can then be opened in Gallery or other apps.
207-
*
208-
* @param m Media file to download
209-
*/
210-
private void downloadMedia(Media m) {
211-
String imageUrl = m.getImageUrl(), fileName = m.getFilename();
212-
213-
if (imageUrl == null
214-
|| fileName == null
215-
|| getContext() == null
216-
|| getActivity() == null) {
217-
Timber.d("Skipping download media as either imageUrl %s or filename %s activity is null", imageUrl, fileName);
218-
return;
219-
}
220-
221-
// Strip 'File:' from beginning of filename, we really shouldn't store it
222-
fileName = fileName.replaceFirst("^File:", "");
223-
224-
Uri imageUri = Uri.parse(imageUrl);
225-
226-
DownloadManager.Request req = new DownloadManager.Request(imageUri);
227-
//These are not the image title and description fields, they are download descs for notifications
228-
req.setDescription(getString(R.string.app_name));
229-
req.setTitle(m.getDisplayTitle());
230-
req.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
231-
232-
// Modern Android updates the gallery automatically. Yay!
233-
req.allowScanningByMediaScanner();
234-
req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
235-
PermissionUtils.checkPermissionsAndPerformAction(getActivity(), WRITE_EXTERNAL_STORAGE,
236-
() -> enqueueRequest(req), () -> Toast.makeText(getContext(),
237-
R.string.download_failed_we_cannot_download_the_file_without_storage_permission,
238-
Toast.LENGTH_SHORT).show(), R.string.storage_permission,
239-
R.string.write_storage_permission_rationale);
240-
241-
}
242-
243-
private void enqueueRequest(DownloadManager.Request req) {
244-
DownloadManager systemService =
245-
(DownloadManager) getActivity().getSystemService(DOWNLOAD_SERVICE);
246-
if (systemService != null) {
247-
systemService.enqueue(req);
248-
}
249-
}
250179

251180
@Override
252181
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
@@ -263,33 +192,16 @@ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
263192
if (m != null) {
264193
// Enable default set of actions, then re-enable different set of actions only if it is a failed contrib
265194
menu.findItem(R.id.menu_browser_current_image).setEnabled(true).setVisible(true);
266-
menu.findItem(R.id.menu_share_current_image).setEnabled(true).setVisible(true);
267-
menu.findItem(R.id.menu_download_current_image).setEnabled(true).setVisible(true);
268-
menu.findItem(R.id.menu_bookmark_current_image).setEnabled(true).setVisible(true);
269-
270-
// Initialize bookmark object
271-
bookmark = new Bookmark(
272-
m.getFilename(),
273-
m.getCreator(),
274-
BookmarkPicturesContentProvider.uriForName(m.getFilename())
275-
);
276-
updateBookmarkState(menu.findItem(R.id.menu_bookmark_current_image));
277195

278196
if (m instanceof Contribution ) {
279197
Contribution c = (Contribution) m;
280198
switch (c.getState()) {
281199
case Contribution.STATE_FAILED:
282200
menu.findItem(R.id.menu_browser_current_image).setEnabled(false).setVisible(false);
283-
menu.findItem(R.id.menu_share_current_image).setEnabled(false).setVisible(false);
284-
menu.findItem(R.id.menu_download_current_image).setEnabled(false).setVisible(false);
285-
menu.findItem(R.id.menu_bookmark_current_image).setEnabled(false).setVisible(false);
286201
break;
287202
case Contribution.STATE_IN_PROGRESS:
288203
case Contribution.STATE_QUEUED:
289204
menu.findItem(R.id.menu_browser_current_image).setEnabled(false).setVisible(false);
290-
menu.findItem(R.id.menu_share_current_image).setEnabled(false).setVisible(false);
291-
menu.findItem(R.id.menu_download_current_image).setEnabled(false).setVisible(false);
292-
menu.findItem(R.id.menu_bookmark_current_image).setEnabled(false).setVisible(false);
293205
break;
294206
case Contribution.STATE_COMPLETED:
295207
// Default set of menu items works fine. Treat same as regular media object
@@ -301,12 +213,6 @@ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
301213
}
302214
}
303215

304-
private void updateBookmarkState(MenuItem item) {
305-
boolean isBookmarked = bookmarkDao.findBookmark(bookmark);
306-
int icon = isBookmarked ? R.drawable.ic_round_star_filled_24px : R.drawable.ic_round_star_border_24px;
307-
item.setIcon(icon);
308-
}
309-
310216
public void showImage(int i) {
311217
Handler handler = new Handler();
312218
handler.postDelayed(() -> pager.setCurrentItem(i), 5);
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading

app/src/main/res/drawable/bg_delete_button.xml

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,9 @@
99
<shape
1010
android:shape="rectangle">
1111
<solid
12-
android:color="@color/deleteButton"/>
12+
android:color="@color/deleteRed"/>
1313
<corners
14-
android:radius="3dp" />
15-
<stroke
16-
android:width="5px"
17-
android:color="@color/deleteRed" />
14+
android:radius="2dp" />
1815
</shape>
1916
</item>
2017

@@ -25,7 +22,7 @@
2522
<solid
2623
android:color="@color/deleteButtonDark"/>
2724
<corners
28-
android:radius="3dp" />
25+
android:radius="2dp" />
2926
</shape>
3027
</item>
3128

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<selector
3+
android:layout_height="match_parent"
4+
android:layout_width="match_parent"
5+
xmlns:android="http://schemas.android.com/apk/res/android">
6+
7+
<item
8+
android:state_enabled="true" >
9+
<shape
10+
android:shape="rectangle">
11+
<solid
12+
android:color="@color/button_blue"/>
13+
<corners
14+
android:radius="2dp" />
15+
</shape>
16+
</item>
17+
18+
</selector>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:viewportHeight="24.0" android:viewportWidth="24.0" android:width="24dp">
3+
<path android:fillColor="#00376d" android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z"/>
4+
</vector>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:viewportHeight="24.0" android:viewportWidth="24.0" android:width="24dp">
3+
<path android:fillColor="#00376d" android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z"/>
4+
</vector>

0 commit comments

Comments
 (0)