Fixes and remove logs
This commit is contained in:
@@ -85,9 +85,9 @@ const extractStorageKey = url => {
|
|||||||
// replace them with backend proxy URLs (which generate fresh signed URLs on
|
// replace them with backend proxy URLs (which generate fresh signed URLs on
|
||||||
// each request). Returns the patched HTML, or the original if nothing changed.
|
// each request). Returns the patched HTML, or the original if nothing changed.
|
||||||
const refreshSignedUrlsInHtml = html => {
|
const refreshSignedUrlsInHtml = html => {
|
||||||
console.debug('1. refreshSignedUrlsInHtml', { html })
|
|
||||||
if (!html) return html
|
if (!html) return html
|
||||||
if (
|
if (
|
||||||
|
!html.includes('dt-data-path') &&
|
||||||
!html.includes('X-Amz-') &&
|
!html.includes('X-Amz-') &&
|
||||||
!html.includes('X-Goog-') &&
|
!html.includes('X-Goog-') &&
|
||||||
!html.includes('sig') &&
|
!html.includes('sig') &&
|
||||||
@@ -95,22 +95,26 @@ const refreshSignedUrlsInHtml = html => {
|
|||||||
) {
|
) {
|
||||||
return html
|
return html
|
||||||
}
|
}
|
||||||
console.debug('2. refreshSignedUrlsInHtml: found potential signed URLs, parsing HTML...')
|
|
||||||
const parser = new DOMParser()
|
const parser = new DOMParser()
|
||||||
const doc = parser.parseFromString(html, 'text/html')
|
const doc = parser.parseFromString(html, 'text/html')
|
||||||
const imgs = doc.querySelectorAll('img[src]')
|
const imgs = doc.querySelectorAll('img[src]')
|
||||||
let changed = false
|
let changed = false
|
||||||
|
|
||||||
imgs.forEach(async img => {
|
imgs.forEach(img => {
|
||||||
|
const stablePath = img.getAttribute('dt-data-path')
|
||||||
if (!img.getAttribute('dt-data-path')) {
|
|
||||||
// not custom tag, skipping:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const src = img.getAttribute('src')
|
const src = img.getAttribute('src')
|
||||||
|
let nextSrc = src
|
||||||
|
|
||||||
img.setAttribute('src', resolvePhotoURL(src))
|
if (stablePath) {
|
||||||
changed = true
|
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
|
return changed ? doc.body.innerHTML : html
|
||||||
|
|||||||
@@ -975,7 +975,10 @@ const ChoreEdit = () => {
|
|||||||
key={att.file_path || idx}
|
key={att.file_path || idx}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const url = resolvePhotoURL(att.sign || att.file_path)
|
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 = [
|
const isImage = [
|
||||||
'jpg',
|
'jpg',
|
||||||
'jpeg',
|
'jpeg',
|
||||||
@@ -1031,7 +1034,8 @@ const ChoreEdit = () => {
|
|||||||
size='sm'
|
size='sm'
|
||||||
variant='plain'
|
variant='plain'
|
||||||
color='danger'
|
color='danger'
|
||||||
onClick={() => {
|
onClick={event => {
|
||||||
|
event.stopPropagation()
|
||||||
DeleteChoreAttachment(choreId, att.file_path)
|
DeleteChoreAttachment(choreId, att.file_path)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
setAttachments(prev =>
|
setAttachments(prev =>
|
||||||
@@ -1054,7 +1058,8 @@ const ChoreEdit = () => {
|
|||||||
size='sm'
|
size='sm'
|
||||||
variant='plain'
|
variant='plain'
|
||||||
color='danger'
|
color='danger'
|
||||||
onClick={() => {
|
onClick={event => {
|
||||||
|
event.stopPropagation()
|
||||||
setAttachments(prev =>
|
setAttachments(prev =>
|
||||||
prev.filter((_, i) => i !== idx),
|
prev.filter((_, i) => i !== idx),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -631,7 +631,7 @@ const ChoreView = () => {
|
|||||||
mb: 0.5,
|
mb: 0.5,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography level='h3'>asde{chore.name}</Typography>
|
<Typography level='h3'>{chore.name}</Typography>
|
||||||
<PendingBadge commands={pendingCmds} />
|
<PendingBadge commands={pendingCmds} />
|
||||||
</Box>
|
</Box>
|
||||||
{chore.isActive === false && (
|
{chore.isActive === false && (
|
||||||
|
|||||||
@@ -34,8 +34,12 @@ function AttachmentBrowserModal({ choreId, isOpen, onClose }) {
|
|||||||
if (!isOpen || !choreId) return
|
if (!isOpen || !choreId) return
|
||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
GetChoreAttachments(choreId)
|
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 : []))
|
.then(data => setAttachments(Array.isArray(data) ? data : []))
|
||||||
|
.catch(() => setAttachments([]))
|
||||||
.finally(() => setIsLoading(false))
|
.finally(() => setIsLoading(false))
|
||||||
}, [isOpen, choreId])
|
}, [isOpen, choreId])
|
||||||
|
|
||||||
@@ -91,7 +95,16 @@ function AttachmentBrowserModal({ choreId, isOpen, onClose }) {
|
|||||||
) : (
|
) : (
|
||||||
<List sx={{ '--ListItem-paddingX': '0px' }}>
|
<List sx={{ '--ListItem-paddingX': '0px' }}>
|
||||||
{attachments.map((attachment, index) => (
|
{attachments.map((attachment, index) => (
|
||||||
<ListItem key={index} sx={{ p: 0 }}>
|
<ListItem
|
||||||
|
key={
|
||||||
|
attachment.id ||
|
||||||
|
attachment.file_path ||
|
||||||
|
attachment.sign ||
|
||||||
|
attachment.file_name ||
|
||||||
|
index
|
||||||
|
}
|
||||||
|
sx={{ p: 0 }}
|
||||||
|
>
|
||||||
<ListItemButton
|
<ListItemButton
|
||||||
onClick={() => handleAttachmentClick(attachment)}
|
onClick={() => handleAttachmentClick(attachment)}
|
||||||
sx={{ borderRadius: 'sm', gap: 1.5, py: 1 }}
|
sx={{ borderRadius: 'sm', gap: 1.5, py: 1 }}
|
||||||
|
|||||||
@@ -92,12 +92,14 @@ function AttachmentViewerModal({ config }) {
|
|||||||
component='img'
|
component='img'
|
||||||
src={url}
|
src={url}
|
||||||
alt={fileName}
|
alt={fileName}
|
||||||
|
onClick={() => url && openUrl(url)}
|
||||||
onLoad={() => setImgLoaded(true)}
|
onLoad={() => setImgLoaded(true)}
|
||||||
onError={() => {
|
onError={() => {
|
||||||
setImgLoaded(true)
|
setImgLoaded(true)
|
||||||
setImgError(true)
|
setImgError(true)
|
||||||
}}
|
}}
|
||||||
sx={{
|
sx={{
|
||||||
|
cursor: url ? 'zoom-in' : 'default',
|
||||||
maxWidth: '100%',
|
maxWidth: '100%',
|
||||||
maxHeight: '65vh',
|
maxHeight: '65vh',
|
||||||
borderRadius: 'md',
|
borderRadius: 'md',
|
||||||
|
|||||||
@@ -88,8 +88,7 @@ const ProfileSettings = () => {
|
|||||||
formData.append('file', compressedFile, 'profile.jpg')
|
formData.append('file', compressedFile, 'profile.jpg')
|
||||||
const response = await apiClient.upload('/users/profile_photo', formData)
|
const response = await apiClient.upload('/users/profile_photo', formData)
|
||||||
if (!response.ok) throw new Error('Upload failed')
|
if (!response.ok) throw new Error('Upload failed')
|
||||||
const data = await response.json()
|
await response.json()
|
||||||
// const url = resolvePhotoURL(data.url || data.sign)
|
|
||||||
|
|
||||||
refetchUserProfile() // Refresh user profile to get the new photoURL
|
refetchUserProfile() // Refresh user profile to get the new photoURL
|
||||||
showSuccess({
|
showSuccess({
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import { useScanToTask } from './useScanToTask'
|
|||||||
* Flow: capture → (auto) processing → done [calls onTaskExtracted + onClose]
|
* Flow: capture → (auto) processing → done [calls onTaskExtracted + onClose]
|
||||||
* → error [retake or cancel]
|
* → error [retake or cancel]
|
||||||
*/
|
*/
|
||||||
const ScanPanel = ({ open, onTaskExtracted, onClose }) => {
|
const ScanPanel = ({ open, onTaskExtracted, onClose, initialImageUrl }) => {
|
||||||
const {
|
const {
|
||||||
isNativeScanner,
|
isNativeScanner,
|
||||||
phase,
|
phase,
|
||||||
@@ -46,12 +46,12 @@ const ScanPanel = ({ open, onTaskExtracted, onClose }) => {
|
|||||||
// Start/stop based on open state
|
// Start/stop based on open state
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open) {
|
if (open) {
|
||||||
activate()
|
activate(initialImageUrl)
|
||||||
} else {
|
} else {
|
||||||
reset()
|
reset()
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [open])
|
}, [open, initialImageUrl])
|
||||||
|
|
||||||
// Start camera when entering capture phase on web
|
// Start camera when entering capture phase on web
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -207,13 +207,22 @@ export function useScanToTask() {
|
|||||||
setPhase('capture')
|
setPhase('capture')
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const activate = useCallback(() => {
|
const activate = useCallback(
|
||||||
setCapturedImage(null)
|
(initialImageUrl = null) => {
|
||||||
setTaskResult(null)
|
setCapturedImage(initialImageUrl)
|
||||||
setErrorMsg('')
|
setTaskResult(null)
|
||||||
setOcrProgress(0)
|
setErrorMsg('')
|
||||||
setPhase('capture')
|
setOcrProgress(0)
|
||||||
}, [])
|
|
||||||
|
if (initialImageUrl) {
|
||||||
|
processImage(initialImageUrl, 'browser')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
setPhase('capture')
|
||||||
|
},
|
||||||
|
[processImage],
|
||||||
|
)
|
||||||
|
|
||||||
const reset = useCallback(() => {
|
const reset = useCallback(() => {
|
||||||
stopCamera()
|
stopCamera()
|
||||||
|
|||||||
@@ -235,8 +235,6 @@ const SmartTaskTitleInput = ({
|
|||||||
caretColor: mode === 'dark' ? '#fff' : '#000',
|
caretColor: mode === 'dark' ? '#fff' : '#000',
|
||||||
border: 'none',
|
border: 'none',
|
||||||
outline: 'none',
|
outline: 'none',
|
||||||
border: 'none',
|
|
||||||
outline: 'none',
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
|
|||||||
Reference in New Issue
Block a user