Skip to content

Commit

Permalink
Sort media files list at startup, add animation in list fragments
Browse files Browse the repository at this point in the history
  • Loading branch information
VishalNehra committed Dec 12, 2023
1 parent 1218864 commit 53fd356
Show file tree
Hide file tree
Showing 15 changed files with 229 additions and 162 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@

package com.amaze.fileutilities.home_page.ui.files

import android.view.View
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import androidx.navigation.fragment.NavHostFragment
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
Expand All @@ -37,6 +41,8 @@ import com.amaze.fileutilities.utilis.getAppCommonSharedPreferences
import com.bumptech.glide.Glide
import com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader
import com.bumptech.glide.util.ViewPreloadSizeProvider
import org.slf4j.Logger
import org.slf4j.LoggerFactory

abstract class AbstractMediaInfoListFragment :
ItemsActionBarFragment(),
Expand All @@ -46,6 +52,7 @@ abstract class AbstractMediaInfoListFragment :
private var linearLayoutManager: LinearLayoutManager? = null
private var gridLayoutManager: GridLayoutManager? = null
private val MAX_PRELOAD = 100
private var log: Logger = LoggerFactory.getLogger(AbstractMediaInfoListFragment::class.java)

override fun onDestroyView() {
getMediaAdapterPreloader().clear()
Expand Down Expand Up @@ -227,6 +234,25 @@ abstract class AbstractMediaInfoListFragment :
}, {
getRecyclerView().clearOnScrollListeners()
setupAdapter()
}, {
when (getMediaListType()) {
MediaFileAdapter.MEDIA_TYPE_IMAGES -> {
getFilesViewModelObj().usedImagesSummaryTransformations = null
}
MediaFileAdapter.MEDIA_TYPE_DOCS -> {
getFilesViewModelObj().usedDocsSummaryTransformations = null
}
MediaFileAdapter.MEDIA_TYPE_AUDIO -> {
getFilesViewModelObj().usedAudiosSummaryTransformations = null
}
MediaFileAdapter.MEDIA_TYPE_VIDEO -> {
getFilesViewModelObj().usedVideosSummaryTransformations = null
}
else -> {
log.warn("unsupported operation to reset data on banner action")
}
}
reloadFragment()
}
)
getRecyclerView().addOnScrollListener(recyclerViewPreloader)
Expand All @@ -246,7 +272,17 @@ abstract class AbstractMediaInfoListFragment :
val animator = DefaultItemAnimator()
getRecyclerView().itemAnimator = animator
getRecyclerView().adapter = mediaFileAdapter

