3 Commits

Author SHA1 Message Date
59df695530 Fix browser phone init not starting on mobile (window.load not firing)
All checks were successful
Create Release / build (push) Successful in 3s
The window.load event was never firing on mobile tablets, preventing
the browser phone from initializing. Changed to poll for Twilio SDK
availability instead of waiting for window.load event.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 19:12:18 -08:00
03b6e5d70f Add debug logging to browser phone for mobile troubleshooting
All checks were successful
Create Release / build (push) Successful in 4s
Adds visible debug output to track SDK loading and device registration
steps on mobile devices where the phone stays stuck on "Connecting".

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 19:02:03 -08:00
f8919af31a Fix SDK autoloader path for Twilio namespace
All checks were successful
Create Release / build (push) Successful in 3s
The SDK files are at twilio/sdk/Twilio/Rest/Client.php but the
autoloader was looking at twilio/sdk/Rest/Client.php. Fixed by
using the full class name in the path instead of stripping the
Twilio\ prefix.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 18:32:19 -08:00
3 changed files with 71 additions and 27 deletions

View File

@@ -7016,7 +7016,8 @@ class TWP_Admin {
<div class="phone-interface">
<div class="phone-display">
<div id="phone-status">Ready</div>
<div id="device-connection-status" style="font-size: 12px; color: #999; margin-top: 5px;">Connecting...</div>
<div id="device-connection-status" style="font-size: 12px; color: #999; margin-top: 5px;">Loading...</div>
<div id="twp-debug-info" style="font-size: 10px; color: #666; margin-top: 3px;"></div>
<div id="phone-number-display"></div>
<div id="call-timer" style="display: none;">00:00</div>
</div>
@@ -7674,6 +7675,7 @@ class TWP_Admin {
// Initialize the browser phone
function initializeBrowserPhone() {
debugLog('initializeBrowserPhone called');
$('#phone-status').text('Initializing...');
updateConnectionStatus('connecting');
@@ -7751,13 +7753,16 @@ class TWP_Admin {
}
async function setupTwilioDevice(token) {
debugLog('setupTwilioDevice called');
try {
// Check if Twilio SDK is available
debugLog('Twilio check: ' + (typeof Twilio) + ', Device: ' + (typeof Twilio !== 'undefined' ? typeof Twilio.Device : 'N/A'));
if (typeof Twilio === 'undefined' || !Twilio.Device) {
throw new Error('Twilio Voice SDK not loaded');
}
console.log('Setting up Twilio Device...');
debugLog('Creating Twilio.Device...');
updateConnectionStatus('connecting');
// Request media permissions before setting up device
@@ -7807,11 +7812,13 @@ class TWP_Admin {
});
console.log('Twilio Device created with audio constraints:', audioConstraints);
debugLog('Device created, setting up handlers...');
// Set up event handlers BEFORE registering
// Device registered and ready
device.on('registered', function() {
console.log('Device registered successfully');
debugLog('Device REGISTERED!');
$('#phone-status').text('Ready').css('color', '#4CAF50');
$('#call-btn').prop('disabled', false);
updateConnectionStatus('connected');
@@ -7893,10 +7900,13 @@ class TWP_Admin {
});
// Register device AFTER setting up event handlers
debugLog('Calling device.register()...');
await device.register();
debugLog('device.register() completed');
} catch (error) {
console.error('Error setting up Twilio Device:', error);
debugLog('ERROR: ' + error.message);
showError('Failed to setup device: ' + error.message);
}
}
@@ -8232,17 +8242,51 @@ class TWP_Admin {
}
});
// Debug helper
function debugLog(msg) {
console.log('TWP Debug: ' + msg);
var debugEl = $('#twp-debug-info');
if (debugEl.length) {
debugEl.append(msg + '<br>');
}
}
// Check if SDK loaded and initialize
$(window).on('load', function() {
setTimeout(function() {
if (typeof Twilio === 'undefined') {
showError('Twilio Voice SDK failed to load. Please check your internet connection and try refreshing the page.');
console.error('Twilio SDK not found. Script may be blocked or failed to load.');
} else {
debugLog('jQuery ready');
// Don't wait for window.load - it may not fire on mobile
// Instead, poll for Twilio SDK availability
var sdkCheckAttempts = 0;
var maxSdkCheckAttempts = 50; // 5 seconds max
function checkAndInitialize() {
sdkCheckAttempts++;
debugLog('SDK check #' + sdkCheckAttempts + ': ' + (typeof Twilio));
if (typeof Twilio !== 'undefined' && Twilio.Device) {
console.log('Twilio SDK loaded successfully');
debugLog('SDK OK, initializing...');
initializeBrowserPhone();
} else if (sdkCheckAttempts < maxSdkCheckAttempts) {
// Keep checking every 100ms
setTimeout(checkAndInitialize, 100);
} else {
showError('Twilio Voice SDK failed to load. Please check your internet connection and try refreshing the page.');
console.error('Twilio SDK not found after ' + sdkCheckAttempts + ' attempts.');
debugLog('SDK FAILED after ' + sdkCheckAttempts + ' attempts');
}
}
// Start checking after a brief delay
setTimeout(checkAndInitialize, 500);
// Also keep the window.load as backup for desktop
$(window).on('load', function() {
debugLog('Window loaded (backup)');
if (typeof Twilio !== 'undefined' && !device) {
debugLog('Backup init triggered');
initializeBrowserPhone();
}
}, 1000);
});
// Clean up on page unload

View File

@@ -101,8 +101,8 @@ if (!defined('TWILIO_AUTOLOADER_REGISTERED')) {
}
// Convert class name to file path
$relative_class = substr($class, 7); // Remove 'Twilio\'
$file = __DIR__ . '/twilio/sdk/' . str_replace('\\', '/', $relative_class) . '.php';
// The SDK structure is: twilio/sdk/Twilio/Rest/Client.php for Twilio\Rest\Client
$file = __DIR__ . '/twilio/sdk/' . str_replace('\\', '/', $class) . '.php';
if (file_exists($file)) {
require_once $file;
@@ -120,10 +120,10 @@ if (!defined('TWILIO_AUTOLOADER_REGISTERED')) {
// Load essential Twilio classes manually to ensure they're available
$essential_classes = [
__DIR__ . '/twilio/sdk/Rest/Client.php',
__DIR__ . '/twilio/sdk/TwiML/VoiceResponse.php',
__DIR__ . '/twilio/sdk/Exceptions/TwilioException.php',
__DIR__ . '/twilio/sdk/Security/RequestValidator.php'
__DIR__ . '/twilio/sdk/Twilio/Rest/Client.php',
__DIR__ . '/twilio/sdk/Twilio/TwiML/VoiceResponse.php',
__DIR__ . '/twilio/sdk/Twilio/Exceptions/TwilioException.php',
__DIR__ . '/twilio/sdk/Twilio/Security/RequestValidator.php'
];
foreach ($essential_classes as $class_file) {

View File

@@ -79,8 +79,8 @@ if (!defined('TWILIO_AUTOLOADER_REGISTERED')) {
}
// Convert class name to file path
$relative_class = substr($class, 7); // Remove 'Twilio\'
$file = __DIR__ . '/twilio/sdk/' . str_replace('\\', '/', $relative_class) . '.php';
// The SDK structure is: twilio/sdk/Twilio/Rest/Client.php for Twilio\Rest\Client
$file = __DIR__ . '/twilio/sdk/' . str_replace('\\', '/', $class) . '.php';
if (file_exists($file)) {
require_once $file;
@@ -98,10 +98,10 @@ if (!defined('TWILIO_AUTOLOADER_REGISTERED')) {
// Load essential Twilio classes manually to ensure they're available
$essential_classes = [
__DIR__ . '/twilio/sdk/Rest/Client.php',
__DIR__ . '/twilio/sdk/TwiML/VoiceResponse.php',
__DIR__ . '/twilio/sdk/Exceptions/TwilioException.php',
__DIR__ . '/twilio/sdk/Security/RequestValidator.php'
__DIR__ . '/twilio/sdk/Twilio/Rest/Client.php',
__DIR__ . '/twilio/sdk/Twilio/TwiML/VoiceResponse.php',
__DIR__ . '/twilio/sdk/Twilio/Exceptions/TwilioException.php',
__DIR__ . '/twilio/sdk/Twilio/Security/RequestValidator.php'
];
foreach ($essential_classes as $class_file) {