Refactor file metadata types

This commit is contained in:
MM20 2023-10-29 22:50:33 +01:00
parent 97fca2d014
commit 0a508a37ba
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
11 changed files with 166 additions and 81 deletions

View File

@ -48,6 +48,7 @@ import androidx.compose.ui.unit.roundToIntRect
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import de.mm20.launcher2.search.File import de.mm20.launcher2.search.File
import de.mm20.launcher2.search.FileMetaType
import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.animation.animateTextStyleAsState import de.mm20.launcher2.ui.animation.animateTextStyleAsState
import de.mm20.launcher2.ui.component.DefaultToolbarAction import de.mm20.launcher2.ui.component.DefaultToolbarAction
@ -136,7 +137,7 @@ fun FileItem(
) )
for ((k, v) in file.metaData) { for ((k, v) in file.metaData) {
Text( Text(
text = stringResource(k, v), text = stringResource(k.labelRes, v),
style = MaterialTheme.typography.bodySmall style = MaterialTheme.typography.bodySmall
) )
} }
@ -365,4 +366,22 @@ private fun formatFileSize(size: Long): String {
size < 1000000000000L -> "${DecimalFormat("#,##0.#").format(size / 1000000000.0)} GB" size < 1000000000000L -> "${DecimalFormat("#,##0.#").format(size / 1000000000.0)} GB"
else -> "${DecimalFormat("#,##0.#").format(size / 1000000000000.0)} TB" else -> "${DecimalFormat("#,##0.#").format(size / 1000000000000.0)} TB"
} }
} }
private val FileMetaType.labelRes: Int
get() {
return when (this) {
FileMetaType.Title -> R.string.file_meta_title
FileMetaType.Artist -> R.string.file_meta_artist
FileMetaType.Album -> R.string.file_meta_album
FileMetaType.Duration -> R.string.file_meta_duration
FileMetaType.Year -> R.string.file_meta_year
FileMetaType.Dimensions -> R.string.file_meta_dimensions
FileMetaType.Location -> R.string.file_meta_location
FileMetaType.AppName -> R.string.file_meta_app_name
FileMetaType.AppVersion -> R.string.file_meta_app_version
FileMetaType.AppMinSdk -> R.string.file_meta_app_min_sdk
FileMetaType.AppPackageName -> R.string.file_meta_app_pkgname
FileMetaType.Owner -> R.string.file_meta_owner
}
}

View File

