fix: group toast icon, left-click spell suggestions, scroll no-yank (0.1.12/batch66)

1. Group message toast had no icon: the generated group icon is a data: URL, but
   the 0.1.11 handler only used ALREADY-cached icons and skipped it. data: URLs
   are synchronous — use them immediately, so every group toast shows an icon.
2. Spell suggestions on a LEFT click: clicking a red-squiggled word in the message
   box now pops the native suggestions menu (renderer asks the shell to synthesize
   a right-click at that point → real dictionary suggestions). No right-click.
3. Scroll felt "stuck" because an incoming message yanked you to the bottom even
   when you'd scrolled up to read history (worse now that bg messages arrive live).
   appendBubble now keeps your position unless you were at the bottom / it's your
   own message, and surfaces the "jump to latest" control instead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-10 14:57:02 +05:30
parent 1dfb6b16cb
commit aa4bb2902d
4 changed files with 55 additions and 9 deletions
+13 -2
View File
@@ -856,7 +856,7 @@
<body>
<script src="/icons.js?v=5"></script>
<script src="https://cdn.jsdelivr.net/npm/@twemoji/api@15.1.0/dist/twemoji.min.js" crossorigin="anonymous"></script>
<script>window.__BUILD='2026-07-10-batch65';console.log('%cBiz Connect','color:#1F3B73;font-weight:bold','build '+window.__BUILD);
<script>window.__BUILD='2026-07-10-batch66';console.log('%cBiz Connect','color:#1F3B73;font-weight:bold','build '+window.__BUILD);
// Render modern (Twemoji) emojis in place of the OS's flat ones. No-op if the CDN didn't load
// (emojis stay as plain Unicode). (#5)
function twemojify(el){ try{ if(el && window.twemoji) window.twemoji.parse(el, { folder:'svg', ext:'.svg' }); }catch(_){} }</script>
@@ -2034,13 +2034,19 @@ function renderThread(keepScroll){
function appendBubble(m){
if(rendered.has(m.id)) return; rendered.add(m.id);
const box=document.getElementById('msgs'); if(!box) return;
// Was the user already at the bottom? If they've scrolled UP to read history, an incoming message
// must NOT yank them back down (that made the thread feel "stuck" — you couldn't stay scrolled up,
// especially now that background messages arrive live). Keep their position + flag "jump to latest".
const atBottom=(box.scrollHeight - box.scrollTop - box.clientHeight) < 160;
const empty=box.querySelector('.empty-thread'); if(empty) empty.remove();
// A new message becomes the newest: move the group "Seen by" off the previous last message.
if(!m.system && !m.deleted){ if(_lastGroupId){ const pe=box.querySelector('.bubble[data-id="'+((window.CSS&&CSS.escape)?CSS.escape(_lastGroupId):_lastGroupId)+'"] .seenby'); if(pe) pe.remove(); } _lastGroupId=m.id; if(m.from===ME.id) _lastMineId=m.id; }
const dk=dayKey(m.created_at); if(dk!==_lastDay){ box.insertAdjacentHTML('beforeend', '<div class="day-sep"><span>'+pEsc(dayLabel(m.created_at))+'</span></div>'); _lastDay=dk; }
box.insertAdjacentHTML('beforeend', bubbleHTML(m));
twemojify(box.lastElementChild);
box.scrollTop=box.scrollHeight;
// Auto-scroll only if they were at the bottom, or it's MY own message (sending always jumps down).
if(atBottom || m.from===ME.id){ box.scrollTop=box.scrollHeight; }
else { const jl=document.getElementById('jumpLatest'); if(jl) jl.style.display='grid'; } // let them jump when ready
}
let _openUnread=0; // set by selectChat (the unread count before it's reset) so we can open at the first unread
// Per-conversation drafts: unsent text is kept (across chat switches AND reloads) until sent.
@@ -2073,6 +2079,11 @@ async function openConvo(kind,id){
inpEl.addEventListener('input', ()=>{ maybeAutocorrect(inpEl); autoGrow(inpEl); setDraft(kind,id,inpEl.value); noteTyping(); }); // auto-correct common typos, keep the draft in sync + emit "typing…"
inpEl.addEventListener('blur', stopTyping);
inpEl.addEventListener('keydown', (e)=>{ if(e.key==='Enter' && !e.shiftKey){ if(mentionItems && mentionItems.length) return; e.preventDefault(); sendMessage(); } }); // Enter sends, Shift+Enter = newline
// Desktop: LEFT-click a red-squiggled word → native spelling suggestions right there (the shell
// pops a suggestions menu only if the clicked word is actually misspelled). No right-click needed.
if(window.bizConnectNative && window.bizConnectNative.spellSuggestAt){
inpEl.addEventListener('click',(e)=>{ if(inpEl.selectionStart!==inpEl.selectionEnd) return; try{ window.bizConnectNative.spellSuggestAt(e.clientX, e.clientY); }catch(_){} });
}
}
refreshTyping(kind,id); // if someone's already typing in this conversation, show it right away
// #5: tapping the header avatar previews the DP / group photo full-size.