Enhance browser phone with real-time updates and audible alerts
- Fix token expiration: Extend refresh buffer to 10 minutes for reliability - Add real-time queue updates: Reduce polling to 5 seconds for instant feedback - Implement audible alert system: 30-second repeating notifications with user toggle - Optimize Discord/Slack notifications: Non-blocking requests for immediate delivery - Add persistent alert preferences: Toggle button with localStorage integration - Clean up debug file: Remove unused debug-phone-numbers.php 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
		@@ -434,10 +434,33 @@
 | 
			
		||||
.queue-actions {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    gap: 8px;
 | 
			
		||||
    flex-wrap: wrap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.queue-actions .twp-btn {
 | 
			
		||||
    flex: 1;
 | 
			
		||||
    min-width: 80px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Alert Toggle Button */
 | 
			
		||||
#twp-alert-toggle {
 | 
			
		||||
    position: relative;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#twp-alert-toggle.alert-on {
 | 
			
		||||
    background-color: #28a745 !important;
 | 
			
		||||
    border-color: #28a745;
 | 
			
		||||
    color: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#twp-alert-toggle.alert-off {
 | 
			
		||||
    background-color: #6c757d !important;
 | 
			
		||||
    border-color: #6c757d;
 | 
			
		||||
    color: white;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#twp-alert-toggle:hover {
 | 
			
		||||
    opacity: 0.8;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.twp-btn-secondary {
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,11 @@
 | 
			
		||||
    let selectedQueue = null;
 | 
			
		||||
    let tokenRefreshTimer = null;
 | 
			
		||||
    let tokenExpiry = null;
 | 
			
		||||
    let queuePollingTimer = null;
 | 
			
		||||
    let lastQueueUpdate = {};
 | 
			
		||||
    let alertSound = null;
 | 
			
		||||
    let alertInterval = null;
 | 
			
		||||
    let alertEnabled = false;
 | 
			
		||||
    
 | 
			
		||||
    // Initialize when document is ready
 | 
			
		||||
    $(document).ready(function() {
 | 
			
		||||
@@ -263,6 +268,7 @@
 | 
			
		||||
        // Accept queue call button
 | 
			
		||||
        $('#twp-accept-queue-call').on('click', function() {
 | 
			
		||||
            acceptQueueCall();
 | 
			
		||||
            stopAlert(); // Stop alert when accepting call
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        // Refresh queues button
 | 
			
		||||
@@ -270,6 +276,11 @@
 | 
			
		||||
            loadUserQueues();
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        // Alert toggle button
 | 
			
		||||
        $(document).on('click', '#twp-alert-toggle', function() {
 | 
			
		||||
            toggleAlert();
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        // Queue item selection
 | 
			
		||||
        $(document).on('click', '.queue-item', function() {
 | 
			
		||||
            const queueId = $(this).data('queue-id');
 | 
			
		||||
@@ -313,6 +324,9 @@
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Stop alerts when making a call
 | 
			
		||||
        stopAlert();
 | 
			
		||||
        
 | 
			
		||||
        updateCallState('connecting');
 | 
			
		||||
        showCallInfo('Connecting...');
 | 
			
		||||
        
 | 
			
		||||
@@ -420,12 +434,20 @@
 | 
			
		||||
        updateCallState('idle');
 | 
			
		||||
        hideCallInfo();
 | 
			
		||||
        $('.twp-browser-phone-container').removeClass('incoming-call');
 | 
			
		||||
        
 | 
			
		||||
        // Restart alerts if enabled and there are waiting calls
 | 
			
		||||
        if (alertEnabled) {
 | 
			
		||||
            const hasWaitingCalls = userQueues.some(q => parseInt(q.current_waiting) > 0);
 | 
			
		||||
            if (hasWaitingCalls) {
 | 
			
		||||
                setTimeout(startAlert, 1000); // Small delay to avoid immediate alert
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Load user's assigned queues
 | 
			
		||||
     */
 | 
			
		||||
    function loadUserQueues() {
 | 
			
		||||
    function loadUserQueues(silent = false) {
 | 
			
		||||
        $.ajax({
 | 
			
		||||
            url: twp_frontend_ajax.ajax_url,
 | 
			
		||||
            method: 'POST',
 | 
			
		||||
@@ -435,18 +457,44 @@
 | 
			
		||||
            },
 | 
			
		||||
            success: function(response) {
 | 
			
		||||
                if (response.success) {
 | 
			
		||||
                    // Check for new calls in queues
 | 
			
		||||
                    checkForNewCalls(response.data);
 | 
			
		||||
                    userQueues = response.data;
 | 
			
		||||
                    displayQueues();
 | 
			
		||||
                } else {
 | 
			
		||||
                } else if (!silent) {
 | 
			
		||||
                    showMessage('Failed to load queues: ' + (response.data || 'Unknown error'), 'error');
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            error: function() {
 | 
			
		||||
                showMessage('Failed to load queues', 'error');
 | 
			
		||||
                if (!silent) {
 | 
			
		||||
                    showMessage('Failed to load queues', 'error');
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Check for new calls in queues and trigger alerts
 | 
			
		||||
     */
 | 
			
		||||
    function checkForNewCalls(newQueues) {
 | 
			
		||||
        newQueues.forEach(function(queue) {
 | 
			
		||||
            const queueId = queue.id;
 | 
			
		||||
            const currentWaiting = parseInt(queue.current_waiting) || 0;
 | 
			
		||||
            const previousWaiting = lastQueueUpdate[queueId] || 0;
 | 
			
		||||
            
 | 
			
		||||
            // If waiting count increased, we have new calls
 | 
			
		||||
            if (currentWaiting > previousWaiting) {
 | 
			
		||||
                console.log('New call detected in queue:', queue.queue_name);
 | 
			
		||||
                // Trigger alert if enabled
 | 
			
		||||
                if (alertEnabled && !currentCall) {
 | 
			
		||||
                    startAlert();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            lastQueueUpdate[queueId] = currentWaiting;
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Display queues in the UI
 | 
			
		||||
     */
 | 
			
		||||
@@ -653,16 +701,29 @@
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Periodic status updates
 | 
			
		||||
    setInterval(function() {
 | 
			
		||||
        if (isConnected) {
 | 
			
		||||
            loadUserQueues(); // This will refresh all queue data including waiting counts
 | 
			
		||||
    // Start queue polling with faster interval
 | 
			
		||||
    startQueuePolling();
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Start polling for queue updates
 | 
			
		||||
     */
 | 
			
		||||
    function startQueuePolling() {
 | 
			
		||||
        // Clear any existing timer
 | 
			
		||||
        if (queuePollingTimer) {
 | 
			
		||||
            clearInterval(queuePollingTimer);
 | 
			
		||||
        }
 | 
			
		||||
    }, 30000); // Every 30 seconds
 | 
			
		||||
        
 | 
			
		||||
        // Poll every 5 seconds for real-time updates
 | 
			
		||||
        queuePollingTimer = setInterval(function() {
 | 
			
		||||
            if (isConnected) {
 | 
			
		||||
                loadUserQueues(true); // Silent update
 | 
			
		||||
            }
 | 
			
		||||
        }, 5000); // Every 5 seconds
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Schedule token refresh
 | 
			
		||||
     * Refreshes token 5 minutes before expiry
 | 
			
		||||
     * Refreshes token 10 minutes before expiry for safety
 | 
			
		||||
     */
 | 
			
		||||
    function scheduleTokenRefresh() {
 | 
			
		||||
        // Clear any existing timer
 | 
			
		||||
@@ -672,11 +733,17 @@
 | 
			
		||||
        
 | 
			
		||||
        if (!tokenExpiry) {
 | 
			
		||||
            console.error('Token expiry time not set');
 | 
			
		||||
            // Retry in 30 seconds if token expiry not set
 | 
			
		||||
            setTimeout(function() {
 | 
			
		||||
                if (tokenExpiry) {
 | 
			
		||||
                    scheduleTokenRefresh();
 | 
			
		||||
                }
 | 
			
		||||
            }, 30000);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Calculate time until refresh (5 minutes before expiry)
 | 
			
		||||
        const refreshBuffer = 5 * 60 * 1000; // 5 minutes in milliseconds
 | 
			
		||||
        // Calculate time until refresh (10 minutes before expiry for extra safety)
 | 
			
		||||
        const refreshBuffer = 10 * 60 * 1000; // 10 minutes in milliseconds
 | 
			
		||||
        const timeUntilRefresh = tokenExpiry - Date.now() - refreshBuffer;
 | 
			
		||||
        
 | 
			
		||||
        if (timeUntilRefresh <= 0) {
 | 
			
		||||
@@ -734,14 +801,127 @@
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Initialize alert sound
 | 
			
		||||
     */
 | 
			
		||||
    function initAlertSound() {
 | 
			
		||||
        // Create audio element for alert sound
 | 
			
		||||
        alertSound = new Audio();
 | 
			
		||||
        alertSound.src = 'data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQAAAAA='; // Simple beep sound
 | 
			
		||||
        // Use Web Audio API for better sound
 | 
			
		||||
        const audioContext = new (window.AudioContext || window.webkitAudioContext)();
 | 
			
		||||
        
 | 
			
		||||
        // Create a simple beep sound
 | 
			
		||||
        function playBeep() {
 | 
			
		||||
            const oscillator = audioContext.createOscillator();
 | 
			
		||||
            const gainNode = audioContext.createGain();
 | 
			
		||||
            
 | 
			
		||||
            oscillator.connect(gainNode);
 | 
			
		||||
            gainNode.connect(audioContext.destination);
 | 
			
		||||
            
 | 
			
		||||
            oscillator.frequency.value = 800; // Frequency in Hz
 | 
			
		||||
            gainNode.gain.setValueAtTime(0.3, audioContext.currentTime);
 | 
			
		||||
            gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.5);
 | 
			
		||||
            
 | 
			
		||||
            oscillator.start(audioContext.currentTime);
 | 
			
		||||
            oscillator.stop(audioContext.currentTime + 0.5);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        return playBeep;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    const playAlertSound = initAlertSound();
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Start alert for new calls
 | 
			
		||||
     */
 | 
			
		||||
    function startAlert() {
 | 
			
		||||
        if (!alertEnabled || alertInterval) return;
 | 
			
		||||
        
 | 
			
		||||
        // Play initial alert
 | 
			
		||||
        playAlertSound();
 | 
			
		||||
        
 | 
			
		||||
        // Repeat every 30 seconds
 | 
			
		||||
        alertInterval = setInterval(function() {
 | 
			
		||||
            if (alertEnabled && !currentCall) {
 | 
			
		||||
                playAlertSound();
 | 
			
		||||
            } else {
 | 
			
		||||
                stopAlert();
 | 
			
		||||
            }
 | 
			
		||||
        }, 30000);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Stop alert
 | 
			
		||||
     */
 | 
			
		||||
    function stopAlert() {
 | 
			
		||||
        if (alertInterval) {
 | 
			
		||||
            clearInterval(alertInterval);
 | 
			
		||||
            alertInterval = null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Toggle alert on/off
 | 
			
		||||
     */
 | 
			
		||||
    function toggleAlert() {
 | 
			
		||||
        alertEnabled = !alertEnabled;
 | 
			
		||||
        localStorage.setItem('twp_alert_enabled', alertEnabled);
 | 
			
		||||
        
 | 
			
		||||
        // Update button state
 | 
			
		||||
        updateAlertButton();
 | 
			
		||||
        
 | 
			
		||||
        if (!alertEnabled) {
 | 
			
		||||
            stopAlert();
 | 
			
		||||
            showMessage('Queue alerts disabled', 'info');
 | 
			
		||||
        } else {
 | 
			
		||||
            showMessage('Queue alerts enabled', 'success');
 | 
			
		||||
            // Check if there are waiting calls
 | 
			
		||||
            const hasWaitingCalls = userQueues.some(q => parseInt(q.current_waiting) > 0);
 | 
			
		||||
            if (hasWaitingCalls && !currentCall) {
 | 
			
		||||
                startAlert();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Update alert button UI
 | 
			
		||||
     */
 | 
			
		||||
    function updateAlertButton() {
 | 
			
		||||
        const $btn = $('#twp-alert-toggle');
 | 
			
		||||
        if (alertEnabled) {
 | 
			
		||||
            $btn.removeClass('alert-off').addClass('alert-on').html('🔔 Alerts ON');
 | 
			
		||||
        } else {
 | 
			
		||||
            $btn.removeClass('alert-on').addClass('alert-off').html('🔕 Alerts OFF');
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Load alert preference from localStorage
 | 
			
		||||
     */
 | 
			
		||||
    function loadAlertPreference() {
 | 
			
		||||
        const saved = localStorage.getItem('twp_alert_enabled');
 | 
			
		||||
        alertEnabled = saved === null ? true : saved === 'true';
 | 
			
		||||
        updateAlertButton();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Clean up on page unload
 | 
			
		||||
    $(window).on('beforeunload', function() {
 | 
			
		||||
        if (tokenRefreshTimer) {
 | 
			
		||||
            clearTimeout(tokenRefreshTimer);
 | 
			
		||||
        }
 | 
			
		||||
        if (queuePollingTimer) {
 | 
			
		||||
            clearInterval(queuePollingTimer);
 | 
			
		||||
        }
 | 
			
		||||
        if (alertInterval) {
 | 
			
		||||
            clearInterval(alertInterval);
 | 
			
		||||
        }
 | 
			
		||||
        if (twilioDevice) {
 | 
			
		||||
            twilioDevice.destroy();
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    // Load alert preference on init
 | 
			
		||||
    loadAlertPreference();
 | 
			
		||||
    
 | 
			
		||||
})(jQuery);
 | 
			
		||||
@@ -1,83 +0,0 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * Debug script to see what Twilio SDK actually returns
 | 
			
		||||
 * Run this to debug phone number issues
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
// Load WordPress (adjust path as needed)
 | 
			
		||||
$wp_load_path = dirname(dirname(dirname(dirname(__FILE__)))) . '/wp-load.php';
 | 
			
		||||
if (!file_exists($wp_load_path)) {
 | 
			
		||||
    echo "WordPress not found. Please adjust the path in this script.\n";
 | 
			
		||||
    echo "Looking for: $wp_load_path\n";
 | 
			
		||||
    exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
require_once $wp_load_path;
 | 
			
		||||
 | 
			
		||||
echo "Debug: Twilio Phone Numbers\n";
 | 
			
		||||
echo "===========================\n\n";
 | 
			
		||||
 | 
			
		||||
// Load Twilio SDK
 | 
			
		||||
$autoloader = __DIR__ . '/vendor/autoload.php';
 | 
			
		||||
if (!file_exists($autoloader)) {
 | 
			
		||||
    echo "ERROR: SDK not found. Run ./install-twilio-sdk.sh first.\n";
 | 
			
		||||
    exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
require_once $autoloader;
 | 
			
		||||
 | 
			
		||||
// Get Twilio credentials from WordPress
 | 
			
		||||
$account_sid = get_option('twp_twilio_account_sid');
 | 
			
		||||
$auth_token = get_option('twp_twilio_auth_token');
 | 
			
		||||
 | 
			
		||||
if (empty($account_sid) || empty($auth_token)) {
 | 
			
		||||
    echo "ERROR: Twilio credentials not configured in WordPress.\n";
 | 
			
		||||
    exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
echo "Account SID: " . substr($account_sid, 0, 10) . "...\n";
 | 
			
		||||
echo "Auth Token: " . substr($auth_token, 0, 10) . "...\n\n";
 | 
			
		||||
 | 
			
		||||
try {
 | 
			
		||||
    // Create Twilio client
 | 
			
		||||
    $client = new \Twilio\Rest\Client($account_sid, $auth_token);
 | 
			
		||||
    echo "✅ Twilio client created successfully\n\n";
 | 
			
		||||
    
 | 
			
		||||
    // Get phone numbers
 | 
			
		||||
    echo "Fetching phone numbers...\n";
 | 
			
		||||
    $numbers = $client->incomingPhoneNumbers->read([], 10);
 | 
			
		||||
    
 | 
			
		||||
    if (empty($numbers)) {
 | 
			
		||||
        echo "No phone numbers found in your Twilio account.\n";
 | 
			
		||||
        exit(0);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    echo "Found " . count($numbers) . " phone number(s):\n\n";
 | 
			
		||||
    
 | 
			
		||||
    foreach ($numbers as $i => $number) {
 | 
			
		||||
        echo "=== Phone Number " . ($i + 1) . " ===\n";
 | 
			
		||||
        echo "SID: " . $number->sid . "\n";
 | 
			
		||||
        echo "Phone Number: " . $number->phoneNumber . "\n";
 | 
			
		||||
        echo "Friendly Name: " . ($number->friendlyName ?: '[Not set]') . "\n";
 | 
			
		||||
        echo "Voice URL: " . ($number->voiceUrl ?: '[Not set]') . "\n";
 | 
			
		||||
        echo "SMS URL: " . ($number->smsUrl ?: '[Not set]') . "\n";
 | 
			
		||||
        echo "Account SID: " . $number->accountSid . "\n";
 | 
			
		||||
        
 | 
			
		||||
        // Debug capabilities object
 | 
			
		||||
        echo "\nCapabilities (raw object):\n";
 | 
			
		||||
        var_dump($number->capabilities);
 | 
			
		||||
        
 | 
			
		||||
        echo "\nCapabilities (properties):\n";
 | 
			
		||||
        echo "- Voice: " . ($number->capabilities->voice ? 'YES' : 'NO') . "\n";
 | 
			
		||||
        echo "- SMS: " . ($number->capabilities->sms ? 'YES' : 'NO') . "\n";  
 | 
			
		||||
        echo "- MMS: " . ($number->capabilities->mms ? 'YES' : 'NO') . "\n";
 | 
			
		||||
        echo "\n" . str_repeat('-', 40) . "\n\n";
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
} catch (Exception $e) {
 | 
			
		||||
    echo "ERROR: " . $e->getMessage() . "\n";
 | 
			
		||||
    echo "Class: " . get_class($e) . "\n";
 | 
			
		||||
    exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
echo "Debug complete!\n";
 | 
			
		||||
@@ -347,12 +347,14 @@ class TWP_Notifications {
 | 
			
		||||
     * Send webhook request
 | 
			
		||||
     */
 | 
			
		||||
    private static function send_webhook_request($webhook_url, $payload, $service) {
 | 
			
		||||
        // Send notification immediately without blocking
 | 
			
		||||
        $response = wp_remote_post($webhook_url, array(
 | 
			
		||||
            'headers' => array(
 | 
			
		||||
                'Content-Type' => 'application/json',
 | 
			
		||||
            ),
 | 
			
		||||
            'body' => json_encode($payload),
 | 
			
		||||
            'timeout' => 30,
 | 
			
		||||
            'timeout' => 10, // Reduce timeout for faster processing
 | 
			
		||||
            'blocking' => false, // Non-blocking request for immediate processing
 | 
			
		||||
        ));
 | 
			
		||||
 | 
			
		||||
        if (is_wp_error($response)) {
 | 
			
		||||
@@ -360,15 +362,9 @@ class TWP_Notifications {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $response_code = wp_remote_retrieve_response_code($response);
 | 
			
		||||
        if ($response_code >= 200 && $response_code < 300) {
 | 
			
		||||
            error_log("TWP {$service} notification sent successfully");
 | 
			
		||||
            return true;
 | 
			
		||||
        } else {
 | 
			
		||||
            error_log("TWP {$service} notification failed with response code: " . $response_code);
 | 
			
		||||
            error_log("Response body: " . wp_remote_retrieve_body($response));
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        // For non-blocking requests, we can't check response code immediately
 | 
			
		||||
        error_log("TWP {$service} notification sent (non-blocking)");
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -193,6 +193,9 @@ class TWP_Shortcodes {
 | 
			
		||||
                        <button id="twp-refresh-queues" class="twp-btn twp-btn-secondary">
 | 
			
		||||
                            Refresh
 | 
			
		||||
                        </button>
 | 
			
		||||
                        <button id="twp-alert-toggle" class="twp-btn twp-btn-secondary alert-off">
 | 
			
		||||
                            🔕 Alerts OFF
 | 
			
		||||
                        </button>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user