feat: неблокирующий сбор User Flow и гостевых ошибок (api#376 api#377)
deploy-preland / deploy zoomstage.online (push) Successful in 1m1s
deploy-preland / deploy zoomstage.online (push) Successful in 1m1s
This commit is contained in:
1 parent
791761a782
commit
ba33a76a34
5 files changed
+87
-12
No files matched your search
+20
-11
@@ -108,7 +108,7 @@ $basePickerAccept = 'image/jpeg,image/png,image/gif,image/webp,image/bmp,image/a
|
||||
let leavingUploadPage = false;
|
||||
let uploadAttempt = 0;
|
||||
const recovery = window.ZoomzillaUploadRecovery.create({scope: 'preland', target: createApiUrl});
|
||||
const metadata = () => ({actionUrl: createApiUrl, redirectBase: redirectUrlBase, redirectUtm: redirectUrlUtm, utmDigits: {...utmDigits}});
|
||||
const metadata = () => ({actionUrl: createApiUrl, redirectBase: redirectUrlBase, redirectUtm: redirectUrlUtm, utmDigits: {...utmDigits}, analytics: window.ZoomzillaAnalytics?.metadata()});
|
||||
const clearRecovery = () => recovery.clear().catch(() => {});
|
||||
let uploadDots = 1;
|
||||
let uploadDotsTimer = null;
|
||||
@@ -157,6 +157,7 @@ $basePickerAccept = 'image/jpeg,image/png,image/gif,image/webp,image/bmp,image/a
|
||||
return;
|
||||
}
|
||||
if (e.target !== fileInput) {
|
||||
if(e.isTrusted)window.ZoomzillaAnalytics?.emit('upload_click');
|
||||
fileInput.click();
|
||||
}
|
||||
});
|
||||
@@ -193,6 +194,7 @@ $basePickerAccept = 'image/jpeg,image/png,image/gif,image/webp,image/bmp,image/a
|
||||
});
|
||||
|
||||
function handleSelectedFile(file) {
|
||||
window.ZoomzillaAnalytics?.begin();
|
||||
if (maxUploadBytes > 0 && file.size > maxUploadBytes) {
|
||||
rejectOversizedFile(file);
|
||||
return;
|
||||
@@ -202,9 +204,11 @@ $basePickerAccept = 'image/jpeg,image/png,image/gif,image/webp,image/bmp,image/a
|
||||
}
|
||||
|
||||
function redirectToTour(record) {
|
||||
const azv=window.ZoomzillaAnalytics?.handoff(record.meta.analytics);
|
||||
let targetUrl = record.meta.redirectBase + encodeURIComponent(record.key);
|
||||
const redirectQuery = window.ZoomzillaUtmHandoff.query(record.meta, utmDigits);
|
||||
if (redirectQuery) targetUrl += '&' + redirectQuery;
|
||||
if(azv)targetUrl+='&azv='+encodeURIComponent(azv);
|
||||
const shownTheme = window.ZoomzillaTheme.current();
|
||||
targetUrl += '&shown_theme=' + encodeURIComponent(shownTheme);
|
||||
window.PublicNavigationGuard.allowNavigation(() => { window.location.href = targetUrl; });
|
||||
@@ -222,6 +226,7 @@ $basePickerAccept = 'image/jpeg,image/png,image/gif,image/webp,image/bmp,image/a
|
||||
formData.append('original_name', file.name || 'upload');
|
||||
formData.append('original_size', String(file.size || 0));
|
||||
formData.append('client_key', clientKey);
|
||||
window.ZoomzillaAnalytics?.append(formData,record.meta.analytics);
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', record.meta.actionUrl, true);
|
||||
xhr.withCredentials = true;
|
||||
@@ -230,12 +235,12 @@ $basePickerAccept = 'image/jpeg,image/png,image/gif,image/webp,image/bmp,image/a
|
||||
if (attempt !== uploadAttempt || leavingUploadPage) return;
|
||||
if (xhr.status >= 200 && xhr.status < 300) {
|
||||
try { const result = JSON.parse(xhr.responseText); if (!result?.id) throw new Error(); await recovery.accepted({id: result.id}); redirectToTour(record); }
|
||||
catch (_) { showUploadError(genericErrorMsg); }
|
||||
catch (_) { showUploadError(genericErrorMsg, false, false, true, xhr); }
|
||||
return;
|
||||
}
|
||||
showUploadError(genericErrorMsg, false, xhr.status === 408 || xhr.status >= 500);
|
||||
showUploadError(genericErrorMsg, false, xhr.status === 408 || xhr.status >= 500, true, xhr);
|
||||
};
|
||||
xhr.onerror = () => { if (attempt === uploadAttempt && !leavingUploadPage) showUploadError(genericErrorMsg, true, true); };
|
||||
xhr.onerror = () => { if (attempt === uploadAttempt && !leavingUploadPage) showUploadError(genericErrorMsg, true, true, true, xhr); };
|
||||
xhr.send(formData);
|
||||
} catch (_) { if (attempt === uploadAttempt && !leavingUploadPage) showUploadError(genericErrorMsg); }
|
||||
}
|
||||
@@ -249,7 +254,7 @@ $basePickerAccept = 'image/jpeg,image/png,image/gif,image/webp,image/bmp,image/a
|
||||
const record = saved || await recovery.remember(new File([bytes], file.name, {type: file.type, lastModified: file.lastModified}), metadata());
|
||||
if (attempt === uploadAttempt && !leavingUploadPage) uploadPreparedFile(file, bytes, record);
|
||||
})
|
||||
.catch(() => { if (attempt === uploadAttempt && !leavingUploadPage) showUploadError(genericErrorMsg); });
|
||||
.catch(() => { if (attempt === uploadAttempt && !leavingUploadPage) showUploadError(genericErrorMsg, false, false, false); });
|
||||
}
|
||||
function uploadPreparedFile(file, bytes, record) {
|
||||
const attempt = uploadAttempt;
|
||||
@@ -260,6 +265,7 @@ $basePickerAccept = 'image/jpeg,image/png,image/gif,image/webp,image/bmp,image/a
|
||||
const clientKey = record.key;
|
||||
formData.append('file', bytes, file.name || 'upload');
|
||||
formData.append('client_key', clientKey);
|
||||
window.ZoomzillaAnalytics?.append(formData,record.meta.analytics);
|
||||
|
||||
const actionUrl = record.meta.actionUrl;
|
||||
xhr.open('POST', actionUrl, true);
|
||||
@@ -280,13 +286,13 @@ $basePickerAccept = 'image/jpeg,image/png,image/gif,image/webp,image/bmp,image/a
|
||||
try {
|
||||
response = JSON.parse(xhr.responseText);
|
||||
} catch (e) {
|
||||
showUploadError(genericErrorMsg);
|
||||
showUploadError(genericErrorMsg, false, false, true, xhr);
|
||||
return;
|
||||
}
|
||||
|
||||
const imageId = response?.id || response?.data?.id || response?.image?.id || response?.image_id;
|
||||
if (!imageId) {
|
||||
showUploadError(genericErrorMsg);
|
||||
showUploadError(genericErrorMsg, false, false, true, xhr);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -297,21 +303,23 @@ $basePickerAccept = 'image/jpeg,image/png,image/gif,image/webp,image/bmp,image/a
|
||||
|
||||
// Переход: $redirect_url_base . client_key . ($redirect_url_utm ? '&' . $redirect_url_utm : '')
|
||||
try { await recovery.accepted({id: imageId}); redirectToTour(record); }
|
||||
catch (_) { showUploadError(genericErrorMsg); }
|
||||
catch (_) { showUploadError(genericErrorMsg, false, false, true, xhr); }
|
||||
} else {
|
||||
showUploadError(genericErrorMsg, false, xhr.status === 408 || xhr.status >= 500);
|
||||
showUploadError(genericErrorMsg, false, xhr.status === 408 || xhr.status >= 500, true, xhr);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.onerror = () => {
|
||||
if (attempt === uploadAttempt && !leavingUploadPage) showUploadError(genericErrorMsg, true, true);
|
||||
if (attempt === uploadAttempt && !leavingUploadPage) showUploadError(genericErrorMsg, true, true, true, xhr);
|
||||
};
|
||||
|
||||
xhr.send(formData);
|
||||
}
|
||||
|
||||
function showUploadError(msg, keepRecovery = false, connection = false) {
|
||||
function showUploadError(msg, keepRecovery = false, connection = false, recordAnalytics = true, analyticsRequest = null) {
|
||||
if (leavingUploadPage) return;
|
||||
const failureProof=analyticsRequest?.getResponseHeader?.('X-Analytics-Failure');
|
||||
if(recordAnalytics)window.ZoomzillaAnalytics?.emit('photo_error',{stage:'upload',reason_code:'upload_failed',...(analyticsRequest?.status>=100?{http_status:analyticsRequest.status}:{}),...(failureProof?{failure_proof:failureProof}:{})});
|
||||
uploadAttempt++;
|
||||
if (!keepRecovery) clearRecovery();
|
||||
resetUploadPending();
|
||||
@@ -333,6 +341,7 @@ $basePickerAccept = 'image/jpeg,image/png,image/gif,image/webp,image/bmp,image/a
|
||||
(async () => {
|
||||
try {
|
||||
const saved = await recovery.load();
|
||||
window.ZoomzillaAnalytics?.restore(saved?.meta?.analytics);
|
||||
if (!saved) return;
|
||||
if (performance.getEntriesByType('navigation')[0]?.type !== 'reload' || saved.sourceUrl !== location.href || saved.meta.actionUrl !== createApiUrl) { clearRecovery(); return; }
|
||||
if (saved.result?.id) { beginUploadPending(); redirectToTour(saved); }
|
||||
|
||||
Reference in new issue
Block a user