From 12d95dd4b1d449fbefaf125b8012d6c18b8d33c0 Mon Sep 17 00:00:00 2001 From: Mo Tarbin Date: Tue, 7 Jul 2026 00:23:36 -0400 Subject: [PATCH] Fixes and remove logs --- src/utils/Helpers.jsx | 24 +++++++++++-------- src/views/ChoreEdit/ChoreEdit.jsx | 11 ++++++--- src/views/ChoreEdit/ChoreView.jsx | 2 +- .../Modals/Inputs/AttachmentBrowserModal.jsx | 17 +++++++++++-- .../Modals/Inputs/AttachmentViewerModal.jsx | 2 ++ src/views/Settings/ProfileSettings.jsx | 3 +-- src/views/components/ScanToTask/ScanPanel.jsx | 6 ++--- .../components/ScanToTask/useScanToTask.js | 23 ++++++++++++------ src/views/components/SmartTaskTitleInput.jsx | 2 -- 9 files changed, 60 insertions(+), 30 deletions(-) diff --git a/src/utils/Helpers.jsx b/src/utils/Helpers.jsx index 5e33a12..b276778 100644 --- a/src/utils/Helpers.jsx +++ b/src/utils/Helpers.jsx @@ -85,9 +85,9 @@ const extractStorageKey = url => { // replace them with backend proxy URLs (which generate fresh signed URLs on // each request). Returns the patched HTML, or the original if nothing changed. const refreshSignedUrlsInHtml = html => { - console.debug('1. refreshSignedUrlsInHtml', { html }) if (!html) return html if ( + !html.includes('dt-data-path') && !html.includes('X-Amz-') && !html.includes('X-Goog-') && !html.includes('sig') && @@ -95,22 +95,26 @@ const refreshSignedUrlsInHtml = html => { ) { return html } - console.debug('2. refreshSignedUrlsInHtml: found potential signed URLs, parsing HTML...') const parser = new DOMParser() const doc = parser.parseFromString(html, 'text/html') const imgs = doc.querySelectorAll('img[src]') let changed = false - imgs.forEach(async img => { - - if (!img.getAttribute('dt-data-path')) { - // not custom tag, skipping: - return - } + imgs.forEach(img => { + const stablePath = img.getAttribute('dt-data-path') const src = img.getAttribute('src') + let nextSrc = src - img.setAttribute('src', resolvePhotoURL(src)) - changed = true + if (stablePath) { + nextSrc = resolvePhotoURL(stablePath) + } else if (isCloudSignedUrl(src)) { + nextSrc = resolvePhotoURL(extractStorageKey(src)) + } + + if (nextSrc && nextSrc !== src) { + img.setAttribute('src', nextSrc) + changed = true + } }) return changed ? doc.body.innerHTML : html diff --git a/src/views/ChoreEdit/ChoreEdit.jsx b/src/views/ChoreEdit/ChoreEdit.jsx index a6d0a25..7ac6cd4 100644 --- a/src/views/ChoreEdit/ChoreEdit.jsx +++ b/src/views/ChoreEdit/ChoreEdit.jsx @@ -975,7 +975,10 @@ const ChoreEdit = () => { key={att.file_path || idx} onClick={() => { const url = resolvePhotoURL(att.sign || att.file_path) - const ext = att.file_name?.split('.').pop().toLowerCase() + const ext = (att.file_name || '') + .split('.') + .pop() + .toLowerCase() const isImage = [ 'jpg', 'jpeg', @@ -1031,7 +1034,8 @@ const ChoreEdit = () => { size='sm' variant='plain' color='danger' - onClick={() => { + onClick={event => { + event.stopPropagation() DeleteChoreAttachment(choreId, att.file_path) .then(() => { setAttachments(prev => @@ -1054,7 +1058,8 @@ const ChoreEdit = () => { size='sm' variant='plain' color='danger' - onClick={() => { + onClick={event => { + event.stopPropagation() setAttachments(prev => prev.filter((_, i) => i !== idx), ) diff --git a/src/views/ChoreEdit/ChoreView.jsx b/src/views/ChoreEdit/ChoreView.jsx index ffd55fb..0b51fd3 100644 --- a/src/views/ChoreEdit/ChoreView.jsx +++ b/src/views/ChoreEdit/ChoreView.jsx @@ -631,7 +631,7 @@ const ChoreView = () => { mb: 0.5, }} > - asde{chore.name} + {chore.name} {chore.isActive === false && ( diff --git a/src/views/Modals/Inputs/AttachmentBrowserModal.jsx b/src/views/Modals/Inputs/AttachmentBrowserModal.jsx index 55b1f54..3de68f5 100644 --- a/src/views/Modals/Inputs/AttachmentBrowserModal.jsx +++ b/src/views/Modals/Inputs/AttachmentBrowserModal.jsx @@ -34,8 +34,12 @@ function AttachmentBrowserModal({ choreId, isOpen, onClose }) { if (!isOpen || !choreId) return setIsLoading(true) GetChoreAttachments(choreId) - .then(res => res.json()) + .then(async res => { + if (!res.ok) throw new Error('Failed to fetch attachments') + return res.json() + }) .then(data => setAttachments(Array.isArray(data) ? data : [])) + .catch(() => setAttachments([])) .finally(() => setIsLoading(false)) }, [isOpen, choreId]) @@ -91,7 +95,16 @@ function AttachmentBrowserModal({ choreId, isOpen, onClose }) { ) : ( {attachments.map((attachment, index) => ( - + handleAttachmentClick(attachment)} sx={{ borderRadius: 'sm', gap: 1.5, py: 1 }} diff --git a/src/views/Modals/Inputs/AttachmentViewerModal.jsx b/src/views/Modals/Inputs/AttachmentViewerModal.jsx index 741a5ab..317b2f9 100644 --- a/src/views/Modals/Inputs/AttachmentViewerModal.jsx +++ b/src/views/Modals/Inputs/AttachmentViewerModal.jsx @@ -92,12 +92,14 @@ function AttachmentViewerModal({ config }) { component='img' src={url} alt={fileName} + onClick={() => url && openUrl(url)} onLoad={() => setImgLoaded(true)} onError={() => { setImgLoaded(true) setImgError(true) }} sx={{ + cursor: url ? 'zoom-in' : 'default', maxWidth: '100%', maxHeight: '65vh', borderRadius: 'md', diff --git a/src/views/Settings/ProfileSettings.jsx b/src/views/Settings/ProfileSettings.jsx index 1bb2c2c..27e2f28 100644 --- a/src/views/Settings/ProfileSettings.jsx +++ b/src/views/Settings/ProfileSettings.jsx @@ -88,8 +88,7 @@ const ProfileSettings = () => { formData.append('file', compressedFile, 'profile.jpg') const response = await apiClient.upload('/users/profile_photo', formData) if (!response.ok) throw new Error('Upload failed') - const data = await response.json() - // const url = resolvePhotoURL(data.url || data.sign) + await response.json() refetchUserProfile() // Refresh user profile to get the new photoURL showSuccess({ diff --git a/src/views/components/ScanToTask/ScanPanel.jsx b/src/views/components/ScanToTask/ScanPanel.jsx index 88bf541..855ac07 100644 --- a/src/views/components/ScanToTask/ScanPanel.jsx +++ b/src/views/components/ScanToTask/ScanPanel.jsx @@ -21,7 +21,7 @@ import { useScanToTask } from './useScanToTask' * Flow: capture → (auto) processing → done [calls onTaskExtracted + onClose] * → error [retake or cancel] */ -const ScanPanel = ({ open, onTaskExtracted, onClose }) => { +const ScanPanel = ({ open, onTaskExtracted, onClose, initialImageUrl }) => { const { isNativeScanner, phase, @@ -46,12 +46,12 @@ const ScanPanel = ({ open, onTaskExtracted, onClose }) => { // Start/stop based on open state useEffect(() => { if (open) { - activate() + activate(initialImageUrl) } else { reset() } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [open]) + }, [open, initialImageUrl]) // Start camera when entering capture phase on web useEffect(() => { diff --git a/src/views/components/ScanToTask/useScanToTask.js b/src/views/components/ScanToTask/useScanToTask.js index 2b5eea4..66b5d95 100644 --- a/src/views/components/ScanToTask/useScanToTask.js +++ b/src/views/components/ScanToTask/useScanToTask.js @@ -207,13 +207,22 @@ export function useScanToTask() { setPhase('capture') }, []) - const activate = useCallback(() => { - setCapturedImage(null) - setTaskResult(null) - setErrorMsg('') - setOcrProgress(0) - setPhase('capture') - }, []) + const activate = useCallback( + (initialImageUrl = null) => { + setCapturedImage(initialImageUrl) + setTaskResult(null) + setErrorMsg('') + setOcrProgress(0) + + if (initialImageUrl) { + processImage(initialImageUrl, 'browser') + return + } + + setPhase('capture') + }, + [processImage], + ) const reset = useCallback(() => { stopCamera() diff --git a/src/views/components/SmartTaskTitleInput.jsx b/src/views/components/SmartTaskTitleInput.jsx index bd8a9ff..9a66b32 100644 --- a/src/views/components/SmartTaskTitleInput.jsx +++ b/src/views/components/SmartTaskTitleInput.jsx @@ -235,8 +235,6 @@ const SmartTaskTitleInput = ({ caretColor: mode === 'dark' ? '#fff' : '#000', border: 'none', outline: 'none', - border: 'none', - outline: 'none', }} />