This commit is contained in:
xds
2026-02-24 12:04:17 +03:00
parent 1a7295aa77
commit a1d37ac517
8 changed files with 341 additions and 56 deletions

View File

@@ -592,6 +592,8 @@ const allPreviewImages = computed(() => {
for (const assetId of gen.result_list) {
images.push({
url: API_URL + '/assets/' + assetId,
assetId: assetId,
is_liked: gen.liked_assets?.includes(assetId),
genId: gen.id,
prompt: gen.prompt,
gen: gen
@@ -602,6 +604,25 @@ const allPreviewImages = computed(() => {
return images
})
const handleLiked = ({ id, is_liked }) => {
// Update local state in history
historyGenerations.value.forEach(gen => {
if (gen.id === id) {
gen.is_liked = is_liked
}
})
}
const toggleLike = async (gen) => {
if (!gen || !gen.id) return
try {
const response = await dataService.toggleLike(gen.id)
handleLiked({ id: gen.id, is_liked: response.is_liked })
} catch (e) {
console.error('Failed to toggle like', e)
}
}
const openImagePreview = (url) => {
const idx = allPreviewImages.value.findIndex(img => img.url === url)
previewIndex.value = idx >= 0 ? idx : 0
@@ -895,6 +916,12 @@ const confirmAddToAlbum = async () => {
<img v-if="child.result_list && child.result_list.length > 0"
:src="API_URL + '/assets/' + child.result_list[0] + '?thumbnail=true'"
class="w-full h-full object-cover" />
<!-- Child: Liked badge -->
<div v-if="child.is_liked"
class="absolute top-1 right-1 z-20 w-4 h-4 rounded-full bg-pink-500 shadow-lg flex items-center justify-center border border-pink-400">
<i class="pi pi-heart-fill text-white text-[6px]"></i>
</div>
<!-- Child: processing -->
<div v-else-if="['processing', 'starting', 'running'].includes(child.status)"
@@ -942,6 +969,10 @@ const confirmAddToAlbum = async () => {
<!-- Top right: edit, delete -->
<div class="flex justify-end items-start gap-0.5">
<Button :icon="child.is_liked ? 'pi pi-heart-fill' : 'pi pi-heart'" size="small"
class="!w-5 !h-5 !rounded-full !border-none !text-[8px] transition-colors"
:class="child.is_liked ? '!bg-pink-500 !text-white' : '!bg-white/20 !text-white hover:!bg-pink-500'"
@click.stop="toggleLike(child)" />
<Button icon="pi pi-pencil" size="small"
class="!w-5 !h-5 !rounded-full !bg-white/20 !border-none !text-white !text-[8px] hover:!bg-violet-500"
@click.stop="useResultAsAsset(child)" />
@@ -1000,6 +1031,12 @@ const confirmAddToAlbum = async () => {
class="w-full h-full object-cover cursor-pointer"
@click.stop="isSelectMode ? toggleImageSelection(item.result_list[0]) : openImagePreview(API_URL + '/assets/' + item.result_list[0])" />
<!-- Liked badge for single item -->
<div v-if="item.is_liked"
class="absolute top-2 right-2 z-20 w-6 h-6 rounded-full bg-pink-500 shadow-lg flex items-center justify-center border border-pink-400">
<i class="pi pi-heart-fill text-white text-[10px]"></i>
</div>
<!-- FAILED: error display -->
<div v-else-if="item.status === 'failed'"
class="w-full h-full flex flex-col items-center justify-between p-3 text-center bg-red-500/10 border border-red-500/20 relative group">
@@ -1064,6 +1101,10 @@ const confirmAddToAlbum = async () => {
<div
class="flex justify-end items-start translate-y-[-10px] group-hover:translate-y-0 transition-transform duration-200 w-full z-10">
<div class="flex gap-1">
<Button :icon="item.is_liked ? 'pi pi-heart-fill' : 'pi pi-heart'"
class="!w-6 !h-6 !rounded-full !border-none !text-[10px] transition-colors"
:class="item.is_liked ? '!bg-pink-500 !text-white' : '!bg-white/20 !text-white hover:!bg-pink-500'"
@click.stop="toggleLike(item)" />
<Button v-if="item.result_list && item.result_list.length > 0"
icon="pi pi-pencil" v-tooltip.left="'Edit (Use Result)'"
class="!w-6 !h-6 !rounded-full !bg-white/20 !border-none !text-white text-[10px] hover:!bg-violet-500"
@@ -1370,6 +1411,7 @@ const confirmAddToAlbum = async () => {
@reuse-prompt="reusePrompt"
@reuse-asset="reuseAsset"
@use-result-as-asset="useResultAsAsset"
@liked="handleLiked"
/>
<Dialog v-model:visible="isAssetPickerVisible" modal header="Select Assets"