+ env
This commit is contained in:
@@ -104,52 +104,48 @@ const navItems = computed(() => {
|
|||||||
<div class="contents">
|
<div class="contents">
|
||||||
<!-- Sidebar (Desktop -> Top Bar) -->
|
<!-- Sidebar (Desktop -> Top Bar) -->
|
||||||
<nav
|
<nav
|
||||||
class="hidden md:flex glass-panel w-[calc(100%-2rem)] mx-4 mt-4 mb-2 flex-row items-center px-8 py-3 rounded-2xl z-40 border border-white/5 bg-slate-900/50 backdrop-blur-md shrink-0 justify-between">
|
class="hidden md:flex glass-panel w-[calc(100%-2rem)] mx-4 mt-2 mb-1 flex-row items-center px-4 py-1.5 rounded-xl z-40 border border-white/5 bg-slate-900/50 backdrop-blur-md shrink-0 justify-between">
|
||||||
|
|
||||||
<!-- Logo -->
|
<!-- Logo -->
|
||||||
<img src="/web-app-manifest-512x512.png" alt="Logo"
|
<img src="/web-app-manifest-512x512.png" alt="Logo"
|
||||||
class="w-10 h-10 rounded-xl shadow-lg shadow-violet-500/20 shrink-0" />
|
class="w-7 h-7 rounded-lg shadow-lg shadow-violet-500/20 shrink-0" />
|
||||||
|
|
||||||
<!-- Project Switcher -->
|
<!-- Project Switcher -->
|
||||||
<div class="hidden lg:block ml-4 relative">
|
<div class="hidden lg:block ml-2 relative">
|
||||||
<button @click="isProjectMenuOpen = !isProjectMenuOpen"
|
<button @click="isProjectMenuOpen = !isProjectMenuOpen"
|
||||||
class="flex items-center gap-2 px-3 py-1.5 rounded-lg hover:bg-white/5 transition-colors text-slate-400 hover:text-slate-200">
|
class="flex items-center gap-1.5 px-2 py-1 rounded-lg hover:bg-white/5 transition-colors text-slate-400 hover:text-slate-200 text-xs">
|
||||||
<i v-if="selectedProject" class="pi pi-folder text-violet-400"></i>
|
<i v-if="selectedProject" class="pi pi-folder text-violet-400 text-[10px]"></i>
|
||||||
<i v-else class="pi pi-user"></i>
|
<i v-else class="pi pi-user text-[10px]"></i>
|
||||||
|
|
||||||
<span class="max-w-[150px] truncate font-medium">
|
<span class="max-w-[120px] truncate font-medium">
|
||||||
{{ selectedProject ? getProjectName(selectedProject) : 'Personal Workspace' }}
|
{{ selectedProject ? getProjectName(selectedProject) : 'Personal' }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<i class="pi pi-chevron-down text-xs ml-1 opacity-50"></i>
|
<i class="pi pi-chevron-down text-[8px] opacity-50"></i>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- Custom Dropdown Menu -->
|
<!-- Custom Dropdown Menu -->
|
||||||
<div v-if="isProjectMenuOpen"
|
<div v-if="isProjectMenuOpen"
|
||||||
class="absolute top-full left-0 mt-2 w-56 bg-slate-900 border border-white/10 shadow-xl rounded-xl overflow-hidden z-50 py-1">
|
class="absolute top-full left-0 mt-1 w-48 bg-slate-900 border border-white/10 shadow-xl rounded-lg overflow-hidden z-50 py-1">
|
||||||
|
|
||||||
<!-- Personal Workspace Option -->
|
<!-- Personal Workspace Option -->
|
||||||
<div @click="selectProject(null)"
|
<div @click="selectProject(null)"
|
||||||
class="flex items-center gap-3 px-4 py-3 hover:bg-white/5 cursor-pointer transition-colors"
|
class="flex items-center gap-2 px-3 py-2 hover:bg-white/5 cursor-pointer transition-colors text-xs"
|
||||||
:class="{ 'text-violet-400 bg-white/5': !selectedProject, 'text-slate-300': selectedProject }">
|
:class="{ 'text-violet-400 bg-white/5': !selectedProject, 'text-slate-300': selectedProject }">
|
||||||
<i class="pi pi-user"></i>
|
<i class="pi pi-user text-[10px]"></i>
|
||||||
<span class="font-medium">Personal Workspace</span>
|
<span class="font-medium">Personal Workspace</span>
|
||||||
<i v-if="!selectedProject" class="pi pi-check ml-auto text-sm"></i>
|
<i v-if="!selectedProject" class="pi pi-check ml-auto text-[10px]"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="h-px bg-white/5 my-1"></div>
|
<div class="h-px bg-white/5 my-1"></div>
|
||||||
|
|
||||||
<!-- Project Options -->
|
<!-- Project Options -->
|
||||||
<div v-for="project in projects" :key="project.id" @click="selectProject(project.id)"
|
<div v-for="project in projects" :key="project.id" @click="selectProject(project.id)"
|
||||||
class="flex items-center gap-3 px-4 py-3 hover:bg-white/5 cursor-pointer transition-colors"
|
class="flex items-center gap-2 px-3 py-2 hover:bg-white/5 cursor-pointer transition-colors text-xs"
|
||||||
:class="{ 'text-violet-400 bg-white/5': selectedProject === project.id, 'text-slate-300': selectedProject !== project.id }">
|
:class="{ 'text-violet-400 bg-white/5': selectedProject === project.id, 'text-slate-300': selectedProject !== project.id }">
|
||||||
<i class="pi pi-folder"></i>
|
<i class="pi pi-folder text-[10px]"></i>
|
||||||
<span class="truncate">{{ project.name }}</span>
|
<span class="truncate">{{ project.name }}</span>
|
||||||
<i v-if="selectedProject === project.id" class="pi pi-check ml-auto text-sm"></i>
|
<i v-if="selectedProject === project.id" class="pi pi-check ml-auto text-[10px]"></i>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-if="projects.length === 0" class="px-4 py-3 text-slate-500 text-sm font-italic">
|
|
||||||
No projects found
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -159,33 +155,33 @@ const navItems = computed(() => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Nav Items -->
|
<!-- Nav Items -->
|
||||||
<div class="flex flex-row gap-2 items-center justify-center flex-1 mx-8">
|
<div class="flex flex-row gap-1 items-center justify-center flex-1 mx-4">
|
||||||
<div v-for="item in navItems" :key="item.path" :class="[
|
<div v-for="item in navItems" :key="item.path" :class="[
|
||||||
'px-4 py-2 flex items-center gap-2 rounded-xl cursor-pointer transition-all duration-300',
|
'px-3 py-1 flex items-center gap-1.5 rounded-lg cursor-pointer transition-all duration-300',
|
||||||
isActive(item.path)
|
isActive(item.path)
|
||||||
? 'bg-white/10 text-slate-50 shadow-inner'
|
? 'bg-white/10 text-slate-50 shadow-inner'
|
||||||
: 'text-slate-400 hover:bg-white/5 hover:text-slate-50'
|
: 'text-slate-400 hover:bg-white/5 hover:text-slate-50'
|
||||||
]" @click="router.push(item.path)" v-tooltip.bottom="item.tooltip">
|
]" @click="router.push(item.path)" v-tooltip.bottom="item.tooltip">
|
||||||
<span class="text-xl">{{ item.icon }}</span>
|
<span class="text-base">{{ item.icon }}</span>
|
||||||
<span class="text-sm font-medium hidden lg:block">{{ item.tooltip }}</span>
|
<span class="text-[11px] font-medium hidden lg:block">{{ item.tooltip }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Right Actions -->
|
<!-- Right Actions -->
|
||||||
<div class="flex items-center gap-4 shrink-0">
|
<div class="flex items-center gap-3 shrink-0">
|
||||||
<!-- Usage Stat -->
|
<!-- Usage Stat -->
|
||||||
<div v-if="usageCost > 0" class="hidden xl:flex flex-col items-end mr-2">
|
<div v-if="usageCost > 0" class="hidden xl:flex flex-col items-end mr-1">
|
||||||
<span class="text-[10px] font-bold text-slate-500 uppercase tracking-tighter">Usage</span>
|
<span class="text-[8px] font-bold text-slate-500 uppercase tracking-tighter">Usage</span>
|
||||||
<span class="text-sm font-bold text-violet-400">${{ usageCost.toFixed(2) }}</span>
|
<span class="text-xs font-bold text-violet-400">${{ usageCost.toFixed(2) }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div @click="handleLogout"
|
<div @click="handleLogout"
|
||||||
class="w-10 h-10 rounded-xl bg-red-500/10 text-red-400 flex items-center justify-center cursor-pointer hover:bg-red-500/20 transition-all font-bold"
|
class="w-7 h-7 rounded-lg bg-red-500/10 text-red-400 flex items-center justify-center cursor-pointer hover:bg-red-500/20 transition-all font-bold"
|
||||||
v-tooltip.bottom="'Logout'">
|
v-tooltip.bottom="'Logout'">
|
||||||
<i class="pi pi-power-off"></i>
|
<i class="pi pi-power-off text-xs"></i>
|
||||||
</div>
|
</div>
|
||||||
<!-- Profile Avatar Placeholder -->
|
<!-- Profile Avatar Placeholder -->
|
||||||
<div class="w-10 h-10 rounded-full bg-slate-800 border-2 border-violet-600 flex items-center justify-center font-bold text-slate-50 cursor-pointer hover:scale-105 transition-all"
|
<div class="w-7 h-7 rounded-full bg-slate-800 border-2 border-violet-600 flex items-center justify-center font-bold text-slate-50 cursor-pointer hover:scale-105 transition-all text-xs"
|
||||||
title="Profile">
|
title="Profile">
|
||||||
U
|
U
|
||||||
</div>
|
</div>
|
||||||
@@ -194,14 +190,14 @@ const navItems = computed(() => {
|
|||||||
|
|
||||||
<!-- Mobile Bottom Nav -->
|
<!-- Mobile Bottom Nav -->
|
||||||
<nav
|
<nav
|
||||||
class="md:hidden fixed bottom-0 left-0 right-0 h-16 bg-slate-900/90 backdrop-blur-xl border-t border-white/10 z-50 flex justify-around items-center px-2">
|
class="md:hidden fixed bottom-0 left-0 right-0 h-12 bg-slate-900/90 backdrop-blur-xl border-t border-white/10 z-50 flex justify-around items-center px-2">
|
||||||
<div v-for="item in navItems" :key="item.path" :class="[
|
<div v-for="item in navItems" :key="item.path" :class="[
|
||||||
'flex flex-col items-center gap-1 p-2 rounded-xl transition-all',
|
'flex flex-col items-center p-1.5 rounded-lg transition-all',
|
||||||
isActive(item.path)
|
isActive(item.path)
|
||||||
? 'text-white bg-white/10 relative top-[-10px] shadow-lg shadow-violet-500/20 border border-violet-500/30'
|
? 'text-white bg-white/10 shadow-lg shadow-violet-500/20 border border-violet-500/30'
|
||||||
: 'text-slate-400 hover:text-slate-200'
|
: 'text-slate-400 hover:text-slate-200'
|
||||||
]" @click="router.push(item.path)">
|
]" @click="router.push(item.path)">
|
||||||
<span class="text-xl">{{ item.icon }}</span>
|
<span class="text-lg">{{ item.icon }}</span>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -413,7 +413,7 @@ const handleGenerate = async () => {
|
|||||||
prompt: prompt.value,
|
prompt: prompt.value,
|
||||||
assets_list: selectedAssets.value.map(a => a.id),
|
assets_list: selectedAssets.value.map(a => a.id),
|
||||||
linked_character_id: selectedCharacter.value?.id || selectedCharacter.value?._id || null,
|
linked_character_id: selectedCharacter.value?.id || selectedCharacter.value?._id || null,
|
||||||
environment_id: selectedEnvironment.value?.id || selectedEnvironment.value?._id || null,
|
environment_id: (selectedCharacter.value && useEnvironment.value) ? (selectedEnvironment.value?.id || selectedEnvironment.value?._id || null) : null,
|
||||||
telegram_id: sendToTelegram.value ? telegramId.value : null,
|
telegram_id: sendToTelegram.value ? telegramId.value : null,
|
||||||
use_profile_image: selectedCharacter.value ? useProfileImage.value : false,
|
use_profile_image: selectedCharacter.value ? useProfileImage.value : false,
|
||||||
count: generationCount.value
|
count: generationCount.value
|
||||||
@@ -854,48 +854,48 @@ const confirmAddToAlbum = async () => {
|
|||||||
<div class="flex flex-col h-full font-sans">
|
<div class="flex flex-col h-full font-sans">
|
||||||
<main class="flex-1 relative flex flex-col h-full overflow-hidden">
|
<main class="flex-1 relative flex flex-col h-full overflow-hidden">
|
||||||
<header
|
<header
|
||||||
class="p-4 flex justify-between items-center z-10 border-b border-white/5 bg-slate-900/80 backdrop-blur-sm">
|
class="p-2 px-4 flex justify-between items-center z-10 border-b border-white/5 bg-slate-900/80 backdrop-blur-sm">
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-2">
|
||||||
<h1
|
<h1
|
||||||
class="text-xl font-bold bg-gradient-to-r from-white to-slate-400 bg-clip-text text-transparent m-0">
|
class="text-base font-bold bg-gradient-to-r from-white to-slate-400 bg-clip-text text-transparent m-0">
|
||||||
Gallery</h1>
|
Gallery</h1>
|
||||||
|
|
||||||
<span class="text-xs text-slate-500 border-l border-white/10 pl-3">History</span>
|
<span class="text-[10px] text-slate-500 border-l border-white/10 pl-2">History</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-1.5">
|
||||||
<Dropdown v-model="filterCharacter" :options="characters" optionLabel="name"
|
<Dropdown v-model="filterCharacter" :options="characters" optionLabel="name"
|
||||||
placeholder="All Characters" showClear
|
placeholder="All Characters" showClear
|
||||||
class="!w-48 !bg-slate-800/60 !border-white/10 !text-white !rounded-xl !text-sm" :pt="{
|
class="!w-40 !bg-slate-800/60 !border-white/10 !text-white !rounded-lg !text-[10px]" :pt="{
|
||||||
root: { class: '!bg-slate-800/60 !h-8' },
|
root: { class: '!bg-slate-800/60 !h-7' },
|
||||||
input: { class: '!text-white !text-xs !py-1 !px-2' },
|
input: { class: '!text-white !text-[10px] !py-0.5 !px-2' },
|
||||||
trigger: { class: '!text-slate-400 !w-6' },
|
trigger: { class: '!text-slate-400 !w-5' },
|
||||||
panel: { class: '!bg-slate-800 !border-white/10' },
|
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' },
|
item: { class: '!text-slate-300 hover:!bg-white/10 hover:!text-white !text-[10px] !py-1' },
|
||||||
clearIcon: { class: '!text-slate-400 hover:!text-white' }
|
clearIcon: { class: '!text-slate-400 hover:!text-white !text-[8px]' }
|
||||||
}">
|
}">
|
||||||
<template #value="slotProps">
|
<template #value="slotProps">
|
||||||
<div v-if="slotProps.value" class="flex items-center gap-1.5">
|
<div v-if="slotProps.value" class="flex items-center gap-1">
|
||||||
<img v-if="slotProps.value.avatar_image" :src="API_URL + slotProps.value.avatar_image"
|
<img v-if="slotProps.value.avatar_image" :src="API_URL + slotProps.value.avatar_image"
|
||||||
class="w-5 h-5 rounded-full object-cover" />
|
class="w-4 h-4 rounded-full object-cover" />
|
||||||
<span class="text-xs">{{ slotProps.value.name }}</span>
|
<span class="text-[10px]">{{ slotProps.value.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
<span v-else class="text-xs text-slate-400">{{ slotProps.placeholder }}</span>
|
<span v-else class="text-[10px] text-slate-400">{{ slotProps.placeholder }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #option="slotProps">
|
<template #option="slotProps">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-1.5">
|
||||||
<img v-if="slotProps.option.avatar_image" :src="API_URL + slotProps.option.avatar_image"
|
<img v-if="slotProps.option.avatar_image" :src="API_URL + slotProps.option.avatar_image"
|
||||||
class="w-6 h-6 rounded-full object-cover" />
|
class="w-5 h-5 rounded-full object-cover" />
|
||||||
<span>{{ slotProps.option.name }}</span>
|
<span class="text-[10px]">{{ slotProps.option.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
<Button icon="pi pi-refresh" @click="refreshHistory" rounded text
|
<Button icon="pi pi-refresh" @click="refreshHistory" rounded text
|
||||||
class="!text-slate-400 hover:!bg-white/10 !w-8 !h-8 md:hidden" />
|
class="!text-slate-400 hover:!bg-white/10 !w-7 !h-7 !p-0 md:hidden" />
|
||||||
<Button :icon="isSelectMode ? 'pi pi-times' : 'pi pi-check-square'" @click="toggleSelectMode"
|
<Button :icon="isSelectMode ? 'pi pi-times' : 'pi pi-check-square'" @click="toggleSelectMode"
|
||||||
rounded text class="!w-8 !h-8"
|
rounded text class="!w-7 !h-7 !p-0"
|
||||||
:class="isSelectMode ? '!text-violet-400 !bg-violet-500/20' : '!text-slate-400 hover:!bg-white/10'" />
|
:class="isSelectMode ? '!text-violet-400 !bg-violet-500/20' : '!text-slate-400 hover:!bg-white/10'" />
|
||||||
<Button icon="pi pi-cog" @click="isSettingsVisible = true" rounded text
|
<Button icon="pi pi-cog" @click="isSettingsVisible = true" rounded text
|
||||||
class="!text-slate-400 hover:!bg-white/10 !w-8 !h-8" v-if="!isSettingsVisible" />
|
class="!text-slate-400 hover:!bg-white/10 !w-7 !h-7 !p-0" v-if="!isSettingsVisible" />
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ const imageCount = ref(1)
|
|||||||
const sendToTelegram = ref(false)
|
const sendToTelegram = ref(false)
|
||||||
const telegramId = ref('')
|
const telegramId = ref('')
|
||||||
const useProfileImage = ref(true)
|
const useProfileImage = ref(true)
|
||||||
|
const useEnvironment = ref(false)
|
||||||
const isImprovingPrompt = ref(false)
|
const isImprovingPrompt = ref(false)
|
||||||
const previousPrompt = ref('')
|
const previousPrompt = ref('')
|
||||||
let _savedCharacterId = null
|
let _savedCharacterId = null
|
||||||
@@ -129,6 +130,7 @@ const saveSettings = () => {
|
|||||||
sendToTelegram: sendToTelegram.value,
|
sendToTelegram: sendToTelegram.value,
|
||||||
telegramId: telegramId.value,
|
telegramId: telegramId.value,
|
||||||
useProfileImage: useProfileImage.value,
|
useProfileImage: useProfileImage.value,
|
||||||
|
useEnvironment: useEnvironment.value,
|
||||||
selectedCharacterId: selectedCharacter.value?.id || selectedCharacter.value?._id || null,
|
selectedCharacterId: selectedCharacter.value?.id || selectedCharacter.value?._id || null,
|
||||||
selectedEnvironmentId: selectedEnvironment.value?.id || selectedEnvironment.value?._id || null,
|
selectedEnvironmentId: selectedEnvironment.value?.id || selectedEnvironment.value?._id || null,
|
||||||
selectedAssetIds: selectedAssets.value.map(a => a.id),
|
selectedAssetIds: selectedAssets.value.map(a => a.id),
|
||||||
@@ -152,6 +154,7 @@ const restoreSettings = () => {
|
|||||||
sendToTelegram.value = s.sendToTelegram || false
|
sendToTelegram.value = s.sendToTelegram || false
|
||||||
telegramId.value = s.telegramId || localStorage.getItem('telegram_id') || ''
|
telegramId.value = s.telegramId || localStorage.getItem('telegram_id') || ''
|
||||||
if (s.useProfileImage !== undefined) useProfileImage.value = s.useProfileImage
|
if (s.useProfileImage !== undefined) useProfileImage.value = s.useProfileImage
|
||||||
|
if (s.useEnvironment !== undefined) useEnvironment.value = s.useEnvironment
|
||||||
_savedCharacterId = s.selectedCharacterId || null
|
_savedCharacterId = s.selectedCharacterId || null
|
||||||
_savedEnvironmentId = s.selectedEnvironmentId || null
|
_savedEnvironmentId = s.selectedEnvironmentId || null
|
||||||
if (s.selectedAssetIds && s.selectedAssetIds.length > 0) {
|
if (s.selectedAssetIds && s.selectedAssetIds.length > 0) {
|
||||||
@@ -167,7 +170,7 @@ const restoreSettings = () => {
|
|||||||
}
|
}
|
||||||
restoreSettings()
|
restoreSettings()
|
||||||
|
|
||||||
watch([prompt, quality, aspectRatio, imageCount, selectedModel, sendToTelegram, telegramId, useProfileImage, selectedCharacter, selectedEnvironment, selectedAssets], saveSettings, { deep: true })
|
watch([prompt, quality, aspectRatio, imageCount, selectedModel, sendToTelegram, telegramId, useProfileImage, useEnvironment, selectedCharacter, selectedEnvironment, selectedAssets], saveSettings, { deep: true })
|
||||||
|
|
||||||
const viewMode = ref('feed') // 'feed' or 'gallery'
|
const viewMode = ref('feed') // 'feed' or 'gallery'
|
||||||
const isSubmitting = ref(false)
|
const isSubmitting = ref(false)
|
||||||
@@ -289,7 +292,7 @@ const handleGenerate = async () => {
|
|||||||
quality: quality.value.key,
|
quality: quality.value.key,
|
||||||
assets_list: selectedAssets.value.map(a => a.id),
|
assets_list: selectedAssets.value.map(a => a.id),
|
||||||
linked_character_id: selectedCharacter.value?.id || selectedCharacter.value?._id || null,
|
linked_character_id: selectedCharacter.value?.id || selectedCharacter.value?._id || null,
|
||||||
environment_id: selectedEnvironment.value?.id || selectedEnvironment.value?._id || null,
|
environment_id: (selectedCharacter.value && useEnvironment.value) ? (selectedEnvironment.value?.id || selectedEnvironment.value?._id || null) : null,
|
||||||
telegram_id: sendToTelegram.value ? telegramId.value : null,
|
telegram_id: sendToTelegram.value ? telegramId.value : null,
|
||||||
use_profile_image: selectedCharacter.value ? useProfileImage.value : false,
|
use_profile_image: selectedCharacter.value ? useProfileImage.value : false,
|
||||||
count: imageCount.value,
|
count: imageCount.value,
|
||||||
@@ -909,45 +912,46 @@ watch(viewMode, (v) => {
|
|||||||
<main class="flex-1 flex flex-col min-w-0 bg-slate-950/50 relative">
|
<main class="flex-1 flex flex-col min-w-0 bg-slate-950/50 relative">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<header
|
<header
|
||||||
class="h-12 border-b border-white/5 flex items-center justify-between px-6 bg-slate-900/80 backdrop-blur z-20">
|
class="h-10 border-b border-white/5 flex items-center justify-between px-4 bg-slate-900/80 backdrop-blur z-20">
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex items-center gap-3">
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<div v-if="isEditingName" class="flex items-center gap-2">
|
<div v-if="isEditingName" class="flex items-center gap-2">
|
||||||
<InputText v-model="editableName"
|
<InputText v-model="editableName"
|
||||||
class="idea-name-input !bg-slate-800 !border-violet-500/50 !text-white !py-0.5 !h-8 !text-base !font-bold"
|
class="idea-name-input !bg-slate-800 !border-violet-500/50 !text-white !py-0.5 !h-7 !text-sm !font-bold"
|
||||||
@keyup.enter="saveName"
|
@keyup.enter="saveName"
|
||||||
@blur="saveName"
|
@blur="saveName"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<h1 v-else class="text-base font-bold text-slate-200 truncate max-w-[200px] md:max-w-md cursor-pointer hover:text-violet-400 transition-colors"
|
<h1 v-else class="text-sm font-bold text-slate-200 truncate max-w-[150px] md:max-w-md cursor-pointer hover:text-violet-400 transition-colors"
|
||||||
@click="toggleEditName">
|
@click="toggleEditName">
|
||||||
{{ currentIdea?.name || 'Loading...' }}
|
{{ currentIdea?.name || 'Loading...' }}
|
||||||
<i class="pi pi-pencil text-[9px] ml-1 opacity-50"></i>
|
<i class="pi pi-pencil text-[8px] ml-1 opacity-50"></i>
|
||||||
</h1>
|
</h1>
|
||||||
<span
|
<span
|
||||||
class="px-2 py-0.5 rounded-full bg-slate-800 text-[9px] text-slate-400 border border-white/5">Idea
|
class="px-1.5 py-0.5 rounded-full bg-slate-800 text-[8px] text-slate-500 border border-white/5">Idea</span>
|
||||||
Session</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-2">
|
||||||
<!-- View Toggle -->
|
<!-- View Toggle -->
|
||||||
<div class="flex bg-slate-800 rounded-lg p-1 border border-white/5">
|
<div class="flex bg-slate-800 rounded-lg p-0.5 border border-white/5">
|
||||||
<button @click="viewMode = 'feed'"
|
<button @click="viewMode = 'feed'"
|
||||||
class="px-3 py-1.5 rounded-md text-xs font-medium transition-all"
|
class="px-2 py-1 rounded-md text-[10px] font-medium transition-all"
|
||||||
:class="viewMode === 'feed' ? 'bg-violet-600 text-white shadow-lg' : 'text-slate-400 hover:text-slate-200'">
|
:class="viewMode === 'feed' ? 'bg-violet-600 text-white shadow-lg' : 'text-slate-400 hover:text-slate-200'">
|
||||||
<i class="pi pi-list mr-1"></i> Feed
|
<i class="pi pi-list mr-1"></i> Feed
|
||||||
</button>
|
</button>
|
||||||
<button @click="viewMode = 'gallery'"
|
<button @click="viewMode = 'gallery'"
|
||||||
class="px-3 py-1.5 rounded-md text-xs font-medium transition-all"
|
class="px-2 py-1 rounded-md text-[10px] font-medium transition-all"
|
||||||
:class="viewMode === 'gallery' ? 'bg-violet-600 text-white shadow-lg' : 'text-slate-400 hover:text-slate-200'">
|
:class="viewMode === 'gallery' ? 'bg-violet-600 text-white shadow-lg' : 'text-slate-400 hover:text-slate-200'">
|
||||||
<i class="pi pi-th-large mr-1"></i> Gallery
|
<i class="pi pi-th-large mr-1"></i> Gallery
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button icon="pi pi-trash" text rounded severity="danger" v-tooltip.bottom="'Delete Idea'"
|
<Button icon="pi pi-trash" text rounded severity="danger" size="small"
|
||||||
|
class="!w-7 !h-7"
|
||||||
|
v-tooltip.bottom="'Delete Idea'"
|
||||||
@click="deleteIdea" />
|
@click="deleteIdea" />
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
@@ -1208,17 +1212,28 @@ watch(viewMode, (v) => {
|
|||||||
</Dropdown>
|
</Dropdown>
|
||||||
|
|
||||||
<div v-if="selectedCharacter"
|
<div v-if="selectedCharacter"
|
||||||
class="flex items-center gap-2 mt-2 px-1 animate-in fade-in slide-in-from-top-1">
|
class="flex flex-wrap items-center gap-x-4 gap-y-2 mt-2 px-1 animate-in fade-in slide-in-from-top-1">
|
||||||
<Checkbox v-model="useProfileImage" :binary="true" inputId="idea-use-profile-img"
|
<div class="flex items-center gap-2">
|
||||||
class="!border-white/20" :pt="{
|
<Checkbox v-model="useProfileImage" :binary="true" inputId="idea-use-profile-img"
|
||||||
box: ({ props, state }) => ({
|
class="!border-white/20" :pt="{
|
||||||
class: ['!bg-slate-800 !border-white/20', { '!bg-violet-600 !border-violet-600': props.modelValue }]
|
box: ({ props, state }) => ({
|
||||||
})
|
class: ['!bg-slate-800 !border-white/20', { '!bg-violet-600 !border-violet-600': props.modelValue }]
|
||||||
}" />
|
})
|
||||||
<label for="idea-use-profile-img"
|
}" />
|
||||||
class="text-xs text-slate-300 cursor-pointer select-none">Use
|
<label for="idea-use-profile-img"
|
||||||
Character
|
class="text-xs text-slate-300 cursor-pointer select-none">Use Photo</label>
|
||||||
Photo</label>
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<Checkbox v-model="useEnvironment" :binary="true" inputId="idea-use-env"
|
||||||
|
class="!border-white/20" :pt="{
|
||||||
|
box: ({ props, state }) => ({
|
||||||
|
class: ['!bg-slate-800 !border-white/20', { '!bg-violet-600 !border-violet-600': props.modelValue }]
|
||||||
|
})
|
||||||
|
}" />
|
||||||
|
<label for="idea-use-env"
|
||||||
|
class="text-xs text-slate-300 cursor-pointer select-none">Use Environment</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -1245,7 +1260,7 @@ watch(viewMode, (v) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Environment Row (Below) -->
|
<!-- Environment Row (Below) -->
|
||||||
<div v-if="selectedCharacter" class="flex-1 flex flex-col gap-1 animate-in fade-in slide-in-from-top-1">
|
<div v-if="selectedCharacter && useEnvironment" class="flex-1 flex flex-col gap-1 animate-in fade-in slide-in-from-top-1 mt-2">
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<label class="text-[10px] font-bold text-slate-400 uppercase tracking-wider">Environment</label>
|
<label class="text-[10px] font-bold text-slate-400 uppercase tracking-wider">Environment</label>
|
||||||
<Button v-if="selectedEnvironment" icon="pi pi-times" @click="selectedEnvironment = null" text size="small"
|
<Button v-if="selectedEnvironment" icon="pi pi-times" @click="selectedEnvironment = null" text size="small"
|
||||||
|
|||||||
@@ -320,12 +320,12 @@ const handleAssetPickerUpload = async (event) => {
|
|||||||
<!-- Content Area (Scrollable) -->
|
<!-- Content Area (Scrollable) -->
|
||||||
<div class="flex-1 overflow-y-auto p-4 md:p-6 pb-48 custom-scrollbar">
|
<div class="flex-1 overflow-y-auto p-4 md:p-6 pb-48 custom-scrollbar">
|
||||||
<!-- Top Bar -->
|
<!-- Top Bar -->
|
||||||
<header class="flex justify-between items-end mb-4 border-b border-white/5 pb-4">
|
<header class="flex justify-between items-center mb-3 border-b border-white/5 pb-2">
|
||||||
<div>
|
<div>
|
||||||
<h1
|
<h1
|
||||||
class="text-2xl font-bold m-0 bg-gradient-to-r from-violet-400 to-fuchsia-400 bg-clip-text text-transparent">
|
class="text-lg font-bold m-0 bg-gradient-to-r from-violet-400 to-fuchsia-400 bg-clip-text text-transparent">
|
||||||
Ideas</h1>
|
Ideas</h1>
|
||||||
<p class="mt-1 mb-0 text-xs text-slate-400">Your creative sessions and experiments</p>
|
<p class="mt-0.5 mb-0 text-[10px] text-slate-500">Your creative sessions</p>
|
||||||
</div>
|
</div>
|
||||||
<!-- REMOVED NEW IDEA BUTTON -->
|
<!-- REMOVED NEW IDEA BUTTON -->
|
||||||
</header>
|
</header>
|
||||||
|
|||||||
Reference in New Issue
Block a user