Files
myprojplanet_vite/src/modules/viaggi/components/chat/ChatWindow.vue
Surya Paolo 11c17bdd8e - Parte 3 : Viaggi
- Chat
2025-12-24 00:26:29 +01:00

149 lines
4.6 KiB
Vue

<template>
<div class="chat-window">
<!-- Header -->
<div class="chat-window__header">
<q-btn
v-if="showBackButton"
flat
round
dense
icon="arrow_back"
@click="$emit('back')"
/>
<q-avatar size="40px" class="chat-window__avatar" @click="$emit('user-click', otherUser)">
<img v-if="otherUser?.profile?.img" :src="otherUser.profile.img" />
<span v-else>{{ userInitials }}</span>
</q-avatar>
<div class="chat-window__header-info">
<span class="chat-window__header-name">{{ userName }}</span>
<span v-if="rideInfo" class="chat-window__header-ride">
<q-icon name="directions_car" size="12px" />
{{ rideInfo }}
</span>
</div>
<q-space />
<q-btn flat round dense icon="more_vert">
<q-menu>
<q-list dense style="min-width: 180px">
<q-item clickable v-close-popup @click="$emit('view-profile', otherUser)">
<q-item-section avatar>
<q-icon name="person" />
</q-item-section>
<q-item-section>Vedi profilo</q-item-section>
</q-item>
<q-item v-if="chat?.rideId" clickable v-close-popup @click="$emit('view-ride', chat.rideId)">
<q-item-section avatar>
<q-icon name="directions_car" />
</q-item-section>
<q-item-section>Vedi viaggio</q-item-section>
</q-item>
<q-separator />
<q-item clickable v-close-popup @click="$emit('block')">
<q-item-section avatar>
<q-icon name="block" color="negative" />
</q-item-section>
<q-item-section class="text-negative">Blocca utente</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</div>
<!-- Messages area -->
<div
ref="messagesContainer"
class="chat-window__messages"
@scroll="onScroll"
>
<!-- Load more -->
<div v-if="hasMoreMessages" class="chat-window__load-more">
<q-btn
flat
no-caps
color="primary"
label="Carica messaggi precedenti"
:loading="loadingMore"
@click="$emit('load-more')"
/>
</div>
<!-- Loading -->
<div v-if="loading" class="chat-window__loading">
<q-spinner color="primary" size="32px" />
</div>
<!-- Empty state -->
<div v-else-if="messages.length === 0" class="chat-window__empty">
<q-icon name="chat_bubble_outline" size="64px" color="grey-4" />
<span>Inizia la conversazione</span>
<p>Scrivi un messaggio per iniziare a chattare con {{ userName }}</p>
</div>
<!-- Messages grouped by date -->
<template v-else>
<template v-for="(group, groupIndex) in groupedMessages" :key="groupIndex">
<!-- Date separator -->
<div class="chat-window__date-separator">
<span>{{ group.date }}</span>
</div>
<!-- Messages -->
<MessageBubble
v-for="(message, msgIndex) in group.messages"
:key="message._id"
:message="message"
:is-own="isOwnMessage(message)"
:show-avatar="shouldShowAvatar(group.messages, msgIndex)"
:show-sender-name="chat?.type === 'group'"
:reply-to="getReplyMessage(message.replyTo)"
@reply="setReplyTo"
@delete="deleteMessage"
@ride-click="(id) => $emit('view-ride', id)"
/>
</template>
</template>
<!-- Scroll to bottom button -->
<transition name="fade">
<q-btn
v-if="showScrollButton"
round
color="primary"
icon="keyboard_arrow_down"
size="sm"
class="chat-window__scroll-btn"
@click="scrollToBottom"
>
<q-badge v-if="newMessagesCount > 0" color="negative" floating rounded>
{{ newMessagesCount }}
</q-badge>
</q-btn>
</transition>
</div>
<!-- Input -->
<ChatInput
:reply-to="replyTo"
:sending="sending"
:disabled="isBlocked"
@send="sendMessage"
@cancel-reply="replyTo = null"
@share-location="shareLocation"
@share-ride="$emit('share-ride')"
/>
<!-- Blocked banner -->
<div v-if="isBlocked" class="chat-window__blocked">
<q-icon name="block" size="20px" />
<span>Questa conversazione è stata bloccata</span>
</div>
</div>
</template>
<script lang="ts" src="./ChatWindow.ts" />
<style lang="scss" src="./ChatWindow.scss" />