mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-27 04:43:54 +01:00
[GSoC] Saved Image Fragment Scroll State (#4528)
* Saved Image Fragment Scroll State * Fix delete image * Fixed Delete bug * Changed custom selector icon
This commit is contained in:
parent
e8f7d0f03b
commit
d78e6deb4e
11 changed files with 186 additions and 83 deletions
|
|
@ -1,19 +1,7 @@
|
||||||
package fr.free.nrw.commons.customselector.helper
|
package fr.free.nrw.commons.customselector.helper
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import com.mapbox.android.core.FileUtils
|
|
||||||
import fr.free.nrw.commons.customselector.model.Folder
|
import fr.free.nrw.commons.customselector.model.Folder
|
||||||
import fr.free.nrw.commons.customselector.model.Image
|
import fr.free.nrw.commons.customselector.model.Image
|
||||||
import fr.free.nrw.commons.filepicker.Constants
|
|
||||||
import timber.log.Timber
|
|
||||||
import java.io.*
|
|
||||||
import java.math.BigInteger
|
|
||||||
import java.security.MessageDigest
|
|
||||||
import java.security.NoSuchAlgorithmException
|
|
||||||
import kotlin.collections.ArrayList
|
|
||||||
import kotlin.collections.HashMap
|
|
||||||
import kotlin.collections.LinkedHashMap
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Image Helper object, includes all the static functions required by custom selector.
|
* Image Helper object, includes all the static functions required by custom selector.
|
||||||
|
|
@ -24,7 +12,7 @@ object ImageHelper {
|
||||||
/**
|
/**
|
||||||
* Returns the list of folders from given image list.
|
* Returns the list of folders from given image list.
|
||||||
*/
|
*/
|
||||||
fun folderListFromImages(images: List<Image>): List<Folder> {
|
fun folderListFromImages(images: List<Image>): ArrayList<Folder> {
|
||||||
val folderMap: MutableMap<Long, Folder> = LinkedHashMap()
|
val folderMap: MutableMap<Long, Folder> = LinkedHashMap()
|
||||||
for (image in images) {
|
for (image in images) {
|
||||||
val bucketId = image.bucketId
|
val bucketId = image.bucketId
|
||||||
|
|
@ -61,6 +49,17 @@ object ImageHelper {
|
||||||
return list.indexOf(image)
|
return list.indexOf(image)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getIndex: Returns the index of image in given list.
|
||||||
|
*/
|
||||||
|
fun getIndexFromId(list: ArrayList<Image>, imageId: Long): Int {
|
||||||
|
for(i in list){
|
||||||
|
if(i.id == imageId)
|
||||||
|
return list.indexOf(i)
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the list of indices from the master list.
|
* Gets the list of indices from the master list.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
package fr.free.nrw.commons.customselector.listeners
|
package fr.free.nrw.commons.customselector.listeners
|
||||||
|
|
||||||
interface FolderClickListener {
|
interface FolderClickListener {
|
||||||
fun onFolderClick(folderId: Long, folderName: String)
|
fun onFolderClick(folderId: Long, folderName: String, lastItemId: Long)
|
||||||
}
|
}
|
||||||
|
|
@ -11,6 +11,7 @@ import com.bumptech.glide.Glide
|
||||||
import fr.free.nrw.commons.R
|
import fr.free.nrw.commons.R
|
||||||
import fr.free.nrw.commons.customselector.listeners.FolderClickListener
|
import fr.free.nrw.commons.customselector.listeners.FolderClickListener
|
||||||
import fr.free.nrw.commons.customselector.model.Folder
|
import fr.free.nrw.commons.customselector.model.Folder
|
||||||
|
import fr.free.nrw.commons.customselector.model.Image
|
||||||
|
|
||||||
class FolderAdapter(
|
class FolderAdapter(
|
||||||
/**
|
/**
|
||||||
|
|
@ -43,16 +44,38 @@ class FolderAdapter(
|
||||||
*/
|
*/
|
||||||
override fun onBindViewHolder(holder: FolderViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: FolderViewHolder, position: Int) {
|
||||||
val folder = folders[position]
|
val folder = folders[position]
|
||||||
|
val toBeRemoved = ArrayList<Image>()
|
||||||
|
|
||||||
|
for(image in folder.images) {
|
||||||
|
// Remove all the top images that do not exist anymore
|
||||||
|
if(context.contentResolver.getType(image.uri) == null){
|
||||||
|
// File not found
|
||||||
|
toBeRemoved.add(image)
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
holder.image.setImageDrawable (null)
|
||||||
|
folder.images.removeAll(toBeRemoved)
|
||||||
val count = folder.images.size
|
val count = folder.images.size
|
||||||
|
|
||||||
|
if(count == 0) {
|
||||||
|
// Folder is empty, remove folder from the adapter.
|
||||||
|
holder.itemView.post{
|
||||||
|
val updatePosition = folders.indexOf(folder)
|
||||||
|
folders.removeAt(updatePosition)
|
||||||
|
notifyItemRemoved(updatePosition)
|
||||||
|
notifyItemRangeChanged(updatePosition, folders.size)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
val previewImage = folder.images[0]
|
val previewImage = folder.images[0]
|
||||||
Glide.with(context).load(previewImage.uri).into(holder.image)
|
Glide.with(context).load(previewImage.uri).into(holder.image)
|
||||||
holder.name.text = folder.name
|
holder.name.text = folder.name
|
||||||
holder.count.text = count.toString()
|
holder.count.text = count.toString()
|
||||||
holder.itemView.setOnClickListener {
|
holder.itemView.setOnClickListener {
|
||||||
itemClickListener.onFolderClick(folder.bucketId, folder.name)
|
itemClickListener.onFolderClick(folder.bucketId, folder.name, 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo load image thumbnail.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
package fr.free.nrw.commons.customselector.ui.adapter
|
package fr.free.nrw.commons.customselector.ui.adapter
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.ViewGroup
|
|
||||||
import fr.free.nrw.commons.R
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
|
@ -11,6 +10,7 @@ import androidx.constraintlayout.widget.Group
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
|
import fr.free.nrw.commons.R
|
||||||
import fr.free.nrw.commons.customselector.helper.ImageHelper
|
import fr.free.nrw.commons.customselector.helper.ImageHelper
|
||||||
import fr.free.nrw.commons.customselector.listeners.ImageSelectListener
|
import fr.free.nrw.commons.customselector.listeners.ImageSelectListener
|
||||||
import fr.free.nrw.commons.customselector.model.Image
|
import fr.free.nrw.commons.customselector.model.Image
|
||||||
|
|
@ -68,12 +68,21 @@ class ImageAdapter(
|
||||||
*/
|
*/
|
||||||
override fun onBindViewHolder(holder: ImageViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ImageViewHolder, position: Int) {
|
||||||
val image=images[position]
|
val image=images[position]
|
||||||
|
holder.image.setImageDrawable (null)
|
||||||
|
if (context.contentResolver.getType(image.uri) == null) {
|
||||||
|
// Image does not exist anymore, update adapter.
|
||||||
|
holder.itemView.post {
|
||||||
|
val updatedPosition = images.indexOf(image)
|
||||||
|
images.remove(image)
|
||||||
|
notifyItemRemoved(updatedPosition)
|
||||||
|
notifyItemRangeChanged(updatedPosition, images.size)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
val selectedIndex = ImageHelper.getIndex(selectedImages, image)
|
val selectedIndex = ImageHelper.getIndex(selectedImages, image)
|
||||||
val isSelected = selectedIndex != -1
|
val isSelected = selectedIndex != -1
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
holder.itemSelected(selectedIndex + 1)
|
holder.itemSelected(selectedIndex + 1)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
holder.itemUnselected();
|
holder.itemUnselected();
|
||||||
}
|
}
|
||||||
Glide.with(context).load(image.uri).thumbnail(0.3f).into(holder.image)
|
Glide.with(context).load(image.uri).thumbnail(0.3f).into(holder.image)
|
||||||
|
|
@ -82,6 +91,7 @@ class ImageAdapter(
|
||||||
selectOrRemoveImage(holder, position)
|
selectOrRemoveImage(holder, position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle click event on an image, update counter on images.
|
* Handle click event on an image, update counter on images.
|
||||||
|
|
@ -128,6 +138,10 @@ class ImageAdapter(
|
||||||
return images.size
|
return images.size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getImageIdAt(position: Int): Long {
|
||||||
|
return images.get(position).id
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Image view holder.
|
* Image view holder.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.ImageButton
|
import android.widget.ImageButton
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.fragment.app.FragmentManager
|
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import fr.free.nrw.commons.R
|
import fr.free.nrw.commons.R
|
||||||
import fr.free.nrw.commons.customselector.listeners.FolderClickListener
|
import fr.free.nrw.commons.customselector.listeners.FolderClickListener
|
||||||
|
|
@ -17,7 +16,7 @@ import fr.free.nrw.commons.theme.BaseActivity
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class CustomSelectorActivity: BaseActivity(), FolderClickListener, ImageSelectListener, FragmentManager.OnBackStackChangedListener {
|
class CustomSelectorActivity: BaseActivity(), FolderClickListener, ImageSelectListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View model.
|
* View model.
|
||||||
|
|
@ -58,10 +57,11 @@ class CustomSelectorActivity: BaseActivity(), FolderClickListener, ImageSelectLi
|
||||||
setupViews()
|
setupViews()
|
||||||
|
|
||||||
// Open folder if saved in prefs.
|
// Open folder if saved in prefs.
|
||||||
if(prefs.contains("FolderId")){
|
if(prefs.contains(FOLDER_ID)){
|
||||||
val lastOpenFolderId: Long = prefs.getLong("FolderId", 0L)
|
val lastOpenFolderId: Long = prefs.getLong(FOLDER_ID, 0L)
|
||||||
val lastOpenFolderName: String? = prefs.getString("FolderName", null)
|
val lastOpenFolderName: String? = prefs.getString(FOLDER_NAME, null)
|
||||||
lastOpenFolderName?.let { onFolderClick(lastOpenFolderId, it) }
|
val lastItemId: Long = prefs.getLong(ITEM_ID, 0)
|
||||||
|
lastOpenFolderName?.let { onFolderClick(lastOpenFolderId, it, lastItemId) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,9 +107,9 @@ class CustomSelectorActivity: BaseActivity(), FolderClickListener, ImageSelectLi
|
||||||
/**
|
/**
|
||||||
* override on folder click, change the toolbar title on folder click.
|
* override on folder click, change the toolbar title on folder click.
|
||||||
*/
|
*/
|
||||||
override fun onFolderClick(folderId: Long, folderName: String) {
|
override fun onFolderClick(folderId: Long, folderName: String, lastItemId: Long) {
|
||||||
supportFragmentManager.beginTransaction()
|
supportFragmentManager.beginTransaction()
|
||||||
.add(R.id.fragment_container, ImageFragment.newInstance(folderId))
|
.add(R.id.fragment_container, ImageFragment.newInstance(folderId, lastItemId))
|
||||||
.addToBackStack(null)
|
.addToBackStack(null)
|
||||||
.commit()
|
.commit()
|
||||||
|
|
||||||
|
|
@ -172,25 +172,27 @@ class CustomSelectorActivity: BaseActivity(), FolderClickListener, ImageSelectLi
|
||||||
super.onBackPressed()
|
super.onBackPressed()
|
||||||
val fragment = supportFragmentManager.findFragmentById(R.id.fragment_container)
|
val fragment = supportFragmentManager.findFragmentById(R.id.fragment_container)
|
||||||
if(fragment != null && fragment is FolderFragment){
|
if(fragment != null && fragment is FolderFragment){
|
||||||
|
isImageFragmentOpen = false
|
||||||
changeTitle(getString(R.string.custom_selector_title))
|
changeTitle(getString(R.string.custom_selector_title))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On activity destroy
|
||||||
|
* If image fragment is open, overwrite its attributes otherwise discard the values.
|
||||||
|
*/
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
if(isImageFragmentOpen){
|
if(isImageFragmentOpen){
|
||||||
prefs.edit().putLong("FolderId", bucketId).putString("FolderName", bucketName).apply()
|
prefs.edit().putLong(FOLDER_ID, bucketId).putString(FOLDER_NAME, bucketName).apply()
|
||||||
} else {
|
} else {
|
||||||
prefs.edit().remove("FolderId").remove("FolderName").apply()
|
prefs.edit().remove(FOLDER_ID).remove(FOLDER_NAME).apply()
|
||||||
}
|
}
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
companion object {
|
||||||
* Called whenever the contents of the back stack change.
|
const val FOLDER_ID : String = "FolderId"
|
||||||
*/
|
const val FOLDER_NAME : String = "FolderName"
|
||||||
override fun onBackStackChanged() {
|
const val ITEM_ID : String = "ItemId"
|
||||||
if(supportFragmentManager.backStackEntryCount == 0) {
|
|
||||||
isImageFragmentOpen = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -14,6 +14,7 @@ import fr.free.nrw.commons.customselector.helper.ImageHelper
|
||||||
import fr.free.nrw.commons.customselector.model.Result
|
import fr.free.nrw.commons.customselector.model.Result
|
||||||
import fr.free.nrw.commons.customselector.listeners.FolderClickListener
|
import fr.free.nrw.commons.customselector.listeners.FolderClickListener
|
||||||
import fr.free.nrw.commons.customselector.model.CallbackStatus
|
import fr.free.nrw.commons.customselector.model.CallbackStatus
|
||||||
|
import fr.free.nrw.commons.customselector.model.Folder
|
||||||
import fr.free.nrw.commons.customselector.ui.adapter.FolderAdapter
|
import fr.free.nrw.commons.customselector.ui.adapter.FolderAdapter
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment
|
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment
|
||||||
import fr.free.nrw.commons.media.MediaClient
|
import fr.free.nrw.commons.media.MediaClient
|
||||||
|
|
@ -55,6 +56,11 @@ class FolderFragment : CommonsDaggerSupportFragment() {
|
||||||
*/
|
*/
|
||||||
private lateinit var gridLayoutManager: GridLayoutManager
|
private lateinit var gridLayoutManager: GridLayoutManager
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Folder List.
|
||||||
|
*/
|
||||||
|
private lateinit var folders : ArrayList<Folder>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Companion newInstance.
|
* Companion newInstance.
|
||||||
*/
|
*/
|
||||||
|
|
@ -102,7 +108,7 @@ class FolderFragment : CommonsDaggerSupportFragment() {
|
||||||
*/
|
*/
|
||||||
private fun handleResult(result: Result) {
|
private fun handleResult(result: Result) {
|
||||||
if(result.status is CallbackStatus.SUCCESS){
|
if(result.status is CallbackStatus.SUCCESS){
|
||||||
val folders = ImageHelper.folderListFromImages(result.images)
|
folders = ImageHelper.folderListFromImages(result.images)
|
||||||
folderAdapter.init(folders)
|
folderAdapter.init(folders)
|
||||||
folderAdapter.notifyDataSetChanged()
|
folderAdapter.notifyDataSetChanged()
|
||||||
selectorRV?.let {
|
selectorRV?.let {
|
||||||
|
|
@ -114,6 +120,11 @@ class FolderFragment : CommonsDaggerSupportFragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
folderAdapter.notifyDataSetChanged()
|
||||||
|
super.onResume()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return Column count ie span count for grid view adapter.
|
* Return Column count ie span count for grid view adapter.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package fr.free.nrw.commons.customselector.ui.selector
|
package fr.free.nrw.commons.customselector.ui.selector
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
|
@ -13,11 +15,15 @@ import fr.free.nrw.commons.R
|
||||||
import fr.free.nrw.commons.customselector.helper.ImageHelper
|
import fr.free.nrw.commons.customselector.helper.ImageHelper
|
||||||
import fr.free.nrw.commons.customselector.listeners.ImageSelectListener
|
import fr.free.nrw.commons.customselector.listeners.ImageSelectListener
|
||||||
import fr.free.nrw.commons.customselector.model.CallbackStatus
|
import fr.free.nrw.commons.customselector.model.CallbackStatus
|
||||||
|
import fr.free.nrw.commons.customselector.model.Image
|
||||||
import fr.free.nrw.commons.customselector.model.Result
|
import fr.free.nrw.commons.customselector.model.Result
|
||||||
import fr.free.nrw.commons.customselector.ui.adapter.ImageAdapter
|
import fr.free.nrw.commons.customselector.ui.adapter.ImageAdapter
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment
|
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment
|
||||||
import kotlinx.android.synthetic.main.fragment_custom_selector.*
|
import fr.free.nrw.commons.theme.BaseActivity
|
||||||
import kotlinx.android.synthetic.main.fragment_custom_selector.view.*
|
import kotlinx.android.synthetic.main.fragment_custom_selector.view.*
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileInputStream
|
||||||
|
import java.net.URI
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ImageFragment: CommonsDaggerSupportFragment() {
|
class ImageFragment: CommonsDaggerSupportFragment() {
|
||||||
|
|
@ -27,13 +33,18 @@ class ImageFragment: CommonsDaggerSupportFragment() {
|
||||||
*/
|
*/
|
||||||
private var bucketId: Long? = null
|
private var bucketId: Long? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Last ImageItem Id.
|
||||||
|
*/
|
||||||
|
private var lastItemId: Long? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View model for images.
|
* View model for images.
|
||||||
*/
|
*/
|
||||||
private var viewModel: CustomSelectorViewModel? = null
|
private var viewModel: CustomSelectorViewModel? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View Elements
|
* View Elements.
|
||||||
*/
|
*/
|
||||||
private var selectorRV: RecyclerView? = null
|
private var selectorRV: RecyclerView? = null
|
||||||
private var loader: ProgressBar? = null
|
private var loader: ProgressBar? = null
|
||||||
|
|
@ -67,14 +78,16 @@ class ImageFragment: CommonsDaggerSupportFragment() {
|
||||||
* BucketId args name
|
* BucketId args name
|
||||||
*/
|
*/
|
||||||
const val BUCKET_ID = "BucketId"
|
const val BUCKET_ID = "BucketId"
|
||||||
|
const val LAST_ITEM_ID = "LastItemId"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* newInstance from bucketId.
|
* newInstance from bucketId.
|
||||||
*/
|
*/
|
||||||
fun newInstance(bucketId: Long): ImageFragment {
|
fun newInstance(bucketId: Long, lastItemId: Long): ImageFragment {
|
||||||
val fragment = ImageFragment()
|
val fragment = ImageFragment()
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
args.putLong(BUCKET_ID, bucketId)
|
args.putLong(BUCKET_ID, bucketId)
|
||||||
|
args.putLong(LAST_ITEM_ID, lastItemId)
|
||||||
fragment.arguments = args
|
fragment.arguments = args
|
||||||
return fragment
|
return fragment
|
||||||
}
|
}
|
||||||
|
|
@ -87,6 +100,7 @@ class ImageFragment: CommonsDaggerSupportFragment() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
bucketId = arguments?.getLong(BUCKET_ID)
|
bucketId = arguments?.getLong(BUCKET_ID)
|
||||||
|
lastItemId = arguments?.getLong(LAST_ITEM_ID, 0)
|
||||||
viewModel = ViewModelProvider(requireActivity(),customSelectorViewModelFactory).get(CustomSelectorViewModel::class.java)
|
viewModel = ViewModelProvider(requireActivity(),customSelectorViewModelFactory).get(CustomSelectorViewModel::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,6 +130,8 @@ class ImageFragment: CommonsDaggerSupportFragment() {
|
||||||
return root
|
return root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lateinit var filteredImages: ArrayList<Image>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle view model result.
|
* Handle view model result.
|
||||||
*/
|
*/
|
||||||
|
|
@ -123,9 +139,14 @@ class ImageFragment: CommonsDaggerSupportFragment() {
|
||||||
if(result.status is CallbackStatus.SUCCESS){
|
if(result.status is CallbackStatus.SUCCESS){
|
||||||
val images = result.images
|
val images = result.images
|
||||||
if(images.isNotEmpty()) {
|
if(images.isNotEmpty()) {
|
||||||
imageAdapter.init(ImageHelper.filterImages(images,bucketId))
|
filteredImages = ImageHelper.filterImages(images, bucketId)
|
||||||
|
imageAdapter.init(filteredImages)
|
||||||
selectorRV?.let {
|
selectorRV?.let {
|
||||||
it.visibility = View.VISIBLE
|
it.visibility = View.VISIBLE
|
||||||
|
lastItemId?.let { pos ->
|
||||||
|
(it.layoutManager as GridLayoutManager)
|
||||||
|
.scrollToPosition(ImageHelper.getIndexFromId(filteredImages, pos))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
|
@ -149,11 +170,35 @@ class ImageFragment: CommonsDaggerSupportFragment() {
|
||||||
// todo change span count depending on the device orientation and other factos.
|
// todo change span count depending on the device orientation and other factos.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
imageAdapter.notifyDataSetChanged()
|
||||||
|
super.onResume()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OnDestroy Cleanup the imageLoader coroutine.
|
* OnDestroy
|
||||||
|
* Cleanup the imageLoader coroutine.
|
||||||
|
* Save the Image Fragment state.
|
||||||
*/
|
*/
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
imageLoader?.cleanUP()
|
imageLoader?.cleanUP()
|
||||||
|
|
||||||
|
val position = (selectorRV?.layoutManager as GridLayoutManager)
|
||||||
|
.findFirstVisibleItemPosition()
|
||||||
|
|
||||||
|
// Check for empty RecyclerView.
|
||||||
|
if (position != -1) {
|
||||||
|
context?.let { context ->
|
||||||
|
context.getSharedPreferences(
|
||||||
|
"CustomSelector",
|
||||||
|
BaseActivity.MODE_PRIVATE
|
||||||
|
)?.let { prefs ->
|
||||||
|
prefs.edit()?.let { editor ->
|
||||||
|
editor.putLong("ItemId", imageAdapter.getImageIdAt(position))?.apply()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -13,6 +13,7 @@ import fr.free.nrw.commons.upload.FileProcessor
|
||||||
import fr.free.nrw.commons.upload.FileUtilsWrapper
|
import fr.free.nrw.commons.upload.FileUtilsWrapper
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import java.io.FileNotFoundException
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.net.UnknownHostException
|
import java.net.UnknownHostException
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
@ -86,6 +87,8 @@ class ImageLoader @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
val imageSHA1 = getImageSHA1(image.uri)
|
val imageSHA1 = getImageSHA1(image.uri)
|
||||||
|
if(imageSHA1.isEmpty())
|
||||||
|
return@launch
|
||||||
val uploadedStatus = getFromUploaded(imageSHA1)
|
val uploadedStatus = getFromUploaded(imageSHA1)
|
||||||
|
|
||||||
val sha1 = uploadedStatus?.let {
|
val sha1 = uploadedStatus?.let {
|
||||||
|
|
@ -195,9 +198,14 @@ class ImageLoader @Inject constructor(
|
||||||
mapImageSHA1[uri]?.let{
|
mapImageSHA1[uri]?.let{
|
||||||
return@withContext it
|
return@withContext it
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
val result = fileUtilsWrapper.getSHA1(context.contentResolver.openInputStream(uri))
|
val result = fileUtilsWrapper.getSHA1(context.contentResolver.openInputStream(uri))
|
||||||
mapImageSHA1[uri] = result
|
mapImageSHA1[uri] = result
|
||||||
result
|
result
|
||||||
|
} catch (e: FileNotFoundException){
|
||||||
|
e.printStackTrace()
|
||||||
|
""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
3
app/src/main/res/drawable/ic_custom_image_picker.xml
Normal file
3
app/src/main/res/drawable/ic_custom_image_picker.xml
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -79,7 +79,7 @@
|
||||||
app:useCompatPadding="true"
|
app:useCompatPadding="true"
|
||||||
app:elevation="@dimen/tiny_margin"
|
app:elevation="@dimen/tiny_margin"
|
||||||
app:fabSize="mini"
|
app:fabSize="mini"
|
||||||
app:srcCompat="@drawable/commons_logo"
|
app:srcCompat="@drawable/ic_custom_image_picker"
|
||||||
android:background="@drawable/commons"/>
|
android:background="@drawable/commons"/>
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:background="@color/white"
|
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
|
@ -29,7 +28,6 @@
|
||||||
android:id="@+id/album_overlay"
|
android:id="@+id/album_overlay"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@color/black"
|
|
||||||
android:alpha="0.15" />
|
android:alpha="0.15" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue