UI: Agregar iconos a expandir/colapsar y notificacion al copiar
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m4s
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m4s
This commit is contained in:
@@ -164,7 +164,30 @@
|
||||
</div>
|
||||
|
||||
<!-- Messages -->
|
||||
<div ref="messagesContainer" class="flex-1 overflow-y-auto p-4 space-y-2">
|
||||
<div
|
||||
ref="messagesContainer"
|
||||
class="flex-1 overflow-y-auto p-4 space-y-2"
|
||||
@scroll="handleScroll"
|
||||
>
|
||||
<!-- Load more indicator -->
|
||||
<div
|
||||
v-if="loadingMore"
|
||||
class="flex justify-center py-2"
|
||||
>
|
||||
<UIcon name="i-lucide-loader-2" class="w-5 h-5 animate-spin text-[var(--wa-text-muted)]" />
|
||||
</div>
|
||||
<div
|
||||
v-else-if="hasMoreMessages"
|
||||
class="flex justify-center py-2"
|
||||
>
|
||||
<button
|
||||
class="text-xs text-[var(--wa-text-muted)] hover:text-[var(--wa-text)]"
|
||||
@click="loadMoreMessages"
|
||||
>
|
||||
Cargar mensajes anteriores
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<MessagesMessageBubble
|
||||
v-for="message in reversedMessages"
|
||||
:key="message.id"
|
||||
@@ -220,6 +243,8 @@ const chats = ref<any[]>([])
|
||||
const messages = ref<any[]>([])
|
||||
const loadingChats = ref(false)
|
||||
const loadingMessages = ref(false)
|
||||
const loadingMore = ref(false)
|
||||
const hasMoreMessages = ref(true)
|
||||
const showDebugPanel = ref(false)
|
||||
const showChatsDebug = ref(false)
|
||||
const showSelectedChatDebug = ref(false)
|
||||
@@ -264,8 +289,15 @@ watch(selectedChat, async (chat) => {
|
||||
}
|
||||
|
||||
loadingMessages.value = true
|
||||
hasMoreMessages.value = true // Reset for new chat
|
||||
try {
|
||||
messages.value = await $fetch(`/api/messages/${selectedInstance.value.value}/${chat.id}`)
|
||||
const result = await $fetch(`/api/messages/${selectedInstance.value.value}/${chat.id}?limit=50`)
|
||||
messages.value = result as any[]
|
||||
|
||||
// If we got less than 50, there are no more messages
|
||||
if ((result as any[]).length < 50) {
|
||||
hasMoreMessages.value = false
|
||||
}
|
||||
|
||||
// Subscribe to presence updates for this chat (if not a group)
|
||||
if (!chat.isGroup && chat.jid) {
|
||||
@@ -279,6 +311,55 @@ watch(selectedChat, async (chat) => {
|
||||
}
|
||||
})
|
||||
|
||||
// Load more messages (infinite scroll)
|
||||
const loadMoreMessages = async () => {
|
||||
if (!selectedInstance.value?.value || !selectedChat.value || loadingMore.value || !hasMoreMessages.value) return
|
||||
|
||||
const oldestMessage = messages.value[messages.value.length - 1] // Messages are in DESC order
|
||||
if (!oldestMessage) return
|
||||
|
||||
loadingMore.value = true
|
||||
const previousScrollHeight = messagesContainer.value?.scrollHeight || 0
|
||||
|
||||
try {
|
||||
const instanceId = selectedInstance.value.value
|
||||
const chatId = selectedChat.value.id
|
||||
const before = oldestMessage.timestamp
|
||||
|
||||
const olderMessages = await $fetch(`/api/messages/${instanceId}/${chatId}?limit=50&before=${before}`)
|
||||
|
||||
if ((olderMessages as any[]).length < 50) {
|
||||
hasMoreMessages.value = false
|
||||
}
|
||||
|
||||
if ((olderMessages as any[]).length > 0) {
|
||||
messages.value = [...messages.value, ...(olderMessages as any[])]
|
||||
|
||||
// Maintain scroll position after loading
|
||||
nextTick(() => {
|
||||
if (messagesContainer.value) {
|
||||
const newScrollHeight = messagesContainer.value.scrollHeight
|
||||
messagesContainer.value.scrollTop = newScrollHeight - previousScrollHeight
|
||||
}
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error loading more messages:', e)
|
||||
} finally {
|
||||
loadingMore.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// Handle scroll for infinite scroll
|
||||
const handleScroll = () => {
|
||||
if (!messagesContainer.value) return
|
||||
|
||||
// Load more when scrolled near the top (< 100px)
|
||||
if (messagesContainer.value.scrollTop < 100 && hasMoreMessages.value && !loadingMore.value) {
|
||||
loadMoreMessages()
|
||||
}
|
||||
}
|
||||
|
||||
// Computed presence text for current chat
|
||||
const currentChatPresence = computed(() => {
|
||||
if (!selectedChat.value?.jid) return null
|
||||
@@ -484,5 +565,28 @@ onMounted(() => {
|
||||
console.log('[Messages] Message sent:', data)
|
||||
// Already handled by the send function
|
||||
})
|
||||
|
||||
// Listen for reaction updates
|
||||
on('message.reaction', (data) => {
|
||||
console.log('[Messages] Reaction received:', data)
|
||||
|
||||
// If it's for the current instance and chat, reload messages
|
||||
if (data.instanceId === selectedInstance.value?.value && selectedChat.value) {
|
||||
reloadMessages()
|
||||
}
|
||||
})
|
||||
|
||||
// Listen for message status updates
|
||||
on('message.status', (data) => {
|
||||
console.log('[Messages] Message status update:', data)
|
||||
|
||||
// Update message status in local state
|
||||
if (data.instanceId === selectedInstance.value?.value) {
|
||||
const messageIndex = messages.value.findIndex(m => m.messageId === data.messageId)
|
||||
if (messageIndex !== -1) {
|
||||
messages.value[messageIndex].status = data.status
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user