<template>
<div class="session-list-wrap">
<div
v-if="!visibleSessions.length && !sessionsStore.loading"
class="empty-sessions"
>
<i class="ph ph-chat-dots"></i>
<p>No conversations yet</p>
</div>
<RecycleScroller
v-else
class="session-scroller"
:items="visibleSessions"
:item-size="74"
key-field="session_id"
>
<template #default="{ item }">
<SessionItem
:session="item"
:active="item.session_id === chatStore.currentId"
@select="onSelect(item)"
@delete="onDelete(item)"
@pin="onPin(item)"
/>
</template>
</RecycleScroller>
</div>
</template>
<script setup>
import { computed } from 'vue'
import { RecycleScroller } from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
import { useSessionsStore } from '@/stores/sessions.js'
import { useChatStore } from '@/stores/chat.js'
import { useProfilesStore } from '@/stores/profiles.js'
import SessionItem from './SessionItem.vue'
const emit = defineEmits(['select'])
const sessionsStore = useSessionsStore()
const chatStore = useChatStore()
const profilesStore = useProfilesStore()
const visibleSessions = computed(() => {
const pid = profilesStore.selectedProfileId
if (!pid) return sessionsStore.sessions
return sessionsStore.sessions.filter(s => s.profile_id === pid)
})
async function onSelect(session) {
await chatStore.loadSession(session.session_id)
emit('select', session)
}
async function onDelete(session) {
const wasActive = session.session_id === chatStore.currentId
await sessionsStore.deleteSession(session.session_id)
if (wasActive && sessionsStore.sessions.length) {
await chatStore.loadSession(sessionsStore.sessions[0].session_id)
}
}
async function onPin(session) {
await sessionsStore.pinSession(session.session_id, !session.pinned)
}
</script>
<style scoped>
.session-list-wrap {
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
}
.session-scroller {
flex: 1;
overflow-y: auto;
}
.empty-sessions {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
padding: 32px 16px;
color: var(--color-text-dark, #787c99);
font-size: 13px;
i { font-size: 32px; opacity: 0.4; }
p { margin: 0; }
}
</style>