From 6f75927432cf80923514f9f327c5c0b706f2652c Mon Sep 17 00:00:00 2001 From: Rohit Verma Date: Tue, 14 Jan 2025 09:43:16 +0530 Subject: [PATCH 1/9] fix IndexOutOfBounds error when removing thumbnails --- .../main/java/fr/free/nrw/commons/upload/UploadActivity.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt b/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt index 020284934..64c79dd36 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt @@ -797,7 +797,10 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C } } - override fun onThumbnailDeleted(position: Int) = presenter!!.deletePictureAtIndex(position) + override fun onThumbnailDeleted(position: Int) { + presenter!!.deletePictureAtIndex(position) + thumbnailsAdapter?.notifyItemRemoved(position) + } /** * The adapter used to show image upload intermediate fragments From d0b6ce5c52e00a64e7c445dfaf833d75553223c5 Mon Sep 17 00:00:00 2001 From: Rohit Verma Date: Tue, 14 Jan 2025 10:04:40 +0530 Subject: [PATCH 2/9] refactor: resolve compiler warnings --- .../free/nrw/commons/upload/UploadActivity.kt | 83 ++++++++++--------- .../mediaDetails/UploadMediaDetailFragment.kt | 2 +- .../mediaDetails/UploadMediaPresenter.kt | 14 ++-- 3 files changed, 51 insertions(+), 48 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt b/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt index 64c79dd36..fb8a86d65 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt @@ -122,7 +122,7 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C /** * Set the value of the showPermissionDialog variable. * - * @param showPermissionsDialog `true` to indicate to show + * @property isShowPermissionsDialog `true` to indicate to show * Permissions Dialog if permissions are missing, `false` otherwise. */ /** @@ -187,7 +187,7 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C } init() - binding.rlContainerTitle.setOnClickListener { v: View? -> onRlContainerTitleClicked() } + binding.rlContainerTitle.setOnClickListener { _: View? -> onRlContainerTitleClicked() } nearbyPopupAnswers = mutableMapOf() //getting the current dpi of the device and if it is less than 320dp i.e. overlapping //threshold, thumbnails automatically minimizes @@ -201,7 +201,7 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C } locationManager!!.requestLocationUpdatesFromProvider(LocationManager.GPS_PROVIDER) locationManager!!.requestLocationUpdatesFromProvider(LocationManager.NETWORK_PROVIDER) - store = BasicKvStore(this, storeNameForCurrentUploadImagesSize).apply { + store = BasicKvStore(this, STORE_NAME_FOR_CURRENT_UPLOAD_IMAGE_SIZE).apply { clearAll() } checkStoragePermissions() @@ -241,7 +241,7 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C override fun onPageSelected(position: Int) { currentSelectedPosition = position - if (position >= uploadableFiles!!.size) { + if (position >= uploadableFiles.size) { binding.cvContainerTopCard.visibility = View.GONE } else { thumbnailsAdapter!!.notifyDataSetChanged() @@ -274,7 +274,7 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .filter { result: Boolean? -> result!! } - .subscribe { result: Boolean? -> + .subscribe { _: Boolean? -> showAlertDialog( this, getString(R.string.block_notification_title), @@ -284,7 +284,7 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C }) } - fun checkStoragePermissions() { + private fun checkStoragePermissions() { // Check if all required permissions are granted val hasAllPermissions = hasPermission(this, PERMISSIONS_STORAGE) val hasPartialAccess = hasPartialAccess(this) @@ -355,7 +355,7 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C showLongToast(this, messageResourceId) } - override fun getUploadableFiles(): List? { + override fun getUploadableFiles(): List { return uploadableFiles } @@ -375,8 +375,8 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C binding.tvTopCardTitle.text = resources .getQuantityString( R.plurals.upload_count_title, - uploadableFiles!!.size, - uploadableFiles!!.size + uploadableFiles.size, + uploadableFiles.size ) } @@ -444,15 +444,16 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C receiveInternalSharedItems() } - if (uploadableFiles == null || uploadableFiles!!.isEmpty()) { + if (uploadableFiles.isEmpty()) { handleNullMedia() } else { //Show thumbnails - if (uploadableFiles!!.size > 1) { - if (!defaultKvStore.getBoolean("hasAlreadyLaunchedCategoriesDialog")) { //If there is only file, no need to show the image thumbnails + if (uploadableFiles.size > 1) { + if (!defaultKvStore.getBoolean("hasAlreadyLaunchedCategoriesDialog")) { + // If there is only file, no need to show the image thumbnails showAlertDialogForCategories() } - if (uploadableFiles!!.size > 3 && + if (uploadableFiles.size > 3 && !defaultKvStore.getBoolean("hasAlreadyLaunchedBigMultiupload") ) { showAlertForBattery() @@ -464,8 +465,8 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C binding.tvTopCardTitle.text = resources .getQuantityString( R.plurals.upload_count_title, - uploadableFiles!!.size, - uploadableFiles!!.size + uploadableFiles.size, + uploadableFiles.size ) @@ -474,7 +475,7 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C } - for (uploadableFile in uploadableFiles!!) { + for (uploadableFile in uploadableFiles) { val uploadMediaDetailFragment = UploadMediaDetailFragment() if (!uploadIsOfAPlace) { @@ -497,8 +498,8 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C object : UploadMediaDetailFragmentCallback { override fun deletePictureAtIndex(index: Int) { store!!.putInt( - keyForCurrentUploadImagesSize, - (store!!.getInt(keyForCurrentUploadImagesSize) - 1) + KEY_FOR_CURRENT_UPLOAD_IMAGE_SIZE, + (store!!.getInt(KEY_FOR_CURRENT_UPLOAD_IMAGE_SIZE) - 1) ) presenter!!.deletePictureAtIndex(index) } @@ -576,11 +577,11 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C fragments!!.add(mediaLicenseFragment!!) } else { for (i in 1 until fragments!!.size) { - fragments!![i]!!.callback = object : UploadBaseFragment.Callback { + fragments!![i].callback = object : UploadBaseFragment.Callback { override fun onNextButtonClicked(index: Int) { if (index < fragments!!.size - 1) { binding.vpUpload.setCurrentItem(index + 1, false) - fragments!![index + 1]!!.onBecameVisible() + fragments!![index + 1].onBecameVisible() (binding.rvThumbnails.layoutManager as LinearLayoutManager) .scrollToPositionWithOffset( if ((index > 0)) index - 1 else 0, @@ -594,7 +595,7 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C override fun onPreviousButtonClicked(index: Int) { if (index != 0) { binding.vpUpload.setCurrentItem(index - 1, true) - fragments!![index - 1]!!.onBecameVisible() + fragments!![index - 1].onBecameVisible() (binding.rvThumbnails.layoutManager as LinearLayoutManager) .scrollToPositionWithOffset( if ((index > 3)) index - 2 else 0, @@ -632,11 +633,12 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C binding.vpUpload.offscreenPageLimit = fragments!!.size } // Saving size of uploadableFiles - store!!.putInt(keyForCurrentUploadImagesSize, uploadableFiles!!.size) + store!!.putInt(KEY_FOR_CURRENT_UPLOAD_IMAGE_SIZE, uploadableFiles.size) } /** - * Changes current image when one image upload is cancelled, to highlight next image in the top thumbnail. + * Changes current image when one image upload is cancelled, to highlight next image in the top + * thumbnail. * Fixes: [Issue](https://github.com/commons-app/apps-android-commons/issues/5511) * * @param index Index of image to be removed @@ -771,7 +773,7 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C override fun onNextButtonClicked(index: Int) { if (index < fragments!!.size - 1) { binding.vpUpload.setCurrentItem(index + 1, false) - fragments!![index + 1]!!.onBecameVisible() + fragments!![index + 1].onBecameVisible() (binding.rvThumbnails.layoutManager as LinearLayoutManager) .scrollToPositionWithOffset(if ((index > 0)) index - 1 else 0, 0) if (index < fragments!!.size - 4) { @@ -786,10 +788,10 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C override fun onPreviousButtonClicked(index: Int) { if (index != 0) { binding.vpUpload.setCurrentItem(index - 1, true) - fragments!![index - 1]!!.onBecameVisible() + fragments!![index - 1].onBecameVisible() (binding.rvThumbnails.layoutManager as LinearLayoutManager) .scrollToPositionWithOffset(if ((index > 3)) index - 2 else 0, 0) - if ((index != 1) && ((index - 1) < uploadableFiles!!.size)) { + if ((index != 1) && ((index - 1) < uploadableFiles.size)) { // Shows the top card if it was hidden because of the last image being deleted and // now the user has hit previous button to go back to the media details showHideTopCard(true) @@ -827,11 +829,11 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C } - fun onRlContainerTitleClicked() { + private fun onRlContainerTitleClicked() { binding.rvThumbnails.visibility = if (isTitleExpanded) View.GONE else View.VISIBLE isTitleExpanded = !isTitleExpanded - binding.ibToggleTopCard.rotation = binding.ibToggleTopCard.rotation + 180 + binding.ibToggleTopCard.rotation += 180 } override fun onDestroy() { @@ -882,7 +884,7 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C .setView(view) .setTitle(getString(R.string.multiple_files_depiction_header)) .setMessage(getString(R.string.multiple_files_depiction)) - .setPositiveButton("OK") { dialog: DialogInterface?, which: Int -> + .setPositiveButton("OK") { _: DialogInterface?, _: Int -> if (checkBox.isChecked) { // Save the user's choice to not show the dialog again defaultKvStore.putBoolean("hasAlreadyLaunchedCategoriesDialog", true) @@ -916,14 +918,14 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C getString(R.string.cancel), { /* Since opening the right settings page might be device dependent, using - https://github.com/WaseemSabir/BatteryPermissionHelper - directly appeared like a promising idea. - However, this simply closed the popup and did not make - the settings page appear on a Pixel as well as a Xiaomi device. - Used the standard intent instead of using this library as - it shows a list of all the apps on the device and allows users to - turn battery optimisation off. - */ + https://github.com/WaseemSabir/BatteryPermissionHelper + directly appeared like a promising idea. + However, this simply closed the popup and did not make + the settings page appear on a Pixel as well as a Xiaomi device. + Used the standard intent instead of using this library as + it shows a list of all the apps on the device and allows users to + turn battery optimisation off. + */ val batteryOptimisationSettingsIntent = Intent( Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS ) @@ -961,7 +963,8 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C Also, location information is discarded if the difference between current location and location recorded just before capturing the image is greater than 100 meters */ - if (isLocationTagUnchecked || locationDifference > 100 || !defaultKvStore.getBoolean("inAppCameraLocationPref") + if (isLocationTagUnchecked || locationDifference > 100 + || !defaultKvStore.getBoolean("inAppCameraLocationPref") || !isInAppCameraUpload ) { currLocation = null @@ -982,8 +985,8 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C @JvmField var nearbyPopupAnswers: MutableMap? = null - const val keyForCurrentUploadImagesSize: String = "CurrentUploadImagesSize" - const val storeNameForCurrentUploadImagesSize: String = "CurrentUploadImageQualities" + const val KEY_FOR_CURRENT_UPLOAD_IMAGE_SIZE: String = "CurrentUploadImagesSize" + const val STORE_NAME_FOR_CURRENT_UPLOAD_IMAGE_SIZE: String = "CurrentUploadImageQualities" /** * Sets the flag indicating whether the upload is of a specific place. diff --git a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.kt b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.kt index af850a7e3..4a4c13ba7 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.kt @@ -532,7 +532,7 @@ class UploadMediaDetailFragment : UploadBaseFragment(), UploadMediaDetailsContra basicKvStore!!.putBoolean(keyForShowingAlertDialog, false) if (isInternetConnectionEstablished(requireActivity())) { val sizeOfUploads = basicKvStore!!.getInt( - UploadActivity.keyForCurrentUploadImagesSize + UploadActivity.KEY_FOR_CURRENT_UPLOAD_IMAGE_SIZE ) for (i in indexOfFragment until sizeOfUploads) { presenter.getImageQuality( diff --git a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.kt b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.kt index 90c426091..1213ffdb1 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.kt @@ -310,7 +310,7 @@ class UploadMediaPresenter @Inject constructor( private fun storeImageQuality( imageResult: Int, uploadItemIndex: Int, activity: Activity, uploadItem: UploadItem ) { - val store = BasicKvStore(activity, UploadActivity.storeNameForCurrentUploadImagesSize) + val store = BasicKvStore(activity, UploadActivity.STORE_NAME_FOR_CURRENT_UPLOAD_IMAGE_SIZE) val value = store.getString(UPLOAD_QUALITIES_KEY, null) try { val jsonObject = value.asJsonObject().apply { @@ -339,8 +339,8 @@ class UploadMediaPresenter @Inject constructor( */ override fun checkImageQuality(uploadItem: UploadItem, index: Int) { if ((uploadItem.imageQuality != IMAGE_OK) && (uploadItem.imageQuality != IMAGE_KEEP)) { - val value = basicKvStoreFactory?.let { it(UploadActivity.storeNameForCurrentUploadImagesSize) } - ?.getString(UPLOAD_QUALITIES_KEY, null) + val value = basicKvStoreFactory(UploadActivity.STORE_NAME_FOR_CURRENT_UPLOAD_IMAGE_SIZE) + .getString(UPLOAD_QUALITIES_KEY, null) try { val imageQuality = value.asJsonObject()["UploadItem$index"] as Int view.showProgress(false) @@ -363,8 +363,8 @@ class UploadMediaPresenter @Inject constructor( * @param index Index of the UploadItem which was deleted */ override fun updateImageQualitiesJSON(size: Int, index: Int) { - val value = basicKvStoreFactory?.let { it(UploadActivity.storeNameForCurrentUploadImagesSize) } - ?.getString(UPLOAD_QUALITIES_KEY, null) + val value = basicKvStoreFactory(UploadActivity.STORE_NAME_FOR_CURRENT_UPLOAD_IMAGE_SIZE) + .getString(UPLOAD_QUALITIES_KEY, null) try { val jsonObject = value.asJsonObject().apply { for (i in index until (size - 1)) { @@ -372,8 +372,8 @@ class UploadMediaPresenter @Inject constructor( } remove("UploadItem" + (size - 1)) } - basicKvStoreFactory?.let { it(UploadActivity.storeNameForCurrentUploadImagesSize) } - ?.putString(UPLOAD_QUALITIES_KEY, jsonObject.toString()) + basicKvStoreFactory(UploadActivity.STORE_NAME_FOR_CURRENT_UPLOAD_IMAGE_SIZE) + .putString(UPLOAD_QUALITIES_KEY, jsonObject.toString()) } catch (e: Exception) { Timber.e(e) } From c07a6acd0bff068bd34c4fdcbe0c02aebe232b20 Mon Sep 17 00:00:00 2001 From: Rohit Verma Date: Tue, 14 Jan 2025 10:14:12 +0530 Subject: [PATCH 3/9] refactor: replace deprecated onBackPressed with onBackPressedCallback --- .../free/nrw/commons/upload/UploadActivity.kt | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt b/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt index fb8a86d65..aeac598f9 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt @@ -14,6 +14,7 @@ import android.os.Bundle import android.provider.Settings import android.view.View import android.widget.CheckBox +import androidx.activity.OnBackPressedCallback import androidx.appcompat.app.AlertDialog import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager @@ -166,6 +167,8 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C private var _binding: ActivityUploadBinding? = null private val binding: ActivityUploadBinding get() = _binding!! + private lateinit var onBackPressedCallback: OnBackPressedCallback + @SuppressLint("CheckResult") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -173,6 +176,23 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C _binding = ActivityUploadBinding.inflate(layoutInflater) setContentView(binding.root) + // Overrides the back button to make sure the user is prepared to lose their progress + onBackPressedCallback = object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + showAlertDialog( + this@UploadActivity, + getString(R.string.back_button_warning), + getString(R.string.back_button_warning_desc), + getString(R.string.back_button_continue), + getString(R.string.back_button_warning), + null + ) { + finish() + } + } + } + onBackPressedDispatcher.addCallback(this, onBackPressedCallback) + /* If Configuration of device is changed then get the new fragments created by the system and populate the fragments ArrayList @@ -850,21 +870,7 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C if (uploadCategoriesFragment != null) { uploadCategoriesFragment!!.callback = null } - } - - /** - * Overrides the back button to make sure the user is prepared to lose their progress - */ - @SuppressLint("MissingSuperCall") - override fun onBackPressed() { - showAlertDialog( - this, - getString(R.string.back_button_warning), - getString(R.string.back_button_warning_desc), - getString(R.string.back_button_continue), - getString(R.string.back_button_warning), - null - ) { finish() } + onBackPressedCallback.remove() } /** From a6c9334e3ec3e8125c62c3029297c4818d4c4c9a Mon Sep 17 00:00:00 2001 From: Rohit Verma Date: Tue, 14 Jan 2025 10:51:31 +0530 Subject: [PATCH 4/9] test: remove unit test as no longer needed --- .../nrw/commons/upload/UploadActivityUnitTests.kt | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/app/src/test/kotlin/fr/free/nrw/commons/upload/UploadActivityUnitTests.kt b/app/src/test/kotlin/fr/free/nrw/commons/upload/UploadActivityUnitTests.kt index 1173d09b0..97fe68862 100644 --- a/app/src/test/kotlin/fr/free/nrw/commons/upload/UploadActivityUnitTests.kt +++ b/app/src/test/kotlin/fr/free/nrw/commons/upload/UploadActivityUnitTests.kt @@ -262,15 +262,4 @@ class UploadActivityUnitTests { method.isAccessible = true method.invoke(activity) } - - @Test - @Throws(Exception::class) - fun testOnBackPressed() { - val method: Method = - UploadActivity::class.java.getDeclaredMethod( - "onBackPressed", - ) - method.isAccessible = true - method.invoke(activity) - } } From b5bee2628f6ccd0d994b2a5d105ab8dfd4c34b25 Mon Sep 17 00:00:00 2001 From: Rohit Verma Date: Sat, 18 Jan 2025 22:21:38 +0530 Subject: [PATCH 5/9] replace notifyItemDeleted with notifyDatasetChanged --- app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt b/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt index aeac598f9..71ffb74d8 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt @@ -821,7 +821,7 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C override fun onThumbnailDeleted(position: Int) { presenter!!.deletePictureAtIndex(position) - thumbnailsAdapter?.notifyItemRemoved(position) + thumbnailsAdapter?.notifyDataSetChanged() } /** From 566a3c6ee348ca5d21c1c05885699133efe0207d Mon Sep 17 00:00:00 2001 From: Rohit Verma Date: Tue, 25 Feb 2025 19:43:10 +0530 Subject: [PATCH 6/9] refactor: resolve compilation issue by using correct property name --- .../upload/mediaDetails/UploadMediaPresenter.kt | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.kt b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.kt index 1213ffdb1..77999cf2f 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.kt @@ -339,8 +339,10 @@ class UploadMediaPresenter @Inject constructor( */ override fun checkImageQuality(uploadItem: UploadItem, index: Int) { if ((uploadItem.imageQuality != IMAGE_OK) && (uploadItem.imageQuality != IMAGE_KEEP)) { - val value = basicKvStoreFactory(UploadActivity.STORE_NAME_FOR_CURRENT_UPLOAD_IMAGE_SIZE) - .getString(UPLOAD_QUALITIES_KEY, null) + + val value = basicKvStoreFactory?.let { it(UploadActivity.STORE_NAME_FOR_CURRENT_UPLOAD_IMAGE_SIZE) } + ?.getString(UPLOAD_QUALITIES_KEY, null) + try { val imageQuality = value.asJsonObject()["UploadItem$index"] as Int view.showProgress(false) @@ -363,8 +365,9 @@ class UploadMediaPresenter @Inject constructor( * @param index Index of the UploadItem which was deleted */ override fun updateImageQualitiesJSON(size: Int, index: Int) { - val value = basicKvStoreFactory(UploadActivity.STORE_NAME_FOR_CURRENT_UPLOAD_IMAGE_SIZE) - .getString(UPLOAD_QUALITIES_KEY, null) + val value = basicKvStoreFactory?.let { it(UploadActivity.STORE_NAME_FOR_CURRENT_UPLOAD_IMAGE_SIZE) } + ?.getString(UPLOAD_QUALITIES_KEY, null) + try { val jsonObject = value.asJsonObject().apply { for (i in index until (size - 1)) { @@ -372,8 +375,9 @@ class UploadMediaPresenter @Inject constructor( } remove("UploadItem" + (size - 1)) } - basicKvStoreFactory(UploadActivity.STORE_NAME_FOR_CURRENT_UPLOAD_IMAGE_SIZE) - .putString(UPLOAD_QUALITIES_KEY, jsonObject.toString()) + + basicKvStoreFactory?.let { it(UploadActivity.STORE_NAME_FOR_CURRENT_UPLOAD_IMAGE_SIZE) } + ?.putString(UPLOAD_QUALITIES_KEY, jsonObject.toString()) } catch (e: Exception) { Timber.e(e) } From e15d8b156d162ded6723e79e8c2177a2202b335a Mon Sep 17 00:00:00 2001 From: Rohit Verma Date: Sun, 9 Mar 2025 22:08:45 +0530 Subject: [PATCH 7/9] fix: remove if-condition to prevent hiding top card and refactor code --- .../nrw/commons/upload/UploadPresenter.kt | 47 +++++++++---------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadPresenter.kt b/app/src/main/java/fr/free/nrw/commons/upload/UploadPresenter.kt index 9ee8fb483..5d721f408 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/UploadPresenter.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadPresenter.kt @@ -146,34 +146,31 @@ class UploadPresenter @Inject internal constructor( override fun deletePictureAtIndex(index: Int) { val uploadableFiles = view.getUploadableFiles() - if (index == uploadableFiles!!.size - 1) { - // If the next fragment to be shown is not one of the MediaDetailsFragment - // lets hide the top card so that it doesn't appear on the other fragments - view.showHideTopCard(false) - } - view.setImageCancelled(true) - repository.deletePicture(uploadableFiles[index].getFilePath()) - if (uploadableFiles.size == 1) { - view.showMessage(R.string.upload_cancelled) - view.finish() - return - } - - presenter.updateImageQualitiesJSON(uploadableFiles.size, index) - view.onUploadMediaDeleted(index) - if (index != uploadableFiles.size && index != 0) { - // if the deleted image was not the last item to be uploaded, check quality of next - repository.getUploadItem(index)?.let { - presenter.checkImageQuality(it, index) + uploadableFiles?.let { + view.setImageCancelled(true) + repository.deletePicture(uploadableFiles[index].getFilePath()) + if (uploadableFiles.size == 1) { + view.showMessage(R.string.upload_cancelled) + view.finish() + return } - } - if (uploadableFiles.size < 2) { - view.showHideTopCard(false) - } + presenter.updateImageQualitiesJSON(uploadableFiles.size, index) + view.onUploadMediaDeleted(index) + if (index != uploadableFiles.size && index != 0) { + // if the deleted image was not the last item to be uploaded, check quality of next + repository.getUploadItem(index)?.let { + presenter.checkImageQuality(it, index) + } + } - //In case lets update the number of uploadable media - view.updateTopCardTitle() + if (uploadableFiles.size < 2) { + view.showHideTopCard(false) + } + + //In case lets update the number of uploadable media + view.updateTopCardTitle() + } } override fun onAttachView(view: UploadContract.View) { From 900297829207bb56a6ec06469d0bdf3133e08ce1 Mon Sep 17 00:00:00 2001 From: Rohit Verma Date: Wed, 2 Apr 2025 16:31:02 +0530 Subject: [PATCH 8/9] fix: hide the thumbnail card on fragments other than MediaDetailFragment --- .../main/java/fr/free/nrw/commons/upload/UploadActivity.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt b/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt index 71ffb74d8..8b7e41370 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt @@ -387,6 +387,11 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C override fun onUploadMediaDeleted(index: Int) { fragments!!.removeAt(index) //Remove the corresponding fragment uploadableFiles.removeAt(index) //Remove the files from the list + + if(fragments!![currentSelectedPosition] !is UploadMediaDetailFragment) { + // Should hide the top card current fragment is not the media detail fragment + showHideTopCard(false) + } thumbnailsAdapter!!.notifyItemRemoved(index) //Notify the thumbnails adapter uploadImagesAdapter!!.notifyDataSetChanged() //Notify the ViewPager } From 3842ba952fdff7e20dbfa42bb4dd2805f96ec857 Mon Sep 17 00:00:00 2001 From: Rohit Verma Date: Wed, 2 Apr 2025 17:07:46 +0530 Subject: [PATCH 9/9] refactor: avoid checking fragment is currentSelectedPosition is out of bounds --- .../main/java/fr/free/nrw/commons/upload/UploadActivity.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt b/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt index 8b7e41370..ee0b21210 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.kt @@ -388,7 +388,10 @@ class UploadActivity : BaseActivity(), UploadContract.View, UploadBaseFragment.C fragments!!.removeAt(index) //Remove the corresponding fragment uploadableFiles.removeAt(index) //Remove the files from the list - if(fragments!![currentSelectedPosition] !is UploadMediaDetailFragment) { + val isMediaDetailFragment = fragments!!.getOrNull(currentSelectedPosition)?.let { + it is UploadMediaDetailFragment + } ?: false + if(!isMediaDetailFragment) { // Should hide the top card current fragment is not the media detail fragment showHideTopCard(false) }