@ -6,6 +6,7 @@ import de.mm20.launcher2.base.R
import de.mm20.launcher2.icons.ColorLayer import de.mm20.launcher2.icons.ColorLayer
import de.mm20.launcher2.icons.StaticLauncherIcon import de.mm20.launcher2.icons.StaticLauncherIcon
import de.mm20.launcher2.icons.TintedIconLayer import de.mm20.launcher2.icons.TintedIconLayer
import kotlinx.collections.immutable.ImmutableMap
import java.util.Locale import java.util.Locale
interface File : SavableSearchable { interface File : SavableSearchable {
@ -13,7 +14,7 @@ interface File : SavableSearchable {
val mimeType: String val mimeType: String
val size: Long val size: Long
val isDirectory: Boolean val isDirectory: Boolean
val metaData: List<Pair<Int, String>> val metaData: ImmutableMap<FileMetaType, String>
val isStoredInCloud: Boolean val isStoredInCloud: Boolean
@ -139,4 +140,19 @@ interface File : SavableSearchable {
fun share(context: Context) {} fun share(context: Context) {}
suspend fun delete(context: Context) {} suspend fun delete(context: Context) {}
}
enum class FileMetaType {
Title,
Artist,
Album,
Duration,
Year,
Dimensions,
Location,
AppName,
AppVersion,
AppMinSdk,
AppPackageName,
Owner,
} }

View File

@ -11,9 +11,12 @@ import de.mm20.launcher2.files.providers.OwncloudFile
import de.mm20.launcher2.ktx.jsonObjectOf import de.mm20.launcher2.ktx.jsonObjectOf
import de.mm20.launcher2.permissions.PermissionGroup import de.mm20.launcher2.permissions.PermissionGroup
import de.mm20.launcher2.permissions.PermissionsManager import de.mm20.launcher2.permissions.PermissionsManager
import de.mm20.launcher2.search.FileMetaType
import de.mm20.launcher2.search.SavableSearchable import de.mm20.launcher2.search.SavableSearchable
import de.mm20.launcher2.search.SearchableDeserializer import de.mm20.launcher2.search.SearchableDeserializer
import de.mm20.launcher2.search.SearchableSerializer import de.mm20.launcher2.search.SearchableSerializer
import kotlinx.collections.immutable.persistentMapOf
import kotlinx.collections.immutable.toImmutableMap
import org.json.JSONObject import org.json.JSONObject
import org.koin.core.component.KoinComponent import org.koin.core.component.KoinComponent
import org.koin.core.component.get import org.koin.core.component.get
@ -93,8 +96,8 @@ internal class GDriveFileSerializer : SearchableSerializer {
for ((k, v) in searchable.metaData) { for ((k, v) in searchable.metaData) {
put( put(
when (k) { when (k) {
R.string.file_meta_owner -> "owner" FileMetaType.Owner -> "owner"
R.string.file_meta_dimensions -> "dimensions" FileMetaType.Dimensions -> "dimensions"
else -> "other" else -> "other"
}, v }, v
) )
@ -119,10 +122,10 @@ internal class GDriveFileDeserializer : SearchableDeserializer {
val uri = json.getString("uri") val uri = json.getString("uri")
val owner = json.optString("owner") val owner = json.optString("owner")
val dimensions = json.optString("dimensions") val dimensions = json.optString("dimensions")
val metaData = mutableListOf<Pair<Int, String>>() val metaData = mutableMapOf<FileMetaType, String>()
owner.takeIf { it.isNotEmpty() }?.let { metaData.add(R.string.file_meta_owner to it) } owner.takeIf { it.isNotEmpty() }?.let { metaData[FileMetaType.Owner] = it }
dimensions.takeIf { it.isNotEmpty() } dimensions.takeIf { it.isNotEmpty() }
?.let { metaData.add(R.string.file_meta_dimensions to it) } ?.let { metaData[FileMetaType.Dimensions] = it }
return GDriveFile( return GDriveFile(
fileId = id, fileId = id,
label = label, label = label,
@ -132,7 +135,7 @@ internal class GDriveFileDeserializer : SearchableDeserializer {
directoryColor = color, directoryColor = color,
isDirectory = directory, isDirectory = directory,
viewUri = uri, viewUri = uri,
metaData = metaData metaData = metaData.toImmutableMap()
) )
} }
} }
@ -151,8 +154,8 @@ internal class OneDriveFileSerializer : SearchableSerializer {
for ((k, v) in searchable.metaData) { for ((k, v) in searchable.metaData) {
put( put(
when (k) { when (k) {
R.string.file_meta_owner -> "owner" FileMetaType.Owner -> "owner"
R.string.file_meta_dimensions -> "dimensions" FileMetaType.Dimensions -> "dimensions"
else -> "other" else -> "other"
}, v }, v
) )
@ -175,10 +178,10 @@ internal class OneDriveFileDeserializer : SearchableDeserializer {
val webUrl = json.getString("webUrl") val webUrl = json.getString("webUrl")
val owner = json.optString("owner") val owner = json.optString("owner")
val dimensions = json.optString("dimensions") val dimensions = json.optString("dimensions")
val metaData = mutableListOf<Pair<Int, String>>() val metaData = mutableMapOf<FileMetaType, String>()
owner.takeIf { it.isNotEmpty() }?.let { metaData.add(R.string.file_meta_owner to it) } owner.takeIf { it.isNotEmpty() }?.let { metaData[FileMetaType.Owner] = it }
dimensions.takeIf { it.isNotEmpty() } dimensions.takeIf { it.isNotEmpty() }
?.let { metaData.add(R.string.file_meta_dimensions to it) } ?.let { metaData[FileMetaType.Dimensions] = it }
return OneDriveFile( return OneDriveFile(
fileId = fileId, fileId = fileId,
label = label, label = label,
@ -186,7 +189,7 @@ internal class OneDriveFileDeserializer : SearchableDeserializer {
mimeType = mimeType, mimeType = mimeType,
size = size, size = size,
isDirectory = isDirectory, isDirectory = isDirectory,
metaData = metaData, metaData = metaData.toImmutableMap(),
webUrl = webUrl webUrl = webUrl
) )
} }
@ -207,7 +210,7 @@ internal class NextcloudFileSerializer : SearchableSerializer {
for ((k, v) in searchable.metaData) { for ((k, v) in searchable.metaData) {
put( put(
when (k) { when (k) {
R.string.file_meta_owner -> "owner" FileMetaType.Owner -> "owner"
else -> "other" else -> "other"
}, v }, v
) )
@ -239,7 +242,7 @@ internal class NextcloudFileDeserializer : SearchableDeserializer {
size = size, size = size,
isDirectory = isDirectory, isDirectory = isDirectory,
server = server, server = server,
metaData = owner?.let { listOf(R.string.file_meta_owner to it) } ?: emptyList() metaData = owner?.let { persistentMapOf(FileMetaType.Owner to it) } ?: persistentMapOf()
) )
} }
@ -260,7 +263,7 @@ internal class OwncloudFileSerializer : SearchableSerializer {
for ((k, v) in searchable.metaData) { for ((k, v) in searchable.metaData) {
put( put(
when (k) { when (k) {
R.string.file_meta_owner -> "owner" FileMetaType.Owner -> "owner"
else -> "other" else -> "other"
}, v }, v
) )
@ -292,7 +295,7 @@ internal class OwncloudFileDeserializer : SearchableDeserializer {
size = size, size = size,
isDirectory = isDirectory, isDirectory = isDirectory,
server = server, server = server,
metaData = owner?.let { listOf(R.string.file_meta_owner to it) } ?: emptyList() metaData = owner?.let { persistentMapOf(FileMetaType.Owner to it) } ?: persistentMapOf()
) )
} }

View File

@ -8,7 +8,9 @@ import de.mm20.launcher2.files.GDriveFileSerializer
import de.mm20.launcher2.files.R import de.mm20.launcher2.files.R
import de.mm20.launcher2.ktx.tryStartActivity import de.mm20.launcher2.ktx.tryStartActivity
import de.mm20.launcher2.search.File import de.mm20.launcher2.search.File
import de.mm20.launcher2.search.FileMetaType
import de.mm20.launcher2.search.SearchableSerializer import de.mm20.launcher2.search.SearchableSerializer
import kotlinx.collections.immutable.ImmutableMap
internal data class GDriveFile( internal data class GDriveFile(
val fileId: String, val fileId: String,
@ -17,7 +19,7 @@ internal data class GDriveFile(
override val mimeType: String, override val mimeType: String,
override val size: Long, override val size: Long,
override val isDirectory: Boolean, override val isDirectory: Boolean,
override val metaData: List<Pair<Int, String>>, override val metaData: ImmutableMap<FileMetaType, String>,
val directoryColor: String?, val directoryColor: String?,
val viewUri: String, val viewUri: String,
override val labelOverride: String? = null, override val labelOverride: String? = null,

View File

@ -5,6 +5,9 @@ import de.mm20.launcher2.files.R
import de.mm20.launcher2.gservices.DriveFileMeta import de.mm20.launcher2.gservices.DriveFileMeta
import de.mm20.launcher2.gservices.GoogleApiHelper import de.mm20.launcher2.gservices.GoogleApiHelper
import de.mm20.launcher2.search.File import de.mm20.launcher2.search.File
import de.mm20.launcher2.search.FileMetaType
import kotlinx.collections.immutable.ImmutableMap
import kotlinx.collections.immutable.toImmutableMap
internal class GDriveFileProvider( internal class GDriveFileProvider(
private val context: Context private val context: Context
@ -27,13 +30,13 @@ internal class GDriveFileProvider(
} }
} }
private fun getMetadata(file: DriveFileMeta): List<Pair<Int, String>> { private fun getMetadata(file: DriveFileMeta): ImmutableMap<FileMetaType, String> {
val metaData = mutableListOf<Pair<Int, String>>() val metaData = mutableMapOf<FileMetaType, String>()
val owners = file.owners val owners = file.owners
metaData.add(R.string.file_meta_owner to owners.joinToString(separator = ", ")) metaData[FileMetaType.Owner] = owners.joinToString(separator = ", ")
val width = file.width ?: file.width val width = file.width
val height = file.height ?: file.height val height = file.height
if (width != null && height != null) metaData.add(R.string.file_meta_dimensions to "${width}x$height") if (width != null && height != null) metaData[FileMetaType.Dimensions] = "${width}x${height}"
return metaData return metaData.toImmutableMap()
} }
} }

View File

@ -17,13 +17,19 @@ import androidx.core.content.FileProvider
import androidx.exifinterface.media.ExifInterface import androidx.exifinterface.media.ExifInterface
import de.mm20.launcher2.crashreporter.CrashReporter import de.mm20.launcher2.crashreporter.CrashReporter
import de.mm20.launcher2.files.LocalFileSerializer import de.mm20.launcher2.files.LocalFileSerializer
import de.mm20.launcher2.files.R import de.mm20.launcher2.icons.ColorLayer
import de.mm20.launcher2.icons.* import de.mm20.launcher2.icons.LauncherIcon
import de.mm20.launcher2.icons.StaticIconLayer
import de.mm20.launcher2.icons.StaticLauncherIcon
import de.mm20.launcher2.icons.TransparentLayer
import de.mm20.launcher2.ktx.formatToString import de.mm20.launcher2.ktx.formatToString
import de.mm20.launcher2.ktx.tryStartActivity import de.mm20.launcher2.ktx.tryStartActivity
import de.mm20.launcher2.media.ThumbnailUtilsCompat import de.mm20.launcher2.media.ThumbnailUtilsCompat
import de.mm20.launcher2.search.File import de.mm20.launcher2.search.File
import de.mm20.launcher2.search.FileMetaType
import de.mm20.launcher2.search.SearchableSerializer import de.mm20.launcher2.search.SearchableSerializer
import kotlinx.collections.immutable.ImmutableMap
import kotlinx.collections.immutable.toImmutableMap
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -36,7 +42,7 @@ internal data class LocalFile(
override val mimeType: String, override val mimeType: String,
override val size: Long, override val size: Long,
override val isDirectory: Boolean, override val isDirectory: Boolean,
override val metaData: List<Pair<Int, String>>, override val metaData: ImmutableMap<FileMetaType, String>,
override val labelOverride: String? = null override val labelOverride: String? = null
) : File { ) : File {
@ -75,6 +81,7 @@ internal data class LocalFile(
backgroundLayer = ColorLayer() backgroundLayer = ColorLayer()
) )
} }
mimeType.startsWith("video/") -> { mimeType.startsWith("video/") -> {
val thumbnail = withContext(Dispatchers.IO) { val thumbnail = withContext(Dispatchers.IO) {
ThumbnailUtilsCompat.createVideoThumbnail( ThumbnailUtilsCompat.createVideoThumbnail(
@ -91,6 +98,7 @@ internal data class LocalFile(
backgroundLayer = ColorLayer() backgroundLayer = ColorLayer()
) )
} }
mimeType.startsWith("audio/") -> { mimeType.startsWith("audio/") -> {
val thumbnail = withContext(Dispatchers.IO) { val thumbnail = withContext(Dispatchers.IO) {
val mediaMetadataRetriever = MediaMetadataRetriever() val mediaMetadataRetriever = MediaMetadataRetriever()
@ -123,6 +131,7 @@ internal data class LocalFile(
) )
} }
mimeType == "application/vnd.android.package-archive" -> { mimeType == "application/vnd.android.package-archive" -> {
val pkgInfo = context.packageManager.getPackageArchiveInfo(path, 0) val pkgInfo = context.packageManager.getPackageArchiveInfo(path, 0)
val icon = withContext(Dispatchers.IO) { val icon = withContext(Dispatchers.IO) {
@ -145,6 +154,7 @@ internal data class LocalFile(
} ?: TransparentLayer, } ?: TransparentLayer,
) )
} }
else -> { else -> {
return StaticLauncherIcon( return StaticLauncherIcon(
foregroundLayer = StaticIconLayer( foregroundLayer = StaticIconLayer(
@ -238,48 +248,55 @@ internal data class LocalFile(
context: Context, context: Context,
mimeType: String, mimeType: String,
path: String path: String
): List<Pair<Int, String>> { ): ImmutableMap<FileMetaType, String> {
val metaData = mutableListOf<Pair<Int, String>>() val metaData = mutableMapOf<FileMetaType, String>()
when { when {
mimeType.startsWith("audio/") -> { mimeType.startsWith("audio/") -> {
val retriever = MediaMetadataRetriever() val retriever = MediaMetadataRetriever()
try { try {
retriever.setDataSource(path) retriever.setDataSource(path)
arrayOf(
R.string.file_meta_title to MediaMetadataRetriever.METADATA_KEY_TITLE, retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE)
R.string.file_meta_artist to MediaMetadataRetriever.METADATA_KEY_ARTIST, ?.let { metaData[FileMetaType.Title] = it }
R.string.file_meta_album to MediaMetadataRetriever.METADATA_KEY_ALBUM, retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST)
R.string.file_meta_year to MediaMetadataRetriever.METADATA_KEY_YEAR ?.let { metaData[FileMetaType.Artist] = it }
).forEach { retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM)
retriever.extractMetadata(it.second) ?.let { metaData[FileMetaType.Album] = it }
?.let { m -> metaData.add(it.first to m) } retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_YEAR)
} ?.let { metaData[FileMetaType.Year] = it }
val duration = retriever
retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION) .extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)
?.toLong() ?: 0 ?.toLongOrNull()
val d = DateUtils.formatElapsedTime((duration) / 1000) ?.let {
metaData.add(3, R.string.file_meta_duration to d) metaData[FileMetaType.Duration] =
DateUtils.formatElapsedTime((it) / 1000)
}
retriever.release() retriever.release()
} catch (e: RuntimeException) { } catch (e: RuntimeException) {
retriever.release() retriever.release()
} }
} }
mimeType.startsWith("video/") -> { mimeType.startsWith("video/") -> {
val retriever = MediaMetadataRetriever() val retriever = MediaMetadataRetriever()
try { try {
retriever.setDataSource(path) retriever.setDataSource(path)
val width = val width =
retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH) retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)
?.toLong() ?: 0 ?.toLongOrNull()
val height = val height =
retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT) retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)
?.toLong() ?: 0 ?.toLongOrNull()
metaData.add(R.string.file_meta_dimensions to "${width}x$height") if (width != null && height != null) {
metaData[FileMetaType.Dimensions] = "${width}x$height"
}
val duration = val duration =
retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION) retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)
?.toLong() ?: 0 ?.toLongOrNull()
val d = DateUtils.formatElapsedTime(duration / 1000) ?.let {
metaData.add(R.string.file_meta_duration to d) metaData[FileMetaType.Duration] =
DateUtils.formatElapsedTime((it) / 1000)
}
val loc = val loc =
retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_LOCATION) retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_LOCATION)
if (Geocoder.isPresent() && loc != null) { if (Geocoder.isPresent() && loc != null) {
@ -290,9 +307,15 @@ internal data class LocalFile(
loc.lastIndexOfAny(charArrayOf('+', '-')), loc.lastIndexOfAny(charArrayOf('+', '-')),
loc.indexOf('/') loc.indexOf('/')
).toDouble() ).toDouble()
val list = Geocoder(context).getFromLocation(lon, lat, 1) val list = try {
Geocoder(context).getFromLocation(lon, lat, 1)
} catch (e: IOException) {
null
} catch (e: IllegalArgumentException) {
null
}
if (list != null && list.size > 0) { if (list != null && list.size > 0) {
metaData.add(R.string.file_meta_location to list[0].formatToString()) metaData[FileMetaType.Location] = list[0].formatToString()
} }
} }
retriever.release() retriever.release()
@ -304,40 +327,48 @@ internal data class LocalFile(
retriever.release() retriever.release()
} }
} }
mimeType.startsWith("image/") -> { mimeType.startsWith("image/") -> {
val options = BitmapFactory.Options() val options = BitmapFactory.Options()
options.inJustDecodeBounds = true options.inJustDecodeBounds = true
BitmapFactory.decodeFile(path, options) BitmapFactory.decodeFile(path, options)
val width = options.outWidth val width = options.outWidth
val height = options.outHeight val height = options.outHeight
metaData.add(R.string.file_meta_dimensions to "${width}x$height") if (height >= 0 && width >= 0) {
metaData[FileMetaType.Dimensions] = "${width}x$height"
}
try { try {
val exif = ExifInterface(path) val exif = ExifInterface(path)
val loc = exif.latLong val loc = exif.latLong
if (loc != null && Geocoder.isPresent()) { if (loc != null && Geocoder.isPresent()) {
val list = Geocoder(context).getFromLocation(loc[0], loc[1], 1) val list = try {
Geocoder(context).getFromLocation(loc[0], loc[1], 1)
} catch (e: IllegalArgumentException) {
null
} catch (e: IOException) {
null
}
if (list != null && list.size > 0) { if (list != null && list.size > 0) {
metaData.add(R.string.file_meta_location to list[0].formatToString()) metaData[FileMetaType.Location] = list[0].formatToString()
} }
} }
} catch (_: IOException) { } catch (_: IOException) {
} }
} }
mimeType == "application/vnd.android.package-archive" -> { mimeType == "application/vnd.android.package-archive" -> {
val pkgInfo = context.packageManager.getPackageArchiveInfo(path, 0) val pkgInfo = context.packageManager.getPackageArchiveInfo(path, 0)
?: return metaData ?: return metaData.toImmutableMap()
metaData.add( metaData[FileMetaType.AppName] =
R.string.file_meta_app_name to pkgInfo.applicationInfo.loadLabel( pkgInfo.applicationInfo.loadLabel(context.packageManager).toString()
context.packageManager metaData[FileMetaType.AppPackageName] = pkgInfo.packageName
).toString() metaData[FileMetaType.AppVersion] = pkgInfo.versionName
) metaData[FileMetaType.AppMinSdk] =
metaData.add(R.string.file_meta_app_pkgname to pkgInfo.packageName) pkgInfo.applicationInfo.minSdkVersion.toString()
metaData.add(R.string.file_meta_app_version to pkgInfo.versionName)
metaData.add(R.string.file_meta_app_min_sdk to pkgInfo.applicationInfo.minSdkVersion.toString())
} }
} }
return metaData return metaData.toImmutableMap()
} }
} }

