From 8baa1bf8a23cf70411bc4029db7a8d36625ee800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B8=D0=BA=D1=82=D0=BE=D1=80?= <78488229+viktor138irk@users.noreply.github.com> Date: Fri, 8 May 2026 21:45:56 +0900 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D0=BC=D0=BE=D0=B1=D0=B8=D0=BB=D1=8C=D0=BD=D1=8B?= =?UTF-8?q?=D0=B9=20=D0=B2=D0=B8=D0=B4=D0=B6=D0=B5=D1=82=20=D1=87=D0=B0?= =?UTF-8?q?=D1=82=D0=B0=20=D0=B8=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=BA=D0=BD=D0=BE=D0=BF=D0=BA=D0=B0=20?= =?UTF-8?q?=D0=B7=D0=B0=D0=BA=D1=80=D1=8B=D1=82=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- widget/src/widget.js | 69 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 12 deletions(-) diff --git a/widget/src/widget.js b/widget/src/widget.js index c899513..fc91ba3 100644 --- a/widget/src/widget.js +++ b/widget/src/widget.js @@ -13,35 +13,62 @@ const style = document.createElement('style'); style.textContent = ` - .raspi-chat-button{position:fixed;right:20px;bottom:20px;z-index:2147483000;border:0;border-radius:999px;background:#172033;color:#fff;padding:14px 18px;font:700 14px system-ui;box-shadow:0 14px 35px rgba(0,0,0,.18);cursor:pointer} - .raspi-chat-panel{position:fixed;right:20px;bottom:78px;z-index:2147483000;width:340px;max-width:calc(100vw - 40px);height:430px;display:none;flex-direction:column;border-radius:22px;overflow:hidden;background:#fff;box-shadow:0 22px 70px rgba(0,0,0,.22);font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif} + .raspi-chat-button{position:fixed;right:18px;bottom:18px;z-index:2147483000;border:0;border-radius:999px;background:#172033;color:#fff;padding:13px 17px;font:700 14px system-ui;box-shadow:0 14px 35px rgba(0,0,0,.18);cursor:pointer;line-height:1} + .raspi-chat-panel{position:fixed;right:18px;bottom:72px;z-index:2147483000;width:360px;max-width:calc(100vw - 32px);height:460px;max-height:calc(100vh - 96px);display:none;flex-direction:column;border-radius:22px;overflow:hidden;background:#fff;box-shadow:0 22px 70px rgba(0,0,0,.22);font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif} .raspi-chat-panel.open{display:flex} - .raspi-chat-header{padding:16px;background:#172033;color:#fff;font-weight:800} - .raspi-chat-messages{flex:1;padding:14px;overflow:auto;background:#f4f6fb;color:#172033;font-size:14px} - .raspi-chat-message{margin:0 0 10px;padding:10px 12px;border-radius:14px;background:#fff;line-height:1.45} + .raspi-chat-header{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:54px;padding:12px 14px 12px 16px;background:#172033;color:#fff;font-weight:800;line-height:1.2} + .raspi-chat-title{display:flex;flex-direction:column;gap:2px;min-width:0} + .raspi-chat-title strong{font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis} + .raspi-chat-title span{font-size:11px;font-weight:600;color:rgba(255,255,255,.68)} + .raspi-chat-close{width:34px;height:34px;display:grid;place-items:center;border:0;border-radius:12px;background:rgba(255,255,255,.1);color:#fff;font:800 22px/1 system-ui;cursor:pointer;flex:0 0 auto} + .raspi-chat-close:hover{background:rgba(255,255,255,.16)} + .raspi-chat-messages{flex:1;padding:14px;overflow:auto;background:#f4f6fb;color:#172033;font-size:14px;overscroll-behavior:contain} + .raspi-chat-message{margin:0 0 10px;padding:10px 12px;border-radius:14px;background:#fff;line-height:1.45;word-wrap:break-word;white-space:pre-wrap} .raspi-chat-message.operator{background:#dfe8ff;margin-left:18px} .raspi-chat-message.visitor{background:#fff;margin-right:18px} .raspi-chat-system{opacity:.7;font-size:12px;padding:4px 2px} - .raspi-chat-form{display:flex;gap:8px;padding:12px;border-top:1px solid #e7ebf3} - .raspi-chat-input{flex:1;border:1px solid #d7deea;border-radius:12px;padding:10px;font:14px system-ui} - .raspi-chat-send{border:0;border-radius:12px;background:#4f6bff;color:#fff;padding:0 14px;font-weight:800;cursor:pointer} + .raspi-chat-form{display:flex;gap:8px;padding:10px;border-top:1px solid #e7ebf3;background:#fff} + .raspi-chat-input{flex:1;min-width:0;border:1px solid #d7deea;border-radius:12px;padding:10px;font:14px system-ui;outline:none} + .raspi-chat-input:focus{border-color:#4f6bff;box-shadow:0 0 0 3px rgba(79,107,255,.12)} + .raspi-chat-send{border:0;border-radius:12px;background:#4f6bff;color:#fff;min-width:44px;padding:0 14px;font-weight:800;cursor:pointer} + @media (max-width: 560px){ + .raspi-chat-button{right:14px;bottom:14px;padding:13px 16px} + .raspi-chat-panel{right:10px;left:10px;bottom:74px;width:auto;max-width:none;height:min(560px,calc(100vh - 92px));max-height:calc(100vh - 92px);border-radius:20px} + .raspi-chat-header{min-height:50px;padding:10px 12px 10px 14px} + .raspi-chat-close{width:38px;height:38px;border-radius:13px} + .raspi-chat-messages{padding:12px;font-size:13px} + .raspi-chat-message.operator{margin-left:10px} + .raspi-chat-message.visitor{margin-right:10px} + .raspi-chat-form{padding:9px} + } + @media (max-height: 560px){ + .raspi-chat-panel{top:10px;bottom:10px;height:auto;max-height:none} + } `; document.head.appendChild(style); const button = document.createElement('button'); button.className = 'raspi-chat-button'; + button.type = 'button'; button.textContent = '💬 Чат'; const panel = document.createElement('section'); panel.className = 'raspi-chat-panel'; + panel.setAttribute('aria-label', 'Чат поддержки'); panel.innerHTML = ` -
StackWorks Support
+
+
+ StackWorks Support + Обычно отвечаем быстро +
+ +
Здравствуйте! Чем можем помочь?
- +
`; @@ -50,12 +77,29 @@ const messages = panel.querySelector('[data-role="messages"]'); const form = panel.querySelector('[data-role="form"]'); const input = panel.querySelector('[data-role="input"]'); + const closeButton = panel.querySelector('[data-role="close"]'); let socket = null; let reconnectTimer = null; - button.addEventListener('click', () => { - panel.classList.toggle('open'); + function openChat() { + panel.classList.add('open'); + button.style.display = 'none'; + setTimeout(() => input?.focus(), 120); + } + + function closeChat() { + panel.classList.remove('open'); + button.style.display = ''; + } + + button.addEventListener('click', openChat); + closeButton.addEventListener('click', closeChat); + + document.addEventListener('keydown', (event) => { + if (event.key === 'Escape' && panel.classList.contains('open')) { + closeChat(); + } }); function addMessage(text, type = 'visitor') { @@ -91,6 +135,7 @@ if (payload.type === 'operator_message') { addMessage(payload.message?.body || 'Новое сообщение от оператора', 'operator'); + openChat(); } } catch { // ignore invalid frames