Fix for offline mode
This commit is contained in:
@@ -64,7 +64,8 @@ impl ThumbnailCache {
|
||||
image_type: &str,
|
||||
tag: &str,
|
||||
) -> Option<PathBuf> {
|
||||
let query = Query::with_params(
|
||||
// Primary lookup: exact (item_id, image_type, tag) match.
|
||||
let exact = Query::with_params(
|
||||
"SELECT file_path FROM thumbnails
|
||||
WHERE item_id = ? AND image_type = ? AND image_tag = ?",
|
||||
vec![
|
||||
@@ -74,12 +75,60 @@ impl ThumbnailCache {
|
||||
],
|
||||
);
|
||||
|
||||
let path_str: String = db.query_optional(query, |row| row.get(0)).await.ok()??;
|
||||
let path = PathBuf::from(&path_str);
|
||||
if let Ok(Some(path_str)) = db.query_optional(exact, |row| row.get::<_, String>(0)).await {
|
||||
let path = PathBuf::from(&path_str);
|
||||
if path.exists() {
|
||||
self.touch(&db, item_id, image_type, Some(tag)).await;
|
||||
return Some(path);
|
||||
}
|
||||
// File gone — drop the stale row and fall through to the tag-agnostic
|
||||
// lookup below (another cached image for this item may still exist).
|
||||
let _ = db.execute(Query::with_params(
|
||||
"DELETE FROM thumbnails WHERE item_id = ? AND image_type = ? AND image_tag = ?",
|
||||
vec![
|
||||
QueryParam::String(item_id.to_string()),
|
||||
QueryParam::String(image_type.to_string()),
|
||||
QueryParam::String(tag.to_string()),
|
||||
],
|
||||
)).await;
|
||||
}
|
||||
|
||||
// Fallback: any cached image for this item + type, newest first. The
|
||||
// `image_tag` is a cache-busting version, and callers don't always pass
|
||||
// the same tag the image was cached under — e.g. the mini player asks for
|
||||
// the album image using the *track's* primary_image_tag. Ignoring the tag
|
||||
// here lets those still resolve offline instead of hitting the server.
|
||||
let any_tag = Query::with_params(
|
||||
"SELECT file_path FROM thumbnails
|
||||
WHERE item_id = ? AND image_type = ?
|
||||
ORDER BY cached_at DESC LIMIT 1",
|
||||
vec![
|
||||
QueryParam::String(item_id.to_string()),
|
||||
QueryParam::String(image_type.to_string()),
|
||||
],
|
||||
);
|
||||
|
||||
let path_str: String = db.query_optional(any_tag, |row| row.get(0)).await.ok()??;
|
||||
let path = PathBuf::from(&path_str);
|
||||
if path.exists() {
|
||||
// Update last_accessed for LRU tracking
|
||||
let update_query = Query::with_params(
|
||||
self.touch(&db, item_id, image_type, None).await;
|
||||
Some(path)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Update `last_accessed` for LRU tracking. When `tag` is `Some`, scope to
|
||||
/// that exact row; when `None`, touch every row for the item + type.
|
||||
async fn touch(
|
||||
&self,
|
||||
db: &Arc<RusqliteService>,
|
||||
item_id: &str,
|
||||
image_type: &str,
|
||||
tag: Option<&str>,
|
||||
) {
|
||||
let query = match tag {
|
||||
Some(tag) => Query::with_params(
|
||||
"UPDATE thumbnails SET last_accessed = CURRENT_TIMESTAMP
|
||||
WHERE item_id = ? AND image_type = ? AND image_tag = ?",
|
||||
vec![
|
||||
@@ -87,23 +136,17 @@ impl ThumbnailCache {
|
||||
QueryParam::String(image_type.to_string()),
|
||||
QueryParam::String(tag.to_string()),
|
||||
],
|
||||
);
|
||||
let _ = db.execute(update_query).await;
|
||||
Some(path)
|
||||
} else {
|
||||
// Clean up stale database entry
|
||||
let delete_query = Query::with_params(
|
||||
"DELETE FROM thumbnails
|
||||
WHERE item_id = ? AND image_type = ? AND image_tag = ?",
|
||||
),
|
||||
None => Query::with_params(
|
||||
"UPDATE thumbnails SET last_accessed = CURRENT_TIMESTAMP
|
||||
WHERE item_id = ? AND image_type = ?",
|
||||
vec![
|
||||
QueryParam::String(item_id.to_string()),
|
||||
QueryParam::String(image_type.to_string()),
|
||||
QueryParam::String(tag.to_string()),
|
||||
],
|
||||
);
|
||||
let _ = db.execute(delete_query).await;
|
||||
None
|
||||
}
|
||||
),
|
||||
};
|
||||
let _ = db.execute(query).await;
|
||||
}
|
||||
|
||||
/// Save thumbnail to cache
|
||||
|
||||
Reference in New Issue
Block a user