val slideUpAnimation: Animation =
AnimationUtils.loadAnimation(requireContext(), R.anim.slide_up_fade_in)
getRecyclerView().startAnimation(slideUpAnimation)
getRecyclerView().visibility = View.VISIBLE
}
}
}
private fun reloadFragment() {
val navController = NavHostFragment.findNavController(this)
navController.popBackStack()
navController.navigate(R.id.navigation_files)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ import androidx.core.graphics.drawable.toBitmap
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.liveData
import androidx.lifecycle.switchMap
import androidx.lifecycle.viewModelScope
import com.abedelazizshe.lightcompressorlibrary.CompressionListener
import com.abedelazizshe.lightcompressorlibrary.VideoCompressor
Expand Down Expand Up @@ -158,15 +158,15 @@ class FilesViewModel(val applicationContext: Application) :
private var trashBinConfig: TrashBinConfig? = null
private val TRASH_BIN_BASE_PATH = Environment.getExternalStorageDirectory()
.path + File.separator + ".AmazeData"
private var usedVideosSummaryTransformations: LiveData<Pair<StorageSummary,
var usedVideosSummaryTransformations: LiveData<Pair<StorageSummary,
ArrayList<MediaFileInfo>>?>? = null
private var usedAudiosSummaryTransformations: LiveData<Pair<StorageSummary,
var usedAudiosSummaryTransformations: LiveData<Pair<StorageSummary,
ArrayList<MediaFileInfo>>?>? = null
var usedPlaylistsSummaryTransformations: LiveData<Pair<StorageSummary,
ArrayList<MediaFileInfo>>?>? = null
private var usedImagesSummaryTransformations: LiveData<Pair<StorageSummary,
var usedImagesSummaryTransformations: LiveData<Pair<StorageSummary,
ArrayList<MediaFileInfo>>?>? = null
private var usedDocsSummaryTransformations: LiveData<Pair<StorageSummary,
var usedDocsSummaryTransformations: LiveData<Pair<StorageSummary,
ArrayList<MediaFileInfo>>?>? = null

private var allApps: AtomicReference<List<Pair<ApplicationInfo,
Expand Down Expand Up @@ -305,7 +305,7 @@ class FilesViewModel(val applicationContext: Application) :
fun usedImagesSummaryTransformations():
LiveData<Pair<StorageSummary, ArrayList<MediaFileInfo>>?> {
if (usedImagesSummaryTransformations == null) {
usedImagesSummaryTransformations = Transformations.switchMap(internalStorageStats()) {
usedImagesSummaryTransformations = internalStorageStats().switchMap {
input ->
getImagesSummaryLiveData(input)
}
Expand All @@ -316,7 +316,7 @@ class FilesViewModel(val applicationContext: Application) :
fun usedAudiosSummaryTransformations():
LiveData<Pair<StorageSummary, ArrayList<MediaFileInfo>>?> {
if (usedAudiosSummaryTransformations == null) {
usedAudiosSummaryTransformations = Transformations.switchMap(internalStorageStats()) {
usedAudiosSummaryTransformations = internalStorageStats().switchMap {
input ->
getAudiosSummaryLiveData(input)
}
Expand All @@ -328,7 +328,7 @@ class FilesViewModel(val applicationContext: Application) :
LiveData<Pair<StorageSummary, ArrayList<MediaFileInfo>>?> {
if (usedPlaylistsSummaryTransformations == null) {
usedPlaylistsSummaryTransformations =
Transformations.switchMap(internalStorageStats()) {
internalStorageStats().switchMap {
input ->
getPlaylistsSummaryLiveData(input)
}
Expand All @@ -339,7 +339,7 @@ class FilesViewModel(val applicationContext: Application) :
fun usedVideosSummaryTransformations():
LiveData<Pair<StorageSummary, ArrayList<MediaFileInfo>>?> {
if (usedVideosSummaryTransformations == null) {
usedVideosSummaryTransformations = Transformations.switchMap(internalStorageStats()) {
usedVideosSummaryTransformations = internalStorageStats().switchMap {
input ->
getVideosSummaryLiveData(input)
}
Expand All @@ -350,7 +350,7 @@ class FilesViewModel(val applicationContext: Application) :
fun usedDocsSummaryTransformations():
LiveData<Pair<StorageSummary, ArrayList<MediaFileInfo>>?> {
if (usedDocsSummaryTransformations == null) {
usedDocsSummaryTransformations = Transformations.switchMap(internalStorageStats()) {
usedDocsSummaryTransformations = internalStorageStats().switchMap {
input ->
getDocumentsSummaryLiveData(input)
}
Expand Down Expand Up @@ -2688,6 +2688,15 @@ class FilesViewModel(val applicationContext: Application) :
}
val metaInfoAndSummaryPair = CursorUtils
.listImages(applicationContext.applicationContext)
val sortingPref = MediaFileListSorter.SortingPreference.newInstance(
applicationContext
.getAppCommonSharedPreferences(),
MediaFileAdapter.MEDIA_TYPE_IMAGES
)
MediaFileListSorter.generateMediaFileListHeadersAndSort(
applicationContext,
metaInfoAndSummaryPair.second, sortingPref
)
setMediaInfoSummary(metaInfoAndSummaryPair.first, storageSummary)
emit(metaInfoAndSummaryPair)
}
Expand Down Expand Up @@ -2727,6 +2736,15 @@ class FilesViewModel(val applicationContext: Application) :
it.path
}
)
val sortingPref = MediaFileListSorter.SortingPreference.newInstance(
applicationContext
.getAppCommonSharedPreferences(),
MediaFileAdapter.MEDIA_TYPE_AUDIO
)
MediaFileListSorter.generateMediaFileListHeadersAndSort(
applicationContext,
metaInfoAndSummaryPair.second, sortingPref
)
setMediaInfoSummary(metaInfoAndSummaryPair.first, storageSummary)
emit(metaInfoAndSummaryPair)
metaInfoAndSummaryPair.second.forEach {
Expand Down Expand Up @@ -2778,6 +2796,15 @@ class FilesViewModel(val applicationContext: Application) :
}
mediaStorageSummary?.let {
setMediaInfoSummary(it, storageSummary)
val sortingPref = MediaFileListSorter.SortingPreference.newInstance(
applicationContext
.getAppCommonSharedPreferences(),
MediaFileAdapter.MEDIA_TYPE_AUDIO
)
MediaFileListSorter.generateMediaFileListHeadersAndSort(
applicationContext,
playlistFiles, sortingPref
)
emit(Pair(it, playlistFiles))
playlistFiles.forEach {
mediaFileInfo ->
Expand All @@ -2803,6 +2830,15 @@ class FilesViewModel(val applicationContext: Application) :
}
val metaInfoAndSummaryPair = CursorUtils
.listVideos(applicationContext.applicationContext)
val sortingPref = MediaFileListSorter.SortingPreference.newInstance(
applicationContext
.getAppCommonSharedPreferences(),
MediaFileAdapter.MEDIA_TYPE_VIDEO
)
MediaFileListSorter.generateMediaFileListHeadersAndSort(
applicationContext,
metaInfoAndSummaryPair.second, sortingPref
)
setMediaInfoSummary(metaInfoAndSummaryPair.first, storageSummary)
emit(metaInfoAndSummaryPair)
}
Expand Down Expand Up @@ -2839,6 +2875,15 @@ class FilesViewModel(val applicationContext: Application) :
mediaFiles.add(mediaFileInfo)
}
val docsSummary = StorageSummary(size, 0, longSize)
val sortingPref = MediaFileListSorter.SortingPreference.newInstance(
applicationContext
.getAppCommonSharedPreferences(),
MediaFileAdapter.MEDIA_TYPE_DOCS
)
MediaFileListSorter.generateMediaFileListHeadersAndSort(
applicationContext,
mediaFiles, sortingPref
)
emit(Pair(docsSummary, mediaFiles))
setMediaInfoSummary(docsSummary, storageSummary)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ class MediaFileAdapter(
((item: MenuItem, actionItems: List<MediaFileInfo>) -> Unit)?,
// callback called if we want to refresh data when user tries to switch groupping / sorting
// eg. in case of audio player we would want to utilise different dataset for playlists
private val invalidateDataCallback: (() -> Unit)?
private val invalidateDataCallback: (() -> Unit)?,
private val reloadListCallback: () -> Unit
) : AbstractMediaFilesAdapter(
context,
preloader, isGrid, listItemPressedCallback, toggleCheckCallback
Expand All @@ -83,10 +84,6 @@ class MediaFileAdapter(
preloader.clear()
onlyItemsCounts = 0
headerListItems.clear()
MediaFileListSorter.generateMediaFileListHeadersAndSort(
context,
mediaFileInfoList, sortingPreference
)
var lastHeader: String? = null
value.add(ListItem(TYPE_BANNER))
preloader.addItem("")
Expand Down Expand Up @@ -375,7 +372,9 @@ class MediaFileAdapter(
holder.mediaTypeHeaderView.initOptionsItems(
optionsMenuSelected, headerListItems,
sortingPreference, mediaListType
)
) {
reloadListCallback()
}
drawBannerCallback.invoke(holder.mediaTypeHeaderView)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,26 +181,28 @@ class MediaFileListSorter(private val sortingPreference: SortingPreference) :
Collections.sort(mediaFileList, MediaFileListSorter(sortingPreference))
}

fun getGroupNameByType(groupType: Int, resources: Resources): String {
return when (groupType) {
fun getGroupNameByType(groupType: Int, isAsc: Boolean, resources: Resources): String {
val text = when (groupType) {
GROUP_PARENT -> resources.getString(R.string.parent)
GROUP_NAME -> resources.getString(R.string.name)
GROUP_DATE -> resources.getString(R.string.date)
GROUP_ALBUM -> resources.getString(R.string.album)
GROUP_ARTIST -> resources.getString(R.string.artist)
GROUP_PLAYLISTS -> resources.getString(R.string.playlists)
else -> ""
else -> return ""
}
return text.plus(if (!isAsc) "" else "")
}

fun getSortNameByType(sortBy: Int, resources: Resources): String {
return when (sortBy) {
fun getSortNameByType(sortBy: Int, isAsc: Boolean, resources: Resources): String {
val text = when (sortBy) {
SORT_NAME -> resources.getString(R.string.name)
SORT_SIZE -> resources.getString(R.string.size)
SORT_MODIF -> resources.getString(R.string.date)
SORT_LENGTH -> resources.getString(R.string.duration)
else -> ""
else -> return ""
}
return text.plus(if (!isAsc) "" else "")
}
}

Expand Down
Loading

0 comments on commit 53fd356

Please sign in to comment.