Form changes Horizon - Upload Daily Field Work Photo
This commit is contained in:
parent
07a127d003
commit
f5b6ae5550
|
|
@ -190,6 +190,13 @@
|
|||
style="display:none;">
|
||||
|
||||
<div class="d-flex flex-wrap gap-2 mt-2">
|
||||
|
||||
<button type="button" id="switch-photo-camera"
|
||||
class="btn btn-info" style="display:none;">
|
||||
<i class="mdi mdi-camera-switch me-1"></i>
|
||||
Switch Camera
|
||||
</button>
|
||||
|
||||
<button type="button" id="capture-photo"
|
||||
class="btn btn-success" style="display:none;">
|
||||
Capture Photo
|
||||
|
|
@ -392,30 +399,34 @@
|
|||
|
||||
let photoStream = null;
|
||||
|
||||
let photoStream = null;
|
||||
let currentCamera = 'environment';
|
||||
|
||||
const video = document.getElementById('photo-camera-preview');
|
||||
const preview = document.getElementById('photo-captured-preview');
|
||||
const photoInput = document.getElementById('field-upload_photo');
|
||||
|
||||
$('#start-photo-camera').on('click', async function () {
|
||||
// Start camera
|
||||
async function startPhotoCamera(cameraType = currentCamera) {
|
||||
|
||||
try {
|
||||
// Stop previous camera before switching
|
||||
stopPhotoCamera();
|
||||
|
||||
currentCamera = cameraType;
|
||||
|
||||
if (!navigator.mediaDevices ||
|
||||
!navigator.mediaDevices.getUserMedia) {
|
||||
throw new Error('Camera API is unavailable. Use HTTPS or localhost.');
|
||||
throw new Error('Camera access requires HTTPS or localhost.');
|
||||
}
|
||||
|
||||
// Request camera permission
|
||||
photoStream = await navigator.mediaDevices.getUserMedia({
|
||||
video: {
|
||||
facingMode: { ideal: 'environment' }
|
||||
facingMode: { exact: currentCamera }
|
||||
},
|
||||
audio: false
|
||||
});
|
||||
|
||||
// Check required elements
|
||||
if (!video || !preview || !photoInput) {
|
||||
throw new Error('Camera elements are missing from the page.');
|
||||
}
|
||||
|
||||
video.srcObject = photoStream;
|
||||
video.style.display = 'block';
|
||||
preview.style.display = 'none';
|
||||
|
|
@ -423,43 +434,73 @@
|
|||
await video.play();
|
||||
|
||||
$('#start-photo-camera').hide();
|
||||
$('#switch-photo-camera').show();
|
||||
$('#capture-photo').show();
|
||||
$('#retake-photo').hide();
|
||||
|
||||
} catch (error) {
|
||||
|
||||
console.error('Camera error:', error);
|
||||
|
||||
// Stop any partially opened camera stream
|
||||
if (photoStream) {
|
||||
photoStream.getTracks().forEach(track => track.stop());
|
||||
photoStream = null;
|
||||
}
|
||||
stopPhotoCamera();
|
||||
|
||||
if (error.name === 'NotAllowedError' ||
|
||||
error.name === 'PermissionDeniedError') {
|
||||
// Some devices do not support the requested camera.
|
||||
// Fall back to the browser's preferred camera.
|
||||
if (error.name === 'OverconstrainedError' ||
|
||||
error.name === 'NotFoundError') {
|
||||
|
||||
try {
|
||||
photoStream = await navigator.mediaDevices.getUserMedia({
|
||||
video: true,
|
||||
audio: false
|
||||
});
|
||||
|
||||
video.srcObject = photoStream;
|
||||
video.style.display = 'block';
|
||||
await video.play();
|
||||
|
||||
$('#start-photo-camera').hide();
|
||||
$('#switch-photo-camera').show();
|
||||
$('#capture-photo').show();
|
||||
|
||||
return;
|
||||
|
||||
} catch (fallbackError) {
|
||||
console.error('Fallback camera error:', fallbackError);
|
||||
}
|
||||
}
|
||||
|
||||
Swal.fire({
|
||||
icon: 'warning',
|
||||
title: 'Camera Access Denied',
|
||||
text: 'Please enable camera permission for this website in your browser settings, then try again.'
|
||||
});
|
||||
|
||||
} else {
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Unable to Open Camera',
|
||||
text: error.message || 'Please check your camera and try again.'
|
||||
title: 'Camera Unavailable',
|
||||
text: 'Please check camera permission and camera availability.'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Open camera
|
||||
$('#start-photo-camera').on('click', function () {
|
||||
startPhotoCamera('environment');
|
||||
});
|
||||
|
||||
// Switch between front and back cameras
|
||||
$('#switch-photo-camera').on('click', function () {
|
||||
|
||||
const nextCamera =
|
||||
currentCamera === 'environment' ? 'user' : 'environment';
|
||||
|
||||
startPhotoCamera(nextCamera);
|
||||
});
|
||||
|
||||
// Capture photo
|
||||
$('#capture-photo').on('click', function () {
|
||||
|
||||
if (!photoStream || !video.videoWidth) {
|
||||
return;
|
||||
}
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
|
||||
canvas.width = video.videoWidth;
|
||||
canvas.height = video.videoHeight;
|
||||
|
||||
|
|
@ -468,6 +509,7 @@
|
|||
);
|
||||
|
||||
canvas.toBlob(function (blob) {
|
||||
|
||||
if (!blob) {
|
||||
Swal.fire('Error', 'Could not capture the photo.', 'error');
|
||||
return;
|
||||
|
|
@ -489,28 +531,38 @@
|
|||
|
||||
stopPhotoCamera();
|
||||
|
||||
$('#start-photo-camera').show();
|
||||
$('#switch-photo-camera').hide();
|
||||
$('#capture-photo').hide();
|
||||
$('#start-photo-camera').hide();
|
||||
$('#retake-photo').show();
|
||||
$('#retake-photo').hide();
|
||||
|
||||
}, 'image/jpeg', 0.9);
|
||||
});
|
||||
|
||||
// Retake photo
|
||||
$('#retake-photo').on('click', function () {
|
||||
|
||||
photoInput.value = '';
|
||||
preview.src = '';
|
||||
preview.style.display = 'none';
|
||||
|
||||
$('#retake-photo').hide();
|
||||
$('#start-photo-camera').trigger('click');
|
||||
|
||||
startPhotoCamera(currentCamera);
|
||||
});
|
||||
|
||||
// Stop camera
|
||||
function stopPhotoCamera() {
|
||||
|
||||
if (photoStream) {
|
||||
photoStream.getTracks().forEach(track => track.stop());
|
||||
photoStream = null;
|
||||
}
|
||||
|
||||
if (video) {
|
||||
video.srcObject = null;
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('beforeunload', stopPhotoCamera);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue