feat: the chat's arrow down midway between the answers' right edge and the chat's border, fading in and out
This commit is contained in:
1 parent
46f7f743b3
commit
4fb26a9652
2 files changed
+18
-5
No files matched your search
@@ -25,7 +25,7 @@
|
|||||||
'<button type="button" class="btn ghost small icon close x ai-close" aria-label="Закрыть"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round"><path d="M18 6 6 18M6 6l12 12"/></svg></button></div>' +
|
'<button type="button" class="btn ghost small icon close x ai-close" aria-label="Закрыть"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.6" stroke-linecap="round"><path d="M18 6 6 18M6 6l12 12"/></svg></button></div>' +
|
||||||
'<div class="ai-chats" inert><div class="ai-chats-in"><button type="button" class="ai-chatnew">+ Новый чат</button><div class="ai-chatlist"></div></div></div>' +
|
'<div class="ai-chats" inert><div class="ai-chats-in"><button type="button" class="ai-chatnew">+ Новый чат</button><div class="ai-chatlist"></div></div></div>' +
|
||||||
'<div class="ai-chat-body"><div class="ai-list"><div class="ai-hello"><span class="ai-hello-icon"><svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 9a2 2 0 0 1-2 2H6l-4 4V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2z"/><path d="M18 9h2a2 2 0 0 1 2 2v11l-4-4h-6a2 2 0 0 1-2-2v-1"/></svg></span><span class="ai-hello-text">Спросите AI помощника</span></div></div>' +
|
'<div class="ai-chat-body"><div class="ai-list"><div class="ai-hello"><span class="ai-hello-icon"><svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 9a2 2 0 0 1-2 2H6l-4 4V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2z"/><path d="M18 9h2a2 2 0 0 1 2 2v11l-4-4h-6a2 2 0 0 1-2-2v-1"/></svg></span><span class="ai-hello-text">Спросите AI помощника</span></div></div>' +
|
||||||
'<button type="button" class="ai-jump" hidden title="К последним сообщениям" aria-label="К последним сообщениям"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14M5 12l7 7 7-7"/></svg></button>' +
|
'<button type="button" class="ai-jump" tabindex="-1" title="К последним сообщениям" aria-label="К последним сообщениям"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14M5 12l7 7 7-7"/></svg></button>' +
|
||||||
'<div class="ai-file-error" role="alert"></div></div>' +
|
'<div class="ai-file-error" role="alert"></div></div>' +
|
||||||
'<div class="ai-pills">' +
|
'<div class="ai-pills">' +
|
||||||
'<button type="button" class="ai-pill" data-mode="agent" aria-pressed="false" title="Сам выполняет шаги один за другим, спрашивая перед каждой командой и записью файла">' +
|
'<button type="button" class="ai-pill" data-mode="agent" aria-pressed="false" title="Сам выполняет шаги один за другим, спрашивая перед каждой командой и записью файла">' +
|
||||||
@@ -47,7 +47,19 @@
|
|||||||
let attachments = [];
|
let attachments = [];
|
||||||
const importingPaneFiles = new Set();
|
const importingPaneFiles = new Set();
|
||||||
const nearBottom = () => list.scrollHeight - list.scrollTop - list.clientHeight < 80;
|
const nearBottom = () => list.scrollHeight - list.scrollTop - list.clientHeight < 80;
|
||||||
function updateJump() { jump.hidden = nearBottom() || !isOpen(); }
|
function updateJump() { showJump(!nearBottom() && isOpen()); }
|
||||||
|
// The arrow down fades in and out, midway between the right edge the
|
||||||
|
// answers reach (their max-width, 92% of the list) and the chat's border.
|
||||||
|
function showJump(on) {
|
||||||
|
if (on && !jump.classList.contains('show')) {
|
||||||
|
const body = list.parentNode.getBoundingClientRect(), l = list.getBoundingClientRect(), cs = getComputedStyle(list);
|
||||||
|
const pl = parseFloat(cs.paddingLeft), inner = list.clientWidth - pl - parseFloat(cs.paddingRight);
|
||||||
|
const gap = body.right - (l.left + list.clientLeft + pl + inner * 0.92);
|
||||||
|
jump.style.right = Math.max(2, (gap - jump.offsetWidth) / 2) + 'px';
|
||||||
|
}
|
||||||
|
jump.classList.toggle('show', on);
|
||||||
|
jump.tabIndex = on ? 0 : -1;
|
||||||
|
}
|
||||||
list.addEventListener('scroll', updateJump, {passive: true});
|
list.addEventListener('scroll', updateJump, {passive: true});
|
||||||
jump.onclick = () => { list.scrollTo({top: list.scrollHeight, behavior: 'smooth'}); };
|
jump.onclick = () => { list.scrollTo({top: list.scrollHeight, behavior: 'smooth'}); };
|
||||||
function scrollIfFollowing(follow) { if (follow) list.scrollTop = list.scrollHeight; updateJump(); }
|
function scrollIfFollowing(follow) { if (follow) list.scrollTop = list.scrollHeight; updateJump(); }
|
||||||
@@ -217,7 +229,7 @@
|
|||||||
drawChats();
|
drawChats();
|
||||||
list.querySelectorAll('.ai-msg').forEach(m => m.remove());
|
list.querySelectorAll('.ai-msg').forEach(m => m.remove());
|
||||||
list.scrollTop = 0;
|
list.scrollTop = 0;
|
||||||
jump.hidden = true;
|
showJump(false);
|
||||||
hideFileError();
|
hideFileError();
|
||||||
q('.ai-hello').hidden = !!id;
|
q('.ai-hello').hidden = !!id;
|
||||||
if (!id) { updateJump(); return; }
|
if (!id) { updateJump(); return; }
|
||||||
|
|||||||
@@ -868,9 +868,10 @@ body.touch.term-active .ai-fab { bottom:104px; }
|
|||||||
.ai-hello-text { color:var(--muted); font-size:14px; font-weight:500; }
|
.ai-hello-text { color:var(--muted); font-size:14px; font-weight:500; }
|
||||||
@keyframes ai-hello-in { from { opacity:0; transform:translateY(6px); } }
|
@keyframes ai-hello-in { from { opacity:0; transform:translateY(6px); } }
|
||||||
.ai-list { height:100%; box-sizing:border-box; overflow:auto; padding:12px; display:flex; flex-direction:column; gap:10px; }
|
.ai-list { height:100%; box-sizing:border-box; overflow:auto; padding:12px; display:flex; flex-direction:column; gap:10px; }
|
||||||
.ai-jump { position:absolute; right:14px; bottom:14px; z-index:2; width:38px; height:38px; padding:0; border-radius:50%; display:inline-flex; align-items:center; justify-content:center; color:var(--text); background:var(--panel); border:1px solid var(--border); box-shadow:0 4px 14px rgba(0,0,0,.35); }
|
.ai-jump { position:absolute; right:4px; bottom:14px; z-index:2; width:32px; height:32px; padding:0; border-radius:50%; display:inline-flex; align-items:center; justify-content:center; color:var(--text); background:var(--panel); border:1px solid var(--border); box-shadow:0 4px 14px rgba(0,0,0,.35);
|
||||||
|
opacity:0; transform:translateY(8px) scale(.85); pointer-events:none; transition:opacity .2s ease, transform .2s ease, background-color .15s; }
|
||||||
|
.ai-jump.show { opacity:1; transform:none; pointer-events:auto; }
|
||||||
.ai-jump:hover { background:#202833; }
|
.ai-jump:hover { background:#202833; }
|
||||||
.ai-jump[hidden] { display:none; }
|
|
||||||
.ai-msg { max-width:92%; padding:8px 11px; border-radius:10px; font-size:14px; line-height:1.45; overflow-wrap:anywhere; }
|
.ai-msg { max-width:92%; padding:8px 11px; border-radius:10px; font-size:14px; line-height:1.45; overflow-wrap:anywhere; }
|
||||||
.ai-msg.user { align-self:flex-end; background:#16324f; white-space:normal; }
|
.ai-msg.user { align-self:flex-end; background:#16324f; white-space:normal; }
|
||||||
.ai-user-copy { white-space:pre-wrap; }
|
.ai-user-copy { white-space:pre-wrap; }
|
||||||
|
|||||||
Reference in new issue
Block a user