149 lines
4.6 KiB
Vue
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" />
|