Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
395 changes: 231 additions & 164 deletions dist/doboard-widget-bundle.js

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions dist/doboard-widget-bundle.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/doboard-widget-bundle.min.js.map

Large diffs are not rendered by default.

79 changes: 60 additions & 19 deletions js/src/fileuploader.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class FileUploader {
this.maxFiles = 5;

/** @type {string[]} Allowed MIME types for files */
this.allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'application/pdf', 'text/plain', 'application/msword', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'];
this.allowedTypes = ['video/mp4', 'video/webm', 'image/jpeg', 'image/png', 'image/gif', 'application/pdf', 'text/plain', 'application/msword', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'];

/** @type {function} HTML escaping function for XSS protection */
this.escapeHtmlHandler = escapeHtmlHandler;
Expand Down Expand Up @@ -393,33 +393,78 @@ class FileUploader {
* Make a screenshot and add it as a file
* @returns {Promise<void>}
Comment thread
veronika-tseleva-cleantalk marked this conversation as resolved.
Comment thread
veronika-tseleva-cleantalk marked this conversation as resolved.
*/

async loadDomToImage() {
return new Promise((resolve, reject) => {
if (window.domtoimage) {
resolve(window.domtoimage);
return;
}
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/dom-to-image-more@3.1.6/dist/dom-to-image-more.min.js';
script.onload = () => resolve(window.domtoimage);
script.onerror = () => reject(new Error('Failed to load dom-to-image-more'));
document.head.appendChild(script);
Comment thread
veronika-tseleva-cleantalk marked this conversation as resolved.
Comment thread
veronika-tseleva-cleantalk marked this conversation as resolved.
});
Comment on lines +397 to +408
Comment on lines +397 to +408
}

async makeScreenshot() {
if (typeof html2canvas === 'undefined') {
console.error("SpotFix Error: in Screenshot Library");
return null;
}
let blob = null;
try {
const canvas = await html2canvas(document.body, {
useCORS: true,
allowTaint: true,
logging: false,
scale: window.devicePixelRatio || 1
const domtoimageLib = await this.loadDomToImage();
if (!domtoimageLib) throw new Error('domtoimageLib failed to load');

blob = await domtoimageLib.toBlob(document.body, {
width: window.innerWidth,
height: window.innerHeight,
style: {
transform: `translate(${-window.scrollX}px, ${-window.scrollY}px)`,
},
});

const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png'));
if (!blob) return null;
if (!blob) throw new Error('dom-to-image-more returned an empty result');

} catch (primaryError) {
console.warn('SpotFix: dom-to-image-more failed, trying html2canvas...', primaryError);

try {
if (typeof html2canvas === 'undefined') {
throw new Error('html2canvas is not defined in the global scope');
}

const canvas = await html2canvas(document.body, {
useCORS: true,
allowTaint: true,
logging: false,
scale: window.devicePixelRatio || 1,
x: window.scrollX,
y: window.scrollY,
width: window.innerWidth,
height: window.innerHeight,
});

blob = await new Promise(res => canvas.toBlob(res, 'image/png'));

if (!blob) throw new Error('html2canvas returned an empty canvas');

} catch (fallbackError) {
console.error('SpotFix Error: Both screenshot libraries failed.', fallbackError);
return null;
}
}

if (blob) {
const now = new Date();
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const month = String(now.getMonth() + 1).padStart(2, '0');
const year = now.getFullYear();

const fileName = `Screenshot_${hours}-${minutes}_${day}_${month}_${year}.png`;

const file = new File([blob], fileName, {
type: 'image/png',
lastModified: Date.now()
lastModified: Date.now(),
});

if (this.uploaderWrapper && this.uploaderWrapper.style.display !== 'block') {
Expand All @@ -428,10 +473,6 @@ class FileUploader {

this.clearError();
this.addFile(file);

} catch (err) {
console.error("SpotFix Error: creating screenshot:", err);
return null;
}
}
}
}
4 changes: 2 additions & 2 deletions js/src/handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,13 @@ async function getUserDetails(params, nonRequesting = false) {
async function handleCreateTask(sessionId, taskDetails) {
try {
const result = await createTaskDoboard(sessionId, taskDetails);
if (result && result.taskId && taskDetails.taskDescription) {
if (result && result.taskId && (taskDetails.taskDescription || taskDetails.has_files)) {
const sign = `<br><br><br><em>The spot has been posted at the following URL <a href="${window.location.href}"><span class="task-link task-link--done">${window.location.href}</span></a></em>`;

const commentResponse = await addTaskComment({
projectToken: taskDetails.projectToken,
accountId: taskDetails.accountId,
}, result.taskId, taskDetails.taskDescription + sign);
}, result.taskId, (taskDetails.taskDescription ?? '') + sign);

result.initialComment = commentResponse;
}
Expand Down
Loading