fix payement link and gallery image

This commit is contained in:
javad committed 2026-10-06 11:18:31 +03:30
1 parent de3135b588
commit 1cbbbbd0dc
24 files changed
+654 -116

No files matched your search

+10 -18
View File
@@ -87,20 +87,8 @@ document.querySelectorAll('[data-conversation-workspace]').forEach(workspace=>{
form?.addEventListener('submit',()=>{form.dataset.submitting='true'});
window.addEventListener('pageshow',()=>{if(submissionSucceeded){form?.reset();if(input){input.value='';resize()}setComposerOpen(false,false)}});
const pollUrl=workspace.dataset.pollUrl;
const readUrl=workspace.dataset.readUrl;
const pollInterval=3000;
let pollController=null,pollRunning=false,pollGeneration=0,pollErrors=0,nextPollAt=0;
let readRunning=false;
const cookie=name=>document.cookie.split('; ').find(row=>row.startsWith(`${name}=`))?.split('=').slice(1).join('=')||'';
const acknowledgeVisibleMessages=async()=>{
if(!readUrl||readRunning||document.visibilityState!=='visible')return;
const messageIds=[...scroller.querySelectorAll('[data-message-id]')].map(item=>item.dataset.messageId).filter(Boolean);
if(!messageIds.length)return;
readRunning=true;
try{await fetch(readUrl,{method:'POST',credentials:'same-origin',headers:{'Content-Type':'application/json','X-CSRFToken':decodeURIComponent(cookie('csrftoken'))},body:JSON.stringify({message_ids:messageIds})})}catch(error){console.error('Message read acknowledgement failed',error)}finally{readRunning=false}
};
acknowledgeVisibleMessages();
// Keep the staff/customer conversation synchronized even while another tab is
// active. Browsers may throttle background timers, so visibility is used only
// to trigger an immediate catch-up, never as a hard polling gate.
@@ -109,7 +97,7 @@ document.querySelectorAll('[data-conversation-workspace]').forEach(workspace=>{
// local networks, installed PWAs and some mobile browsers). Let fetch be the
// source of truth and use the existing error backoff when the origin really
// is unavailable.
const canPoll=()=>Boolean(pollUrl);
const canPoll=()=>Boolean(workspace.dataset.pollUrl) && !workspace.dataset.accessDenied;
const schedulePoll=()=>{const delay=pollErrors?Math.min(30000,pollInterval*(2**Math.min(pollErrors,3))):pollInterval;nextPollAt=Date.now()+delay};
const applyPollUpdate=data=>{
if(!data.changed)return;
@@ -124,7 +112,6 @@ document.querySelectorAll('[data-conversation-workspace]').forEach(workspace=>{
const count=workspace.querySelector('[data-conversation-count]');if(count)count.textContent=String(data.count??'');
workspace.querySelectorAll('[data-ticket-status]').forEach(item=>item.textContent=data.status||item.textContent);
groupDates();
acknowledgeVisibleMessages();
scroller.querySelectorAll('img:not([data-poll-bound]),audio:not([data-poll-bound])').forEach(media=>{media.dataset.pollBound='true';const event=media.tagName==='IMG'?'load':'loadedmetadata';media.addEventListener(event,()=>{if(wasAtBottom)scrollLatest(false)},{once:true})});
if(wasAtBottom){scrollLatest(true);jump.hidden=true}else jump.hidden=false;
};
@@ -132,17 +119,22 @@ document.querySelectorAll('[data-conversation-workspace]').forEach(workspace=>{
if(!canPoll()||pollRunning)return;
const generation=++pollGeneration;pollRunning=true;const controller=new AbortController();pollController=controller;
try{
const url=new URL(pollUrl,location.origin);url.searchParams.set('version',workspace.dataset.pollVersion||'');url.searchParams.set('cursor',workspace.dataset.pollCursor||'');
const url=new URL(workspace.dataset.pollUrl,location.origin);url.searchParams.set('version',workspace.dataset.pollVersion||'');url.searchParams.set('cursor',workspace.dataset.pollCursor||'');
const response=await fetch(url,{method:'GET',signal:controller.signal,cache:'no-store',headers:{Accept:'application/json'}});
if(response.redirected){location.assign(response.url);return}
if(generation!==pollGeneration || !canPoll())return;
if(response.redirected){workspace.dispatchEvent(new Event('conversation:access-denied'));location.assign(response.url);return}
if([401,403,404].includes(response.status)){workspace.dispatchEvent(new Event('conversation:access-denied'));return}
if(!response.ok)throw new Error(`HTTP ${response.status}`);
applyPollUpdate(await response.json());pollErrors=0;
const data=await response.json();
if(generation!==pollGeneration || !canPoll())return;
applyPollUpdate(data);pollErrors=0;
}catch(error){if(error.name!=='AbortError'){pollErrors+=1;console.error('Ticket polling failed',error)}}finally{if(generation===pollGeneration){pollRunning=false;pollController=null;schedulePoll()}}
};
const startPolling=()=>{if(!canPoll()||pollRunning||Date.now()<nextPollAt)return;poll()};
const stopPolling=()=>{pollGeneration+=1;if(pollController){pollController.abort();pollController=null}pollRunning=false;nextPollAt=0};
const restartPolling=()=>{stopPolling();startPolling()};
document.addEventListener('visibilitychange',()=>{if(document.visibilityState==='visible'){restartPolling();acknowledgeVisibleMessages()}});
document.addEventListener('visibilitychange',()=>{if(document.visibilityState==='visible')restartPolling()});
workspace.addEventListener('conversation:access-denied',stopPolling);
window.addEventListener('focus',startPolling);
window.addEventListener('pageshow',restartPolling);
window.addEventListener('online',restartPolling);