From d36e8589959790a5f809d33c47f5f9934d14d82a Mon Sep 17 00:00:00 2001 From: Kanahia <114223204+kanahia1@users.noreply.github.com> Date: Wed, 28 Feb 2024 22:33:13 +0530 Subject: [PATCH 1/8] Fixes #5502 updateactivity.kt --- .../fr/free/nrw/commons/edit/EditActivity.kt | 75 ++++++++++--------- 1 file changed, 40 insertions(+), 35 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/edit/EditActivity.kt b/app/src/main/java/fr/free/nrw/commons/edit/EditActivity.kt index 273c83c31..806bf10bb 100644 --- a/app/src/main/java/fr/free/nrw/commons/edit/EditActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/edit/EditActivity.kt @@ -6,6 +6,7 @@ import android.animation.ValueAnimator import android.content.Intent import android.graphics.BitmapFactory import android.graphics.Matrix +import android.graphics.drawable.BitmapDrawable import android.media.ExifInterface import android.os.Bundle import android.util.Log @@ -17,7 +18,10 @@ import androidx.core.graphics.rotationMatrix import androidx.core.graphics.scaleMatrix import androidx.core.net.toUri import androidx.lifecycle.ViewModelProvider -import fr.free.nrw.commons.databinding.ActivityEditBinding +import fr.free.nrw.commons.R +import kotlinx.android.synthetic.main.activity_edit.btn_save +import kotlinx.android.synthetic.main.activity_edit.iv +import kotlinx.android.synthetic.main.activity_edit.rotate_btn import timber.log.Timber import java.io.File @@ -33,15 +37,15 @@ class EditActivity : AppCompatActivity() { private var imageUri = "" private lateinit var vm: EditViewModel private val sourceExifAttributeList = mutableListOf>() - private lateinit var binding: ActivityEditBinding + private var totalRotation = 0 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - binding = ActivityEditBinding.inflate(layoutInflater) - setContentView(binding.root) + setContentView(R.layout.activity_edit) supportActionBar?.title = "" val intent = intent imageUri = intent.getStringExtra("image") ?: "" + imageRotation = intent.getIntExtra("rotation",0) vm = ViewModelProvider(this).get(EditViewModel::class.java) val sourceExif = imageUri.toUri().path?.let { ExifInterface(it) } val exifTags = arrayOf( @@ -85,9 +89,9 @@ class EditActivity : AppCompatActivity() { * for the "Rotate" and "Save" buttons. */ private fun init() { - binding.iv.adjustViewBounds = true - binding.iv.scaleType = ImageView.ScaleType.MATRIX - binding.iv.post(Runnable { + iv.adjustViewBounds = true + iv.scaleType = ImageView.ScaleType.MATRIX + iv.post(Runnable { val options = BitmapFactory.Options() options.inJustDecodeBounds = true BitmapFactory.decodeFile(imageUri, options) @@ -102,26 +106,27 @@ class EditActivity : AppCompatActivity() { options.inSampleSize = scaleFactor options.inJustDecodeBounds = false val scaledBitmap = BitmapFactory.decodeFile(imageUri, options) - binding.iv.setImageBitmap(scaledBitmap) + iv.setImageBitmap(scaledBitmap) // Update the ImageView with the scaled bitmap - val scale = binding.iv.measuredWidth.toFloat() / scaledBitmap.width.toFloat() - binding.iv.layoutParams.height = (scale * scaledBitmap.height).toInt() - binding.iv.imageMatrix = scaleMatrix(scale, scale) + val scale = iv.measuredWidth.toFloat() / scaledBitmap.width.toFloat() + iv.layoutParams.height = (scale * scaledBitmap.height).toInt() + iv.imageMatrix = scaleMatrix(scale, scale) } else { options.inJustDecodeBounds = false val bitmap = BitmapFactory.decodeFile(imageUri, options) - binding.iv.setImageBitmap(bitmap) + iv.setImageBitmap(bitmap) - val scale = binding.iv.measuredWidth.toFloat() / bitmapWidth.toFloat() - binding.iv.layoutParams.height = (scale * bitmapHeight).toInt() - binding.iv.imageMatrix = scaleMatrix(scale, scale) + val scale = iv.measuredWidth.toFloat() / bitmapWidth.toFloat() + iv.layoutParams.height = (scale * bitmapHeight).toInt() + iv.imageMatrix = scaleMatrix(scale, scale) } + animateImageHeight(false) }) - binding.rotateBtn.setOnClickListener { - animateImageHeight() + rotate_btn.setOnClickListener { + animateImageHeight(true) } - binding.btnSave.setOnClickListener { + btn_save.setOnClickListener { getRotatedImage() } } @@ -131,19 +136,20 @@ class EditActivity : AppCompatActivity() { /** * Animates the height, rotation, and scale of an ImageView to provide a smooth * transition effect when rotating an image by 90 degrees. + * @param shouldRotate A boolean indicating whether the image should rotate by 90 degrees. * * This function calculates the new height, rotation, and scale for the ImageView * based on the current image rotation angle and animates the changes using a * ValueAnimator. It also disables a rotate button during the animation to prevent * further rotation actions. */ - private fun animateImageHeight() { - val drawableWidth: Float = binding.iv.getDrawable().getIntrinsicWidth().toFloat() - val drawableHeight: Float = binding.iv.getDrawable().getIntrinsicHeight().toFloat() - val viewWidth: Float = binding.iv.getMeasuredWidth().toFloat() - val viewHeight: Float = binding.iv.getMeasuredHeight().toFloat() + private fun animateImageHeight(shouldRotate : Boolean) { + val drawableWidth: Float = iv.getDrawable().getIntrinsicWidth().toFloat() + val drawableHeight: Float = iv.getDrawable().getIntrinsicHeight().toFloat() + val viewWidth: Float = iv.getMeasuredWidth().toFloat() + val viewHeight: Float = iv.getMeasuredHeight().toFloat() val rotation = imageRotation % 360 - val newRotation = rotation + 90 + val newRotation = if (shouldRotate) rotation + 90 else rotation val newViewHeight: Int val imageScale: Float @@ -171,12 +177,12 @@ class EditActivity : AppCompatActivity() { animator.addListener(object : AnimatorListener { override fun onAnimationStart(animation: Animator) { - binding.rotateBtn.setEnabled(false) + rotate_btn.setEnabled(false) } override fun onAnimationEnd(animation: Animator) { imageRotation = newRotation % 360 - binding.rotateBtn.setEnabled(true) + rotate_btn.setEnabled(true) } override fun onAnimationCancel(animation: Animator) { @@ -194,7 +200,7 @@ class EditActivity : AppCompatActivity() { (complementaryAnimVal * viewHeight + animVal * newViewHeight).toInt() val animatedScale = complementaryAnimVal * imageScale + animVal * newImageScale val animatedRotation = complementaryAnimVal * rotation + animVal * newRotation - binding.iv.getLayoutParams().height = animatedHeight + iv.getLayoutParams().height = animatedHeight val matrix: Matrix = rotationMatrix( animatedRotation, drawableWidth / 2, @@ -207,11 +213,11 @@ class EditActivity : AppCompatActivity() { drawableHeight / 2 ) matrix.postTranslate( - -(drawableWidth - binding.iv.getMeasuredWidth()) / 2, - -(drawableHeight - binding.iv.getMeasuredHeight()) / 2 + -(drawableWidth - iv.getMeasuredWidth()) / 2, + -(drawableHeight - iv.getMeasuredHeight()) / 2 ) - binding.iv.setImageMatrix(matrix) - binding.iv.requestLayout() + iv.setImageMatrix(matrix) + iv.requestLayout() } animator.start() @@ -231,9 +237,7 @@ class EditActivity : AppCompatActivity() { val filePath = imageUri.toUri().path val file = filePath?.let { File(it) } - - - val rotatedImage = file?.let { vm.rotateImage(imageRotation, it) } + val rotatedImage = if(imageRotation == 0) file else file?.let { vm.rotateImage(imageRotation, it) } if (rotatedImage == null) { Toast.makeText(this, "Failed to rotate to image", Toast.LENGTH_LONG).show() } @@ -241,6 +245,7 @@ class EditActivity : AppCompatActivity() { copyExifData(editedImageExif) val resultIntent = Intent() resultIntent.putExtra("editedImageFilePath", rotatedImage?.toUri()?.path ?: "Error"); + resultIntent.putExtra("editedImageRotation",imageRotation) setResult(RESULT_OK, resultIntent); finish(); } @@ -295,4 +300,4 @@ class EditActivity : AppCompatActivity() { -} \ No newline at end of file +} From a19ae2e507a5d98d7767059819a467a2ea4cc055 Mon Sep 17 00:00:00 2001 From: Kanahia <114223204+kanahia1@users.noreply.github.com> Date: Wed, 28 Feb 2024 22:35:36 +0530 Subject: [PATCH 2/8] Fixes #5502 UploadMediaDetailFragment.java --- .../UploadMediaDetailFragment.java | 82 +++++++++---------- 1 file changed, 38 insertions(+), 44 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java index 85ce3b78b..7537704c9 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java @@ -36,7 +36,6 @@ import fr.free.nrw.commons.R; import fr.free.nrw.commons.edit.EditActivity; import fr.free.nrw.commons.contributions.MainActivity; import fr.free.nrw.commons.filepicker.UploadableFile; -import fr.free.nrw.commons.kvstore.BasicKvStore; import fr.free.nrw.commons.kvstore.JsonKvStore; import fr.free.nrw.commons.location.LatLng; import fr.free.nrw.commons.nearby.Place; @@ -70,6 +69,11 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements private static final int REQUEST_CODE_FOR_EDIT_ACTIVITY = 1212; private static final int REQUEST_CODE_FOR_VOICE_INPUT = 1213; + /** + * Stores the rotation angle of the image in degrees. + */ + private int rotation = 0; + /** * A key for applicationKvStore. By this key we can retrieve the location of last UploadItem ex. * 12.3433,54.78897 from applicationKvStore. @@ -196,10 +200,10 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements } if(savedInstanceState!=null){ - if(uploadMediaDetailAdapter.getItems().size()==0){ - uploadMediaDetailAdapter.setItems(savedInstanceState.getParcelableArrayList(UPLOAD_MEDIA_DETAILS)); - presenter.setUploadMediaDetails(uploadMediaDetailAdapter.getItems(), callback.getIndexInViewFlipper(this)); - } + if(uploadMediaDetailAdapter.getItems().size()==0){ + uploadMediaDetailAdapter.setItems(savedInstanceState.getParcelableArrayList(UPLOAD_MEDIA_DETAILS)); + presenter.setUploadMediaDetails(uploadMediaDetailAdapter.getItems(), callback.getIndexInViewFlipper(this)); + } } } @@ -223,7 +227,7 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements // If the image EXIF data contains the location, show the map icon with a green tick if (inAppPictureLocation != null || - (uploadableFile != null && uploadableFile.hasLocation())) { + (uploadableFile != null && uploadableFile.hasLocation())) { Drawable mapTick = getResources().getDrawable(R.drawable.ic_map_available_20dp); locationImageView.setImageDrawable(mapTick); locationTextView.setText(R.string.edit_location); @@ -252,10 +256,7 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements photoViewBackgroundImage.setOnScaleChangeListener( (scaleFactor, focusX, focusY) -> { //Whenever the uses plays with the image, lets collapse the media detail container - //only if it is not already collapsed, which resolves flickering of arrow - if (isExpanded) { - expandCollapseLlMediaDetail(false); - } + expandCollapseLlMediaDetail(false); }); } @@ -310,35 +311,31 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements @Override public void showSimilarImageFragment(String originalFilePath, String possibleFilePath, ImageCoordinates similarImageCoordinates) { - BasicKvStore basicKvStore = new BasicKvStore(getActivity(), "IsAnyImageCancelled"); - if (!basicKvStore.getBoolean("IsAnyImageCancelled", false)) { - SimilarImageDialogFragment newFragment = new SimilarImageDialogFragment(); - newFragment.setCallback(new SimilarImageDialogFragment.Callback() { - @Override - public void onPositiveResponse() { - Timber.d("positive response from similar image fragment"); - presenter.useSimilarPictureCoordinates(similarImageCoordinates, - callback.getIndexInViewFlipper(UploadMediaDetailFragment.this)); + SimilarImageDialogFragment newFragment = new SimilarImageDialogFragment(); + newFragment.setCallback(new SimilarImageDialogFragment.Callback() { + @Override + public void onPositiveResponse() { + Timber.d("positive response from similar image fragment"); + presenter.useSimilarPictureCoordinates(similarImageCoordinates, callback.getIndexInViewFlipper(UploadMediaDetailFragment.this)); - // set the description text when user selects to use coordinate from the other image - // which was taken within 120s - // fixing: https://github.com/commons-app/apps-android-commons/issues/4700 - uploadMediaDetailAdapter.getItems().get(0).setDescriptionText( - getString(R.string.similar_coordinate_description_auto_set)); - updateMediaDetails(uploadMediaDetailAdapter.getItems()); - } + // set the description text when user selects to use coordinate from the other image + // which was taken within 20s + // fixing: https://github.com/commons-app/apps-android-commons/issues/4700 + uploadMediaDetailAdapter.getItems().get(0).setDescriptionText( + getString(R.string.similar_coordinate_description_auto_set)); + updateMediaDetails(uploadMediaDetailAdapter.getItems()); + } - @Override - public void onNegativeResponse() { - Timber.d("negative response from similar image fragment"); - } - }); - Bundle args = new Bundle(); - args.putString("originalImagePath", originalFilePath); - args.putString("possibleImagePath", possibleFilePath); - newFragment.setArguments(args); - newFragment.show(getChildFragmentManager(), "dialog"); - } + @Override + public void onNegativeResponse() { + Timber.d("negative response from similar image fragment"); + } + }); + Bundle args = new Bundle(); + args.putString("originalImagePath", originalFilePath); + args.putString("possibleImagePath", possibleFilePath); + newFragment.setArguments(args); + newFragment.show(getChildFragmentManager(), "dialog"); } @Override @@ -463,8 +460,7 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements false); } else { uploadItem.setImageQuality(ImageUtils.IMAGE_KEEP); - // Calling below, instead of onNextButtonClicked() to not show locationDialog twice - onImageValidationSuccess(); + onNextButtonClicked(); } } @@ -487,11 +483,7 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements // validate image only when same file name error does not occur // show the same file name error if exists. - // If image with same file name exists check the bit in errorCode is set or not - if ((errorCode & FILE_NAME_EXISTS) != 0) { - Timber.d("Trying to show duplicate picture popup"); - showDuplicatePicturePopup(uploadItem); - } else { + if ((errorCode & FILE_NAME_EXISTS) == 0) { uploadItem.setImageQuality(ImageUtils.IMAGE_KEEP); onImageValidationSuccess(); } @@ -530,6 +522,7 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements editableUploadItem = uploadItem; Intent intent = new Intent(getContext(), EditActivity.class); intent.putExtra("image", uploadableFile.getFilePath().toString()); + intent.putExtra("rotation",rotation); startActivityForResult(intent, REQUEST_CODE_FOR_EDIT_ACTIVITY); } @@ -615,6 +608,7 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements } if (requestCode == REQUEST_CODE_FOR_EDIT_ACTIVITY && resultCode == RESULT_OK) { String result = data.getStringExtra("editedImageFilePath"); + rotation = data.getIntExtra("editedImageRotation",0); if (Objects.equals(result, "Error")) { Timber.e("Error in rotating image"); From 5c0ccbb4016387fcb0df60a0c5c3021c39590193 Mon Sep 17 00:00:00 2001 From: Kanahia <114223204+kanahia1@users.noreply.github.com> Date: Fri, 1 Mar 2024 23:16:18 +0530 Subject: [PATCH 3/8] Delete app/src/main/res/values-yue-hant directory --- app/src/main/res/values-yue-hant/error.xml | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 app/src/main/res/values-yue-hant/error.xml diff --git a/app/src/main/res/values-yue-hant/error.xml b/app/src/main/res/values-yue-hant/error.xml deleted file mode 100644 index 68579e4a0..000000000 --- a/app/src/main/res/values-yue-hant/error.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - 同享壞咗 - 哎呀。出咗錯! - 多謝你! - From ba64707aee0c737b003484e91caa29c6b7b6b1e4 Mon Sep 17 00:00:00 2001 From: Kanahia Date: Wed, 20 Mar 2024 12:34:35 +0530 Subject: [PATCH 4/8] removed values-yue-hant --- app/src/main/res/values-yue-hant/error.xml | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 app/src/main/res/values-yue-hant/error.xml diff --git a/app/src/main/res/values-yue-hant/error.xml b/app/src/main/res/values-yue-hant/error.xml deleted file mode 100644 index 68579e4a0..000000000 --- a/app/src/main/res/values-yue-hant/error.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - 同享壞咗 - 哎呀。出咗錯! - 多謝你! - From eaff12be39668e3c87f3e3505520bee23f4dd6d9 Mon Sep 17 00:00:00 2001 From: Kanahia Date: Wed, 20 Mar 2024 12:59:15 +0530 Subject: [PATCH 5/8] Fixed issues caused by merging --- .../fr/free/nrw/commons/edit/EditActivity.kt | 65 +++++++++---------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/edit/EditActivity.kt b/app/src/main/java/fr/free/nrw/commons/edit/EditActivity.kt index 806bf10bb..b177f9c04 100644 --- a/app/src/main/java/fr/free/nrw/commons/edit/EditActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/edit/EditActivity.kt @@ -6,7 +6,6 @@ import android.animation.ValueAnimator import android.content.Intent import android.graphics.BitmapFactory import android.graphics.Matrix -import android.graphics.drawable.BitmapDrawable import android.media.ExifInterface import android.os.Bundle import android.util.Log @@ -18,10 +17,7 @@ import androidx.core.graphics.rotationMatrix import androidx.core.graphics.scaleMatrix import androidx.core.net.toUri import androidx.lifecycle.ViewModelProvider -import fr.free.nrw.commons.R -import kotlinx.android.synthetic.main.activity_edit.btn_save -import kotlinx.android.synthetic.main.activity_edit.iv -import kotlinx.android.synthetic.main.activity_edit.rotate_btn +import fr.free.nrw.commons.databinding.ActivityEditBinding import timber.log.Timber import java.io.File @@ -37,11 +33,13 @@ class EditActivity : AppCompatActivity() { private var imageUri = "" private lateinit var vm: EditViewModel private val sourceExifAttributeList = mutableListOf>() + private lateinit var binding: ActivityEditBinding private var totalRotation = 0 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_edit) + binding = ActivityEditBinding.inflate(layoutInflater) + setContentView(binding.root) supportActionBar?.title = "" val intent = intent imageUri = intent.getStringExtra("image") ?: "" @@ -89,9 +87,9 @@ class EditActivity : AppCompatActivity() { * for the "Rotate" and "Save" buttons. */ private fun init() { - iv.adjustViewBounds = true - iv.scaleType = ImageView.ScaleType.MATRIX - iv.post(Runnable { + binding.iv.adjustViewBounds = true + binding.iv.scaleType = ImageView.ScaleType.MATRIX + binding.iv.post(Runnable { val options = BitmapFactory.Options() options.inJustDecodeBounds = true BitmapFactory.decodeFile(imageUri, options) @@ -106,27 +104,27 @@ class EditActivity : AppCompatActivity() { options.inSampleSize = scaleFactor options.inJustDecodeBounds = false val scaledBitmap = BitmapFactory.decodeFile(imageUri, options) - iv.setImageBitmap(scaledBitmap) + binding.iv.setImageBitmap(scaledBitmap) // Update the ImageView with the scaled bitmap - val scale = iv.measuredWidth.toFloat() / scaledBitmap.width.toFloat() - iv.layoutParams.height = (scale * scaledBitmap.height).toInt() - iv.imageMatrix = scaleMatrix(scale, scale) + val scale = binding.iv.measuredWidth.toFloat() / scaledBitmap.width.toFloat() + binding.iv.layoutParams.height = (scale * scaledBitmap.height).toInt() + binding.iv.imageMatrix = scaleMatrix(scale, scale) } else { options.inJustDecodeBounds = false val bitmap = BitmapFactory.decodeFile(imageUri, options) - iv.setImageBitmap(bitmap) + binding.iv.setImageBitmap(bitmap) - val scale = iv.measuredWidth.toFloat() / bitmapWidth.toFloat() - iv.layoutParams.height = (scale * bitmapHeight).toInt() - iv.imageMatrix = scaleMatrix(scale, scale) + val scale = binding.iv.measuredWidth.toFloat() / bitmapWidth.toFloat() + binding.iv.layoutParams.height = (scale * bitmapHeight).toInt() + binding.iv.imageMatrix = scaleMatrix(scale, scale) } animateImageHeight(false) }) - rotate_btn.setOnClickListener { + binding.rotateBtn.setOnClickListener { animateImageHeight(true) } - btn_save.setOnClickListener { + binding.btnSave.setOnClickListener { getRotatedImage() } } @@ -137,17 +135,16 @@ class EditActivity : AppCompatActivity() { * Animates the height, rotation, and scale of an ImageView to provide a smooth * transition effect when rotating an image by 90 degrees. * @param shouldRotate A boolean indicating whether the image should rotate by 90 degrees. - * * This function calculates the new height, rotation, and scale for the ImageView * based on the current image rotation angle and animates the changes using a * ValueAnimator. It also disables a rotate button during the animation to prevent * further rotation actions. */ private fun animateImageHeight(shouldRotate : Boolean) { - val drawableWidth: Float = iv.getDrawable().getIntrinsicWidth().toFloat() - val drawableHeight: Float = iv.getDrawable().getIntrinsicHeight().toFloat() - val viewWidth: Float = iv.getMeasuredWidth().toFloat() - val viewHeight: Float = iv.getMeasuredHeight().toFloat() + val drawableWidth: Float = binding.iv.getDrawable().getIntrinsicWidth().toFloat() + val drawableHeight: Float = binding.iv.getDrawable().getIntrinsicHeight().toFloat() + val viewWidth: Float = binding.iv.getMeasuredWidth().toFloat() + val viewHeight: Float = binding.iv.getMeasuredHeight().toFloat() val rotation = imageRotation % 360 val newRotation = if (shouldRotate) rotation + 90 else rotation @@ -177,12 +174,12 @@ class EditActivity : AppCompatActivity() { animator.addListener(object : AnimatorListener { override fun onAnimationStart(animation: Animator) { - rotate_btn.setEnabled(false) + binding.rotateBtn.setEnabled(false) } override fun onAnimationEnd(animation: Animator) { imageRotation = newRotation % 360 - rotate_btn.setEnabled(true) + binding.rotateBtn.setEnabled(true) } override fun onAnimationCancel(animation: Animator) { @@ -200,7 +197,7 @@ class EditActivity : AppCompatActivity() { (complementaryAnimVal * viewHeight + animVal * newViewHeight).toInt() val animatedScale = complementaryAnimVal * imageScale + animVal * newImageScale val animatedRotation = complementaryAnimVal * rotation + animVal * newRotation - iv.getLayoutParams().height = animatedHeight + binding.iv.getLayoutParams().height = animatedHeight val matrix: Matrix = rotationMatrix( animatedRotation, drawableWidth / 2, @@ -213,11 +210,11 @@ class EditActivity : AppCompatActivity() { drawableHeight / 2 ) matrix.postTranslate( - -(drawableWidth - iv.getMeasuredWidth()) / 2, - -(drawableHeight - iv.getMeasuredHeight()) / 2 + -(drawableWidth - binding.iv.getMeasuredWidth()) / 2, + -(drawableHeight - binding.iv.getMeasuredHeight()) / 2 ) - iv.setImageMatrix(matrix) - iv.requestLayout() + binding.iv.setImageMatrix(matrix) + binding.iv.requestLayout() } animator.start() @@ -237,7 +234,9 @@ class EditActivity : AppCompatActivity() { val filePath = imageUri.toUri().path val file = filePath?.let { File(it) } - val rotatedImage = if(imageRotation == 0) file else file?.let { vm.rotateImage(imageRotation, it) } + + + val rotatedImage = file?.let { vm.rotateImage(imageRotation, it) } if (rotatedImage == null) { Toast.makeText(this, "Failed to rotate to image", Toast.LENGTH_LONG).show() } @@ -300,4 +299,4 @@ class EditActivity : AppCompatActivity() { -} +} \ No newline at end of file From fe9f2a921b091b15c4c2af4790d9e67efe697bda Mon Sep 17 00:00:00 2001 From: Kanahia Date: Wed, 20 Mar 2024 13:20:15 +0530 Subject: [PATCH 6/8] Fixed failing tests --- .idea/inspectionProfiles/Project_Default.xml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index a5d456928..16cd6228b 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -1,8 +1,7 @@ \ No newline at end of file From 5574d347f1eaf9c8ff61f5ee5dba14e545c45ace Mon Sep 17 00:00:00 2001 From: Kanahia Date: Wed, 20 Mar 2024 13:20:41 +0530 Subject: [PATCH 7/8] Fixed failing tests --- .../upload/mediaDetails/UploadMediaDetailFragment.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java index 536cc289e..6904fbb34 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java @@ -171,7 +171,9 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements if(savedInstanceState!=null){ if(uploadMediaDetailAdapter.getItems().size()==0){ uploadMediaDetailAdapter.setItems(savedInstanceState.getParcelableArrayList(UPLOAD_MEDIA_DETAILS)); - presenter.setUploadMediaDetails(uploadMediaDetailAdapter.getItems(), callback.getIndexInViewFlipper(this)); + if (callback != null){ + presenter.setUploadMediaDetails(uploadMediaDetailAdapter.getItems(), callback.getIndexInViewFlipper(this)); + } } } From 27c7f16b890927d772463c949a9ba3e945741280 Mon Sep 17 00:00:00 2001 From: Kanahia Date: Mon, 1 Apr 2024 22:31:03 +0530 Subject: [PATCH 8/8] Fixed animation error --- .../fr/free/nrw/commons/edit/EditActivity.kt | 26 +++++++----- .../UploadMediaDetailFragment.java | 42 ++++++++++--------- 2 files changed, 38 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/edit/EditActivity.kt b/app/src/main/java/fr/free/nrw/commons/edit/EditActivity.kt index a20e4fac3..adad2a9c3 100644 --- a/app/src/main/java/fr/free/nrw/commons/edit/EditActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/edit/EditActivity.kt @@ -31,6 +31,7 @@ import java.io.File */ class EditActivity : AppCompatActivity() { private var imageUri = "" + private var imageRotation = 0 private lateinit var vm: EditViewModel private val sourceExifAttributeList = mutableListOf>() private lateinit var binding: ActivityEditBinding @@ -44,6 +45,7 @@ class EditActivity : AppCompatActivity() { val intent = intent imageUri = intent.getStringExtra("image") ?: "" imageRotation = intent.getIntExtra("rotation",0) + totalRotation = imageRotation vm = ViewModelProvider(this).get(EditViewModel::class.java) val sourceExif = imageUri.toUri().path?.let { ExifInterface(it) } val exifTags = arrayOf( @@ -89,7 +91,7 @@ class EditActivity : AppCompatActivity() { private fun init() { binding.iv.adjustViewBounds = true binding.iv.scaleType = ImageView.ScaleType.MATRIX - binding.iv.post(Runnable { + binding.iv.post { val options = BitmapFactory.Options() options.inJustDecodeBounds = true BitmapFactory.decodeFile(imageUri, options) @@ -105,6 +107,8 @@ class EditActivity : AppCompatActivity() { options.inJustDecodeBounds = false val scaledBitmap = BitmapFactory.decodeFile(imageUri, options) binding.iv.setImageBitmap(scaledBitmap) + binding.iv.rotation = (imageRotation % 360).toFloat() + imageRotation = 0 // Update the ImageView with the scaled bitmap val scale = binding.iv.measuredWidth.toFloat() / scaledBitmap.width.toFloat() binding.iv.layoutParams.height = (scale * scaledBitmap.height).toInt() @@ -114,23 +118,21 @@ class EditActivity : AppCompatActivity() { options.inJustDecodeBounds = false val bitmap = BitmapFactory.decodeFile(imageUri, options) binding.iv.setImageBitmap(bitmap) - + binding.iv.rotation = (imageRotation % 360).toFloat() + imageRotation = 0 val scale = binding.iv.measuredWidth.toFloat() / bitmapWidth.toFloat() binding.iv.layoutParams.height = (scale * bitmapHeight).toInt() binding.iv.imageMatrix = scaleMatrix(scale, scale) } - animateImageHeight(false) - }) + } binding.rotateBtn.setOnClickListener { - animateImageHeight(true) + animateImageHeight() } binding.btnSave.setOnClickListener { getRotatedImage() } } - var imageRotation = 0 - /** * Animates the height, rotation, and scale of an ImageView to provide a smooth * transition effect when rotating an image by 90 degrees. @@ -140,13 +142,13 @@ class EditActivity : AppCompatActivity() { * ValueAnimator. It also disables a rotate button during the animation to prevent * further rotation actions. */ - private fun animateImageHeight(shouldRotate : Boolean) { + private fun animateImageHeight() { val drawableWidth: Float = binding.iv.getDrawable().getIntrinsicWidth().toFloat() val drawableHeight: Float = binding.iv.getDrawable().getIntrinsicHeight().toFloat() val viewWidth: Float = binding.iv.getMeasuredWidth().toFloat() val viewHeight: Float = binding.iv.getMeasuredHeight().toFloat() val rotation = imageRotation % 360 - val newRotation = if (shouldRotate) rotation + 90 else rotation + val newRotation = rotation + 90 val newViewHeight: Int val imageScale: Float @@ -179,6 +181,8 @@ class EditActivity : AppCompatActivity() { override fun onAnimationEnd(animation: Animator) { imageRotation = newRotation % 360 + val t1 = totalRotation % 360 + totalRotation = t1 + 90 binding.rotateBtn.setEnabled(true) } @@ -236,7 +240,7 @@ class EditActivity : AppCompatActivity() { val file = filePath?.let { File(it) } - val rotatedImage = file?.let { vm.rotateImage(imageRotation, it) } + val rotatedImage = if(totalRotation == 360 || totalRotation == 0) file else file?.let { vm.rotateImage(totalRotation, it) } if (rotatedImage == null) { Toast.makeText(this, "Failed to rotate to image", Toast.LENGTH_LONG).show() } @@ -247,7 +251,7 @@ class EditActivity : AppCompatActivity() { } val resultIntent = Intent() resultIntent.putExtra("editedImageFilePath", rotatedImage?.toUri()?.path ?: "Error"); - resultIntent.putExtra("editedImageRotation",imageRotation) + resultIntent.putExtra("editedImageRotation",totalRotation) setResult(RESULT_OK, resultIntent); finish(); } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java index b5052f452..6f1f32623 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java @@ -29,6 +29,7 @@ import fr.free.nrw.commons.contributions.MainActivity; import fr.free.nrw.commons.databinding.FragmentUploadMediaDetailFragmentBinding; import fr.free.nrw.commons.edit.EditActivity; import fr.free.nrw.commons.filepicker.UploadableFile; +import fr.free.nrw.commons.kvstore.BasicKvStore; import fr.free.nrw.commons.kvstore.JsonKvStore; import fr.free.nrw.commons.location.LatLng; import fr.free.nrw.commons.nearby.Place; @@ -133,7 +134,7 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements private UploadItem editableUploadItem; private BasicKvStore basicKvStore; - + private final String keyForShowingAlertDialog = "isNoNetworkAlertDialogShowing"; private UploadMediaDetailFragmentCallback callback; @@ -187,19 +188,18 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements } if(savedInstanceState!=null){ - if(uploadMediaDetailAdapter.getItems().size()==0){ + if(uploadMediaDetailAdapter.getItems().size()==0 && callback != null){ uploadMediaDetailAdapter.setItems(savedInstanceState.getParcelableArrayList(UPLOAD_MEDIA_DETAILS)); - if (callback != null){ - presenter.setUploadMediaDetails(uploadMediaDetailAdapter.getItems(), callback.getIndexInViewFlipper(this)); - } + presenter.setUploadMediaDetails(uploadMediaDetailAdapter.getItems(), + indexOfFragment); } } try { if(!presenter.getImageQuality(indexOfFragment, inAppPictureLocation, getActivity())) { startActivityWithFlags( - getActivity(), MainActivity.class, Intent.FLAG_ACTIVITY_CLEAR_TOP, - Intent.FLAG_ACTIVITY_SINGLE_TOP); + getActivity(), MainActivity.class, Intent.FLAG_ACTIVITY_CLEAR_TOP, + Intent.FLAG_ACTIVITY_SINGLE_TOP); } } catch (Exception e) { } @@ -265,7 +265,10 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements binding.backgroundImage.setOnScaleChangeListener( (scaleFactor, focusX, focusY) -> { //Whenever the uses plays with the image, lets collapse the media detail container - expandCollapseLlMediaDetail(false); + //only if it is not already collapsed, which resolves flickering of arrow + if (isExpanded) { + expandCollapseLlMediaDetail(false); + } }); } @@ -337,16 +340,17 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements updateMediaDetails(uploadMediaDetailAdapter.getItems()); } - @Override - public void onNegativeResponse() { - Timber.d("negative response from similar image fragment"); - } - }); - Bundle args = new Bundle(); - args.putString("originalImagePath", originalFilePath); - args.putString("possibleImagePath", possibleFilePath); - newFragment.setArguments(args); - newFragment.show(getChildFragmentManager(), "dialog"); + @Override + public void onNegativeResponse() { + Timber.d("negative response from similar image fragment"); + } + }); + Bundle args = new Bundle(); + args.putString("originalImagePath", originalFilePath); + args.putString("possibleImagePath", possibleFilePath); + newFragment.setArguments(args); + newFragment.show(getChildFragmentManager(), "dialog"); + } } @Override @@ -879,4 +883,4 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements super.onDestroy(); binding = null; } -} +} \ No newline at end of file