fixes
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
<script setup>
|
||||
import { ref, onMounted, onBeforeUnmount, watch, computed } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { dataService } from '../services/dataService'
|
||||
import { aiService } from '../services/aiService'
|
||||
import { postService } from '../services/postService'
|
||||
import {computed, onBeforeUnmount, onMounted, ref, watch} from 'vue'
|
||||
import {useRouter} from 'vue-router'
|
||||
import {dataService} from '../services/dataService'
|
||||
import {aiService} from '../services/aiService'
|
||||
import {postService} from '../services/postService'
|
||||
import Button from 'primevue/button'
|
||||
import Textarea from 'primevue/textarea'
|
||||
import InputText from 'primevue/inputtext'
|
||||
@@ -11,15 +11,13 @@ import Dialog from 'primevue/dialog'
|
||||
import Checkbox from 'primevue/checkbox'
|
||||
import Dropdown from 'primevue/dropdown'
|
||||
import DatePicker from 'primevue/datepicker'
|
||||
import MultiSelect from 'primevue/multiselect'
|
||||
import ProgressSpinner from 'primevue/progressspinner'
|
||||
import ProgressBar from 'primevue/progressbar'
|
||||
import Message from 'primevue/message'
|
||||
import Tag from 'primevue/tag'
|
||||
|
||||
import Skeleton from 'primevue/skeleton'
|
||||
import { useAlbumStore } from '../stores/albums'
|
||||
import { useToast } from 'primevue/usetoast'
|
||||
import {useAlbumStore} from '../stores/albums'
|
||||
import {useToast} from 'primevue/usetoast'
|
||||
import Toast from 'primevue/toast'
|
||||
import GenerationPreviewModal from '../components/GenerationPreviewModal.vue'
|
||||
|
||||
const router = useRouter()
|
||||
const API_URL = import.meta.env.VITE_API_URL
|
||||
@@ -211,10 +209,16 @@ const qualityOptions = ref([
|
||||
{ key: 'FOURK', value: '4K' }
|
||||
])
|
||||
const aspectRatioOptions = ref([
|
||||
{ key: "NINESIXTEEN", value: "9:16" },
|
||||
{ key: "FOURTHREE", value: "4:3" },
|
||||
{ key: "ONEONE", value: "1:1" },
|
||||
{ key: "TWOTHREE", value: "2:3" },
|
||||
{ key: "THREETWO", value: "3:2" },
|
||||
{ key: "THREEFOUR", value: "3:4" },
|
||||
{ key: "SIXTEENNINE", value: "16:9" }
|
||||
{ key: "FOURTHREE", value: "4:3" },
|
||||
{ key: "FOURFIVE", value: "4:5" },
|
||||
{ key: "FIVEFOUR", value: "5:4" },
|
||||
{ key: "NINESIXTEEN", value: "9:16" },
|
||||
{ key: "SIXTEENNINE", value: "16:9" },
|
||||
{ key: "TWENTYONENINE", value: "21:9" }
|
||||
])
|
||||
|
||||
// --- Persistence ---
|
||||
@@ -589,7 +593,8 @@ const allPreviewImages = computed(() => {
|
||||
images.push({
|
||||
url: API_URL + '/assets/' + assetId,
|
||||
genId: gen.id,
|
||||
prompt: gen.prompt
|
||||
prompt: gen.prompt,
|
||||
gen: gen
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -598,48 +603,11 @@ const allPreviewImages = computed(() => {
|
||||
})
|
||||
|
||||
const openImagePreview = (url) => {
|
||||
// Find index of this image in the flat list
|
||||
const idx = allPreviewImages.value.findIndex(img => img.url === url)
|
||||
previewIndex.value = idx >= 0 ? idx : 0
|
||||
previewImage.value = allPreviewImages.value[previewIndex.value] || { url }
|
||||
isImagePreviewVisible.value = true
|
||||
}
|
||||
|
||||
const navigatePreview = (direction) => {
|
||||
const images = allPreviewImages.value
|
||||
if (images.length === 0) return
|
||||
let newIndex = previewIndex.value + direction
|
||||
if (newIndex < 0) newIndex = images.length - 1
|
||||
if (newIndex >= images.length) newIndex = 0
|
||||
previewIndex.value = newIndex
|
||||
previewImage.value = images[newIndex]
|
||||
}
|
||||
|
||||
const onPreviewKeydown = (e) => {
|
||||
if (!isImagePreviewVisible.value) return
|
||||
if (e.key === 'ArrowLeft') {
|
||||
e.preventDefault()
|
||||
navigatePreview(-1)
|
||||
} else if (e.key === 'ArrowRight') {
|
||||
e.preventDefault()
|
||||
navigatePreview(1)
|
||||
} else if (e.key === 'Escape') {
|
||||
isImagePreviewVisible.value = false
|
||||
}
|
||||
}
|
||||
|
||||
watch(isImagePreviewVisible, (visible) => {
|
||||
if (visible) {
|
||||
window.addEventListener('keydown', onPreviewKeydown)
|
||||
} else {
|
||||
window.removeEventListener('keydown', onPreviewKeydown)
|
||||
}
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('keydown', onPreviewKeydown)
|
||||
})
|
||||
|
||||
const reusePrompt = (gen) => {
|
||||
if (gen.prompt) {
|
||||
prompt.value = gen.prompt
|
||||
@@ -1392,44 +1360,15 @@ const confirmAddToAlbum = async () => {
|
||||
|
||||
|
||||
|
||||
<Dialog v-model:visible="isImagePreviewVisible" modal dismissableMask
|
||||
:style="{ width: '95vw', maxWidth: '1100px', background: 'transparent', boxShadow: 'none' }"
|
||||
:pt="{ root: { class: '!bg-transparent !border-none !shadow-none' }, header: { class: '!hidden' }, content: { class: '!bg-transparent !p-0' } }">
|
||||
<div class="relative flex items-center justify-center" @click.self="isImagePreviewVisible = false">
|
||||
|
||||
<!-- Previous Button -->
|
||||
<Button v-if="allPreviewImages.length > 1" icon="pi pi-chevron-left" @click.stop="navigatePreview(-1)"
|
||||
rounded text
|
||||
class="!absolute left-2 top-1/2 -translate-y-1/2 z-20 !text-white !bg-black/50 hover:!bg-black/70 !w-12 !h-12 !rounded-full !border !border-white/20 backdrop-blur-sm transition-all hover:!scale-110" />
|
||||
|
||||
<!-- Image -->
|
||||
<img v-if="previewImage" :src="previewImage.url"
|
||||
class="max-w-full max-h-[85vh] object-contain rounded-xl shadow-2xl select-none"
|
||||
draggable="false" />
|
||||
|
||||
<!-- Next Button -->
|
||||
<Button v-if="allPreviewImages.length > 1" icon="pi pi-chevron-right" @click.stop="navigatePreview(1)"
|
||||
rounded text
|
||||
class="!absolute right-2 top-1/2 -translate-y-1/2 z-20 !text-white !bg-black/50 hover:!bg-black/70 !w-12 !h-12 !rounded-full !border !border-white/20 backdrop-blur-sm transition-all hover:!scale-110" />
|
||||
|
||||
<!-- Close Button -->
|
||||
<Button icon="pi pi-times" @click="isImagePreviewVisible = false" rounded text
|
||||
class="!absolute -top-4 -right-4 z-20 !text-white !bg-black/50 hover:!bg-black/70 !w-10 !h-10" />
|
||||
|
||||
<!-- Counter -->
|
||||
<div v-if="allPreviewImages.length > 1"
|
||||
class="absolute bottom-4 left-1/2 -translate-x-1/2 z-20 bg-black/60 backdrop-blur-sm text-white text-sm font-mono px-4 py-1.5 rounded-full border border-white/10">
|
||||
{{ previewIndex + 1 }} / {{ allPreviewImages.length }}
|
||||
</div>
|
||||
|
||||
<!-- Prompt (click to copy) -->
|
||||
<div v-if="previewImage?.prompt"
|
||||
class="absolute bottom-14 left-1/2 -translate-x-1/2 z-20 bg-black/60 backdrop-blur-sm text-white/80 text-xs px-4 py-2 rounded-xl border border-white/10 max-w-md text-center line-clamp-2 cursor-pointer hover:bg-black/80 hover:border-white/20 transition-all"
|
||||
v-tooltip.top="'Click to copy'" @click.stop="navigator.clipboard.writeText(previewImage.prompt)">
|
||||
{{ previewImage.prompt }}
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
<GenerationPreviewModal
|
||||
v-model:visible="isImagePreviewVisible"
|
||||
:preview-images="allPreviewImages"
|
||||
:initial-index="previewIndex"
|
||||
:api-url="API_URL"
|
||||
@reuse-prompt="reusePrompt"
|
||||
@reuse-asset="reuseAsset"
|
||||
@use-result-as-asset="useResultAsAsset"
|
||||
/>
|
||||
|
||||
<Dialog v-model:visible="isAssetPickerVisible" modal header="Select Assets"
|
||||
:style="{ width: '80vw', maxWidth: '900px' }"
|
||||
|
||||
Reference in New Issue
Block a user