|
218 | 218 | .model-text{flex:1;white-space:pre-wrap} |
219 | 219 | .bubble.error{background:var(--bg-error-container);color:var(--text-on-error-container);width:100%;max-width:100%} |
220 | 220 | .bubble-wrap.error-wrap{display:block} |
221 | | -.pending-dots{display:inline-block;margin-left:6px;font-size:16px;line-height:1;animation:blink 1.2s infinite} |
222 | | -@keyframes blink{0%,100%{opacity:.2}50%{opacity:1}} |
| 221 | +/* pending-dots removed – replaced by spinner on model-icon */ |
| 222 | +.model-icon.loading{background:transparent;font-size:0} |
| 223 | +.model-icon.loading::after{content:'';display:block;width:18px;height:18px;border:2.5px solid var(--outline);border-top-color:var(--primary);border-radius:50%;animation:ai-spin 1.4s linear infinite} |
| 224 | +/* Use CSS-driven keyframe – unaffected by Android animator duration scale */ |
| 225 | +@keyframes ai-spin{to{transform:rotate(360deg)}} |
223 | 226 |
|
224 | 227 | /* ── Command status card ─────────────────────────────────── */ |
225 | 228 | .cmd-status-card{background:var(--bg-secondary-container);border-radius:12px;padding:12px 14px;margin:6px 0;font-size:13px;color:var(--text-on-secondary-container)} |
|
1038 | 1041 | const allModelBubbles = [...msgs.querySelectorAll('.bubble.model')]; |
1039 | 1042 | const last = allModelBubbles.length ? allModelBubbles[allModelBubbles.length - 1] : null; |
1040 | 1043 | const parentWrap = last && last.closest('.bubble-wrap'); |
1041 | | - if (parentWrap && parentWrap.querySelector('.pending-dots')) { |
| 1044 | + if (parentWrap && last.querySelector('.model-icon.loading')) { |
1042 | 1045 | const textSpan = last.querySelector('.model-text') || last; |
1043 | | - // Preserve the icon span if present |
1044 | | - const icon = last.querySelector('.model-icon'); |
1045 | | - if (icon) { |
1046 | | - textSpan.textContent = text; |
1047 | | - if (!isPending) parentWrap.querySelector('.pending-dots')?.remove(); |
1048 | | - } else { |
1049 | | - last.textContent = text; |
1050 | | - if (!isPending) parentWrap.querySelector('.pending-dots')?.remove(); |
| 1046 | + textSpan.textContent = text; |
| 1047 | + if (!isPending) { |
| 1048 | + // Swap spinner icon → real avatar icon |
| 1049 | + const icon = last.querySelector('.model-icon'); |
| 1050 | + if (icon) { icon.classList.remove('loading'); icon.innerHTML = '👤'; } |
1051 | 1051 | } |
1052 | 1052 | } else { |
1053 | 1053 | addModelBubble(text, isPending); |
|
3442 | 3442 | function addModelBubble(text, isPending) { |
3443 | 3443 | const wrap = document.createElement('div'); |
3444 | 3444 | wrap.className = 'bubble-wrap'; |
3445 | | - wrap.innerHTML = `<div class="bubble model"><span class="model-icon">👤</span><span class="model-text">${escHtml(text)}${isPending?'<span class="pending-dots">…</span>':''}</span></div>`; |
| 3445 | + wrap.innerHTML = `<div class="bubble model"><span class="model-icon${isPending?' loading':''}">&#${isPending?'0':128100};</span><span class="model-text">${escHtml(text)}</span></div>`; |
3446 | 3446 | document.getElementById('chat-messages').appendChild(wrap); |
3447 | 3447 | scrollToBottom(); |
3448 | 3448 | } |
|
0 commit comments