Add comprehensive voicemail integration to browser phone
- Add AJAX endpoint for fetching user voicemails with stats and recent list - Create voicemail display section with counts, transcriptions, and playback - Implement click-to-play functionality for voicemail audio - Add refresh and view-all buttons with admin page integration - Style voicemail section with consistent design and dark mode support - Include visual indicators for recordings and formatted durations - Add mobile responsive design and hover effects 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
bindEvents();
|
||||
loadPhoneNumbers();
|
||||
loadUserQueues();
|
||||
loadUserVoicemails();
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -281,6 +282,23 @@
|
||||
toggleAlert();
|
||||
});
|
||||
|
||||
// Voicemail refresh button
|
||||
$('#twp-refresh-voicemails').on('click', function() {
|
||||
loadUserVoicemails();
|
||||
});
|
||||
|
||||
// View all voicemails button
|
||||
$('#twp-view-all-voicemails').on('click', function() {
|
||||
// Open admin voicemails page in new tab
|
||||
window.open(twp_frontend_ajax.admin_url + 'admin.php?page=twilio-wp-voicemails', '_blank');
|
||||
});
|
||||
|
||||
// Voicemail item click handler
|
||||
$(document).on('click', '.voicemail-item', function() {
|
||||
const voicemailId = $(this).data('voicemail-id');
|
||||
playVoicemail(voicemailId);
|
||||
});
|
||||
|
||||
// Queue item selection
|
||||
$(document).on('click', '.queue-item', function() {
|
||||
const queueId = $(this).data('queue-id');
|
||||
@@ -921,6 +939,119 @@
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Load user's voicemails
|
||||
*/
|
||||
function loadUserVoicemails(silent = false) {
|
||||
$.ajax({
|
||||
url: twp_frontend_ajax.ajax_url,
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: 'twp_get_user_voicemails',
|
||||
nonce: twp_frontend_ajax.nonce
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
displayVoicemails(response.data);
|
||||
} else if (!silent) {
|
||||
showMessage('Failed to load voicemails: ' + (response.data || 'Unknown error'), 'error');
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
if (!silent) {
|
||||
showMessage('Failed to load voicemails', 'error');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Display voicemails in the UI
|
||||
*/
|
||||
function displayVoicemails(data) {
|
||||
const $voicemailList = $('#twp-voicemail-list');
|
||||
|
||||
// Update stats
|
||||
$('#twp-total-voicemails').text(data.total_count || 0);
|
||||
$('#twp-today-voicemails').text(data.today_count || 0);
|
||||
|
||||
if (!data.voicemails || data.voicemails.length === 0) {
|
||||
$voicemailList.html('<div class="no-voicemails">No voicemails found.</div>');
|
||||
return;
|
||||
}
|
||||
|
||||
let html = '';
|
||||
data.voicemails.forEach(function(voicemail) {
|
||||
const hasTranscription = voicemail.transcription && voicemail.transcription !== 'No transcription';
|
||||
const hasRecording = voicemail.has_recording;
|
||||
|
||||
html += `
|
||||
<div class="voicemail-item ${hasRecording ? 'has-recording' : ''}" data-voicemail-id="${voicemail.id}">
|
||||
<div class="voicemail-header">
|
||||
<div class="voicemail-from">
|
||||
<span class="phone-icon">📞</span>
|
||||
<span class="from-number">${voicemail.from_number}</span>
|
||||
</div>
|
||||
<div class="voicemail-time">${voicemail.time_ago}</div>
|
||||
</div>
|
||||
<div class="voicemail-details">
|
||||
<div class="voicemail-duration">
|
||||
<span class="duration-icon">⏱️</span>
|
||||
<span>${formatDuration(voicemail.duration)}</span>
|
||||
</div>
|
||||
${hasRecording ? '<span class="recording-indicator">🎵 Recording</span>' : ''}
|
||||
</div>
|
||||
${hasTranscription ? `<div class="voicemail-transcription">${voicemail.transcription}</div>` : ''}
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
$voicemailList.html(html);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format duration in seconds to mm:ss
|
||||
*/
|
||||
function formatDuration(seconds) {
|
||||
if (!seconds || seconds === 0) return '0:00';
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
const remainingSeconds = seconds % 60;
|
||||
return minutes + ':' + String(remainingSeconds).padStart(2, '0');
|
||||
}
|
||||
|
||||
/**
|
||||
* Play voicemail audio
|
||||
*/
|
||||
function playVoicemail(voicemailId) {
|
||||
if (!voicemailId) return;
|
||||
|
||||
// Get voicemail audio URL and play it
|
||||
$.ajax({
|
||||
url: twp_frontend_ajax.ajax_url,
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: 'twp_get_voicemail_audio',
|
||||
voicemail_id: voicemailId,
|
||||
nonce: twp_frontend_ajax.nonce
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success && response.data.audio_url) {
|
||||
// Create and play audio element
|
||||
const audio = new Audio(response.data.audio_url);
|
||||
audio.play().catch(function(error) {
|
||||
showMessage('Failed to play voicemail: ' + error.message, 'error');
|
||||
});
|
||||
showMessage('Playing voicemail...', 'info');
|
||||
} else {
|
||||
showMessage('No audio available for this voicemail', 'error');
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
showMessage('Failed to load voicemail audio', 'error');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Load alert preference on init
|
||||
loadAlertPreference();
|
||||
|
||||
|
Reference in New Issue
Block a user