Many improvemtns and fixes related to decoupling of svelte and rust on android.
🏗️ Build and Test JellyTau / Run Tests (push) Failing after 18s
🏗️ Build and Test JellyTau / Build Android APK (push) Has been skipped
Traceability Validation / Check Requirement Traces (push) Failing after 2s

This commit is contained in:
2026-02-28 19:50:47 +01:00
parent 07f3bf04ca
commit e8e37649fa
53 changed files with 2309 additions and 792 deletions
+13 -37
View File
@@ -1,7 +1,7 @@
<script lang="ts">
import type { MediaItem, Library } from "$lib/api/types";
import { auth } from "$lib/stores/auth";
import { downloads } from "$lib/stores/downloads";
import CachedImage from "$lib/components/common/CachedImage.svelte";
interface Props {
item: MediaItem | Library;
@@ -13,9 +13,6 @@
let { item, size = "medium", showProgress = false, showDownloadStatus = true, onclick }: Props = $props();
// Image URL state - loaded asynchronously
let imageUrl = $state<string>("");
// Check if this item is downloaded
const downloadInfo = $derived(
Object.values($downloads.downloads).find((d) => d.itemId === item.id)
@@ -42,26 +39,11 @@
return "aspect-video";
});
// Load image URL asynchronously from backend
async function loadImageUrl(): Promise<void> {
try {
const repo = auth.getRepository();
const maxWidth = size === "large" ? 400 : size === "medium" ? 300 : 200;
const tag = "primaryImageTag" in item ? item.primaryImageTag : ("imageTag" in item ? item.imageTag : undefined);
const imageTag = $derived(
"primaryImageTag" in item ? item.primaryImageTag : ("imageTag" in item ? item.imageTag : undefined)
);
imageUrl = await repo.getImageUrl(item.id, "Primary", {
maxWidth,
tag,
});
} catch {
imageUrl = "";
}
}
// Load image URL whenever item or size changes
$effect(() => {
loadImageUrl();
});
const maxWidth = $derived(size === "large" ? 400 : size === "medium" ? 300 : 200);
const progress = $derived(() => {
if (!showProgress || !("userData" in item) || !item.userData || !item.runTimeTicks) {
@@ -96,20 +78,14 @@
{onclick}
>
<div class="relative {aspectRatio()} w-full rounded-lg overflow-hidden bg-[var(--color-surface)] shadow-md group-hover/card:shadow-2xl transition-shadow duration-200">
{#if imageUrl}
<img
src={imageUrl}
alt={item.name}
class="w-full h-full object-cover transition-transform duration-300 group-hover/card:scale-110"
loading="lazy"
/>
{:else}
<div class="w-full h-full flex items-center justify-center text-gray-600">
<svg class="w-12 h-12" fill="currentColor" viewBox="0 0 24 24">
<path d="M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-8 12.5v-9l6 4.5-6 4.5z"/>
</svg>
</div>
{/if}
<CachedImage
itemId={item.id}
imageType="Primary"
tag={imageTag}
maxWidth={maxWidth}
alt={item.name}
class="w-full h-full object-cover transition-transform duration-300 group-hover/card:scale-110"
/>
<!-- Hover overlay with smooth gradient -->
<div class="absolute inset-0 bg-gradient-to-t from-black/60 via-black/0 to-black/0 opacity-0 group-hover/card:opacity-100 transition-opacity duration-300 flex items-center justify-center">