- Form values shown correct in MessageHistory of Chat client - Improements to CSS - Move css en js to assets directory - Introduce better Personal Contact Form & Professional Contact Form - Start working on actual Selection Specialist
139 lines
4.4 KiB
JavaScript
139 lines
4.4 KiB
JavaScript
export const MessageHistory = {
|
|
name: 'MessageHistory',
|
|
props: {
|
|
messages: {
|
|
type: Array,
|
|
required: true,
|
|
default: () => []
|
|
},
|
|
isTyping: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
isSubmittingForm: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
apiPrefix: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
autoScroll: {
|
|
type: Boolean,
|
|
default: true
|
|
}
|
|
},
|
|
emits: ['submit-form', 'load-more', 'specialist-complete', 'specialist-error'],
|
|
data() {
|
|
return {
|
|
isAtBottom: true,
|
|
unreadCount: 0
|
|
};
|
|
},
|
|
mounted() {
|
|
this.scrollToBottom();
|
|
this.setupScrollListener();
|
|
},
|
|
updated() {
|
|
if (this.autoScroll && this.isAtBottom) {
|
|
this.$nextTick(() => this.scrollToBottom());
|
|
}
|
|
},
|
|
methods: {
|
|
scrollToBottom() {
|
|
const container = this.$refs.messagesContainer;
|
|
if (container) {
|
|
container.scrollTop = container.scrollHeight;
|
|
this.isAtBottom = true;
|
|
this.showScrollButton = false;
|
|
this.unreadCount = 0;
|
|
}
|
|
},
|
|
|
|
setupScrollListener() {
|
|
const container = this.$refs.messagesContainer;
|
|
if (!container) return;
|
|
|
|
container.addEventListener('scroll', this.handleScroll);
|
|
},
|
|
|
|
handleScroll() {
|
|
const container = this.$refs.messagesContainer;
|
|
if (!container) return;
|
|
|
|
const threshold = 100; // pixels from bottom
|
|
const isNearBottom = container.scrollHeight - container.scrollTop - container.clientHeight < threshold;
|
|
|
|
this.isAtBottom = isNearBottom;
|
|
|
|
// Load more messages when scrolled to top
|
|
if (container.scrollTop === 0) {
|
|
this.$emit('load-more');
|
|
}
|
|
},
|
|
|
|
|
|
handleImageLoaded() {
|
|
// Auto-scroll when images load to maintain position
|
|
if (this.isAtBottom) {
|
|
this.$nextTick(() => this.scrollToBottom());
|
|
}
|
|
},
|
|
|
|
searchMessages(query) {
|
|
// Simple message search
|
|
if (!query.trim()) return this.messages;
|
|
|
|
const searchTerm = query.toLowerCase();
|
|
return this.messages.filter(message =>
|
|
message.content &&
|
|
message.content.toLowerCase().includes(searchTerm)
|
|
);
|
|
},
|
|
|
|
},
|
|
beforeUnmount() {
|
|
// Cleanup scroll listener
|
|
const container = this.$refs.messagesContainer;
|
|
if (container) {
|
|
container.removeEventListener('scroll', this.handleScroll);
|
|
}
|
|
},
|
|
template: `
|
|
<div class="message-history-container">
|
|
<!-- Messages container -->
|
|
<div class="chat-messages" ref="messagesContainer">
|
|
<!-- Loading indicator for load more -->
|
|
<div v-if="$slots.loading" class="load-more-indicator">
|
|
<slot name="loading"></slot>
|
|
</div>
|
|
|
|
<!-- Empty state -->
|
|
<div v-if="messages.length === 0" class="empty-state">
|
|
<div class="empty-icon">💬</div>
|
|
<div class="empty-text">Nog geen berichten</div>
|
|
<div class="empty-subtext">Start een gesprek door een bericht te typen!</div>
|
|
</div>
|
|
|
|
<!-- Message list -->
|
|
<template v-else>
|
|
<!-- Messages -->
|
|
<template v-for="(message, index) in messages" :key="message.id">
|
|
<!-- The actual message -->
|
|
<chat-message
|
|
:message="message"
|
|
:is-submitting-form="isSubmittingForm"
|
|
:api-prefix="apiPrefix"
|
|
@image-loaded="handleImageLoaded"
|
|
@specialist-complete="$emit('specialist-complete', $event)"
|
|
@specialist-error="$emit('specialist-error', $event)"
|
|
></chat-message>
|
|
</template>
|
|
</template>
|
|
|
|
<!-- Typing indicator -->
|
|
<typing-indicator v-if="isTyping"></typing-indicator>
|
|
</div>
|
|
</div>
|
|
`,
|
|
}; |