mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-26 23:48:52 -03:00
feat: Add LoRA selector modal to Cycler widget
- Add LoraListModal component with search and preview tooltip - Make 'Next LoRA' name clickable to open selector modal - Integrate PreviewTooltip with custom resolver for Vue widgets - Disable selector when prompts are queued (consistent with pause button) - Fix tooltip z-index to display above modal backdrop Fixes issue: users couldn't easily identify which index corresponds to specific LoRA in large lists
This commit is contained in:
@@ -23,6 +23,15 @@
|
||||
@update:repeat-count="handleRepeatCountChange"
|
||||
@toggle-pause="handleTogglePause"
|
||||
@reset-index="handleResetIndex"
|
||||
@open-lora-selector="isModalOpen = true"
|
||||
/>
|
||||
|
||||
<LoraListModal
|
||||
:visible="isModalOpen"
|
||||
:lora-list="cachedLoraList"
|
||||
:current-index="state.currentIndex.value"
|
||||
@close="isModalOpen = false"
|
||||
@select="handleModalSelect"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -30,8 +39,9 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import LoraCyclerSettingsView from './lora-cycler/LoraCyclerSettingsView.vue'
|
||||
import LoraListModal from './lora-cycler/LoraListModal.vue'
|
||||
import { useLoraCyclerState } from '../composables/useLoraCyclerState'
|
||||
import type { ComponentWidget, CyclerConfig, LoraPoolConfig } from '../composables/types'
|
||||
import type { ComponentWidget, CyclerConfig, LoraPoolConfig, LoraItem } from '../composables/types'
|
||||
|
||||
type CyclerWidget = ComponentWidget<CyclerConfig>
|
||||
|
||||
@@ -86,6 +96,12 @@ const lastPoolConfigHash = ref('')
|
||||
// Track if component is mounted
|
||||
const isMounted = ref(false)
|
||||
|
||||
// Modal state
|
||||
const isModalOpen = ref(false)
|
||||
|
||||
// Cache for LoRA list (used by modal)
|
||||
const cachedLoraList = ref<LoraItem[]>([])
|
||||
|
||||
// Get pool config from connected node
|
||||
const getPoolConfig = (): LoraPoolConfig | null => {
|
||||
// Check if getPoolConfig method exists on node (added by main.ts)
|
||||
@@ -95,6 +111,17 @@ const getPoolConfig = (): LoraPoolConfig | null => {
|
||||
return null
|
||||
}
|
||||
|
||||
// Update display from LoRA list and index
|
||||
const updateDisplayFromLoraList = (loraList: LoraItem[], index: number) => {
|
||||
if (loraList.length > 0 && index > 0 && index <= loraList.length) {
|
||||
const currentLora = loraList[index - 1]
|
||||
if (currentLora) {
|
||||
state.currentLoraName.value = currentLora.file_name
|
||||
state.currentLoraFilename.value = currentLora.file_name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle index update from user
|
||||
const handleIndexUpdate = async (newIndex: number) => {
|
||||
// Reset execution state when user manually changes index
|
||||
@@ -113,19 +140,18 @@ const handleIndexUpdate = async (newIndex: number) => {
|
||||
try {
|
||||
const poolConfig = getPoolConfig()
|
||||
const loraList = await state.fetchCyclerList(poolConfig)
|
||||
|
||||
if (loraList.length > 0 && newIndex > 0 && newIndex <= loraList.length) {
|
||||
const currentLora = loraList[newIndex - 1]
|
||||
if (currentLora) {
|
||||
state.currentLoraName.value = currentLora.file_name
|
||||
state.currentLoraFilename.value = currentLora.file_name
|
||||
}
|
||||
}
|
||||
cachedLoraList.value = loraList
|
||||
updateDisplayFromLoraList(loraList, newIndex)
|
||||
} catch (error) {
|
||||
console.error('[LoraCyclerWidget] Error updating index:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// Handle LoRA selection from modal
|
||||
const handleModalSelect = (index: number) => {
|
||||
handleIndexUpdate(index)
|
||||
}
|
||||
|
||||
// Handle use custom clip range toggle
|
||||
const handleUseCustomClipRangeChange = (newValue: boolean) => {
|
||||
state.useCustomClipRange.value = newValue
|
||||
@@ -166,14 +192,8 @@ const handleResetIndex = async () => {
|
||||
try {
|
||||
const poolConfig = getPoolConfig()
|
||||
const loraList = await state.fetchCyclerList(poolConfig)
|
||||
|
||||
if (loraList.length > 0) {
|
||||
const currentLora = loraList[0]
|
||||
if (currentLora) {
|
||||
state.currentLoraName.value = currentLora.file_name
|
||||
state.currentLoraFilename.value = currentLora.file_name
|
||||
}
|
||||
}
|
||||
cachedLoraList.value = loraList
|
||||
updateDisplayFromLoraList(loraList, 1)
|
||||
} catch (error) {
|
||||
console.error('[LoraCyclerWidget] Error resetting index:', error)
|
||||
}
|
||||
@@ -191,6 +211,9 @@ const checkPoolConfigChanges = async () => {
|
||||
lastPoolConfigHash.value = newHash
|
||||
try {
|
||||
await state.refreshList(poolConfig)
|
||||
// Update cached list when pool config changes
|
||||
const loraList = await state.fetchCyclerList(poolConfig)
|
||||
cachedLoraList.value = loraList
|
||||
} catch (error) {
|
||||
console.error('[LoraCyclerWidget] Error on pool config change:', error)
|
||||
}
|
||||
@@ -288,6 +311,9 @@ onMounted(async () => {
|
||||
const poolConfig = getPoolConfig()
|
||||
lastPoolConfigHash.value = state.hashPoolConfig(poolConfig)
|
||||
await state.refreshList(poolConfig)
|
||||
// Cache the initial LoRA list for modal
|
||||
const loraList = await state.fetchCyclerList(poolConfig)
|
||||
cachedLoraList.value = loraList
|
||||
} catch (error) {
|
||||
console.error('[LoraCyclerWidget] Error on initial load:', error)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user