238 lines
7.7 KiB
JavaScript
238 lines
7.7 KiB
JavaScript
|
|
// AI Drawer Improvements
|
|||
|
|
// Добавляем стили для кнопок и улучшенный индикатор
|
|||
|
|
|
|||
|
|
const additionalStyles = `
|
|||
|
|
.ai-button {
|
|||
|
|
display: inline-block !important;
|
|||
|
|
padding: 8px 16px !important;
|
|||
|
|
margin: 4px !important;
|
|||
|
|
background: #007bff !important;
|
|||
|
|
color: white !important;
|
|||
|
|
border: none !important;
|
|||
|
|
border-radius: 6px !important;
|
|||
|
|
cursor: pointer !important;
|
|||
|
|
font-size: 14px !important;
|
|||
|
|
transition: background-color 0.2s !important;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.ai-button:hover {
|
|||
|
|
background: #0056b3 !important;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.ai-button.secondary {
|
|||
|
|
background: #6c757d !important;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.ai-button.secondary:hover {
|
|||
|
|
background: #545b62 !important;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.ai-button.success {
|
|||
|
|
background: #28a745 !important;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.ai-button.success:hover {
|
|||
|
|
background: #1e7e34 !important;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.ai-buttons-container {
|
|||
|
|
margin-top: 8px !important;
|
|||
|
|
display: flex !important;
|
|||
|
|
flex-wrap: wrap !important;
|
|||
|
|
gap: 4px !important;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* Полноширинный индикатор печатания */
|
|||
|
|
.ai-typing-bar {
|
|||
|
|
position: absolute !important;
|
|||
|
|
bottom: 60px !important;
|
|||
|
|
left: 0 !important;
|
|||
|
|
right: 0 !important;
|
|||
|
|
background: linear-gradient(90deg, #007bff, #0056b3) !important;
|
|||
|
|
color: white !important;
|
|||
|
|
padding: 12px 16px !important;
|
|||
|
|
font-size: 14px !important;
|
|||
|
|
font-weight: 500 !important;
|
|||
|
|
display: none !important;
|
|||
|
|
z-index: 1000 !important;
|
|||
|
|
box-shadow: 0 -2px 10px rgba(0,123,255,0.3) !important;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.ai-typing-bar.show {
|
|||
|
|
display: block !important;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.ai-typing-bar::before {
|
|||
|
|
content: "🤖" !important;
|
|||
|
|
margin-right: 8px !important;
|
|||
|
|
font-size: 16px !important;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.ai-typing-text::after {
|
|||
|
|
content: "|" !important;
|
|||
|
|
animation: blink 1s infinite !important;
|
|||
|
|
font-weight: bold !important;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@keyframes blink {
|
|||
|
|
0%, 50% { opacity: 1; }
|
|||
|
|
51%, 100% { opacity: 0; }
|
|||
|
|
}
|
|||
|
|
`;
|
|||
|
|
|
|||
|
|
// Функция для добавления кнопок к сообщению
|
|||
|
|
function addButtonsToMessage(messageElement, buttons) {
|
|||
|
|
if (!buttons || buttons.length === 0) return;
|
|||
|
|
|
|||
|
|
const buttonContainer = document.createElement('div');
|
|||
|
|
buttonContainer.className = 'ai-buttons-container';
|
|||
|
|
|
|||
|
|
buttons.forEach(button => {
|
|||
|
|
const btn = document.createElement('button');
|
|||
|
|
btn.className = `ai-button ${button.type || 'secondary'}`;
|
|||
|
|
btn.textContent = button.text;
|
|||
|
|
btn.onclick = () => {
|
|||
|
|
if (button.action) {
|
|||
|
|
button.action();
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
buttonContainer.appendChild(btn);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
messageElement.appendChild(buttonContainer);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Функция для улучшенного эффекта печатания
|
|||
|
|
function typeMessageImproved(element, text, speed = 30) {
|
|||
|
|
let i = 0;
|
|||
|
|
element.textContent = '';
|
|||
|
|
|
|||
|
|
function typeChar() {
|
|||
|
|
if (i < text.length) {
|
|||
|
|
element.textContent += text.charAt(i);
|
|||
|
|
i++;
|
|||
|
|
|
|||
|
|
// Динамическая скорость - быстрее для пробелов и знаков препинания
|
|||
|
|
const currentChar = text.charAt(i - 1);
|
|||
|
|
const delay = (currentChar === ' ' || currentChar === '.' || currentChar === '!') ? speed * 0.5 : speed;
|
|||
|
|
|
|||
|
|
setTimeout(typeChar, delay);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
typeChar();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Добавляем стили в head
|
|||
|
|
const styleElement = document.createElement('style');
|
|||
|
|
styleElement.textContent = additionalStyles;
|
|||
|
|
document.head.appendChild(styleElement);
|
|||
|
|
|
|||
|
|
// Функции для управления полноширинным индикатором
|
|||
|
|
function showTypingBar(message = "🤖 Обрабатываю запрос... (это может занять до 3 минут)") {
|
|||
|
|
let typingBar = document.querySelector('.ai-typing-bar');
|
|||
|
|
|
|||
|
|
if (!typingBar) {
|
|||
|
|
// Создаем индикатор если его нет
|
|||
|
|
typingBar = document.createElement('div');
|
|||
|
|
typingBar.className = 'ai-typing-bar';
|
|||
|
|
typingBar.innerHTML = '<span class="ai-typing-text"></span>';
|
|||
|
|
|
|||
|
|
// Добавляем в AI Drawer
|
|||
|
|
const drawer = document.querySelector('.ai-drawer');
|
|||
|
|
if (drawer) {
|
|||
|
|
drawer.appendChild(typingBar);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Устанавливаем текст
|
|||
|
|
const typingText = typingBar.querySelector('.ai-typing-text');
|
|||
|
|
if (typingText) {
|
|||
|
|
typingText.textContent = message;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Показываем
|
|||
|
|
typingBar.classList.add('show');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function hideTypingBar() {
|
|||
|
|
const typingBar = document.querySelector('.ai-typing-bar');
|
|||
|
|
if (typingBar) {
|
|||
|
|
typingBar.classList.remove('show');
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Функция для демонстрации плавающего индикатора загрузки
|
|||
|
|
function demonstrateFloatingLoading() {
|
|||
|
|
if (window.aiDrawerInstance) {
|
|||
|
|
window.aiDrawerInstance.showLoading('🤖 Обрабатываю ваш запрос...');
|
|||
|
|
|
|||
|
|
// Скрываем через 3 секунды для демонстрации
|
|||
|
|
setTimeout(() => {
|
|||
|
|
window.aiDrawerInstance.hideLoading();
|
|||
|
|
window.aiDrawerInstance.addMessage('Запрос обработан! Вот результат...', false);
|
|||
|
|
}, 3000);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Функция для демонстрации добавления сообщения пользователя
|
|||
|
|
function addUserMessage(text) {
|
|||
|
|
if (window.aiDrawerInstance) {
|
|||
|
|
window.aiDrawerInstance.addMessage(text, true);
|
|||
|
|
|
|||
|
|
// Показываем индикатор загрузки
|
|||
|
|
setTimeout(() => {
|
|||
|
|
demonstrateFloatingLoading();
|
|||
|
|
}, 500);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Функция для демонстрации стриминга
|
|||
|
|
function demonstrateStreaming() {
|
|||
|
|
if (window.aiDrawerInstance) {
|
|||
|
|
console.log('AI Drawer: Demonstrating streaming');
|
|||
|
|
|
|||
|
|
const longText = "Это демонстрация стриминга сообщений! Текст появляется постепенно, символ за символом, создавая эффект печатания. Это делает интерфейс более живым и интересным. Пользователь видит, как ассистент 'печатает' ответ в реальном времени.";
|
|||
|
|
|
|||
|
|
window.aiDrawerInstance.addStreamingMessage(longText, false, 20);
|
|||
|
|
} else {
|
|||
|
|
console.error('AI Drawer: Instance not found');
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Функция для демонстрации индикатора печатания
|
|||
|
|
function demonstrateTypingIndicator() {
|
|||
|
|
if (window.aiDrawerInstance) {
|
|||
|
|
console.log('AI Drawer: Demonstrating typing indicator');
|
|||
|
|
|
|||
|
|
// Показываем индикатор
|
|||
|
|
window.aiDrawerInstance.showTypingIndicator();
|
|||
|
|
|
|||
|
|
// Через 3 секунды скрываем и показываем сообщение
|
|||
|
|
setTimeout(() => {
|
|||
|
|
window.aiDrawerInstance.hideTypingIndicator();
|
|||
|
|
window.aiDrawerInstance.addStreamingMessage("Вот и готов ответ! Индикатор печатания исчез, и появился текст.", false, 25);
|
|||
|
|
}, 3000);
|
|||
|
|
} else {
|
|||
|
|
console.error('AI Drawer: Instance not found');
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Экспортируем функции
|
|||
|
|
window.AIDrawerImprovements = {
|
|||
|
|
addButtonsToMessage,
|
|||
|
|
typeMessageImproved,
|
|||
|
|
showTypingBar,
|
|||
|
|
hideTypingBar,
|
|||
|
|
demonstrateFloatingLoading,
|
|||
|
|
addUserMessage,
|
|||
|
|
demonstrateStreaming,
|
|||
|
|
demonstrateTypingIndicator
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// Экспортируем функции глобально для удобства
|
|||
|
|
window.demonstrateStreaming = demonstrateStreaming;
|
|||
|
|
window.demonstrateTypingIndicator = demonstrateTypingIndicator;
|
|||
|
|
|
|||
|
|
console.log('AI Drawer Improvements loaded');
|