View File

@ -9,7 +9,9 @@ import de.mm20.launcher2.files.NextcloudFileSerializer
import de.mm20.launcher2.files.R import de.mm20.launcher2.files.R
import de.mm20.launcher2.ktx.tryStartActivity import de.mm20.launcher2.ktx.tryStartActivity
import de.mm20.launcher2.search.File import de.mm20.launcher2.search.File
import de.mm20.launcher2.search.FileMetaType
import de.mm20.launcher2.search.SearchableSerializer import de.mm20.launcher2.search.SearchableSerializer
import kotlinx.collections.immutable.ImmutableMap
internal data class NextcloudFile( internal data class NextcloudFile(
val fileId: Long, val fileId: Long,
@ -19,7 +21,7 @@ internal data class NextcloudFile(
override val size: Long, override val size: Long,
override val isDirectory: Boolean, override val isDirectory: Boolean,
val server: String, val server: String,
override val metaData: List<Pair<Int, String>>, override val metaData: ImmutableMap<FileMetaType, String>,
override val labelOverride: String? = null, override val labelOverride: String? = null,
) : File { ) : File {

View File

@ -3,6 +3,8 @@ package de.mm20.launcher2.files.providers
import de.mm20.launcher2.files.R import de.mm20.launcher2.files.R
import de.mm20.launcher2.nextcloud.NextcloudApiHelper import de.mm20.launcher2.nextcloud.NextcloudApiHelper
import de.mm20.launcher2.search.File import de.mm20.launcher2.search.File
import de.mm20.launcher2.search.FileMetaType
import kotlinx.collections.immutable.persistentMapOf
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlin.math.min import kotlin.math.min
@ -23,8 +25,8 @@ internal class NextcloudFileProvider(
size = it.size, size = it.size,
isDirectory = it.isDirectory, isDirectory = it.isDirectory,
server = server, server = server,
metaData = it.owner?.let { listOf(R.string.file_meta_owner to it) } metaData = it.owner?.let { persistentMapOf(FileMetaType.Owner to it) }
?: emptyList() ?: persistentMapOf()
) )
} }
} }

