Add deferred plugin storage strategy
This commit is contained in:
parent
ef1d6c70e8
commit
2efc159741
@ -21,5 +21,13 @@ enum class StorageStrategy {
|
||||
* Use this strategy if your plugin needs to perform network requests to retrieve search
|
||||
* results and if you don't want to implement a cache for search results.
|
||||
*/
|
||||
StoreCopy;
|
||||
StoreCopy,
|
||||
|
||||
/**
|
||||
* The launcher stores all relevant information in its own internal database, like [StoreCopy].
|
||||
* A fresh copy is fetched from the plugin provider when the user opens the search result's
|
||||
* detail view. This allows the plugin provider to update the search result at a later point in
|
||||
* time, without the time constraints of [StoreReference].
|
||||
*/
|
||||
Deferred,
|
||||
}
|
||||
@ -5,6 +5,7 @@ import android.net.Uri
|
||||
import android.provider.MediaStore
|
||||
import androidx.core.database.getStringOrNull
|
||||
import de.mm20.launcher2.crashreporter.CrashReporter
|
||||
import de.mm20.launcher2.files.providers.DeferredFile
|
||||
import de.mm20.launcher2.files.providers.GDriveFile
|
||||
import de.mm20.launcher2.files.providers.LocalFile
|
||||
import de.mm20.launcher2.files.providers.NextcloudFile
|
||||
@ -22,6 +23,7 @@ import de.mm20.launcher2.search.FileMetaType
|
||||
import de.mm20.launcher2.search.SavableSearchable
|
||||
import de.mm20.launcher2.search.SearchableDeserializer
|
||||
import de.mm20.launcher2.search.SearchableSerializer
|
||||
import de.mm20.launcher2.search.UpdateResult
|
||||
import kotlinx.collections.immutable.persistentMapOf
|
||||
import kotlinx.collections.immutable.toImmutableMap
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
@ -331,7 +333,7 @@ internal class PluginFileSerializer(
|
||||
"thumbnailUri" to searchable.thumbnailUri?.toString(),
|
||||
"isDirectory" to searchable.isDirectory,
|
||||
"authority" to searchable.authority,
|
||||
"strategy" to "copy",
|
||||
"strategy" to if (searchable.storageStrategy == StorageStrategy.StoreCopy) "copy" else "deferred",
|
||||
).toString()
|
||||
}
|
||||
}
|
||||
@ -344,14 +346,22 @@ internal class PluginFileSerializer(
|
||||
internal class PluginFileDeserializer(
|
||||
private val context: Context,
|
||||
private val pluginRepository: PluginRepository,
|
||||
): SearchableDeserializer {
|
||||
) : SearchableDeserializer {
|
||||
override suspend fun deserialize(serialized: String): SavableSearchable? {
|
||||
val jsonObject = JSONObject(serialized)
|
||||
|
||||
return if (jsonObject.optString("strategy", "ref") == "ref") {
|
||||
getByRef(jsonObject)
|
||||
} else {
|
||||
getByCopy(jsonObject)
|
||||
return when (jsonObject.optString("strategy", "copy")) {
|
||||
"ref" -> {
|
||||
getByRef(jsonObject)
|
||||
}
|
||||
|
||||
"deferred" -> {
|
||||
getDeferred(jsonObject)
|
||||
}
|
||||
|
||||
else -> {
|
||||
getByCopy(jsonObject)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -368,6 +378,33 @@ internal class PluginFileDeserializer(
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private fun getDeferred(obj: JSONObject): File? {
|
||||
val cached = getByCopy(obj) ?: return null
|
||||
val timestamp = obj.optLong("timestamp", 0L)
|
||||
return DeferredFile(
|
||||
cachedFile = cached as PluginFile,
|
||||
timestamp = timestamp,
|
||||
updatedSelf = {
|
||||
val plugin = pluginRepository.get(cached.authority).firstOrNull()
|
||||
?: return@DeferredFile UpdateResult.PermanentlyUnavailable()
|
||||
if (!plugin.enabled) return@DeferredFile UpdateResult.PermanentlyUnavailable()
|
||||
val provider = PluginFileProvider(context, cached.authority)
|
||||
try {
|
||||
val file = provider.getFile(cached.id)
|
||||
if (file == null) {
|
||||
UpdateResult.PermanentlyUnavailable()
|
||||
} else {
|
||||
UpdateResult.Success(file)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
CrashReporter.logException(e)
|
||||
UpdateResult.TemporarilyUnavailable(e)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun getByCopy(obj: JSONObject): File? {
|
||||
try {
|
||||
val uri = obj.getString("uri")
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
package de.mm20.launcher2.files.providers
|
||||
|
||||
import de.mm20.launcher2.search.File
|
||||
import de.mm20.launcher2.search.UpdatableSearchable
|
||||
import de.mm20.launcher2.search.UpdateResult
|
||||
|
||||
class DeferredFile(
|
||||
cachedFile: File,
|
||||
override val timestamp: Long,
|
||||
override var updatedSelf: (suspend () -> UpdateResult<File>)? = null,
|
||||
) : File by cachedFile, UpdatableSearchable<File>
|
||||
Loading…
x
Reference in New Issue
Block a user