293 lines
9.5 KiB
JavaScript
293 lines
9.5 KiB
JavaScript
// Messaging JavaScript functionality
|
|
class MessagingSystem {
|
|
constructor() {
|
|
this.currentUserId = null;
|
|
this.currentConversationUserId = null;
|
|
this.pollingInterval = null;
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
// Get current user ID from the page
|
|
this.currentUserId = document.querySelector('meta[name="user-id"]')?.content;
|
|
|
|
if (this.currentUserId) {
|
|
this.setupEventListeners();
|
|
this.startPolling();
|
|
}
|
|
}
|
|
|
|
setupEventListeners() {
|
|
// Handle message form submissions
|
|
document.querySelectorAll('form[id$="-form"], form[action*="message/send"]').forEach(form => {
|
|
form.addEventListener('submit', (e) => {
|
|
e.preventDefault();
|
|
this.sendMessage(form);
|
|
});
|
|
});
|
|
|
|
// Handle conversation switching
|
|
document.querySelectorAll('a[href*="message/conversation/"]').forEach(link => {
|
|
link.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
const userId = link.href.split('/').pop();
|
|
this.loadConversation(userId);
|
|
});
|
|
});
|
|
}
|
|
|
|
async sendMessage(form) {
|
|
try {
|
|
const formData = new FormData(form);
|
|
const data = Object.fromEntries(formData.entries());
|
|
|
|
// Show loading state
|
|
const submitButton = form.querySelector('button[type="submit"]');
|
|
const originalText = submitButton.textContent;
|
|
submitButton.textContent = 'Sending...';
|
|
submitButton.disabled = true;
|
|
|
|
const response = await fetch('index.php/message/send', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
},
|
|
body: new URLSearchParams(data)
|
|
});
|
|
|
|
const result = await response.json();
|
|
|
|
if (result.success) {
|
|
// Clear form
|
|
form.reset();
|
|
|
|
// Reload messages or show success
|
|
if (this.currentConversationUserId) {
|
|
await this.loadMessages(this.currentConversationUserId);
|
|
} else {
|
|
this.showFeedback('Message sent successfully!', 'success');
|
|
}
|
|
} else {
|
|
this.showFeedback(result.message || 'Failed to send message', 'error');
|
|
}
|
|
} catch (error) {
|
|
console.error('Error sending message:', error);
|
|
this.showFeedback('Network error. Please try again.', 'error');
|
|
} finally {
|
|
// Restore button state
|
|
const submitButton = form.querySelector('button[type="submit"]');
|
|
submitButton.textContent = originalText;
|
|
submitButton.disabled = false;
|
|
}
|
|
}
|
|
|
|
async loadConversation(userId) {
|
|
this.currentConversationUserId = userId;
|
|
|
|
try {
|
|
const response = await fetch(`index.php/message/conversation/${userId}`, {
|
|
headers: {
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
}
|
|
});
|
|
|
|
if (response.ok) {
|
|
const html = await response.text();
|
|
const conversationContainer = document.querySelector('.conversation-container') ||
|
|
document.querySelector('.panel-default');
|
|
|
|
if (conversationContainer) {
|
|
conversationContainer.innerHTML = html;
|
|
this.setupEventListeners(); // Re-setup event listeners for new content
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('Error loading conversation:', error);
|
|
this.showFeedback('Failed to load conversation', 'error');
|
|
}
|
|
}
|
|
|
|
async loadMessages(userId) {
|
|
try {
|
|
const response = await fetch(`index.php/message/getConversationMessages/${userId}`, {
|
|
headers: {
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
}
|
|
});
|
|
|
|
if (response.ok) {
|
|
const messages = await response.json();
|
|
this.displayMessages(messages);
|
|
}
|
|
} catch (error) {
|
|
console.error('Error loading messages:', error);
|
|
}
|
|
}
|
|
|
|
async loadGlobalMessages() {
|
|
try {
|
|
const response = await fetch('index.php/message/getGlobalMessages', {
|
|
headers: {
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
}
|
|
});
|
|
|
|
if (response.ok) {
|
|
const messages = await response.json();
|
|
this.displayGlobalMessages(messages);
|
|
}
|
|
} catch (error) {
|
|
console.error('Error loading global messages:', error);
|
|
}
|
|
}
|
|
|
|
displayMessages(messages) {
|
|
const messageContainer = document.querySelector('.message-container');
|
|
if (!messageContainer) return;
|
|
|
|
messageContainer.innerHTML = '';
|
|
|
|
messages.forEach(message => {
|
|
const messageDiv = document.createElement('div');
|
|
messageDiv.className = `message ${message.sender_id == this.currentUserId ? 'sent' : 'received'}`;
|
|
|
|
messageDiv.innerHTML = `
|
|
<div class="message-bubble">
|
|
${this.escapeHtml(message.message)}
|
|
</div>
|
|
<div class="message-time">
|
|
${this.formatDate(message.created_at)}
|
|
</div>
|
|
`;
|
|
|
|
messageContainer.appendChild(messageDiv);
|
|
});
|
|
|
|
// Scroll to bottom
|
|
messageContainer.scrollTop = messageContainer.scrollHeight;
|
|
}
|
|
|
|
displayGlobalMessages(messages) {
|
|
const globalContainer = document.querySelector('.global-messages-container');
|
|
if (!globalContainer) return;
|
|
|
|
globalContainer.innerHTML = '';
|
|
|
|
messages.forEach(message => {
|
|
const messageDiv = document.createElement('div');
|
|
messageDiv.className = 'global-message';
|
|
|
|
messageDiv.innerHTML = `
|
|
<div class="message-header">
|
|
<strong>${this.escapeHtml(message.sender_name)}</strong>
|
|
<span class="message-time">${this.formatDate(message.created_at)}</span>
|
|
</div>
|
|
<div class="message-bubble">
|
|
${this.escapeHtml(message.message)}
|
|
</div>
|
|
`;
|
|
|
|
globalContainer.appendChild(messageDiv);
|
|
});
|
|
|
|
// Scroll to bottom
|
|
globalContainer.scrollTop = globalContainer.scrollHeight;
|
|
}
|
|
|
|
startPolling() {
|
|
// Poll for new messages every 5 seconds
|
|
this.pollingInterval = setInterval(() => {
|
|
this.checkForNewMessages();
|
|
}, 5000);
|
|
|
|
// Also check for unread count
|
|
setInterval(() => {
|
|
this.updateUnreadCount();
|
|
}, 10000);
|
|
}
|
|
|
|
async checkForNewMessages() {
|
|
if (this.currentConversationUserId) {
|
|
await this.loadMessages(this.currentConversationUserId);
|
|
}
|
|
}
|
|
|
|
async updateUnreadCount() {
|
|
try {
|
|
const response = await fetch('index.php/message/unreadcount', {
|
|
headers: {
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
}
|
|
});
|
|
|
|
if (response.ok) {
|
|
const data = await response.json();
|
|
this.updateUnreadCountDisplay(data.count);
|
|
}
|
|
} catch (error) {
|
|
console.error('Error updating unread count:', error);
|
|
}
|
|
}
|
|
|
|
updateUnreadCountDisplay(count) {
|
|
const unreadElements = document.querySelectorAll('.unread-count');
|
|
unreadElements.forEach(element => {
|
|
if (count > 0) {
|
|
element.textContent = count;
|
|
element.style.display = 'inline-block';
|
|
} else {
|
|
element.style.display = 'none';
|
|
}
|
|
});
|
|
}
|
|
|
|
showFeedback(message, type) {
|
|
// Create feedback element
|
|
const feedback = document.createElement('div');
|
|
feedback.className = `feedback-${type}`;
|
|
feedback.textContent = message;
|
|
feedback.style.cssText = `
|
|
position: fixed;
|
|
top: 20px;
|
|
right: 20px;
|
|
padding: 15px 20px;
|
|
background: ${type === 'success' ? '#4caf50' : '#f44336'};
|
|
color: white;
|
|
border-radius: 4px;
|
|
z-index: 1000;
|
|
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
|
|
`;
|
|
|
|
document.body.appendChild(feedback);
|
|
|
|
// Remove after 3 seconds
|
|
setTimeout(() => {
|
|
feedback.remove();
|
|
}, 3000);
|
|
}
|
|
|
|
escapeHtml(text) {
|
|
const div = document.createElement('div');
|
|
div.textContent = text;
|
|
return div.innerHTML;
|
|
}
|
|
|
|
formatDate(dateString) {
|
|
const date = new Date(dateString);
|
|
return date.toLocaleString('en-US', {
|
|
month: 'short',
|
|
day: 'numeric',
|
|
hour: '2-digit',
|
|
minute: '2-digit'
|
|
});
|
|
}
|
|
}
|
|
|
|
// Initialize the messaging system when DOM is loaded
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
window.messagingSystem = new MessagingSystem();
|
|
});
|
|
|
|
// Make it available globally for any other scripts that might need it
|
|
window.MessagingSystem = MessagingSystem; |