Fix browser phone call control buttons not appearing
## Frontend Issues Fixed - Call control panel visibility during connected calls - Button event handlers properly bound - JavaScript localization includes user_id for personal queues ## Backend Browser Phone Enhanced - Added complete call control panel with Hold, Transfer, Requeue, Record buttons - Integrated admin-specific JavaScript functions for all call controls - Added agent selection dialogs with status indicators - Call control panel shows/hides based on call state - Button state management (hold/unhold, record/stop recording) - WordPress admin styling with dashicons ## Technical Improvements - Separate admin button IDs to avoid conflicts with frontend - Enhanced call state management in setupCallHandlers() - Admin notification system for user feedback - Proper cleanup when calls end 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -5598,13 +5598,22 @@ class TWP_Admin {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="phone-controls-extra" style="display: none;">
|
<!-- Call Control Panel (shown during active calls) -->
|
||||||
<button id="mute-btn" class="button">
|
<div class="phone-controls-extra" id="admin-call-controls-panel" style="display: none;">
|
||||||
<span class="dashicons dashicons-microphone"></span> Mute
|
<div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin: 15px 0;">
|
||||||
</button>
|
<button id="admin-hold-btn" class="button" title="Put call on hold">
|
||||||
<button id="hold-btn" class="button">
|
<span class="dashicons dashicons-controls-pause"></span> Hold
|
||||||
<span class="dashicons dashicons-controls-pause"></span> Hold
|
</button>
|
||||||
</button>
|
<button id="admin-transfer-btn" class="button" title="Transfer to another agent">
|
||||||
|
<span class="dashicons dashicons-share-alt"></span> Transfer
|
||||||
|
</button>
|
||||||
|
<button id="admin-requeue-btn" class="button" title="Put call back in queue">
|
||||||
|
<span class="dashicons dashicons-backup"></span> Requeue
|
||||||
|
</button>
|
||||||
|
<button id="admin-record-btn" class="button" title="Start/stop recording">
|
||||||
|
<span class="dashicons dashicons-controls-volumeon"></span> Record
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -6064,6 +6073,7 @@ class TWP_Admin {
|
|||||||
$('#answer-btn').hide();
|
$('#answer-btn').hide();
|
||||||
$('#hangup-btn').show();
|
$('#hangup-btn').show();
|
||||||
$('#phone-controls-extra').show();
|
$('#phone-controls-extra').show();
|
||||||
|
$('#admin-call-controls-panel').show();
|
||||||
startCallTimer();
|
startCallTimer();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -6075,8 +6085,13 @@ class TWP_Admin {
|
|||||||
$('#answer-btn').hide();
|
$('#answer-btn').hide();
|
||||||
$('#call-btn').show();
|
$('#call-btn').show();
|
||||||
$('#phone-controls-extra').hide();
|
$('#phone-controls-extra').hide();
|
||||||
|
$('#admin-call-controls-panel').hide();
|
||||||
$('#call-timer').hide();
|
$('#call-timer').hide();
|
||||||
stopCallTimer();
|
stopCallTimer();
|
||||||
|
|
||||||
|
// Reset button states
|
||||||
|
$('#admin-hold-btn').text('Hold').removeClass('btn-active');
|
||||||
|
$('#admin-record-btn').text('Record').removeClass('btn-active');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Call rejected
|
// Call rejected
|
||||||
@@ -6287,6 +6302,31 @@ class TWP_Admin {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Admin call control buttons
|
||||||
|
$('#admin-hold-btn').on('click', function() {
|
||||||
|
if (currentCall) {
|
||||||
|
adminToggleHold();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#admin-transfer-btn').on('click', function() {
|
||||||
|
if (currentCall) {
|
||||||
|
adminShowTransferDialog();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#admin-requeue-btn').on('click', function() {
|
||||||
|
if (currentCall) {
|
||||||
|
adminShowRequeueDialog();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#admin-record-btn').on('click', function() {
|
||||||
|
if (currentCall) {
|
||||||
|
adminToggleRecording();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Check if SDK loaded and initialize
|
// Check if SDK loaded and initialize
|
||||||
$(window).on('load', function() {
|
$(window).on('load', function() {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
@@ -6431,6 +6471,345 @@ class TWP_Admin {
|
|||||||
button.prop('disabled', false).text('Save Changes');
|
button.prop('disabled', false).text('Save Changes');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Admin call control functions
|
||||||
|
var adminIsOnHold = false;
|
||||||
|
var adminIsRecording = false;
|
||||||
|
var adminRecordingSid = null;
|
||||||
|
|
||||||
|
function adminToggleHold() {
|
||||||
|
if (!currentCall) return;
|
||||||
|
|
||||||
|
var callSid = currentCall.parameters.CallSid || currentCall.customParameters.CallSid;
|
||||||
|
var $holdBtn = $('#admin-hold-btn');
|
||||||
|
|
||||||
|
$.post(ajaxurl, {
|
||||||
|
action: 'twp_toggle_hold',
|
||||||
|
call_sid: callSid,
|
||||||
|
hold: !adminIsOnHold,
|
||||||
|
nonce: '<?php echo wp_create_nonce('twp_ajax_nonce'); ?>'
|
||||||
|
}, function(response) {
|
||||||
|
if (response.success) {
|
||||||
|
adminIsOnHold = !adminIsOnHold;
|
||||||
|
if (adminIsOnHold) {
|
||||||
|
$holdBtn.html('<span class="dashicons dashicons-controls-play"></span> Unhold').addClass('btn-active');
|
||||||
|
showNotice('Call placed on hold', 'info');
|
||||||
|
} else {
|
||||||
|
$holdBtn.html('<span class="dashicons dashicons-controls-pause"></span> Hold').removeClass('btn-active');
|
||||||
|
showNotice('Call resumed', 'info');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showNotice('Failed to toggle hold: ' + (response.data || 'Unknown error'), 'error');
|
||||||
|
}
|
||||||
|
}).fail(function() {
|
||||||
|
showNotice('Failed to toggle hold', 'error');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function adminShowTransferDialog() {
|
||||||
|
if (!currentCall) return;
|
||||||
|
|
||||||
|
// Load available agents
|
||||||
|
$.post(ajaxurl, {
|
||||||
|
action: 'twp_get_online_agents',
|
||||||
|
nonce: '<?php echo wp_create_nonce('twp_ajax_nonce'); ?>'
|
||||||
|
}, function(response) {
|
||||||
|
if (response.success && response.data.length > 0) {
|
||||||
|
adminShowAgentTransferDialog(response.data);
|
||||||
|
} else {
|
||||||
|
adminShowManualTransferDialog();
|
||||||
|
}
|
||||||
|
}).fail(function() {
|
||||||
|
adminShowManualTransferDialog();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function adminShowAgentTransferDialog(agents) {
|
||||||
|
var agentOptions = '<div class="agent-list" style="max-height: 200px; overflow-y: auto; border: 1px solid #ccc; margin: 10px 0;">';
|
||||||
|
|
||||||
|
agents.forEach(function(agent) {
|
||||||
|
var statusClass = agent.is_available ? 'available' : 'busy';
|
||||||
|
var statusText = agent.is_available ? '🟢 Available' : '🔴 Busy';
|
||||||
|
var methodIcon = agent.has_phone ? '📱' : '💻';
|
||||||
|
|
||||||
|
agentOptions += '<div class="agent-option" style="padding: 10px; border-bottom: 1px solid #eee; cursor: pointer; display: flex; justify-content: space-between;" data-agent-id="' + agent.id + '" data-transfer-method="' + agent.transfer_method + '" data-transfer-value="' + agent.transfer_value + '">';
|
||||||
|
agentOptions += '<div><strong>' + agent.name + '</strong> ' + methodIcon + '</div>';
|
||||||
|
agentOptions += '<div>' + statusText + '</div>';
|
||||||
|
agentOptions += '</div>';
|
||||||
|
});
|
||||||
|
|
||||||
|
agentOptions += '</div>';
|
||||||
|
|
||||||
|
var dialogHtml = '<div id="admin-transfer-dialog" style="position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; padding: 20px; border: 1px solid #ccc; box-shadow: 0 4px 20px rgba(0,0,0,0.3); z-index: 10000; width: 400px;">';
|
||||||
|
dialogHtml += '<h3>Transfer Call to Agent</h3>';
|
||||||
|
dialogHtml += '<p>Select an agent to transfer this call to:</p>';
|
||||||
|
dialogHtml += agentOptions;
|
||||||
|
dialogHtml += '<p>Or enter phone number manually:</p>';
|
||||||
|
dialogHtml += '<input type="tel" id="admin-transfer-manual" placeholder="+1234567890" style="width: 100%; margin: 10px 0; padding: 8px;" />';
|
||||||
|
dialogHtml += '<div style="text-align: right; margin-top: 15px;">';
|
||||||
|
dialogHtml += '<button id="admin-confirm-transfer" class="button button-primary" style="margin-right: 10px;" disabled>Transfer</button>';
|
||||||
|
dialogHtml += '<button id="admin-cancel-transfer" class="button">Cancel</button>';
|
||||||
|
dialogHtml += '</div>';
|
||||||
|
dialogHtml += '</div>';
|
||||||
|
dialogHtml += '<div id="admin-transfer-overlay" style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.5); z-index: 9999;"></div>';
|
||||||
|
|
||||||
|
$('body').append(dialogHtml);
|
||||||
|
|
||||||
|
var selectedAgent = null;
|
||||||
|
|
||||||
|
$('.agent-option').on('click', function() {
|
||||||
|
$('.agent-option').css('background', '');
|
||||||
|
$(this).css('background', '#e7f3ff');
|
||||||
|
selectedAgent = {
|
||||||
|
id: $(this).data('agent-id'),
|
||||||
|
method: $(this).data('transfer-method'),
|
||||||
|
value: $(this).data('transfer-value')
|
||||||
|
};
|
||||||
|
$('#admin-transfer-manual').val('');
|
||||||
|
$('#admin-confirm-transfer').prop('disabled', false);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#admin-transfer-manual').on('input', function() {
|
||||||
|
var number = $(this).val().trim();
|
||||||
|
if (number) {
|
||||||
|
$('.agent-option').css('background', '');
|
||||||
|
selectedAgent = null;
|
||||||
|
$('#admin-confirm-transfer').prop('disabled', false);
|
||||||
|
} else {
|
||||||
|
$('#admin-confirm-transfer').prop('disabled', !selectedAgent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#admin-confirm-transfer').on('click', function() {
|
||||||
|
var manualNumber = $('#admin-transfer-manual').val().trim();
|
||||||
|
if (manualNumber) {
|
||||||
|
adminTransferCall(manualNumber);
|
||||||
|
} else if (selectedAgent) {
|
||||||
|
adminTransferToAgent(selectedAgent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#admin-cancel-transfer, #admin-transfer-overlay').on('click', function() {
|
||||||
|
adminHideTransferDialog();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function adminShowManualTransferDialog() {
|
||||||
|
var dialogHtml = '<div id="admin-transfer-dialog" style="position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; padding: 20px; border: 1px solid #ccc; box-shadow: 0 4px 20px rgba(0,0,0,0.3); z-index: 10000;">';
|
||||||
|
dialogHtml += '<h3>Transfer Call</h3>';
|
||||||
|
dialogHtml += '<p>Enter the phone number to transfer this call:</p>';
|
||||||
|
dialogHtml += '<input type="tel" id="admin-transfer-number" placeholder="+1234567890" style="width: 100%; margin: 10px 0; padding: 8px;" />';
|
||||||
|
dialogHtml += '<div style="text-align: right; margin-top: 15px;">';
|
||||||
|
dialogHtml += '<button id="admin-confirm-transfer" class="button button-primary" style="margin-right: 10px;">Transfer</button>';
|
||||||
|
dialogHtml += '<button id="admin-cancel-transfer" class="button">Cancel</button>';
|
||||||
|
dialogHtml += '</div>';
|
||||||
|
dialogHtml += '</div>';
|
||||||
|
dialogHtml += '<div id="admin-transfer-overlay" style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.5); z-index: 9999;"></div>';
|
||||||
|
|
||||||
|
$('body').append(dialogHtml);
|
||||||
|
|
||||||
|
$('#admin-confirm-transfer').on('click', function() {
|
||||||
|
var number = $('#admin-transfer-number').val().trim();
|
||||||
|
if (number) {
|
||||||
|
adminTransferCall(number);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#admin-cancel-transfer, #admin-transfer-overlay').on('click', function() {
|
||||||
|
adminHideTransferDialog();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function adminTransferCall(phoneNumber) {
|
||||||
|
if (!currentCall) return;
|
||||||
|
|
||||||
|
var callSid = currentCall.parameters.CallSid || currentCall.customParameters.CallSid;
|
||||||
|
|
||||||
|
$.post(ajaxurl, {
|
||||||
|
action: 'twp_transfer_call',
|
||||||
|
call_sid: callSid,
|
||||||
|
agent_number: phoneNumber,
|
||||||
|
nonce: '<?php echo wp_create_nonce('twp_ajax_nonce'); ?>'
|
||||||
|
}, function(response) {
|
||||||
|
if (response.success) {
|
||||||
|
showNotice('Call transferred successfully', 'success');
|
||||||
|
adminHideTransferDialog();
|
||||||
|
if (currentCall) {
|
||||||
|
currentCall.disconnect();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showNotice('Failed to transfer call: ' + (response.data || 'Unknown error'), 'error');
|
||||||
|
}
|
||||||
|
}).fail(function() {
|
||||||
|
showNotice('Failed to transfer call', 'error');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function adminTransferToAgent(agent) {
|
||||||
|
if (!currentCall) return;
|
||||||
|
|
||||||
|
var callSid = currentCall.parameters.CallSid || currentCall.customParameters.CallSid;
|
||||||
|
|
||||||
|
$.post(ajaxurl, {
|
||||||
|
action: 'twp_transfer_to_agent_queue',
|
||||||
|
call_sid: callSid,
|
||||||
|
agent_id: agent.id,
|
||||||
|
transfer_method: agent.method,
|
||||||
|
transfer_value: agent.value,
|
||||||
|
nonce: '<?php echo wp_create_nonce('twp_ajax_nonce'); ?>'
|
||||||
|
}, function(response) {
|
||||||
|
if (response.success) {
|
||||||
|
showNotice('Call transferred successfully', 'success');
|
||||||
|
adminHideTransferDialog();
|
||||||
|
if (currentCall) {
|
||||||
|
currentCall.disconnect();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showNotice('Failed to transfer call: ' + (response.data || 'Unknown error'), 'error');
|
||||||
|
}
|
||||||
|
}).fail(function() {
|
||||||
|
showNotice('Failed to transfer call', 'error');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function adminHideTransferDialog() {
|
||||||
|
$('#admin-transfer-dialog, #admin-transfer-overlay').remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
function adminShowRequeueDialog() {
|
||||||
|
if (!currentCall) return;
|
||||||
|
|
||||||
|
$.post(ajaxurl, {
|
||||||
|
action: 'twp_get_all_queues',
|
||||||
|
nonce: '<?php echo wp_create_nonce('twp_ajax_nonce'); ?>'
|
||||||
|
}, function(response) {
|
||||||
|
if (response.success && response.data.length > 0) {
|
||||||
|
var options = '';
|
||||||
|
response.data.forEach(function(queue) {
|
||||||
|
options += '<option value="' + queue.id + '">' + queue.queue_name + '</option>';
|
||||||
|
});
|
||||||
|
|
||||||
|
var dialogHtml = '<div id="admin-requeue-dialog" style="position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; padding: 20px; border: 1px solid #ccc; box-shadow: 0 4px 20px rgba(0,0,0,0.3); z-index: 10000;">';
|
||||||
|
dialogHtml += '<h3>Requeue Call</h3>';
|
||||||
|
dialogHtml += '<p>Select a queue to transfer this call to:</p>';
|
||||||
|
dialogHtml += '<select id="admin-requeue-select" style="width: 100%; margin: 10px 0; padding: 8px;">' + options + '</select>';
|
||||||
|
dialogHtml += '<div style="text-align: right; margin-top: 15px;">';
|
||||||
|
dialogHtml += '<button id="admin-confirm-requeue" class="button button-primary" style="margin-right: 10px;">Requeue</button>';
|
||||||
|
dialogHtml += '<button id="admin-cancel-requeue" class="button">Cancel</button>';
|
||||||
|
dialogHtml += '</div>';
|
||||||
|
dialogHtml += '</div>';
|
||||||
|
dialogHtml += '<div id="admin-requeue-overlay" style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.5); z-index: 9999;"></div>';
|
||||||
|
|
||||||
|
$('body').append(dialogHtml);
|
||||||
|
|
||||||
|
$('#admin-confirm-requeue').on('click', function() {
|
||||||
|
var queueId = $('#admin-requeue-select').val();
|
||||||
|
if (queueId) {
|
||||||
|
adminRequeueCall(queueId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#admin-cancel-requeue, #admin-requeue-overlay').on('click', function() {
|
||||||
|
$('#admin-requeue-dialog, #admin-requeue-overlay').remove();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
showNotice('No queues available', 'error');
|
||||||
|
}
|
||||||
|
}).fail(function() {
|
||||||
|
showNotice('Failed to load queues', 'error');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function adminRequeueCall(queueId) {
|
||||||
|
if (!currentCall) return;
|
||||||
|
|
||||||
|
var callSid = currentCall.parameters.CallSid || currentCall.customParameters.CallSid;
|
||||||
|
|
||||||
|
$.post(ajaxurl, {
|
||||||
|
action: 'twp_requeue_call',
|
||||||
|
call_sid: callSid,
|
||||||
|
queue_id: queueId,
|
||||||
|
nonce: '<?php echo wp_create_nonce('twp_ajax_nonce'); ?>'
|
||||||
|
}, function(response) {
|
||||||
|
if (response.success) {
|
||||||
|
showNotice('Call requeued successfully', 'success');
|
||||||
|
$('#admin-requeue-dialog, #admin-requeue-overlay').remove();
|
||||||
|
if (currentCall) {
|
||||||
|
currentCall.disconnect();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showNotice('Failed to requeue call: ' + (response.data || 'Unknown error'), 'error');
|
||||||
|
}
|
||||||
|
}).fail(function() {
|
||||||
|
showNotice('Failed to requeue call', 'error');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function adminToggleRecording() {
|
||||||
|
if (!currentCall) return;
|
||||||
|
|
||||||
|
if (adminIsRecording) {
|
||||||
|
adminStopRecording();
|
||||||
|
} else {
|
||||||
|
adminStartRecording();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function adminStartRecording() {
|
||||||
|
var callSid = currentCall.parameters.CallSid || currentCall.customParameters.CallSid;
|
||||||
|
var $recordBtn = $('#admin-record-btn');
|
||||||
|
|
||||||
|
$.post(ajaxurl, {
|
||||||
|
action: 'twp_start_recording',
|
||||||
|
call_sid: callSid,
|
||||||
|
nonce: '<?php echo wp_create_nonce('twp_ajax_nonce'); ?>'
|
||||||
|
}, function(response) {
|
||||||
|
if (response.success) {
|
||||||
|
adminIsRecording = true;
|
||||||
|
adminRecordingSid = response.data.recording_sid;
|
||||||
|
$recordBtn.html('<span class="dashicons dashicons-controls-volumeoff"></span> Stop Recording').addClass('btn-active');
|
||||||
|
showNotice('Recording started', 'success');
|
||||||
|
} else {
|
||||||
|
showNotice('Failed to start recording: ' + (response.data || 'Unknown error'), 'error');
|
||||||
|
}
|
||||||
|
}).fail(function() {
|
||||||
|
showNotice('Failed to start recording', 'error');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function adminStopRecording() {
|
||||||
|
if (!adminRecordingSid) return;
|
||||||
|
|
||||||
|
var callSid = currentCall ? (currentCall.parameters.CallSid || currentCall.customParameters.CallSid) : '';
|
||||||
|
var $recordBtn = $('#admin-record-btn');
|
||||||
|
|
||||||
|
$.post(ajaxurl, {
|
||||||
|
action: 'twp_stop_recording',
|
||||||
|
call_sid: callSid,
|
||||||
|
recording_sid: adminRecordingSid,
|
||||||
|
nonce: '<?php echo wp_create_nonce('twp_ajax_nonce'); ?>'
|
||||||
|
}, function(response) {
|
||||||
|
if (response.success) {
|
||||||
|
adminIsRecording = false;
|
||||||
|
adminRecordingSid = null;
|
||||||
|
$recordBtn.html('<span class="dashicons dashicons-controls-volumeon"></span> Record').removeClass('btn-active');
|
||||||
|
showNotice('Recording stopped', 'info');
|
||||||
|
} else {
|
||||||
|
showNotice('Failed to stop recording: ' + (response.data || 'Unknown error'), 'error');
|
||||||
|
}
|
||||||
|
}).fail(function() {
|
||||||
|
showNotice('Failed to stop recording', 'error');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function showNotice(message, type) {
|
||||||
|
var noticeClass = type === 'error' ? 'notice-error' : (type === 'success' ? 'notice-success' : 'notice-info');
|
||||||
|
var notice = $('<div class="notice ' + noticeClass + ' is-dismissible" style="margin: 10px 0;"><p>' + message + '</p></div>');
|
||||||
|
$('.browser-phone-container').prepend(notice);
|
||||||
|
setTimeout(function() {
|
||||||
|
notice.fadeOut();
|
||||||
|
}, 4000);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
Reference in New Issue
Block a user