<template>
<div class="chat-area">
<ChatHeader
@toggle-sidebar="emit('toggle-sidebar')"
@toggle-artifacts="emit('toggle-artifacts')"
/>
<!-- Reconnect toast (system-level, shown inline at top) -->
<Transition name="fade">
<GnAlert
v-if="ws.reconnectFailed.value"
variant="warning"
class="reconnect-banner"
>
<i class="ph ph-wifi-slash"></i>
{{ t('chat.connectionLost') }}
<GnIconButton icon="ph ph-arrows-clockwise" :label="t('chat.retry')" @click="retryNow" />
</GnAlert>
</Transition>
<template v-if="chat.currentId">
<MessageList />
<QueuedMessagesChip />
<InputBar :ws="ws" />
</template>
<div v-else class="empty-chat">
<GnEmptyState
icon="ph ph-chat-dots"
:title="t('chat.nothingOpen')"
:text="t('chat.startConversation')"
/>
</div>
</div>
</template>
<script setup>
import { watch, onUnmounted } from 'vue'
import { useChatStore } from '@/stores/chat.js'
import { useWebSocket } from '@/composables/useWebSocket.js'
import { t } from '@/i18n/index.js'
import ChatHeader from './ChatHeader.vue'
import MessageList from './MessageList.vue'
import InputBar from './InputBar.vue'
import QueuedMessagesChip from './QueuedMessagesChip.vue'
const emit = defineEmits(['toggle-sidebar', 'toggle-artifacts'])
const chat = useChatStore()
const ws = useWebSocket()
// Connect/reconnect WS when session changes
watch(
() => chat.currentId,
(id) => {
if (id) ws.connect(id)
else ws.disconnect()
},
{ immediate: true }
)
function retryNow() {
if (chat.currentId) ws.connect(chat.currentId)
}
onUnmounted(() => ws.disconnect())
</script>
<style scoped>
.reconnect-banner {
display: flex;
align-items: center;
gap: 8px;
margin: 8px 16px 0;
font-size: 13px;
}
</style>