fix ui view

This commit is contained in:
javad committed 2026-09-17 09:41:15 +03:30
1 parent 863ca89485
commit 83f4d7c728
9 files changed
+182 -17

No files matched your search

+8 -3
View File
@@ -11,6 +11,7 @@ document.querySelectorAll('[data-conversation-workspace]').forEach(workspace=>{
const atBottom=()=>scroller.scrollHeight-scroller.scrollTop-scroller.clientHeight<80;
const scrollLatest=(smooth=false)=>{const top=scroller.scrollHeight;if(smooth&&typeof scroller.scrollTo==='function')scroller.scrollTo({top,behavior:'smooth'});else scroller.scrollTop=top};
let followLatest=true;
let initialPin=true;
const scheduleLatest=()=>{[0,40,120,300,700,1200].forEach(delay=>setTimeout(()=>{if(initialPin)scrollLatest(false)},delay))};
scheduleLatest();
@@ -22,8 +23,12 @@ document.querySelectorAll('[data-conversation-workspace]').forEach(workspace=>{
sizeObserver?.observe(scroller);if(conversationEnd?.parentElement)sizeObserver?.observe(conversationEnd.parentElement);
setTimeout(()=>{initialPin=false;sizeObserver?.disconnect()},1800);
['wheel','touchstart','pointerdown','keydown'].forEach(eventName=>scroller.addEventListener(eventName,()=>{initialPin=false;sizeObserver?.disconnect()},{once:true,passive:true}));
scroller.addEventListener('scroll',()=>{jump.hidden=atBottom()});
scroller.addEventListener('scroll',()=>{followLatest=atBottom();jump.hidden=followLatest});
jump?.addEventListener('click',()=>{scrollLatest(true);jump.hidden=true});
const layoutObserver='ResizeObserver' in window?new ResizeObserver(()=>{if(followLatest)requestAnimationFrame(()=>scrollLatest(false))}):null;
layoutObserver?.observe(scroller);
if(composer)layoutObserver?.observe(composer);
window.addEventListener('appviewportchange',()=>{if(followLatest)requestAnimationFrame(()=>scrollLatest(false))});
const groupDates=()=>{scroller.querySelectorAll('.date-divider').forEach(item=>item.remove());let previousDate='';scroller.querySelectorAll('[data-message]').forEach(message=>{if(message.dataset.date!==previousDate){const divider=document.createElement('div');divider.className='date-divider';divider.innerHTML=`<span>${message.dataset.dayLabel}</span>`;message.before(divider);previousDate=message.dataset.date}})};
groupDates();
@@ -36,7 +41,7 @@ document.querySelectorAll('[data-conversation-workspace]').forEach(workspace=>{
const replyResult=workspace.dataset.replyResult||new URLSearchParams(location.search).get('reply_result')||'';
const submissionSucceeded=replyResult==='reply'||replyResult==='note';
if(submissionSucceeded){sessionStorage.removeItem(`${baseKey}-reply`);sessionStorage.removeItem(`${baseKey}-note`)}
const setComposerOpen=(open,focus=true)=>{const keepLatestVisible=atBottom();composer?.classList.toggle('is-collapsed',!open);composerToggle?.setAttribute('aria-expanded',String(open));requestAnimationFrame(()=>{if(keepLatestVisible)scrollLatest(false)});if(open&&focus)setTimeout(()=>input?.focus(),80)};
const setComposerOpen=(open,focus=true)=>{const keepLatestVisible=followLatest||atBottom();composer?.classList.toggle('is-collapsed',!open);composerToggle?.setAttribute('aria-expanded',String(open));[0,80,240].forEach(delay=>setTimeout(()=>{if(keepLatestVisible)scrollLatest(false)},delay));if(open&&focus)setTimeout(()=>input?.focus({preventScroll:true}),80)};
const saveDraft=()=>{if(!input)return;sessionStorage.setItem(draftKey(),input.value);if(status){status.textContent=input.value?'پیش‌نویس ذخیره شد':'';clearTimeout(saveDraft.timer);saveDraft.timer=setTimeout(()=>status.textContent='',1800)}};
const loadDraft=()=>{if(!input)return;input.value=sessionStorage.getItem(draftKey())||'';resize();input.dispatchEvent(new Event('input',{bubbles:true}))};
if(input){input.setAttribute('rows','5');input.setAttribute('placeholder','شرح کامل پاسخ، اطلاعات تکمیلی و نتیجه مورد انتظار خود را بنویسید…');input.addEventListener('input',()=>{resize();saveDraft()});loadDraft()}
@@ -117,7 +122,7 @@ document.querySelectorAll('[data-conversation-workspace]').forEach(workspace=>{
// cancel a recursively scheduled timeout. pollRunning prevents overlap and
// nextPollAt preserves the normal interval and network-error backoff.
const pollHeartbeat=setInterval(startPolling,1000);
window.addEventListener('beforeunload',()=>{clearInterval(pollHeartbeat);stopPolling()},{once:true});
window.addEventListener('beforeunload',()=>{clearInterval(pollHeartbeat);stopPolling();layoutObserver?.disconnect()},{once:true});
startPolling();
const resetMessageMenu=menu=>{if(!menu)return;const editor=menu.querySelector('[data-message-editor]');const choices=menu.querySelector('[data-message-menu-choices]');const input=menu.querySelector('[data-message-edit-input]');if(editor)editor.hidden=true;if(choices)choices.hidden=false;if(input){input.value=input.dataset.originalValue||'';input.dispatchEvent(new Event('input',{bubbles:true}))}};