rewrite the way directories are fetched

This commit is contained in:
tibbi 2018-04-23 22:43:01 +02:00
parent 8399b4fccd
commit a6437181cb
8 changed files with 143 additions and 135 deletions

View file

@ -25,11 +25,11 @@ import com.simplemobiletools.commons.views.MyRecyclerView
import com.simplemobiletools.gallery.BuildConfig
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.adapters.DirectoryAdapter
import com.simplemobiletools.gallery.asynctasks.GetDirectoriesAsynctask
import com.simplemobiletools.gallery.dialogs.ChangeSortingDialog
import com.simplemobiletools.gallery.dialogs.FilterMediaDialog
import com.simplemobiletools.gallery.extensions.*
import com.simplemobiletools.gallery.helpers.*
import com.simplemobiletools.gallery.models.AlbumCover
import com.simplemobiletools.gallery.models.Directory
import com.simplemobiletools.gallery.models.Medium
import kotlinx.android.synthetic.main.activity_main.*
@ -58,7 +58,6 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
private var mLatestMediaDateId = 0L
private var mLastMediaHandler = Handler()
private var mTempShowHiddenHandler = Handler()
private var mCurrAsyncTask: GetDirectoriesAsynctask? = null
private var mZoomListener: MyRecyclerView.MyZoomListener? = null
private var mStoredAnimateGifs = true
@ -185,10 +184,6 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
config.temporarilyShowHidden = false
mTempShowHiddenHandler.removeCallbacksAndMessages(null)
removeTempFolder()
if (!mDirs.isEmpty()) {
mCurrAsyncTask?.stopFetching()
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
@ -275,25 +270,14 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
val getImagesOnly = mIsPickImageIntent || mIsGetImageContentIntent
val getVideosOnly = mIsPickVideoIntent || mIsGetVideoContentIntent
if (!mLoadedInitialPhotos) {
getCachedDirectories(getVideosOnly, getImagesOnly) {
if (it.isNotEmpty()) {
gotDirectories(it, true)
getCachedDirectories(getVideosOnly, getImagesOnly) {
if (!mLoadedInitialPhotos) {
runOnUiThread {
directories_refresh_layout.isRefreshing = true
}
}
gotDirectories(it)
}
if (!mLoadedInitialPhotos) {
directories_refresh_layout.isRefreshing = true
}
mLoadedInitialPhotos = true
mCurrAsyncTask?.stopFetching()
mCurrAsyncTask = GetDirectoriesAsynctask(applicationContext, getVideosOnly, getImagesOnly) {
mCurrAsyncTask = null
gotDirectories(addTempFolderIfNeeded(it), false)
}
mCurrAsyncTask!!.execute()
}
private fun showSortingDialog() {
@ -301,7 +285,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
if (config.directorySorting and SORT_BY_DATE_MODIFIED > 0 || config.directorySorting and SORT_BY_DATE_TAKEN > 0) {
getDirectories()
} else {
gotDirectories(mDirs, true)
gotDirectories(mDirs)
}
}
}
@ -338,7 +322,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
invalidateOptionsMenu()
setupLayoutManager()
directories_grid.adapter = null
setupAdapter()
setupAdapter(getCurrentlyDisplayedDirs())
}
}
@ -365,6 +349,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
runOnUiThread {
refreshItems()
}
Thread {
folders.filter { !it.exists() }.forEach {
galleryDB.DirectoryDao().deleteDirPath(it.absolutePath)
@ -429,7 +414,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
FilePickerDialog(this, internalStoragePath, false, config.shouldShowHidden) {
CreateNewFolderDialog(this, it) {
config.tempFolderPath = it
gotDirectories(addTempFolderIfNeeded(mDirs), true)
gotDirectories(addTempFolderIfNeeded(mDirs))
}
}
}
@ -561,116 +546,146 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
}
}
private fun gotDirectories(newDirs: ArrayList<Directory>, isFromCache: Boolean) {
if (!isFromCache) {
Thread {
galleryDB.DirectoryDao().insertAll(newDirs)
}.start()
}
private fun gotDirectories(newDirs: ArrayList<Directory>) {
val dirs = getSortedDirectories(newDirs)
mIsGettingDirs = false
checkLastMediaChanged()
mDirs = dirs
var isPlaceholderVisible = dirs.isEmpty()
runOnUiThread {
directories_refresh_layout.isRefreshing = false
directories_empty_text_label.beVisibleIf(dirs.isEmpty() && !isFromCache)
directories_empty_text.beVisibleIf(dirs.isEmpty() && !isFromCache)
directories_empty_text_label.beVisibleIf(dirs.isEmpty())
directories_empty_text.beVisibleIf(dirs.isEmpty())
directories_grid.beVisibleIf(directories_empty_text_label.isGone())
val allowHorizontalScroll = config.scrollHorizontally && config.viewTypeFiles == VIEW_TYPE_GRID
directories_vertical_fastscroller.beVisibleIf(directories_grid.isVisible() && !allowHorizontalScroll)
directories_horizontal_fastscroller.beVisibleIf(directories_grid.isVisible() && allowHorizontalScroll)
setupAdapter()
setupAdapter(dirs)
}
if (isFromCache) {
Thread {
val mediaFetcher = MediaFetcher(applicationContext)
val getImagesOnly = mIsPickImageIntent || mIsGetImageContentIntent
val getVideosOnly = mIsPickVideoIntent || mIsGetVideoContentIntent
val hidden = getString(R.string.hidden)
val albumCovers = config.parseAlbumCovers()
val hasOTG = hasOTGConnected() && config.OTGBasePath.isNotEmpty()
val includedFolders = config.includedFolders
// cached folders have been loaded, recheck folders one by one starting with the first displayed
Thread {
val mediaFetcher = MediaFetcher(applicationContext)
val getImagesOnly = mIsPickImageIntent || mIsGetImageContentIntent
val getVideosOnly = mIsPickVideoIntent || mIsGetVideoContentIntent
val hiddenString = getString(R.string.hidden)
val albumCovers = config.parseAlbumCovers()
val includedFolders = config.includedFolders
val isSortingAscending = config.directorySorting and SORT_DESCENDING == 0
val mediumDao = galleryDB.MediumDao()
val directoryDao = galleryDB.DirectoryDao()
for (directory in dirs) {
val curMedia = mediaFetcher.getFilesFrom(directory.path, getImagesOnly, getVideosOnly)
Medium.sorting = config.getFileSorting(directory.path)
curMedia.sort()
for (directory in dirs) {
val curMedia = mediaFetcher.getFilesFrom(directory.path, getImagesOnly, getVideosOnly)
val newDir = createDirectoryFromMedia(directory.path, curMedia, albumCovers, hiddenString, includedFolders, isSortingAscending)
val firstItem = curMedia.first()
val lastItem = curMedia.last()
val parentDir = if (hasOTG && firstItem.path.startsWith(OTG_PATH)) {
firstItem.parentPath
} else {
File(firstItem.path).parent
} ?: continue
// we are looping through the already displayed folders looking for changes, do not do anything if nothing changed
if (directory == newDir) {
continue
}
var thumbnail = curMedia.firstOrNull { getDoesFilePathExist(it.path) }?.path ?: ""
if (thumbnail.startsWith(OTG_PATH)) {
thumbnail = thumbnail.getOTGPublicPath(applicationContext)
}
directory.apply {
tmb = newDir.tmb
mediaCnt = newDir.mediaCnt
modified = newDir.modified
taken = newDir.taken
this@apply.size = newDir.size
types = newDir.types
}
albumCovers.forEach {
if (it.path == parentDir && getDoesFilePathExist(it.tmb)) {
thumbnail = it.tmb
showSortedDirs(dirs)
// update directories and media files in the local db, delete invalid items
updateDBDirectory(directory)
mediumDao.insertAll(curMedia)
getCachedMedia(directory.path, getVideosOnly, getImagesOnly) {
it.forEach {
if (!curMedia.contains(it)) {
mediumDao.deleteMediumPath(it.path)
}
}
}
}
val mediaTypes = curMedia.getDirMediaTypes()
val dirName = checkAppendingHidden(parentDir, hidden, includedFolders)
val lastModified = if (config.directorySorting and SORT_DESCENDING > 0) Math.max(firstItem.modified, lastItem.modified) else Math.min(firstItem.modified, lastItem.modified)
val dateTaken = if (config.directorySorting and SORT_DESCENDING > 0) Math.max(firstItem.taken, lastItem.taken) else Math.min(firstItem.taken, lastItem.taken)
val size = curMedia.sumByLong { it.size }
val newDir = Directory(null, parentDir, thumbnail, dirName, curMedia.size, lastModified, dateTaken, size, isPathOnSD(parentDir), mediaTypes)
directory.mediaCnt = curMedia.size
if (directory == newDir) {
continue
}
val foldersToScan = mediaFetcher.getFoldersToScan("")
dirs.forEach {
foldersToScan.remove(it.path)
}
directory.apply {
tmb = thumbnail
mediaCnt = curMedia.size
modified = lastModified
taken = dateTaken
this@apply.size = size
types = mediaTypes
}
for (folder in foldersToScan) {
val newMedia = mediaFetcher.getFilesFrom(folder, getImagesOnly, getVideosOnly)
if (newMedia.isEmpty()) {
continue
}
updateDirectory(directory)
rescanFolderMediaSync(directory.path)
val sortedDirs = getSortedDirectories(dirs).clone() as ArrayList<Directory>
if (isPlaceholderVisible) {
isPlaceholderVisible = false
runOnUiThread {
(directories_grid.adapter as DirectoryAdapter).updateDirs(sortedDirs)
directories_empty_text_label.beGone()
directories_empty_text.beGone()
directories_grid.beVisible()
}
}
}.start()
} else {
storeDirectories()
val newDir = createDirectoryFromMedia(folder, newMedia, albumCovers, hiddenString, includedFolders, isSortingAscending)
dirs.add(newDir)
showSortedDirs(dirs)
directoryDao.insert(newDir)
mediumDao.insertAll(newMedia)
}
mIsGettingDirs = false
mLoadedInitialPhotos = true
runOnUiThread {
directories_refresh_layout.isRefreshing = false
directories_vertical_fastscroller.measureRecyclerView()
}
}.start()
}
private fun showSortedDirs(dirs: ArrayList<Directory>) {
val sortedDirs = getSortedDirectories(dirs).clone() as ArrayList<Directory>
runOnUiThread {
(directories_grid.adapter as DirectoryAdapter).updateDirs(sortedDirs)
}
}
private fun storeDirectories() {
if (!config.temporarilyShowHidden && config.tempFolderPath.isEmpty()) {
storeDirectoryItems(mDirs)
private fun createDirectoryFromMedia(path: String, curMedia: ArrayList<Medium>, albumCovers: ArrayList<AlbumCover>, hiddenString: String,
includedFolders: MutableSet<String>, isSortingAscending: Boolean): Directory {
var thumbnail = curMedia.firstOrNull { getDoesFilePathExist(it.path) }?.path ?: ""
if (thumbnail.startsWith(OTG_PATH)) {
thumbnail = thumbnail.getOTGPublicPath(applicationContext)
}
albumCovers.forEach {
if (it.path == path && getDoesFilePathExist(it.tmb)) {
thumbnail = it.tmb
}
}
val mediaTypes = curMedia.getDirMediaTypes()
val dirName = checkAppendingHidden(path, hiddenString, includedFolders)
val firstItem = curMedia.first()
val lastItem = curMedia.last()
val lastModified = if (!isSortingAscending) Math.max(firstItem.modified, lastItem.modified) else Math.min(firstItem.modified, lastItem.modified)
val dateTaken = if (!isSortingAscending) Math.max(firstItem.taken, lastItem.taken) else Math.min(firstItem.taken, lastItem.taken)
val size = curMedia.sumByLong { it.size }
return Directory(null, path, thumbnail, dirName, curMedia.size, lastModified, dateTaken, size, isPathOnSD(path), mediaTypes)
}
private fun setupAdapter() {
private fun setupAdapter(dirs: ArrayList<Directory>) {
val currAdapter = directories_grid.adapter
if (currAdapter == null) {
initZoomListener()
val fastscroller = if (config.scrollHorizontally) directories_horizontal_fastscroller else directories_vertical_fastscroller
DirectoryAdapter(this, mDirs, this, directories_grid, isPickIntent(intent) || isGetAnyContentIntent(intent), fastscroller) {
DirectoryAdapter(this, dirs, this, directories_grid, isPickIntent(intent) || isGetAnyContentIntent(intent), fastscroller) {
itemClicked((it as Directory).path)
}.apply {
setupZoomListener(mZoomListener)
directories_grid.adapter = this
}
} else {
(currAdapter as DirectoryAdapter).updateDirs(mDirs)
(currAdapter as DirectoryAdapter).updateDirs(dirs)
}
setupScrollDirection()
@ -698,6 +713,8 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
}
}
private fun getCurrentlyDisplayedDirs() = getRecyclerAdapter()?.dirs ?: ArrayList()
private fun getBubbleTextItem(index: Int) = getRecyclerAdapter()?.dirs?.getOrNull(index)?.getBubbleText() ?: ""
private fun setupLatestMediaId() {
@ -714,7 +731,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
return
}
mLastMediaHandler.postDelayed({
/*mLastMediaHandler.postDelayed({
Thread {
val mediaId = getLatestMediaId()
val mediaDateId = getLatestMediaByDateId()
@ -729,7 +746,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
checkLastMediaChanged()
}
}.start()
}, LAST_MEDIA_CHECK_PERIOD)
}, LAST_MEDIA_CHECK_PERIOD)*/
}
override fun refreshItems() {
@ -737,12 +754,12 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
}
override fun recheckPinnedFolders() {
gotDirectories(movePinnedDirectoriesToFront(mDirs), true)
gotDirectories(movePinnedDirectoriesToFront(mDirs))
}
override fun updateDirectories(directories: ArrayList<Directory>, refreshList: Boolean) {
if (refreshList) {
gotDirectories(directories, true)
gotDirectories(directories)
} else {
mDirs = directories
}

View file

@ -669,8 +669,6 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
deleteDirectoryIfEmpty()
finish()
} else {
updateStoredDirectories()
Thread {
val mediumDao = galleryDB.MediumDao()
filtered.forEach {

View file

@ -765,7 +765,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
}
Thread {
updateMediaPath(oldPath, it)
updateDBMediaPath(oldPath, it)
}.start()
updateActionbarTitle()
}

View file

@ -151,7 +151,7 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList<Medium>,
val oldPath = getCurrentPath()
RenameItemDialog(activity, oldPath) {
Thread {
activity.updateMediaPath(oldPath, it)
activity.updateDBMediaPath(oldPath, it)
}.start()
activity.runOnUiThread {

View file

@ -10,7 +10,6 @@ import com.simplemobiletools.commons.helpers.sumByLong
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.extensions.checkAppendingHidden
import com.simplemobiletools.gallery.extensions.config
import com.simplemobiletools.gallery.extensions.galleryDB
import com.simplemobiletools.gallery.extensions.getDirMediaTypes
import com.simplemobiletools.gallery.helpers.MediaFetcher
import com.simplemobiletools.gallery.models.Directory
@ -46,7 +45,6 @@ class GetDirectoriesAsynctask(val context: Context, val isPickVideo: Boolean, va
File(firstItem.path).parent
} ?: continue
context.galleryDB.MediumDao().insertAll(curMedia)
var thumbnail = curMedia.firstOrNull { context.getDoesFilePathExist(it.path) }?.path ?: ""
if (thumbnail.startsWith(OTG_PATH)) {
thumbnail = thumbnail.getOTGPublicPath(context)

View file

@ -152,7 +152,7 @@ fun BaseSimpleActivity.toggleFileVisibility(oldPath: String, hide: Boolean, call
renameFile(oldPath, newPath) {
callback?.invoke(newPath)
Thread {
updateMediaPath(oldPath, newPath)
updateDBMediaPath(oldPath, newPath)
}.start()
}
}

View file

@ -19,7 +19,6 @@ import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.OTG_PATH
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.activities.SettingsActivity
import com.simplemobiletools.gallery.asynctasks.GetDirectoriesAsynctask
import com.simplemobiletools.gallery.asynctasks.GetMediaAsynctask
import com.simplemobiletools.gallery.databases.GalleryDataBase
import com.simplemobiletools.gallery.helpers.*
@ -158,14 +157,6 @@ fun Context.rescanFolderMediaSync(path: String) {
}
}
fun Context.updateStoredDirectories() {
GetDirectoriesAsynctask(this, false, false) {
if (!config.temporarilyShowHidden) {
storeDirectoryItems(it)
}
}.execute()
}
fun Context.storeDirectoryItems(items: ArrayList<Directory>) {
Thread {
galleryDB.DirectoryDao().insertAll(items)
@ -318,12 +309,12 @@ fun Context.removeInvalidDirectories(dirs: ArrayList<Directory>? = null, directo
}
}
fun Context.updateMediaPath(oldPath: String, newPath: String) {
fun Context.updateDBMediaPath(oldPath: String, newPath: String) {
val newFilename = newPath.getFilenameFromPath()
val newParentPath = newPath.getParentPath()
galleryDB.MediumDao().updateMedium(oldPath, newParentPath, newFilename, newPath)
}
fun Context.updateDirectory(directory: Directory) {
fun Context.updateDBDirectory(directory: Directory) {
galleryDB.DirectoryDao().updateDirectory(directory.path, directory.tmb, directory.mediaCnt, directory.modified, directory.taken, directory.size, directory.types)
}

View file

@ -32,12 +32,11 @@ class MediaFetcher(val context: Context) {
val curMedia = ArrayList<Medium>()
if (curPath.startsWith(OTG_PATH)) {
getMediaOnOTG(curPath, curMedia, isPickImage, isPickVideo, filterMedia)
val newMedia = getMediaOnOTG(curPath, isPickImage, isPickVideo, filterMedia)
curMedia.addAll(newMedia)
} else {
val foldersToScan = getFoldersToScan(curPath)
foldersToScan.forEach {
fetchFolderContent(it, curMedia, isPickImage, isPickVideo, filterMedia)
}
val newMedia = fetchFolderContent(curPath, isPickImage, isPickVideo, filterMedia)
curMedia.addAll(newMedia)
}
Medium.sorting = context.config.getFileSorting(curPath)
@ -45,7 +44,7 @@ class MediaFetcher(val context: Context) {
return curMedia
}
private fun getFoldersToScan(path: String): ArrayList<String> {
fun getFoldersToScan(path: String): ArrayList<String> {
val filterMedia = context.config.filterMedia
val projection = arrayOf(MediaStore.Images.Media.DATA)
val uri = MediaStore.Files.getContentUri("external")
@ -160,11 +159,11 @@ class MediaFetcher(val context: Context) {
}
}
private fun fetchFolderContent(path: String, curMedia: ArrayList<Medium>, isPickImage: Boolean, isPickVideo: Boolean, filterMedia: Int) {
if (path.startsWith(OTG_PATH)) {
getMediaOnOTG(path, curMedia, isPickImage, isPickVideo, filterMedia)
private fun fetchFolderContent(path: String, isPickImage: Boolean, isPickVideo: Boolean, filterMedia: Int): ArrayList<Medium> {
return if (path.startsWith(OTG_PATH)) {
getMediaOnOTG(path, isPickImage, isPickVideo, filterMedia)
} else {
getMediaInFolder(path, curMedia, isPickImage, isPickVideo, filterMedia)
getMediaInFolder(path, isPickImage, isPickVideo, filterMedia)
}
}
@ -185,8 +184,9 @@ class MediaFetcher(val context: Context) {
return directories
}
private fun getMediaInFolder(folder: String, curMedia: ArrayList<Medium>, isPickImage: Boolean, isPickVideo: Boolean, filterMedia: Int) {
val files = File(folder).listFiles() ?: return
private fun getMediaInFolder(folder: String, isPickImage: Boolean, isPickVideo: Boolean, filterMedia: Int): ArrayList<Medium> {
val media = ArrayList<Medium>()
val files = File(folder).listFiles() ?: return media
val doExtraCheck = context.config.doExtraCheck
val showHidden = context.config.shouldShowHidden
@ -229,12 +229,14 @@ class MediaFetcher(val context: Context) {
}
val medium = Medium(null, filename, file.absolutePath, folder, dateModified, dateTaken, size, type)
curMedia.add(medium)
media.add(medium)
}
return media
}
private fun getMediaOnOTG(folder: String, curMedia: ArrayList<Medium>, isPickImage: Boolean, isPickVideo: Boolean, filterMedia: Int) {
val files = context.getDocumentFile(folder)?.listFiles() ?: return
private fun getMediaOnOTG(folder: String, isPickImage: Boolean, isPickVideo: Boolean, filterMedia: Int): ArrayList<Medium> {
val media = ArrayList<Medium>()
val files = context.getDocumentFile(folder)?.listFiles() ?: return media
val doExtraCheck = context.config.doExtraCheck
val showHidden = context.config.shouldShowHidden
@ -278,7 +280,9 @@ class MediaFetcher(val context: Context) {
val path = Uri.decode(file.uri.toString().replaceFirst("${context.config.OTGBasePath}%3A", OTG_PATH))
val medium = Medium(null, filename, path, folder, dateModified, dateTaken, size, type)
curMedia.add(medium)
media.add(medium)
}
return media
}
}