diff --git a/app/src/main/java/fr/free/nrw/commons/customselector/ui/adapter/ImageAdapter.kt b/app/src/main/java/fr/free/nrw/commons/customselector/ui/adapter/ImageAdapter.kt index 74b937f97..ff623d496 100644 --- a/app/src/main/java/fr/free/nrw/commons/customselector/ui/adapter/ImageAdapter.kt +++ b/app/src/main/java/fr/free/nrw/commons/customselector/ui/adapter/ImageAdapter.kt @@ -24,6 +24,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.MainScope import kotlinx.coroutines.cancel +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.launch import java.util.TreeMap import kotlin.collections.ArrayList @@ -103,6 +104,18 @@ class ImageAdapter( */ private var imagePositionAsPerIncreasingOrder = 0 + /** + * Stores the number of images currently visible on the screen + */ + private val _currentImagesCount = MutableStateFlow(0) + val currentImagesCount = _currentImagesCount + + /** + * Stores whether images are being loaded or not + */ + private val _isLoadingImages = MutableStateFlow(false) + val isLoadingImages = _isLoadingImages + /** * Coroutine Dispatchers and Scope. */ @@ -184,8 +197,12 @@ class ImageAdapter( // If the position is not already visited, that means the position is new then // finds the next actionable image position from all images if (!alreadyAddedPositions.contains(position)) { - processThumbnailForActionedImage(holder, position, uploadingContributionList) - + processThumbnailForActionedImage( + holder, + position, + uploadingContributionList + ) + _isLoadingImages.value = false // If the position is already visited, that means the image is already present // inside map, so it will fetch the image from the map and load in the holder } else { @@ -231,6 +248,7 @@ class ImageAdapter( position: Int, uploadingContributionList: List, ) { + _isLoadingImages.value = true val next = imageLoader.nextActionableImage( allImages, @@ -252,6 +270,7 @@ class ImageAdapter( actionableImagesMap[next] = allImages[next] alreadyAddedPositions.add(imagePositionAsPerIncreasingOrder) imagePositionAsPerIncreasingOrder++ + _currentImagesCount.value = imagePositionAsPerIncreasingOrder Glide .with(holder.image) .load(allImages[next].uri) @@ -267,6 +286,7 @@ class ImageAdapter( reachedEndOfFolder = true notifyItemRemoved(position) } + _isLoadingImages.value = false } /** @@ -372,6 +392,7 @@ class ImageAdapter( emptyMap: TreeMap, uploadedImages: List = ArrayList(), ) { + _isLoadingImages.value = true allImages = fixedImages val oldImageList: ArrayList = images val newImageList: ArrayList = ArrayList(newImages) @@ -382,6 +403,7 @@ class ImageAdapter( reachedEndOfFolder = false selectedImages = ArrayList() imagePositionAsPerIncreasingOrder = 0 + _currentImagesCount.value = imagePositionAsPerIncreasingOrder val diffResult = DiffUtil.calculateDiff( ImagesDiffCallback(oldImageList, newImageList), @@ -441,6 +463,7 @@ class ImageAdapter( val entry = iterator.next() if (entry.value == image) { imagePositionAsPerIncreasingOrder -= 1 + _currentImagesCount.value = imagePositionAsPerIncreasingOrder iterator.remove() alreadyAddedPositions.removeAt(alreadyAddedPositions.size - 1) notifyItemRemoved(index) diff --git a/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/ImageFragment.kt b/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/ImageFragment.kt index 3912a4d12..39d0d545a 100644 --- a/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/ImageFragment.kt +++ b/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/ImageFragment.kt @@ -12,8 +12,12 @@ import android.widget.ProgressBar import android.widget.Switch import androidx.appcompat.app.AlertDialog import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.view.isVisible +import androidx.lifecycle.Lifecycle import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView import fr.free.nrw.commons.contributions.Contribution @@ -38,6 +42,10 @@ import fr.free.nrw.commons.theme.BaseActivity import fr.free.nrw.commons.upload.FileProcessor import fr.free.nrw.commons.upload.FileUtilsWrapper import io.reactivex.schedulers.Schedulers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.launch import java.util.TreeMap import javax.inject.Inject import kotlin.collections.ArrayList @@ -80,6 +88,12 @@ class ImageFragment : */ var allImages: ArrayList = ArrayList() + /** + * Keeps track of switch state + */ + private val _switchState = MutableStateFlow(false) + val switchState = _switchState.asStateFlow() + /** * View model Factory. */ @@ -214,7 +228,11 @@ class ImageFragment : switch = binding?.switchWidget switch?.visibility = View.VISIBLE - switch?.setOnCheckedChangeListener { _, isChecked -> onChangeSwitchState(isChecked) } + _switchState.value = switch?.isChecked ?: false + switch?.setOnCheckedChangeListener { _, isChecked -> + onChangeSwitchState(isChecked) + _switchState.value = isChecked + } selectorRV = binding?.selectorRv loader = binding?.loader progressLayout = binding?.progressLayout @@ -234,6 +252,28 @@ class ImageFragment : return binding?.root } + /** + * onViewCreated + * Updates empty text view visibility based on image count, switch state, and loading status. + */ + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + viewLifecycleOwner.lifecycleScope.launch { + repeatOnLifecycle(Lifecycle.State.STARTED) { + combine( + imageAdapter.currentImagesCount, + switchState, + imageAdapter.isLoadingImages + ) { imageCount, isChecked, isLoadingImages -> + Triple(imageCount, isChecked, isLoadingImages) + }.collect { (imageCount, isChecked, isLoadingImages) -> + binding?.allImagesUploadedOrMarked?.isVisible = + !isLoadingImages && !isChecked && imageCount == 0 && (switch?.isVisible == true) + } + } + } + } + private fun onChangeSwitchState(checked: Boolean) { if (checked) { showAlreadyActionedImages = true diff --git a/app/src/main/res/layout/fragment_custom_selector.xml b/app/src/main/res/layout/fragment_custom_selector.xml index bbc4c0a07..03381fd24 100644 --- a/app/src/main/res/layout/fragment_custom_selector.xml +++ b/app/src/main/res/layout/fragment_custom_selector.xml @@ -49,6 +49,20 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> + last resort and should only be used when you wish to stop editing forever and also to hide as many of your past associations as possible.

Account deletion on Wikimedia Commons is done by changing your account name to make it so others cannot recognize your contributions in a process called account vanishing. Vanishing does not guarantee complete anonymity or remove contributions to the projects.]]>
Caption Caption copied to clipboard + Congratulations, all pictures in this album have been either uploaded or marked as not for upload.