View File

@ -8,18 +8,20 @@ import de.mm20.launcher2.files.OneDriveFileSerializer
import de.mm20.launcher2.files.R import de.mm20.launcher2.files.R
import de.mm20.launcher2.ktx.tryStartActivity import de.mm20.launcher2.ktx.tryStartActivity
import de.mm20.launcher2.search.File import de.mm20.launcher2.search.File
import de.mm20.launcher2.search.FileMetaType
import de.mm20.launcher2.search.SearchableSerializer import de.mm20.launcher2.search.SearchableSerializer
import kotlinx.collections.immutable.ImmutableMap
internal data class OneDriveFile( internal data class OneDriveFile(
val fileId: String, val fileId: String,
override val label: String, override val label: String,
override val path: String, override val path: String,
override val mimeType: String, override val mimeType: String,
override val size: Long, override val size: Long,
override val isDirectory: Boolean, override val isDirectory: Boolean,
override val metaData: List<Pair<Int, String>>, override val metaData: ImmutableMap<FileMetaType, String>,
val webUrl: String, val webUrl: String,
override val labelOverride: String? = null, override val labelOverride: String? = null,
) : File { ) : File {
override fun overrideLabel(label: String): OneDriveFile { override fun overrideLabel(label: String): OneDriveFile {

View File

@ -8,7 +8,9 @@ import de.mm20.launcher2.files.OwncloudFileSerializer
import de.mm20.launcher2.files.R import de.mm20.launcher2.files.R
import de.mm20.launcher2.ktx.tryStartActivity import de.mm20.launcher2.ktx.tryStartActivity
import de.mm20.launcher2.search.File import de.mm20.launcher2.search.File
import de.mm20.launcher2.search.FileMetaType
import de.mm20.launcher2.search.SearchableSerializer import de.mm20.launcher2.search.SearchableSerializer
import kotlinx.collections.immutable.ImmutableMap
internal data class OwncloudFile( internal data class OwncloudFile(
val fileId: Long, val fileId: Long,
@ -18,7 +20,7 @@ internal data class OwncloudFile(
override val size: Long, override val size: Long,
override val isDirectory: Boolean, override val isDirectory: Boolean,
val server: String, val server: String,
override val metaData: List<Pair<Int, String>>, override val metaData: ImmutableMap<FileMetaType, String>,
override val labelOverride: String? = null, override val labelOverride: String? = null,
) : File { ) : File {

View File

@ -3,6 +3,8 @@ package de.mm20.launcher2.files.providers
import de.mm20.launcher2.files.R import de.mm20.launcher2.files.R
import de.mm20.launcher2.owncloud.OwncloudClient import de.mm20.launcher2.owncloud.OwncloudClient
import de.mm20.launcher2.search.File import de.mm20.launcher2.search.File
import de.mm20.launcher2.search.FileMetaType
import kotlinx.collections.immutable.persistentMapOf
internal class OwncloudFileProvider( internal class OwncloudFileProvider(
private val owncloudClient: OwncloudClient private val owncloudClient: OwncloudClient
@ -19,7 +21,8 @@ internal class OwncloudFileProvider(
size = it.size, size = it.size,
isDirectory = it.isDirectory, isDirectory = it.isDirectory,
server = server, server = server,
metaData = it.owner?.let { listOf(R.string.file_meta_owner to it) } ?: emptyList() metaData = it.owner?.let { persistentMapOf(FileMetaType.Owner to it) }
?: persistentMapOf()
) )
} }
} }