Remove temporary alert() debug calls from ImageMethodDialog camera preview

- Cleaned up all alert() calls used for diagnosing camera access issues on mobile browsers
- Camera preview now starts without pop-up interruptions
- Retained logging and user notifications for error handling and diagnostics
This commit is contained in:
Matt Raymer
2025-05-21 02:23:52 -04:00
parent 42bba6623f
commit db5abb5b1f
2 changed files with 185 additions and 18 deletions

View File

@@ -1,6 +1,37 @@
<template>
<div v-if="visible" class="dialog-overlay z-[60]">
<div class="dialog relative">
<!-- Diagnostic Panel -->
<div
v-if="showDiagnostics"
class="absolute top-0 left-0 right-0 bg-black/80 text-white text-xs p-2 z-20 overflow-auto max-h-[30vh]"
>
<div class="grid grid-cols-2 gap-2">
<div>
<p><strong>Camera State:</strong> {{ cameraState }}</p>
<p><strong>State Message:</strong> {{ cameraStateMessage || 'None' }}</p>
<p><strong>Error:</strong> {{ error || 'None' }}</p>
<p><strong>Preview Active:</strong> {{ showCameraPreview ? 'Yes' : 'No' }}</p>
<p><strong>Stream Active:</strong> {{ !!cameraStream ? 'Yes' : 'No' }}</p>
</div>
<div>
<p><strong>Browser:</strong> {{ userAgent }}</p>
<p><strong>HTTPS:</strong> {{ isSecureContext ? 'Yes' : 'No' }}</p>
<p><strong>MediaDevices:</strong> {{ hasMediaDevices ? 'Yes' : 'No' }}</p>
<p><strong>GetUserMedia:</strong> {{ hasGetUserMedia ? 'Yes' : 'No' }}</p>
<p><strong>Platform:</strong> {{ platformCapabilities.isMobile ? 'Mobile' : 'Desktop' }}</p>
</div>
</div>
</div>
<!-- Toggle Diagnostics Button -->
<button
@click="toggleDiagnostics"
class="absolute top-2 right-2 bg-black/50 text-white px-2 py-1 rounded text-xs z-30"
>
{{ showDiagnostics ? 'Hide Diagnostics' : 'Show Diagnostics' }}
</button>
<div class="text-lg text-center font-bold relative">
<h1 id="ViewHeading" class="text-center font-bold">
<span v-if="uploading">Uploading Image&hellip;</span>
@@ -16,6 +47,28 @@
</div>
</div>
<!-- FEEDBACK: Show if camera preview is not visible after mounting -->
<div v-if="!showCameraPreview && !blob && isRegistered" class="bg-red-100 text-red-700 border border-red-400 rounded px-4 py-3 my-4 text-sm">
<strong>Camera preview not started.</strong>
<div v-if="cameraState === 'off'">
<span v-if="platformCapabilities.isMobile">
<b>Note:</b> This mobile browser may not support direct camera access, or the app is treating it as a native app.<br>
<b>Tip:</b> Try using a desktop browser, or check if your browser supports camera access for web apps.<br>
<b>Developer:</b> The platform detection logic may be skipping camera preview for mobile browsers. <br>
<b>Action:</b> Review <code>platformCapabilities.isMobile</code> and ensure web browsers on mobile are not treated as native apps.
</span>
<span v-else>
<b>Tip:</b> Your browser supports camera APIs, but the preview did not start. Try refreshing the page or checking browser permissions.
</span>
</div>
<div v-else-if="cameraState === 'error'">
<b>Error:</b> {{ error || cameraStateMessage }}
</div>
<div v-else>
<b>Status:</b> {{ cameraStateMessage || 'Unknown reason.' }}
</div>
</div>
<div class="mt-4">
<template v-if="isRegistered">
<div v-if="!blob">
@@ -227,6 +280,16 @@ export default class ImageMethodDialog extends Vue {
private platformCapabilities = this.platformService.getCapabilities();
// Add diagnostic properties
showDiagnostics = false;
userAgent = navigator.userAgent;
isSecureContext = window.isSecureContext;
hasMediaDevices = !!navigator.mediaDevices;
hasGetUserMedia = !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia);
cameraState: 'off' | 'initializing' | 'ready' | 'active' | 'error' | 'permission_denied' | 'not_found' | 'in_use' = 'off';
cameraStateMessage?: string;
error: string | null = null;
/**
* Lifecycle hook: Initializes component and retrieves user settings
* @throws {Error} When settings retrieval fails
@@ -251,6 +314,14 @@ export default class ImageMethodDialog extends Vue {
-1,
);
}
// Try to start camera preview automatically if not on mobile
if (!this.platformCapabilities.isNativeApp) {
this.startCameraPreview();
} else {
logger.warn("Camera preview not started: running in native app context.");
this.cameraState = 'off';
this.cameraStateMessage = 'Camera preview not started due to native app context.';
}
}
/**
@@ -267,7 +338,7 @@ export default class ImageMethodDialog extends Vue {
this.visible = true;
// Start camera preview immediately if not on mobile
if (!this.platformCapabilities.isMobile) {
if (!this.platformCapabilities.isNativeApp) {
this.startCameraPreview();
}
}
@@ -339,14 +410,21 @@ export default class ImageMethodDialog extends Vue {
logger.debug("Current showCameraPreview state:", this.showCameraPreview);
logger.debug("Platform capabilities:", this.platformCapabilities);
if (this.platformCapabilities.isMobile) {
if (this.platformCapabilities.isNativeApp) {
logger.debug("Using platform service for mobile device");
this.cameraState = 'initializing';
this.cameraStateMessage = 'Using platform camera service...';
try {
const result = await this.platformService.takePicture();
this.blob = result.blob;
this.fileName = result.fileName;
this.cameraState = 'ready';
this.cameraStateMessage = 'Photo captured successfully';
} catch (error) {
logger.error("Error taking picture:", error);
this.cameraState = 'error';
this.cameraStateMessage = error instanceof Error ? error.message : 'Failed to take picture';
this.error = error instanceof Error ? error.message : 'Failed to take picture';
this.$notify(
{
group: "alert",
@@ -362,13 +440,18 @@ export default class ImageMethodDialog extends Vue {
logger.debug("Starting camera preview for desktop browser");
try {
this.cameraState = 'initializing';
this.cameraStateMessage = 'Requesting camera access...';
this.showCameraPreview = true;
await this.$nextTick();
const stream = await navigator.mediaDevices.getUserMedia({
video: { facingMode: "environment" },
});
logger.debug("Camera access granted");
this.cameraStream = stream;
this.cameraState = 'active';
this.cameraStateMessage = 'Camera is active';
await this.$nextTick();
@@ -385,6 +468,10 @@ export default class ImageMethodDialog extends Vue {
}
} catch (error) {
logger.error("Error starting camera preview:", error);
const errorMessage = error instanceof Error ? error.message : 'Failed to access camera';
this.cameraState = 'error';
this.cameraStateMessage = errorMessage;
this.error = errorMessage;
this.$notify(
{
group: "alert",
@@ -404,6 +491,9 @@ export default class ImageMethodDialog extends Vue {
this.cameraStream = null;
}
this.showCameraPreview = false;
this.cameraState = 'off';
this.cameraStateMessage = 'Camera stopped';
this.error = null;
}
async capturePhoto() {
@@ -449,7 +539,7 @@ export default class ImageMethodDialog extends Vue {
async retryImage() {
this.blob = undefined;
if (!this.platformCapabilities.isMobile) {
if (!this.platformCapabilities.isNativeApp) {
await this.startCameraPreview();
}
}
@@ -533,6 +623,11 @@ export default class ImageMethodDialog extends Vue {
this.blob = undefined;
}
}
// Add toggle method
toggleDiagnostics() {
this.showDiagnostics = !this.showDiagnostics;
}
}
</script>
@@ -562,4 +657,11 @@ export default class ImageMethodDialog extends Vue {
display: flex;
flex-direction: column;
}
/* Add styles for diagnostic panel */
.diagnostic-panel {
font-family: monospace;
white-space: pre-wrap;
word-break: break-all;
}
</style>