fix payement link and gallery image
This commit is contained in:
1 parent
de3135b588
commit
1cbbbbd0dc
24 files changed
+654
-116
No files matched your search
+10
-18
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user