#14 draft: guarantee the save at leave-time (fixes switch-chats-and-return loss)
Per-keystroke 'input' saves can be missed on mobile (predictive text or a fast tap-away fires no final input event), which lost the whole draft when you switched chats and came back. Added persistCurrentDraft() — snapshots the composer value into the current chat's draft key the instant you leave it (selectChat before the swap, and showWelcome/back). Restore on open was already correct. Skipped while editing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -3420,6 +3420,11 @@ let _openUnread=0; // set by selectChat (the unread count before it's reset) so
|
|||||||
function draftKey(kind,id){ return 'draft_'+((ME&&ME.id)||'')+'_'+kind+':'+id; }
|
function draftKey(kind,id){ return 'draft_'+((ME&&ME.id)||'')+'_'+kind+':'+id; }
|
||||||
function getDraft(kind,id){ try{ return localStorage.getItem(draftKey(kind,id))||''; }catch(_){ return ''; } }
|
function getDraft(kind,id){ try{ return localStorage.getItem(draftKey(kind,id))||''; }catch(_){ return ''; } }
|
||||||
function setDraft(kind,id,val){ try{ if(val&&val.trim()) localStorage.setItem(draftKey(kind,id), val); else localStorage.removeItem(draftKey(kind,id)); }catch(_){} }
|
function setDraft(kind,id,val){ try{ if(val&&val.trim()) localStorage.setItem(draftKey(kind,id), val); else localStorage.removeItem(draftKey(kind,id)); }catch(_){} }
|
||||||
|
// #14: GUARANTEED save of the currently-open chat's draft — called the instant we leave it (switching chats
|
||||||
|
// OR going back to the list). The per-keystroke 'input' save can be missed on mobile (predictive text / a
|
||||||
|
// fast tap-away fires no final input event), which lost the whole draft on switch-and-return. Snapshotting
|
||||||
|
// the composer value at leave-time makes it reliable regardless. Skipped while editing (that's not a draft).
|
||||||
|
function persistCurrentDraft(){ try{ if(selected && !editTarget){ const inp=document.getElementById('msgInput'); if(inp) setDraft(selected.kind, selected.id, inp.value); } }catch(_){} }
|
||||||
// Compositor-only open slide (workflow-verified). armOpenSlide() runs AFTER openConvo's synchronous
|
// Compositor-only open slide (workflow-verified). armOpenSlide() runs AFTER openConvo's synchronous
|
||||||
// render: it pins the pane off-screen (chat-opening), lets a frame paint it, then adds .chat-anim on a
|
// render: it pins the pane off-screen (chat-opening), lets a frame paint it, then adds .chat-anim on a
|
||||||
// double-rAF so the compositor runs the 300ms transform with the main thread idle. All scrollTop/innerHTML
|
// double-rAF so the compositor runs the 300ms transform with the main thread idle. All scrollTop/innerHTML
|
||||||
@@ -3810,6 +3815,7 @@ function openPollModal(gid){
|
|||||||
}
|
}
|
||||||
async function selectChat(kind,id){
|
async function selectChat(kind,id){
|
||||||
ensureNotifyPermission();
|
ensureNotifyPermission();
|
||||||
|
persistCurrentDraft(); // #14: snapshot the outgoing chat's draft BEFORE we swap (reliable across the switch)
|
||||||
stopTyping(); // leaving the previous conversation → tell that peer we stopped
|
stopTyping(); // leaving the previous conversation → tell that peer we stopped
|
||||||
if(_selMode) exitSelect(); // #1: leave forward-selection when changing chats
|
if(_selMode) exitSelect(); // #1: leave forward-selection when changing chats
|
||||||
selected={kind,id};
|
selected={kind,id};
|
||||||
@@ -6045,6 +6051,7 @@ function switchTab(tab){
|
|||||||
if(tab==='meeting' && meetState==='idle'){ renderMeetingLobby(); }
|
if(tab==='meeting' && meetState==='idle'){ renderMeetingLobby(); }
|
||||||
}
|
}
|
||||||
function showWelcome(skipAnim){
|
function showWelcome(skipAnim){
|
||||||
|
persistCurrentDraft(); // #14: save the open chat's draft before we leave it for the list (back button)
|
||||||
const finish=()=>{ selected=null; document.body.classList.remove('chat-open','chat-closing','chat-dragging'); renderChats(searchVal()); renderChatPanel(); updateRailUnread(); };
|
const finish=()=>{ selected=null; document.body.classList.remove('chat-open','chat-closing','chat-dragging'); renderChats(searchVal()); renderChatPanel(); updateRailUnread(); };
|
||||||
// Mobile: slide the outgoing conversation off to the right before swapping back to the chat list, so
|
// Mobile: slide the outgoing conversation off to the right before swapping back to the chat list, so
|
||||||
// "back" has a clear push/pop direction (like Teams/WhatsApp). Desktop just closes instantly.
|
// "back" has a clear push/pop direction (like Teams/WhatsApp). Desktop just closes instantly.
|
||||||
|
|||||||
Reference in New Issue
Block a user