caps_enhancer/modules/novnc-redirect.js

212 lines
8.3 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ==================== МОДУЛЬ ПЕРЕАДРЕСАЦИИ NOVNC ====================
(function() {
const core = window.VideoIPRedirect;
if (!core) {
console.error('[VideoIPRedirect] CORE не загружен!');
return;
}
const debugLog = (msg, ...args) => core.debugLog('novnc', msg, ...args);
debugLog('🖥️ Загрузка модуля...');
// Главная функция - обработка страницы noVNC (переадресация или кнопка)
function handleNoVNCPage() {
debugLog('========== ОБРАБОТКА СТРАНИЦЫ NOVNC ==========');
const pageType = core.checkPageType();
if (!pageType.isNoVNCPage) {
debugLog('Это не страница noVNC, обработка не требуется');
return false;
}
debugLog('⚠️ Обнаружена страница noVNC (экран на 80 порту)');
// Получаем режим работы из конфига
const mode = core.CONFIG.novnc.mode;
debugLog('Режим работы:', mode);
if (mode === 'redirect') {
// Режим автоматической переадресации
return autoRedirect();
} else if (mode === 'button') {
// Режим добавления кнопки
return addSettingsButton();
} else {
debugLog('❌ Неизвестный режим:', mode);
return false;
}
}
// Автоматическая переадресация
function autoRedirect() {
debugLog('========== АВТОМАТИЧЕСКАЯ ПЕРЕАДРЕСАЦИЯ ==========');
const currentUrl = window.location.href;
const currentHost = window.location.hostname;
const currentPort = window.location.port || '80';
debugLog('Текущий URL:', currentUrl);
debugLog('Текущий хост:', currentHost);
debugLog('Текущий порт:', currentPort);
// Проверяем, что мы не уже на целевом порту
if (currentPort === core.TARGET_PORT_VIDEO) {
debugLog('❌ Уже на целевом порту, переадресация не нужна');
return false;
}
// Формируем новый URL с портом 5000 (настройки)
const newUrl = `http://${currentHost}:${core.TARGET_PORT_VIDEO}`;
debugLog('🔄 ВЫПОЛНЯЮ ПЕРЕАДРЕСАЦИЮ...');
debugLog(' С:', currentUrl);
debugLog(' На:', newUrl);
// Показываем уведомление пользователю
showRedirectNotification(newUrl);
// Выполняем переадресацию через задержку из конфига
const delay = core.CONFIG.novnc.redirectDelay || 500;
setTimeout(() => {
debugLog('✅ Переадресация выполнена');
window.location.href = newUrl;
}, delay);
return true;
}
// Добавление кнопки для перехода на настройки
function addSettingsButton() {
debugLog('========== ДОБАВЛЕНИЕ КНОПКИ НАСТРОЕК ==========');
// Проверяем, не добавлена ли уже кнопка
if (document.querySelector('.novnc-settings-btn')) {
debugLog('Кнопка уже добавлена');
return false;
}
const currentHost = window.location.hostname;
const settingsUrl = `http://${currentHost}:${core.TARGET_PORT_VIDEO}`;
debugLog('URL настроек:', settingsUrl);
// Создаём кнопку используя общую функцию стилизации
const button = core.createStyledButton(
`⚙️ Настройки (${currentHost}:${core.TARGET_PORT_VIDEO})`,
(e) => {
e.stopPropagation();
debugLog('Переход на настройки:', settingsUrl);
window.location.href = settingsUrl;
},
'novnc-settings-btn'
);
button.setAttribute('data-caps-ui', 'true');
button.dataset.capsUiDisplay = 'inline-block';
// Дополнительные стили для позиционирования
button.style.position = 'fixed';
button.style.top = '20px';
button.style.right = '20px';
button.style.zIndex = '999999';
button.style.margin = '0';
button.style.fontSize = '14px';
button.style.padding = '10px 20px';
// Добавляем кнопку на страницу
document.body.appendChild(button);
debugLog('✅ Кнопка настроек добавлена');
// React-приложение может заменить содержимое body — следим за удалением кнопки
const observer = new MutationObserver(() => {
if (!document.querySelector('.novnc-settings-btn')) {
debugLog('⚠️ Кнопка удалена, добавляем снова');
document.body.appendChild(button);
}
});
observer.observe(document.body, { childList: true, subtree: false });
setTimeout(() => observer.disconnect(), 15000);
return true;
}
// Показать уведомление о переадресации
function showRedirectNotification(targetUrl) {
const notification = document.createElement('div');
notification.className = 'novnc-redirect-notification';
notification.style.cssText = `
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: linear-gradient(135deg, #00BCD4 0%, #0097A7 100%);
color: white;
padding: 20px 30px;
border-radius: 12px;
box-shadow: 0 8px 24px rgba(0,0,0,0.3);
z-index: 999999;
font-family: Arial, sans-serif;
font-size: 15px;
font-weight: 600;
animation: fadeInScale 0.3s ease-out;
display: flex;
align-items: center;
gap: 15px;
max-width: 400px;
`;
notification.innerHTML = `
<div class="spinner"></div>
<div style="flex: 1;">
<div style="font-size: 16px; margin-bottom: 5px;">🔄 Переадресация...</div>
<div style="font-size: 12px; opacity: 0.9; font-weight: normal;">${targetUrl}</div>
</div>
`;
// Добавляем стили для анимации и крутилки
const style = document.createElement('style');
style.textContent = `
@keyframes fadeInScale {
from {
transform: translate(-50%, -50%) scale(0.8);
opacity: 0;
}
to {
transform: translate(-50%, -50%) scale(1);
opacity: 1;
}
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.novnc-redirect-notification .spinner {
width: 32px;
height: 32px;
border: 3px solid rgba(255, 255, 255, 0.3);
border-top: 3px solid white;
border-radius: 50%;
animation: spin 0.8s linear infinite;
flex-shrink: 0;
}
`;
document.head.appendChild(style);
document.body.appendChild(notification);
debugLog('📢 Уведомление показано');
}
// Публичный API
window.VideoIPRedirect.NoVNCRedirect = {
handleNoVNCPage: handleNoVNCPage,
autoRedirect: autoRedirect,
addSettingsButton: addSettingsButton
};
debugLog('✅ Модуль загружен');
})();