fix: Conversation list overlay issue with Virtua virtualizer (#13648)
This commit is contained in:
@@ -955,10 +955,8 @@ watch(conversationFilters, (newVal, oldVal) => {
|
|||||||
ref="virtualListRef"
|
ref="virtualListRef"
|
||||||
v-slot="{ item, index }"
|
v-slot="{ item, index }"
|
||||||
:data="conversationList"
|
:data="conversationList"
|
||||||
:overscan="10"
|
|
||||||
>
|
>
|
||||||
<ConversationItem
|
<ConversationItem
|
||||||
:key="item.id"
|
|
||||||
:source="item"
|
:source="item"
|
||||||
:label="label"
|
:label="label"
|
||||||
:team-id="teamId"
|
:team-id="teamId"
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ export default {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ConversationCard
|
<ConversationCard
|
||||||
:key="source.id"
|
|
||||||
:active-label="label"
|
:active-label="label"
|
||||||
:team-id="teamId"
|
:team-id="teamId"
|
||||||
:folders-id="foldersId"
|
:folders-id="foldersId"
|
||||||
|
|||||||
@@ -24,6 +24,10 @@ export default {
|
|||||||
type: [String, Date, Number],
|
type: [String, Date, Number],
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
conversationId: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -74,6 +78,15 @@ export default {
|
|||||||
createdAtTimestamp() {
|
createdAtTimestamp() {
|
||||||
this.createdAtTimeAgo = dynamicTime(this.createdAtTimestamp);
|
this.createdAtTimeAgo = dynamicTime(this.createdAtTimestamp);
|
||||||
},
|
},
|
||||||
|
conversationId() {
|
||||||
|
// Reset display values and timer when the row is recycled to a different conversation.
|
||||||
|
this.lastActivityAtTimeAgo = dynamicTime(this.lastActivityTimestamp);
|
||||||
|
this.createdAtTimeAgo = dynamicTime(this.createdAtTimestamp);
|
||||||
|
if (this.isAutoRefreshEnabled) {
|
||||||
|
clearTimeout(this.timer);
|
||||||
|
this.createTimer();
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
if (this.isAutoRefreshEnabled) {
|
if (this.isAutoRefreshEnabled) {
|
||||||
@@ -111,7 +124,6 @@ export default {
|
|||||||
v-tooltip.top="{
|
v-tooltip.top="{
|
||||||
content: tooltipText,
|
content: tooltipText,
|
||||||
delay: { show: 1000, hide: 0 },
|
delay: { show: 1000, hide: 0 },
|
||||||
hideOnClick: true,
|
|
||||||
}"
|
}"
|
||||||
class="ml-auto leading-4 text-xxs text-n-slate-10 hover:text-n-slate-11"
|
class="ml-auto leading-4 text-xxs text-n-slate-10 hover:text-n-slate-11"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref, watch } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { useStore, useMapGetter } from 'dashboard/composables/store';
|
import { useStore, useMapGetter } from 'dashboard/composables/store';
|
||||||
import { getLastMessage } from 'dashboard/helper/conversationHelper';
|
import { getLastMessage } from 'dashboard/helper/conversationHelper';
|
||||||
@@ -50,10 +50,21 @@ const store = useStore();
|
|||||||
|
|
||||||
const hovered = ref(false);
|
const hovered = ref(false);
|
||||||
const showContextMenu = ref(false);
|
const showContextMenu = ref(false);
|
||||||
const contextMenu = ref({
|
const contextMenu = ref({ x: null, y: null });
|
||||||
x: null,
|
|
||||||
y: null,
|
// Reset UI state when conversation changes at same index (no :key, instance reused on reorder)
|
||||||
});
|
// This prevents context menu/hover state from leaking to a different conversation
|
||||||
|
// Emit contextMenuToggle(false) to sync parent state if menu was open during recycling
|
||||||
|
const resetState = () => {
|
||||||
|
if (showContextMenu.value) {
|
||||||
|
emit('contextMenuToggle', false);
|
||||||
|
}
|
||||||
|
hovered.value = false;
|
||||||
|
showContextMenu.value = false;
|
||||||
|
contextMenu.value = { x: null, y: null };
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(() => props.chat.id, resetState);
|
||||||
|
|
||||||
const currentChat = useMapGetter('getSelectedChat');
|
const currentChat = useMapGetter('getSelectedChat');
|
||||||
const inboxesList = useMapGetter('inboxes/getInboxes');
|
const inboxesList = useMapGetter('inboxes/getInboxes');
|
||||||
@@ -352,6 +363,7 @@ const deleteConversation = () => {
|
|||||||
<TimeAgo
|
<TimeAgo
|
||||||
:last-activity-timestamp="chat.timestamp"
|
:last-activity-timestamp="chat.timestamp"
|
||||||
:created-at-timestamp="chat.created_at"
|
:created-at-timestamp="chat.created_at"
|
||||||
|
:conversation-id="chat.id"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ export default {
|
|||||||
v-tooltip="{
|
v-tooltip="{
|
||||||
content: tooltipText,
|
content: tooltipText,
|
||||||
delay: { show: 1500, hide: 0 },
|
delay: { show: 1500, hide: 0 },
|
||||||
hideOnClick: true,
|
|
||||||
}"
|
}"
|
||||||
class="shrink-0 rounded-sm inline-flex items-center justify-center w-3.5 h-3.5"
|
class="shrink-0 rounded-sm inline-flex items-center justify-center w-3.5 h-3.5"
|
||||||
:class="{
|
:class="{
|
||||||
|
|||||||
Reference in New Issue
Block a user