This commit is contained in:
xds
2026-02-12 17:54:14 +03:00
parent 2eda7526ef
commit 0406b175e9
2 changed files with 69 additions and 11 deletions

View File

@@ -54,6 +54,7 @@ const historyFirst = ref(0)
const isSettingsVisible = ref(false)
const isSubmitting = ref(false)
const activeOverlayId = ref(null) // For mobile tap-to-show overlay
const filterCharacter = ref(null) // Character filter for gallery
// Options
const qualityOptions = ref([
@@ -120,6 +121,14 @@ watch([prompt, selectedCharacter, selectedAssets, quality, aspectRatio, sendToTe
saveSettings()
}, { deep: true })
// Watcher for character filter — reload history when filter changes
watch(filterCharacter, async () => {
historyGenerations.value = []
historyTotal.value = 0
historyFirst.value = 0
await refreshHistory()
})
// --- Data Loading ---
const loadData = async () => {
@@ -127,7 +136,7 @@ const loadData = async () => {
const [charsRes, assetsRes, historyRes] = await Promise.all([
dataService.getCharacters(), // Assuming this exists and returns list
dataService.getAssets(100, 0, 'all'), // Load a batch of assets
aiService.getGenerations(historyRows.value, historyFirst.value)
aiService.getGenerations(historyRows.value, historyFirst.value, filterCharacter.value?.id)
])
// Characters
@@ -197,7 +206,7 @@ const loadData = async () => {
const refreshHistory = async () => {
try {
const response = await aiService.getGenerations(historyRows.value, 0)
const response = await aiService.getGenerations(historyRows.value, 0, filterCharacter.value?.id)
if (response && response.generations) {
// Update existing items and add new ones at the top
const newGenerations = []
@@ -352,7 +361,7 @@ const loadMoreHistory = async () => {
try {
const nextOffset = historyGenerations.value.length
const response = await aiService.getGenerations(historyRows.value, nextOffset)
const response = await aiService.getGenerations(historyRows.value, nextOffset, filterCharacter.value?.id)
if (response && response.generations) {
const newGenerations = response.generations.filter(gen =>
@@ -602,6 +611,32 @@ const confirmAddToAlbum = async () => {
<span class="text-xs text-slate-500 border-l border-white/10 pl-3">History</span>
</div>
<div class="flex items-center gap-2">
<Dropdown v-model="filterCharacter" :options="characters" optionLabel="name"
placeholder="All Characters" showClear
class="!w-48 !bg-slate-800/60 !border-white/10 !text-white !rounded-xl !text-sm" :pt="{
root: { class: '!bg-slate-800/60 !h-8' },
input: { class: '!text-white !text-xs !py-1 !px-2' },
trigger: { class: '!text-slate-400 !w-6' },
panel: { class: '!bg-slate-800 !border-white/10' },
item: { class: '!text-slate-300 hover:!bg-white/10 hover:!text-white !text-xs !py-1.5' },
clearIcon: { class: '!text-slate-400 hover:!text-white' }
}">
<template #value="slotProps">
<div v-if="slotProps.value" class="flex items-center gap-1.5">
<img v-if="slotProps.value.avatar_image" :src="API_URL + slotProps.value.avatar_image"
class="w-5 h-5 rounded-full object-cover" />
<span class="text-xs">{{ slotProps.value.name }}</span>
</div>
<span v-else class="text-xs text-slate-400">{{ slotProps.placeholder }}</span>
</template>
<template #option="slotProps">
<div class="flex items-center gap-2">
<img v-if="slotProps.option.avatar_image" :src="API_URL + slotProps.option.avatar_image"
class="w-6 h-6 rounded-full object-cover" />
<span>{{ slotProps.option.name }}</span>
</div>
</template>
</Dropdown>
<Button icon="pi pi-refresh" @click="refreshHistory" rounded text
class="!text-slate-400 hover:!bg-white/10 !w-8 !h-8 md:hidden" />
<Button icon="pi pi-cog" @click="isSettingsVisible = true" rounded text
@@ -645,7 +680,7 @@ const confirmAddToAlbum = async () => {
<i class="pi pi-spin pi-spinner text-violet-500 text-xl mb-2 relative z-10"></i>
<span class="text-[10px] text-violet-300/70 relative z-10 capitalize">{{ gen.status
}}...</span>
}}...</span>
<span v-if="gen.progress"
class="text-[9px] text-violet-400/60 font-mono mt-1 relative z-10">{{
gen.progress }}%</span>
@@ -790,7 +825,8 @@ const confirmAddToAlbum = async () => {
class="flex items-center gap-2 mt-2 px-1 animate-in fade-in slide-in-from-top-1">
<Checkbox v-model="useProfileImage" :binary="true" inputId="use-profile-img" />
<label for="use-profile-img"
class="text-xs text-slate-300 cursor-pointer select-none">Use Character
class="text-xs text-slate-300 cursor-pointer select-none">Use
Character
Photo</label>
</div>
</div>
@@ -801,7 +837,8 @@ const confirmAddToAlbum = async () => {
<div @click="openAssetPicker"
class="w-full bg-slate-800 border border-white/10 rounded-xl p-3 min-h-[46px] cursor-pointer hover:bg-slate-700/50 transition-colors flex flex-wrap gap-2">
<span v-if="selectedAssets.length === 0"
class="text-slate-400 text-sm py-0.5">Select Assets</span>
class="text-slate-400 text-sm py-0.5">Select
Assets</span>
<div v-for="asset in selectedAssets" :key="asset.id"
class="px-2 py-1 bg-violet-600/30 border border-violet-500/30 text-violet-200 text-xs rounded-md flex items-center gap-2 animate-in fade-in zoom-in duration-200"
@click.stop>