fix ui composer

This commit is contained in:
javad committed 2026-09-17 11:08:16 +03:30
1 parent a26ae28189
commit 33930e972c
8 files changed
+73 -16

No files matched your search

+9 -3
View File
@@ -30,6 +30,8 @@ document.querySelectorAll('[data-conversation-workspace]').forEach(workspace=>{
if(composer)layoutObserver?.observe(composer);
let stableViewportHeight=Math.max(window.visualViewport?.height||window.innerHeight,window.innerHeight);
let inputVisibilityFrame=0;
let keyboardWasOpen=false;
let suppressKeyboardCollapse=false;
const ensureInputVisible=()=>{
inputVisibilityFrame=0;
if(!composer||!input||document.activeElement!==input||composer.classList.contains('is-collapsed'))return;
@@ -42,20 +44,24 @@ document.querySelectorAll('[data-conversation-workspace]').forEach(workspace=>{
const inputFocused=document.activeElement===input;
if(!inputFocused)stableViewportHeight=Math.max(stableViewportHeight,height);
const keyboardOpen=inputFocused&&stableViewportHeight-height>120;
const keyboardClosed=keyboardWasOpen&&!keyboardOpen&&stableViewportHeight-height<80;
keyboardWasOpen=keyboardOpen||(keyboardWasOpen&&!keyboardClosed);
composer?.classList.toggle('is-keyboard-active',keyboardOpen);
composer?.setAttribute('data-keyboard-open',String(keyboardOpen));
if(keyboardOpen)scheduleInputVisibility();
if(keyboardClosed&&!suppressKeyboardCollapse&&!composer?.classList.contains('is-collapsed'))setTimeout(()=>setComposerOpen(false,false),0);
};
window.addEventListener('appviewportchange',event=>{if(followLatest)requestAnimationFrame(()=>scrollLatest(false));updateKeyboardState(event.detail?.height||window.visualViewport?.height||window.innerHeight)});
input?.addEventListener('focus',()=>{updateKeyboardState(window.visualViewport?.height||window.innerHeight);scheduleInputVisibility()});
input?.addEventListener('blur',()=>setTimeout(()=>updateKeyboardState(window.visualViewport?.height||window.innerHeight),0));
input?.addEventListener('blur',()=>setTimeout(()=>{composer?.classList.remove('is-keyboard-active');composer?.setAttribute('data-keyboard-open','false')},0));
composer?.addEventListener('pointerdown',event=>{if(!composer.classList.contains('is-collapsed')&&!event.target.closest('[data-composer-close]')){suppressKeyboardCollapse=true;setTimeout(()=>{suppressKeyboardCollapse=false},1200)}},{capture:true});
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();
document.body.addEventListener('htmx:beforeSwap',event=>{if(event.detail.target?.matches('[data-load-older]')){scroller.dataset.previousHeight=scroller.scrollHeight}});
document.body.addEventListener('htmx:afterSwap',event=>{if(event.detail.target?.matches('[data-load-older]')){const previous=Number(scroller.dataset.previousHeight||0);groupDates();scroller.scrollTop+=scroller.scrollHeight-previous}});
const resize=()=>{if(!input)return;input.style.height='auto';input.style.height=`${Math.min(Math.max(input.scrollHeight,112),240)}px`;scheduleInputVisibility()};
const resize=()=>{if(!input)return;const maxHeight=window.matchMedia('(max-width:639px)').matches?144:192;input.style.height='0px';const contentHeight=input.scrollHeight;input.style.height=`${Math.min(Math.max(contentHeight,48),maxHeight)}px`;input.style.overflowY=contentHeight>maxHeight?'auto':'hidden';scheduleInputVisibility()};
const draftKey=()=>`${baseKey}-${mode}`;
const status=workspace.querySelector('[data-draft-status]');
const replyResult=workspace.dataset.replyResult||new URLSearchParams(location.search).get('reply_result')||'';
@@ -64,7 +70,7 @@ document.querySelectorAll('[data-conversation-workspace]').forEach(workspace=>{
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});scheduleInputVisibility()},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()}
if(input){input.setAttribute('rows','1');input.setAttribute('placeholder','پاسخ خود را بنویسید…');input.addEventListener('input',()=>{resize();saveDraft()});loadDraft()}
const hasDraft=Boolean(sessionStorage.getItem(`${baseKey}-reply`)||sessionStorage.getItem(`${baseKey}-note`));
if(submissionSucceeded){form?.reset();if(input){input.value='';resize()}setComposerOpen(false,false)}else setComposerOpen(hasDraft||replyResult==='error',false);
composerToggle?.addEventListener('click',()=>setComposerOpen(true));