coil icon indicating copy to clipboard operation
coil copied to clipboard

Support custom disk cache file naming strategies

Open xVemu opened this issue 2 years ago • 5 comments

Is your feature request related to a problem? Please describe. Thumbnail in share intent must have an image extension, otherwise it's not shown.

Code sample
@OptIn(ExperimentalCoilApi::class)
private suspend fun share(context: Context) = withContext(Dispatchers.IO) {
    val intent = Intent().apply {
        action = Intent.ACTION_SEND
        putExtra(Intent.EXTRA_TEXT, "someLink")
        putExtra(Intent.EXTRA_TITLE, "someTitle")
        type = "text/plain"
        flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
    }

    val request = ImageRequest.Builder(context)
        .data("https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png")
        .build()

    context.imageLoader.execute(request)

    val uri = context.imageLoader.diskCache?.openSnapshot("https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png")?.use { snapshot ->
        FileProvider.getUriForFile(
            context,
            "pl.vemu.zsme.fileprovider",
            snapshot.data.toFile()
        )
    }

    intent.clipData = ClipData(null, arrayOf("image/png"), ClipData.Item(uri))

    val shareIntent = Intent.createChooser(intent, "Share post")
    withContext(Dispatchers.Main) {
        context.startActivity(shareIntent)
    }
}

When I change snapshot.data.toFile() to a file, which is in the same directory, but has .png extension, everything works fine.

Describe the solution you'd like Add option in ImageLoader.Builder to preserve image extension in DiskCache.

xVemu avatar Nov 13 '23 22:11 xVemu

I think this is best handled by adding a filenameFactory (or similar) param to DiskCache.Builder so it's possible to set a custom DiskCache.Key -> String function for creating the file name. That said, if you're sharing an image from Coil's file cache I'd recommend copying it locally as the file can disappear at any time.

colinrtwhite avatar Nov 14 '23 06:11 colinrtwhite

I don't see anything like that, DiskCache.Builder only allows changing directory or fileSystem.

xVemu avatar Nov 14 '23 07:11 xVemu

Sorry, I was proposing a potential API as this doesn't exist yet. After thinking about this more we'd have to be careful adding this API as changing the filenameFactory's logic after files have already been added to the cache would corrupt the disk cache. I think we'd need to have migration/versioning support as well to make this safe.

colinrtwhite avatar Nov 15 '23 20:11 colinrtwhite

Workaround:

val uri = context.imageLoader.diskCache?.openSnapshot("https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png")?.use { snapshot ->
    val newFile = File.createTempFile("shareImage", ".png", File(context.cacheDir, "/image_cache"))

    snapshot.data.toFile().copyTo(newFile, true)
    FileProvider.getUriForFile(context, "pl.vemu.zsme.fileprovider", newFile)
}

xVemu avatar Feb 19 '24 23:02 xVemu

I think this is best handled by adding a filenameFactory (or similar) param to DiskCache.Builder so it's possible to set a custom DiskCache.Key -> String function for creating the file name. That said, if you're sharing an image from Coil's file cache I'd recommend copying it locally as the file can disappear at any time.

Any progress in adding filenameFactory?

titanseason avatar Aug 19 '24 02:08 titanseason