diff --git a/frontend/app/components/AssistStats/pdfGenerator.ts b/frontend/app/components/AssistStats/pdfGenerator.ts index 1364343f7..7570f33c4 100644 --- a/frontend/app/components/AssistStats/pdfGenerator.ts +++ b/frontend/app/components/AssistStats/pdfGenerator.ts @@ -2,7 +2,7 @@ import { fileNameFormat } from 'App/utils'; export const getPdf2 = async () => { // @ts-ignore - import('html2canvas').then(({ default: html2canvas }) => { + import('html2canvas-pro').then(({ default: html2canvas }) => { // @ts-ignore window.html2canvas = html2canvas; diff --git a/frontend/app/components/Dashboard/components/WidgetForm/renderMap.ts b/frontend/app/components/Dashboard/components/WidgetForm/renderMap.ts index 05aaff537..bb7dc991a 100644 --- a/frontend/app/components/Dashboard/components/WidgetForm/renderMap.ts +++ b/frontend/app/components/Dashboard/components/WidgetForm/renderMap.ts @@ -1,6 +1,6 @@ export const renderClickmapThumbnail = () => { // @ts-ignore - return import('html2canvas').then(({ default: html2canvas }) => { + return import('html2canvas-pro').then(({ default: html2canvas }) => { // @ts-ignore window.html2canvas = html2canvas; const element = document.querySelector('#clickmap-render * iframe').contentDocument.body @@ -26,4 +26,4 @@ export const renderClickmapThumbnail = () => { Promise.reject("can't find clickmap container") } }) -} \ No newline at end of file +} diff --git a/frontend/app/components/Session_/Highlight/HighlightPanel.tsx b/frontend/app/components/Session_/Highlight/HighlightPanel.tsx index 0412b4ac4..6773e764d 100644 --- a/frontend/app/components/Session_/Highlight/HighlightPanel.tsx +++ b/frontend/app/components/Session_/Highlight/HighlightPanel.tsx @@ -8,6 +8,7 @@ import { PlayerContext } from 'Components/Session/playerContext'; import { observer } from 'mobx-react-lite'; import { shortDurationFromMs } from 'App/date'; import { toast } from 'react-toastify'; +import { toJpeg } from 'html-to-image'; function maskDuration(input: string): string { const digits = input.replace(/\D/g, ''); @@ -20,6 +21,7 @@ function maskDuration(input: string): string { return `${limitedDigits.slice(0, 2)}:${limitedDigits.slice(2)}`; } + const duration = new RegExp(/(\d{2}):(\d{2})/); function HighlightPanel({ onClose }: { onClose: () => void }) { @@ -41,30 +43,30 @@ function HighlightPanel({ onClose }: { onClose: () => void }) { const [tag, setTag] = React.useState(editNote?.tag ?? TAGS[0]); const onStartChange = (e: React.ChangeEvent) => { - const newState = maskDuration(e.target.value) + const newState = maskDuration(e.target.value); setStartTs(newState); if (duration.test(newState)) { const [_, minutes, seconds] = duration.exec(newState) ?? []; - const newTime = (parseInt(minutes) * 60 + parseInt(seconds))*1000; + const newTime = (parseInt(minutes) * 60 + parseInt(seconds)) * 1000; const sessLength = store.get().endTime; uiPlayerStore.toggleHighlightSelection({ enabled: true, - range: [Math.min(newTime, sessLength), uiPlayerStore.highlightSelection.endTs], - }) + range: [Math.min(newTime, sessLength), uiPlayerStore.highlightSelection.endTs] + }); } }; const onEndChange = (e: React.ChangeEvent) => { - const newState = maskDuration(e.target.value) + const newState = maskDuration(e.target.value); setEndTs(newState); if (duration.test(newState)) { const [_, minutes, seconds] = duration.exec(newState) ?? []; - const newTime = (parseInt(minutes) * 60 + parseInt(seconds))*1000; + const newTime = (parseInt(minutes) * 60 + parseInt(seconds)) * 1000; const sessLength = store.get().endTime; uiPlayerStore.toggleHighlightSelection({ enabled: true, - range: [uiPlayerStore.highlightSelection.startTs, Math.min(newTime, sessLength)], - }) + range: [uiPlayerStore.highlightSelection.startTs, Math.min(newTime, sessLength)] + }); } }; @@ -77,15 +79,16 @@ function HighlightPanel({ onClose }: { onClose: () => void }) { const distance = Math.max(endTime / 40, 2500); uiPlayerStore.toggleHighlightSelection({ enabled: true, - range: [Math.max(time - distance, 0), Math.min(time + distance, endTime)], + range: [Math.max(time - distance, 0), Math.min(time + distance, endTime)] }); return () => { uiPlayerStore.toggleHighlightSelection({ - enabled: false, + enabled: false }); - notesStore.setEditNote(null) + notesStore.setEditNote(null); }; }, []); + React.useEffect(() => { const startStr = shortDurationFromMs( uiPlayerStore.highlightSelection.startTs @@ -95,8 +98,9 @@ function HighlightPanel({ onClose }: { onClose: () => void }) { setEndTs(endStr); }, [ uiPlayerStore.highlightSelection.startTs, - uiPlayerStore.highlightSelection.endTs, + uiPlayerStore.highlightSelection.endTs ]); + React.useEffect(() => { player.pause(); }, [playing]); @@ -104,13 +108,14 @@ function HighlightPanel({ onClose }: { onClose: () => void }) { const addTag = (newTag: iTag) => { setTag(newTag); }; + const tagActive = (checkedTag: iTag) => { return tag === checkedTag; }; const onSave = async () => { try { - notesStore.setSaving(true) + notesStore.setSaving(true); const playerContainer = document.querySelector('iframe')?.contentWindow?.document; let thumbnail; if (playerContainer) { @@ -123,8 +128,8 @@ function HighlightPanel({ onClose }: { onClose: () => void }) { timestamp: parseInt(currentTime, 10), startAt: parseInt(uiPlayerStore.highlightSelection.startTs, 10), endAt: parseInt(uiPlayerStore.highlightSelection.endTs, 10), - thumbnail, - } + thumbnail + }; if (editNote) { await notesStore.updateNote(editNote.noteId, note); toast.success('Highlight updated'); @@ -139,7 +144,7 @@ function HighlightPanel({ onClose }: { onClose: () => void }) { } finally { notesStore.setSaving(false); } - } + }; return (
void }) {
); } + window.__debugElementToImage = (el) => elementToImage(el).then(img => { const a = document.createElement('a'); a.href = img; @@ -241,13 +247,15 @@ window.__debugElementToImage = (el) => elementToImage(el).then(img => { function elementToImage(doc: Document) { const el = doc.body; - const srcMap = new WeakMap() - return import('html2canvas').then(({ default: html2canvas }) => { + const srcMap = new WeakMap(); + + // @ts-ignore + return import('html2canvas-pro').then(({ default: html2canvas }) => { const images = doc.querySelectorAll('img'); images.forEach((img) => { srcMap.set(img, img.src); - img.src = "" - }) + img.src = ''; + }); return html2canvas( el, { @@ -259,18 +267,18 @@ function elementToImage(doc: Document) { height: 900, width: 1200, x: 0, - y: 0, + y: 0 } ).then((canvas) => { images.forEach((img) => { - img.src = srcMap.get(img) - }) + img.src = srcMap.get(img); + }); return canvas.toDataURL('img/png'); }).catch(e => { console.log(e); - return undefined + return undefined; }); - }) + }); } const convertAllImagesToBase64 = (proxyURL, cloned) => { @@ -282,7 +290,7 @@ const convertAllImagesToBase64 = (proxyURL, cloned) => { for (let i = 0; i < images.length; i += 1) { const promise = new Promise((resolve, reject) => { pendingPromisesData.push({ - index: i, resolve, reject, + index: i, resolve, reject }); }); pendingImagesPromises.push(promise); diff --git a/frontend/package.json b/frontend/package.json index 965229bc3..b2999bcc2 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -40,7 +40,7 @@ "fzstd": "^0.1.1", "hls.js": "^1.5.13", "html-to-image": "^1.9.0", - "html2canvas": "^1.4.1", + "html2canvas-pro": "^1.5.8", "immutable": "^4.3.7", "jest-environment-jsdom": "^29.5.0", "js-untar": "^2.0.0", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 1a9de6cb8..2d31befaf 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -8652,7 +8652,17 @@ __metadata: languageName: node linkType: hard -"html2canvas@npm:^1.0.0-rc.5, html2canvas@npm:^1.4.1": +"html2canvas-pro@npm:^1.5.8": + version: 1.5.8 + resolution: "html2canvas-pro@npm:1.5.8" + dependencies: + css-line-break: "npm:^2.1.0" + text-segmentation: "npm:^1.0.3" + checksum: 10c1/1ee4751bc65e307a483e994c7d1ec446c8f2bab27fb1a623551a866c0043f1e5dbfc879d128885f4f6e82d760f620ee8b87f02e8969442d337f8cb5a01cd594b + languageName: node + linkType: hard + +"html2canvas@npm:^1.0.0-rc.5": version: 1.4.1 resolution: "html2canvas@npm:1.4.1" dependencies: @@ -11627,7 +11637,7 @@ __metadata: hls.js: "npm:^1.5.13" html-to-image: "npm:^1.9.0" html-webpack-plugin: "npm:^5.5.0" - html2canvas: "npm:^1.4.1" + html2canvas-pro: "npm:^1.5.8" immutable: "npm:^4.3.7" jest: "npm:^29.5.0" jest-environment-jsdom: "npm:^29.5.0"