mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-26 19:09:52 +00:00
fix: Prevent multiple asset card popovers from opening simultaneously (#6808)
## Summary Ensures only one MediaAssetCard popover is open at a time. ## Changes - Added `hide()` method exposure in MoreButton component - Implemented parent-level state management for tracking open popover - Added VueUse `whenever` to auto-close other popovers when one opens ## Test Plan - Open multiple asset cards' more menus - Verify only one popover remains open at a time 🤖 Generated with [Claude Code](https://claude.com/claude-code) ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6808-fix-Prevent-multiple-asset-card-popovers-from-opening-simultaneously-2b26d73d365081e1b3f0d97b869cedc5) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -68,4 +68,8 @@ const toggle = (event: Event) => {
|
||||
const hide = () => {
|
||||
popover.value?.hide()
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
hide
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -85,10 +85,13 @@
|
||||
:show-output-count="shouldShowOutputCount(item)"
|
||||
:output-count="getOutputCount(item)"
|
||||
:show-delete-button="shouldShowDeleteButton"
|
||||
:open-popover-id="openPopoverId"
|
||||
@click="handleAssetSelect(item)"
|
||||
@zoom="handleZoomClick(item)"
|
||||
@output-count-click="enterFolderView(item)"
|
||||
@asset-deleted="refreshAssets"
|
||||
@popover-opened="openPopoverId = item.id"
|
||||
@popover-closed="openPopoverId = null"
|
||||
/>
|
||||
</template>
|
||||
</VirtualGrid>
|
||||
@@ -199,6 +202,9 @@ const folderPromptId = ref<string | null>(null)
|
||||
const folderExecutionTime = ref<number | undefined>(undefined)
|
||||
const isInFolderView = computed(() => folderPromptId.value !== null)
|
||||
|
||||
// Track which asset's popover is open (for single-instance popover management)
|
||||
const openPopoverId = ref<string | null>(null)
|
||||
|
||||
// Determine if delete button should be shown
|
||||
// Hide delete button when in input tab and not in cloud (OSS mode - files are from local folders)
|
||||
const shouldShowDeleteButton = computed(() => {
|
||||
|
||||
@@ -71,9 +71,10 @@
|
||||
</div>
|
||||
<div v-tooltip.top="$t('mediaAsset.actions.more')">
|
||||
<MoreButton
|
||||
ref="moreButtonRef"
|
||||
size="sm"
|
||||
@menu-opened="isMenuOpen = true"
|
||||
@menu-closed="isMenuOpen = false"
|
||||
@menu-opened="handleMenuOpened"
|
||||
@menu-closed="handleMenuClosed"
|
||||
@mouseenter="handleOverlayMouseEnter"
|
||||
@mouseleave="handleOverlayMouseLeave"
|
||||
>
|
||||
@@ -139,7 +140,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useElementHover } from '@vueuse/core'
|
||||
import { useElementHover, whenever } from '@vueuse/core'
|
||||
import { computed, defineAsyncComponent, provide, ref, toRef } from 'vue'
|
||||
|
||||
import IconButton from '@/components/button/IconButton.vue'
|
||||
@@ -189,7 +190,8 @@ const {
|
||||
selected,
|
||||
showOutputCount,
|
||||
outputCount,
|
||||
showDeleteButton
|
||||
showDeleteButton,
|
||||
openPopoverId
|
||||
} = defineProps<{
|
||||
asset?: AssetItem
|
||||
loading?: boolean
|
||||
@@ -197,15 +199,19 @@ const {
|
||||
showOutputCount?: boolean
|
||||
outputCount?: number
|
||||
showDeleteButton?: boolean
|
||||
openPopoverId?: string | null
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
zoom: [asset: AssetItem]
|
||||
'output-count-click': []
|
||||
'asset-deleted': []
|
||||
'popover-opened': []
|
||||
'popover-closed': []
|
||||
}>()
|
||||
|
||||
const cardContainerRef = ref<HTMLElement>()
|
||||
const moreButtonRef = ref<InstanceType<typeof MoreButton>>()
|
||||
|
||||
const isVideoPlaying = ref(false)
|
||||
const isMenuOpen = ref(false)
|
||||
@@ -339,4 +345,22 @@ const handleOutputCountClick = () => {
|
||||
const handleAssetDelete = () => {
|
||||
emit('asset-deleted')
|
||||
}
|
||||
|
||||
const handleMenuOpened = () => {
|
||||
isMenuOpen.value = true
|
||||
emit('popover-opened')
|
||||
}
|
||||
|
||||
const handleMenuClosed = () => {
|
||||
isMenuOpen.value = false
|
||||
emit('popover-closed')
|
||||
}
|
||||
|
||||
// Close this popover when another opens
|
||||
whenever(
|
||||
() => openPopoverId && openPopoverId !== asset?.id && isMenuOpen.value,
|
||||
() => {
|
||||
moreButtonRef.value?.hide()
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user