mirror of
				https://github.com/commons-app/apps-android-commons.git
				synced 2025-10-31 06:43:56 +01:00 
			
		
		
		
	Add background color option for media detail page (#5394)
* feat: add backgroundColor property on media * feat: add optional menu items for media backgroundColor * fix: test pass when running in batch * refactor: remove backgroundColor from media * refactor: add string for background color menu * chore: remove useless change * feat: change media image background color * feat: pass backgroundColor to ZoomableActivity * chore: remove extra space
This commit is contained in:
		
							parent
							
								
									9028e0ed32
								
							
						
					
					
						commit
						e1e4f9329a
					
				
					 7 changed files with 260 additions and 15 deletions
				
			
		|  | @ -17,6 +17,7 @@ import android.annotation.SuppressLint; | |||
| import android.app.AlertDialog; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.content.SharedPreferences; | ||||
| import android.content.res.Configuration; | ||||
| import android.graphics.drawable.Animatable; | ||||
| import android.net.Uri; | ||||
|  | @ -78,6 +79,7 @@ import fr.free.nrw.commons.di.CommonsDaggerSupportFragment; | |||
| import fr.free.nrw.commons.explore.depictions.WikidataItemDetailsActivity; | ||||
| import fr.free.nrw.commons.kvstore.JsonKvStore; | ||||
| import fr.free.nrw.commons.location.LocationServiceManager; | ||||
| import fr.free.nrw.commons.media.ZoomableActivity.ZoomableActivityConstants; | ||||
| import fr.free.nrw.commons.profile.ProfileActivity; | ||||
| import fr.free.nrw.commons.settings.Prefs; | ||||
| import fr.free.nrw.commons.ui.widget.HtmlTextView; | ||||
|  | @ -111,8 +113,11 @@ import timber.log.Timber; | |||
| public class MediaDetailFragment extends CommonsDaggerSupportFragment implements | ||||
|     CategoryEditHelper.Callback { | ||||
| 
 | ||||
|     private static final int REQUEST_CODE = 1001 ; | ||||
|     private static final int REQUEST_CODE_EDIT_DESCRIPTION = 1002 ; | ||||
|     private static final int REQUEST_CODE = 1001; | ||||
|     private static final int REQUEST_CODE_EDIT_DESCRIPTION = 1002; | ||||
|     private static final String IMAGE_BACKGROUND_COLOR = "image_background_color"; | ||||
|     static final int DEFAULT_IMAGE_BACKGROUND_COLOR = 0; | ||||
|      | ||||
|     private boolean editable; | ||||
|     private boolean isCategoryImage; | ||||
|     private MediaDetailPagerFragment.MediaDetailProvider detailProvider; | ||||
|  | @ -388,6 +393,15 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements | |||
|             zoomableIntent.setData(Uri.parse(media.getImageUrl())); | ||||
|             zoomableIntent.putExtra( | ||||
|                 ZoomableActivity.ZoomableActivityConstants.ORIGIN, "MediaDetails"); | ||||
|              | ||||
|             int backgroundColor = getImageBackgroundColor(); | ||||
|             if (backgroundColor != DEFAULT_IMAGE_BACKGROUND_COLOR) { | ||||
|                 zoomableIntent.putExtra( | ||||
|                     ZoomableActivity.ZoomableActivityConstants.PHOTO_BACKGROUND_COLOR, | ||||
|                     backgroundColor | ||||
|                 ); | ||||
|             } | ||||
|              | ||||
|             ctx.startActivity( | ||||
|                 zoomableIntent | ||||
|             ); | ||||
|  | @ -599,6 +613,10 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements | |||
|      * - when the high resolution image is available, it replaces the low resolution image | ||||
|      */ | ||||
|     private void setupImageView() { | ||||
|         int imageBackgroundColor = getImageBackgroundColor(); | ||||
|         if (imageBackgroundColor != DEFAULT_IMAGE_BACKGROUND_COLOR) { | ||||
|             image.setBackgroundColor(imageBackgroundColor); | ||||
|         } | ||||
| 
 | ||||
|         image.getHierarchy().setPlaceholderImage(R.drawable.image_placeholder); | ||||
|         image.getHierarchy().setFailureImage(R.drawable.image_placeholder); | ||||
|  | @ -1472,4 +1490,28 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements | |||
|     public interface Callback { | ||||
|         void nominatingForDeletion(int index); | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|      * Called when the image background color is changed. | ||||
|      * You should pass a useable color, not a resource id. | ||||
|      * @param color | ||||
|      */ | ||||
|     public void onImageBackgroundChanged(int color) { | ||||
|         int currentColor = getImageBackgroundColor(); | ||||
|         if (currentColor == color) { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         image.setBackgroundColor(color); | ||||
|         getImageBackgroundColorPref().edit().putInt(IMAGE_BACKGROUND_COLOR, color).apply(); | ||||
|     } | ||||
| 
 | ||||
|     private SharedPreferences getImageBackgroundColorPref() { | ||||
|         return getContext().getSharedPreferences(IMAGE_BACKGROUND_COLOR + media.getPageId(), Context.MODE_PRIVATE); | ||||
|     } | ||||
| 
 | ||||
|     private int getImageBackgroundColor() { | ||||
|         SharedPreferences imageBackgroundColorPref = this.getImageBackgroundColorPref(); | ||||
|         return imageBackgroundColorPref.getInt(IMAGE_BACKGROUND_COLOR, DEFAULT_IMAGE_BACKGROUND_COLOR); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -5,6 +5,8 @@ import static fr.free.nrw.commons.Utils.handleWebUrl; | |||
| import android.annotation.SuppressLint; | ||||
| import android.content.ActivityNotFoundException; | ||||
| import android.content.Intent; | ||||
| import android.graphics.Bitmap; | ||||
| import android.graphics.BitmapFactory; | ||||
| import android.net.Uri; | ||||
| import android.os.Bundle; | ||||
| import android.view.LayoutInflater; | ||||
|  | @ -18,6 +20,7 @@ import androidx.appcompat.app.ActionBar; | |||
| import androidx.appcompat.app.AlertDialog; | ||||
| import androidx.appcompat.app.AppCompatActivity; | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.core.content.ContextCompat; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.fragment.app.FragmentManager; | ||||
| import androidx.fragment.app.FragmentStatePagerAdapter; | ||||
|  | @ -41,9 +44,16 @@ import fr.free.nrw.commons.utils.DownloadUtils; | |||
| import fr.free.nrw.commons.utils.ImageUtils; | ||||
| import fr.free.nrw.commons.utils.NetworkUtils; | ||||
| import fr.free.nrw.commons.utils.ViewUtil; | ||||
| import io.reactivex.Observable; | ||||
| import io.reactivex.android.schedulers.AndroidSchedulers; | ||||
| import io.reactivex.disposables.CompositeDisposable; | ||||
| import io.reactivex.schedulers.Schedulers; | ||||
| import java.net.MalformedURLException; | ||||
| import java.net.URL; | ||||
| import java.net.URLConnection; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Objects; | ||||
| import java.util.concurrent.Callable; | ||||
| import javax.inject.Inject; | ||||
| import timber.log.Timber; | ||||
| 
 | ||||
|  | @ -190,6 +200,7 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple | |||
|         } | ||||
| 
 | ||||
|         Media m = provider.getMediaAtPosition(pager.getCurrentItem()); | ||||
|         MediaDetailFragment mediaDetailFragment = this.adapter.getCurrentMediaDetailFragment(); | ||||
|         switch (item.getItemId()) { | ||||
|             case R.id.menu_bookmark_current_image: | ||||
|                 boolean bookmarkExists = bookmarkDao.updateBookmark(bookmark); | ||||
|  | @ -243,6 +254,16 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple | |||
|                 return true; | ||||
|             case R.id.menu_view_report: | ||||
|                 showReportDialog(m); | ||||
|             case R.id.menu_view_set_white_background: | ||||
|                 if (mediaDetailFragment != null) { | ||||
|                     mediaDetailFragment.onImageBackgroundChanged(ContextCompat.getColor(getContext(), R.color.white)); | ||||
|                 } | ||||
|                 return true; | ||||
|             case R.id.menu_view_set_black_background: | ||||
|                 if (mediaDetailFragment != null) { | ||||
|                     mediaDetailFragment.onImageBackgroundChanged(ContextCompat.getColor(getContext(), R.color.black)); | ||||
|                 } | ||||
|                 return true; | ||||
|             default: | ||||
|                 return super.onOptionsItemSelected(item); | ||||
|         } | ||||
|  | @ -372,6 +393,17 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple | |||
|                     if (m.getUser() != null) { | ||||
|                         menu.findItem(R.id.menu_view_user_page).setEnabled(true).setVisible(true); | ||||
|                     } | ||||
| 
 | ||||
|                     try { | ||||
|                         URL mediaUrl = new URL(m.getImageUrl()); | ||||
|                         this.handleBackgroundColorMenuItems( | ||||
|                             () -> BitmapFactory.decodeStream(mediaUrl.openConnection().getInputStream()), | ||||
|                             menu | ||||
|                         ); | ||||
|                     } catch (Exception e) { | ||||
|                         Timber.e("Cant detect media transparency"); | ||||
|                     } | ||||
|                      | ||||
|                     // Initialize bookmark object | ||||
|                     bookmark = new Bookmark( | ||||
|                             m.getFilename(), | ||||
|  | @ -422,6 +454,25 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Decide wether or not we should display the background color menu items | ||||
|      * We display them if the image is transparent | ||||
|      * @param getBitmap | ||||
|      * @param menu | ||||
|      */ | ||||
|     private void handleBackgroundColorMenuItems(Callable<Bitmap> getBitmap, Menu menu) { | ||||
|         Observable.fromCallable( | ||||
|                 getBitmap | ||||
|             ).subscribeOn(Schedulers.newThread()) | ||||
|             .observeOn(AndroidSchedulers.mainThread()) | ||||
|             .subscribe(image -> { | ||||
|                 if (image.hasAlpha()) { | ||||
|                     menu.findItem(R.id.menu_view_set_white_background).setVisible(true).setEnabled(true); | ||||
|                     menu.findItem(R.id.menu_view_set_black_background).setVisible(true).setEnabled(true); | ||||
|                 } | ||||
|             }); | ||||
|     } | ||||
| 
 | ||||
|     private void updateBookmarkState(MenuItem item) { | ||||
|         boolean isBookmarked = bookmarkDao.findBookmark(bookmark); | ||||
|         if(isBookmarked) { | ||||
|  | @ -567,6 +618,18 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple | |||
|             return mCurrentFragment; | ||||
|         } | ||||
| 
 | ||||
|         /** | ||||
|          * If current fragment is of type MediaDetailFragment, return it, otherwise return null. | ||||
|          * @return MediaDetailFragment | ||||
|          */ | ||||
|         public MediaDetailFragment getCurrentMediaDetailFragment() { | ||||
|             if (mCurrentFragment instanceof MediaDetailFragment) { | ||||
|                 return (MediaDetailFragment) mCurrentFragment; | ||||
|             } | ||||
| 
 | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         /** | ||||
|          * Called to inform the adapter of which item is currently considered to be the "primary", | ||||
|          * that is the one show to the user as the current page. | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ import android.widget.Button | |||
| import android.widget.ProgressBar | ||||
| import android.widget.TextView | ||||
| import android.widget.Toast | ||||
| import androidx.core.content.ContextCompat | ||||
| import androidx.lifecycle.ViewModelProvider | ||||
| import butterknife.BindView | ||||
| import butterknife.ButterKnife | ||||
|  | @ -69,6 +70,8 @@ class ZoomableActivity : BaseActivity() { | |||
|     @JvmField | ||||
|     @BindView(R.id.zoomable) | ||||
|     var photo: ZoomableDraweeView? = null | ||||
|      | ||||
|     var photoBackgroundColor: Int? = null | ||||
| 
 | ||||
|     @JvmField | ||||
|     @BindView(R.id.zoom_progress_bar) | ||||
|  | @ -180,6 +183,13 @@ class ZoomableActivity : BaseActivity() { | |||
|                 ).apply() | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         val backgroundColor = intent.getIntExtra(ZoomableActivityConstants.PHOTO_BACKGROUND_COLOR, | ||||
|                 MediaDetailFragment.DEFAULT_IMAGE_BACKGROUND_COLOR); | ||||
| 
 | ||||
|         if (backgroundColor != MediaDetailFragment.DEFAULT_IMAGE_BACKGROUND_COLOR) { | ||||
|             photoBackgroundColor = backgroundColor | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | @ -196,7 +206,7 @@ class ZoomableActivity : BaseActivity() { | |||
|     /** | ||||
|      * Handle view model result. | ||||
|      */ | ||||
|     private fun handleResult(result: Result){ | ||||
|     private fun handleResult(result: Result) { | ||||
|         if(result.status is CallbackStatus.SUCCESS){ | ||||
|             val images = result.images | ||||
|             if(images.isNotEmpty()) { | ||||
|  | @ -608,6 +618,10 @@ class ZoomableActivity : BaseActivity() { | |||
|                 .setControllerListener(loadingListener) | ||||
|                 .build() | ||||
|             photo!!.controller = controller | ||||
|              | ||||
|             if (photoBackgroundColor != null) { | ||||
|                 photo!!.setBackgroundColor(photoBackgroundColor!!) | ||||
|             } | ||||
| 
 | ||||
|             if (!images.isNullOrEmpty()) { | ||||
|                 val selectedIndex = getImagePosition(selectedImages, images!![position]) | ||||
|  | @ -667,5 +681,7 @@ class ZoomableActivity : BaseActivity() { | |||
|          * the custom picker. | ||||
|          */ | ||||
|         const val ORIGIN = "Origin"; | ||||
|          | ||||
|         const val PHOTO_BACKGROUND_COLOR = "photo_background_color" | ||||
|     } | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Pierre Monier
						Pierre Monier