Optimize Imageloader to not create empty MusicDirectory.Entries
This commit is contained in:
parent
611539be55
commit
28097bf325
|
@ -14,8 +14,8 @@ import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView.S
|
|||
import java.text.Collator
|
||||
import org.moire.ultrasonic.R
|
||||
import org.moire.ultrasonic.domain.ArtistOrIndex
|
||||
import org.moire.ultrasonic.domain.MusicDirectory
|
||||
import org.moire.ultrasonic.imageloader.ImageLoader
|
||||
import org.moire.ultrasonic.util.FileUtil
|
||||
import org.moire.ultrasonic.util.Util
|
||||
|
||||
/**
|
||||
|
@ -59,13 +59,14 @@ class ArtistRowAdapter(
|
|||
|
||||
if (Util.getShouldShowArtistPicture()) {
|
||||
holder.coverArt.visibility = View.VISIBLE
|
||||
val key = FileUtil.getArtistArtKey(itemList[listPosition].name, false)
|
||||
imageLoader.loadImage(
|
||||
holder.coverArt,
|
||||
MusicDirectory.Entry("-1").apply {
|
||||
coverArt = holder.coverArtId
|
||||
artist = itemList[listPosition].name
|
||||
},
|
||||
false, 0, R.drawable.ic_contact_picture
|
||||
view = holder.coverArt,
|
||||
id = holder.coverArtId,
|
||||
key = key,
|
||||
large = false,
|
||||
size = 0,
|
||||
defaultResourceId = R.drawable.ic_contact_picture
|
||||
)
|
||||
} else {
|
||||
holder.coverArt.visibility = View.GONE
|
||||
|
|
|
@ -93,10 +93,27 @@ class ImageLoader(
|
|||
defaultResourceId: Int = R.drawable.unknown_album
|
||||
) {
|
||||
val id = entry?.coverArt
|
||||
val key = FileUtil.getAlbumArtKey(entry, large)
|
||||
|
||||
loadImage(view, id, key, large, size, defaultResourceId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the cover of a given entry into an ImageView
|
||||
*/
|
||||
@JvmOverloads
|
||||
@Suppress("LongParameterList", "ComplexCondition")
|
||||
fun loadImage(
|
||||
view: View?,
|
||||
id: String?,
|
||||
key: String?,
|
||||
large: Boolean,
|
||||
size: Int,
|
||||
defaultResourceId: Int = R.drawable.unknown_album
|
||||
) {
|
||||
val requestedSize = resolveSize(size, large)
|
||||
|
||||
if (id != null && id.isNotEmpty() && view is ImageView) {
|
||||
val key = FileUtil.getAlbumArtKey(entry, large)
|
||||
if (id != null && key != null && id.isNotEmpty() && view is ImageView) {
|
||||
val request = ImageRequest.CoverArt(
|
||||
id, key, view, requestedSize,
|
||||
placeHolderDrawableRes = defaultResourceId,
|
||||
|
|
|
@ -41,6 +41,8 @@ object FileUtil {
|
|||
private val TITLE_WITH_TRACK = Pattern.compile("^\\d\\d-.*")
|
||||
const val SUFFIX_LARGE = ".jpeg"
|
||||
const val SUFFIX_SMALL = ".jpeg-small"
|
||||
private const val UNNAMED = "unnamed"
|
||||
|
||||
private val permissionUtil = KoinJavaComponent.inject<PermissionUtil>(
|
||||
PermissionUtil::class.java
|
||||
)
|
||||
|
@ -50,7 +52,7 @@ object FileUtil {
|
|||
|
||||
// Do not generate new name for offline files. Offline files will have their Path as their Id.
|
||||
if (!TextUtils.isEmpty(song.id)) {
|
||||
if (song.id.startsWith(dir!!.absolutePath)) return File(song.id)
|
||||
if (song.id.startsWith(dir.absolutePath)) return File(song.id)
|
||||
}
|
||||
|
||||
// Generate a file name for the song
|
||||
|
@ -66,7 +68,7 @@ object FileUtil {
|
|||
fileName.append(track).append('-')
|
||||
}
|
||||
}
|
||||
fileName.append(fileSystemSafe(song.title!!)).append('.')
|
||||
fileName.append(fileSystemSafe(song.title)).append('.')
|
||||
if (!TextUtils.isEmpty(song.transcodedSuffix)) {
|
||||
fileName.append(song.transcodedSuffix)
|
||||
} else {
|
||||
|
@ -76,7 +78,7 @@ object FileUtil {
|
|||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getPlaylistFile(server: String?, name: String): File {
|
||||
fun getPlaylistFile(server: String?, name: String?): File {
|
||||
val playlistDir = getPlaylistDirectory(server)
|
||||
return File(playlistDir, String.format(Locale.ROOT, "%s.m3u", fileSystemSafe(name)))
|
||||
}
|
||||
|
@ -89,7 +91,8 @@ object FileUtil {
|
|||
return playlistDir
|
||||
}
|
||||
|
||||
fun getPlaylistDirectory(server: String?): File {
|
||||
@JvmStatic
|
||||
fun getPlaylistDirectory(server: String? = null): File {
|
||||
val playlistDir: File
|
||||
if (server != null) {
|
||||
playlistDir = File(playlistDirectory, server)
|
||||
|
@ -105,7 +108,7 @@ object FileUtil {
|
|||
* @param entry The album entry
|
||||
* @return File object. Not guaranteed that it exists
|
||||
*/
|
||||
fun getAlbumArtFile(entry: MusicDirectory.Entry?): File? {
|
||||
fun getAlbumArtFile(entry: MusicDirectory.Entry): File {
|
||||
val albumDir = getAlbumDirectory(entry)
|
||||
return getAlbumArtFile(albumDir)
|
||||
}
|
||||
|
@ -117,20 +120,30 @@ object FileUtil {
|
|||
* @return String The hash key
|
||||
*/
|
||||
fun getAlbumArtKey(entry: MusicDirectory.Entry?, large: Boolean): String? {
|
||||
if (entry == null) return null
|
||||
val albumDir = getAlbumDirectory(entry)
|
||||
return getAlbumArtKey(albumDir, large)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cache key for a given artist
|
||||
* @param name The artist name
|
||||
* @param large Whether to get the key for the large or the default image
|
||||
* @return String The hash key
|
||||
*/
|
||||
fun getArtistArtKey(name: String?, large: Boolean): String {
|
||||
val artist = fileSystemSafe(name)
|
||||
val dir = File(String.format(Locale.ROOT, "%s/%s/%s", musicDirectory.path, artist, UNNAMED))
|
||||
return getAlbumArtKey(dir, large)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cache key for a given album entry
|
||||
* @param albumDir The album directory
|
||||
* @param large Whether to get the key for the large or the default image
|
||||
* @return String The hash key
|
||||
*/
|
||||
private fun getAlbumArtKey(albumDir: File?, large: Boolean): String? {
|
||||
if (albumDir == null) {
|
||||
return null
|
||||
}
|
||||
private fun getAlbumArtKey(albumDir: File, large: Boolean): String {
|
||||
val suffix = if (large) SUFFIX_LARGE else SUFFIX_SMALL
|
||||
return String.format(Locale.ROOT, "%s%s", Util.md5Hex(albumDir.path), suffix)
|
||||
}
|
||||
|
@ -149,12 +162,11 @@ object FileUtil {
|
|||
* @param albumDir The album directory
|
||||
* @return File object. Not guaranteed that it exists
|
||||
*/
|
||||
fun getAlbumArtFile(albumDir: File?): File? {
|
||||
@JvmStatic
|
||||
fun getAlbumArtFile(albumDir: File): File {
|
||||
val albumArtDir = albumArtDirectory
|
||||
val key = getAlbumArtKey(albumDir, true)
|
||||
return if (key == null) {
|
||||
null
|
||||
} else File(albumArtDir, key)
|
||||
return File(albumArtDir, key)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -162,6 +174,7 @@ object FileUtil {
|
|||
* @param cacheKey The key (== the filename)
|
||||
* @return File object. Not guaranteed that it exists
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getAlbumArtFile(cacheKey: String?): File? {
|
||||
val albumArtDir = albumArtDirectory
|
||||
return if (cacheKey == null) {
|
||||
|
@ -177,10 +190,7 @@ object FileUtil {
|
|||
return albumArtDir
|
||||
}
|
||||
|
||||
fun getAlbumDirectory(entry: MusicDirectory.Entry?): File? {
|
||||
if (entry == null) {
|
||||
return null
|
||||
}
|
||||
fun getAlbumDirectory(entry: MusicDirectory.Entry): File {
|
||||
val dir: File
|
||||
if (!TextUtils.isEmpty(entry.path)) {
|
||||
val f = File(fileSystemSafeDir(entry.path))
|
||||
|
@ -193,10 +203,10 @@ object FileUtil {
|
|||
)
|
||||
)
|
||||
} else {
|
||||
val artist = fileSystemSafe(entry.artist!!)
|
||||
var album = fileSystemSafe(entry.album!!)
|
||||
if ("unnamed" == album) {
|
||||
album = fileSystemSafe(entry.title!!)
|
||||
val artist = fileSystemSafe(entry.artist)
|
||||
var album = fileSystemSafe(entry.album)
|
||||
if (UNNAMED == album) {
|
||||
album = fileSystemSafe(entry.title)
|
||||
}
|
||||
dir = File(String.format(Locale.ROOT, "%s/%s/%s", musicDirectory.path, artist, album))
|
||||
}
|
||||
|
@ -225,11 +235,13 @@ object FileUtil {
|
|||
// GetExternalFilesDir will always return a directory which Ultrasonic
|
||||
// can access without any extra privileges.
|
||||
@JvmStatic
|
||||
val ultrasonicDirectory: File?
|
||||
get() = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) File(
|
||||
Environment.getExternalStorageDirectory(),
|
||||
"Android/data/org.moire.ultrasonic"
|
||||
) else UApp.applicationContext().getExternalFilesDir(null)
|
||||
val ultrasonicDirectory: File
|
||||
get() {
|
||||
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) File(
|
||||
Environment.getExternalStorageDirectory(),
|
||||
"Android/data/org.moire.ultrasonic"
|
||||
) else UApp.applicationContext().getExternalFilesDir(null)!!
|
||||
}
|
||||
|
||||
// After Android M, the location of the files must be queried differently.
|
||||
// GetExternalFilesDir will always return a directory which Ultrasonic
|
||||
|
@ -237,6 +249,7 @@ object FileUtil {
|
|||
@JvmStatic
|
||||
val defaultMusicDirectory: File
|
||||
get() = getOrCreateDirectory("music")
|
||||
|
||||
@JvmStatic
|
||||
val musicDirectory: File
|
||||
get() {
|
||||
|
@ -285,11 +298,12 @@ object FileUtil {
|
|||
* @param name The filename in question.
|
||||
* @return The filename with special characters replaced by hyphens.
|
||||
*/
|
||||
private fun fileSystemSafe(name: String): String {
|
||||
var filename = name
|
||||
if (filename.trim { it <= ' ' }.isEmpty()) {
|
||||
return "unnamed"
|
||||
private fun fileSystemSafe(name: String?): String {
|
||||
if (name == null || name.trim { it <= ' ' }.isEmpty()) {
|
||||
return UNNAMED
|
||||
}
|
||||
var filename: String = name
|
||||
|
||||
for (s in FILE_SYSTEM_UNSAFE) {
|
||||
filename = filename.replace(s, "-")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue