hardened camera mounting handling

This commit is contained in:
Christopher Sanden
2026-03-19 16:15:37 +01:00
parent 63e65001e2
commit 57daa96be6
5 changed files with 434 additions and 12 deletions

View File

@@ -21,6 +21,7 @@ import { useAuthContext } from "@/hooks/use-auth-context"
import { NoteImageChange, useNotes } from "@/src/notes/NotesContext"
import { StagedNoteImage, validateStagedNoteImage } from "@/src/notes/image-utils"
import { pickImageFromCamera, pickImageFromLibrary } from "@/src/notes/native-image-picker"
import { usePickerLifecycleGuard } from "@/src/notes/use-picker-lifecycle-guard"
import { detailScreenStyles as styles } from "@/src/styles/app-styles"
import { useAppTheme } from "@/src/theme/AppThemeProvider"
@@ -45,6 +46,7 @@ export default function DetailScreen() {
const insets = useSafeAreaInsets()
const headerHeight = useHeaderHeight()
const { colorScheme, palette } = useAppTheme()
const { endPicker, isScreenActive, tryBeginPicker } = usePickerLifecycleGuard()
const formatTimestamp = (value: string) => {
const parsed = new Date(value)
@@ -85,10 +87,14 @@ export default function DetailScreen() {
}, [fetchNoteById, id, note])
const attachFromCamera = async () => {
if (!tryBeginPicker()) {
return
}
try {
const image = await pickImageFromCamera()
if (image) {
if (image && isScreenActive()) {
validateStagedNoteImage(image)
setStagedImage(image)
setImageChange({ type: "replace", image })
@@ -96,15 +102,23 @@ export default function DetailScreen() {
setStatusMessage(null)
}
} catch (error) {
setLocalErrorMessage(error instanceof Error ? error.message : "The camera could not be opened.")
if (isScreenActive()) {
setLocalErrorMessage(error instanceof Error ? error.message : "The camera could not be opened.")
}
} finally {
endPicker()
}
}
const attachFromGallery = async () => {
if (!tryBeginPicker()) {
return
}
try {
const image = await pickImageFromLibrary()
if (image) {
if (image && isScreenActive()) {
validateStagedNoteImage(image)
setStagedImage(image)
setImageChange({ type: "replace", image })
@@ -112,7 +126,11 @@ export default function DetailScreen() {
setStatusMessage(null)
}
} catch (error) {
setLocalErrorMessage(error instanceof Error ? error.message : "The gallery could not be opened.")
if (isScreenActive()) {
setLocalErrorMessage(error instanceof Error ? error.message : "The gallery could not be opened.")
}
} finally {
endPicker()
}
}

View File

@@ -18,6 +18,7 @@ import UploadProgressBar from "@/components/upload-progress-bar"
import { useNotes } from "@/src/notes/NotesContext"
import { StagedNoteImage, validateStagedNoteImage } from "@/src/notes/image-utils"
import { pickImageFromCamera, pickImageFromLibrary } from "@/src/notes/native-image-picker"
import { usePickerLifecycleGuard } from "@/src/notes/use-picker-lifecycle-guard"
import { newNoteScreenStyles as styles } from "@/src/styles/app-styles"
import { useAppTheme } from "@/src/theme/AppThemeProvider"
@@ -34,32 +35,49 @@ export default function NewNoteScreen() {
const { colorScheme, palette } = useAppTheme()
const [contentHeight, setContentHeight] = useState(160)
const scrollRef = useRef<ScrollView>(null)
const { endPicker, isScreenActive, tryBeginPicker } = usePickerLifecycleGuard()
const attachFromCamera = async () => {
if (!tryBeginPicker()) {
return
}
try {
const image = await pickImageFromCamera()
if (image) {
if (image && isScreenActive()) {
validateStagedNoteImage(image)
setStagedImage(image)
setLocalErrorMessage(null)
}
} catch (error) {
setLocalErrorMessage(error instanceof Error ? error.message : "The camera could not be opened.")
if (isScreenActive()) {
setLocalErrorMessage(error instanceof Error ? error.message : "The camera could not be opened.")
}
} finally {
endPicker()
}
}
const attachFromGallery = async () => {
if (!tryBeginPicker()) {
return
}
try {
const image = await pickImageFromLibrary()
if (image) {
if (image && isScreenActive()) {
validateStagedNoteImage(image)
setStagedImage(image)
setLocalErrorMessage(null)
}
} catch (error) {
setLocalErrorMessage(error instanceof Error ? error.message : "The gallery could not be opened.")
if (isScreenActive()) {
setLocalErrorMessage(error instanceof Error ? error.message : "The gallery could not be opened.")
}
} finally {
endPicker()
}
}