Merge branch 'afiqhamzah-feat-add-capture-marhun-picture' into 'main'

Afiqhamzah feat add capture marhun picture

See merge request online-sistem1/lelong!339
This commit is contained in:
Muhamad Amir Hassan Hamzan
2022-12-15 07:11:26 +00:00
12 changed files with 307 additions and 177 deletions
+2
View File
@@ -298,3 +298,5 @@ PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
MARHUN_CAMERAS = "Doccamera"
+7
View File
@@ -0,0 +1,7 @@
<?php
return [
'marhun_cameras' => array_map(fn ($camera_label) => trim($camera_label), explode(',', env('MARHUN_CAMERAS'))) ?? 'Doccamera'
];
+1 -1
View File
@@ -16805,4 +16805,4 @@ a.article:hover {
.user-info {
/* display: flex; */
}
}
+7
View File
@@ -0,0 +1,7 @@
body {
padding-right: 0px !important
}
.modal-open {
overflow-y: auto;
}
+9
View File
File diff suppressed because one or more lines are too long
+11 -1
View File
File diff suppressed because one or more lines are too long
+42
View File
@@ -0,0 +1,42 @@
function marhunPhotoCapturerDebugger() {
return {
scan: function () {
if ('mediaDevices' in navigator && navigator.mediaDevices.getUserMedia) {
// let camera_label = "HP TrueVision HD Camera (05c8:03d2)";
// let camera_label = "USB Camera (0c45:6366)";
let camera_label = "Doccamera (2b19:0200)";
const generateCameraListing = (cameras) => {
let title = "Available cameras: ";
let content = cameras.map((camera, index) => {
index = index + 1;
return `${index}. ${camera.label}\n`;
});
return `${title}\n${content.join('')}`;
};
navigator.mediaDevices.enumerateDevices()
.then(devices => devices.filter(x => x.kind === 'videoinput'))
.then(devices => devices.map(device => {
let altered_label = device.label.split(" ");
altered_label.splice(-1);
altered_label = altered_label.join(" ");
return {
label: altered_label,
deviceId: device.deviceId,
};
}))
.then(devices => alert(generateCameraListing(devices)))
}
return true;
},
}
}
+127 -150
View File
@@ -1,183 +1,160 @@
function marhunPhotoCapturerFactory(modal_selector) {
return {
return {
constraints: {
audio: false,
video: {
height: { ideal: 1080 }
},
facingMode: { exact: "environment" },
},
constraints: {
audio: false,
video: true,
},
imageCapturer: null,
imageCapturer: null,
start: function start() {
navigator.mediaDevices.getUserMedia(this.constraints)
.then(this.gotMedia)
.catch(e => { console.error('getUserMedia() failed: ', e); });
},
captureMedia: function (mediastream) {
gotMedia: function (mediastream) {
let videoTrack = mediastream.getVideoTracks()[0];
let imageCapturer = new ImageCapture(videoTrack);
let modal = document.querySelector(modal_selector);
let videoTag = modal.querySelector('.video-tag-overallmarhun');
let modal = document.querySelector(modal_selector);
let imageTag = modal.querySelector('.image-tag-overallmarhun');
videoTag.srcObject = mediastream;
let setMarhunPhotoInputToCapturedPhoto = function (blob) {
const modal = document.querySelector(modal_selector);
const marhunPhotoInput = modal.querySelector('#inputGroupFile04');
let videoTrack = mediastream.getVideoTracks()[0];
this.imageCapturer = new ImageCapture(videoTrack);
const marhunPhotoFile = new File([blob], 'marhun_photo.png', {
type: 'image/png',
lastModified: new Date().getTime(),
});
const dataTransfer = new DataTransfer();
dataTransfer.items.add(marhunPhotoFile);
marhunPhotoInput.files = dataTransfer.files;
};
imageCapturer.takePhoto()
.then((blob) => {
imageTag.src = URL.createObjectURL(blob);
imageTag.classList.add('marhun-uploaded');
// Timeout needed in Chrome, see https://crbug.com/711524
setTimeout(() => {
const capabilities = videoTrack.getCapabilities()
console.log(capabilities)
modal.querySelector('.video-tag-overallmarhun').classList.add('d-none');
// Check whether zoom is supported or not.
if (!capabilities.zoom) {
return;
}
modal.querySelector('.camera-shutter').classList.remove('d-none');
modal.querySelector('.camera-shutter').classList.add('d-flex');
}, 500);
window.setTimeout(() => {
modal.querySelector('.image-tag-overallmarhun').classList.remove('d-none');
modal.querySelector('.camera-shutter').classList.remove('d-flex');
modal.querySelector('.camera-shutter').classList.add('d-none');
modal.querySelector('.camera-button').classList.add('d-none')
}, 1000);
},
modal.querySelector('button[type="submit"]').disabled = false;
captureMedia: function (mediastream) {
return blob;
let videoTrack = mediastream.getVideoTracks()[0];
let imageCapturer = new ImageCapture(videoTrack);
})
.then(blob => setMarhunPhotoInputToCapturedPhoto(blob))
.catch((err) => {
console.error("takePhoto() failed: ", err);
});
let modal = document.querySelector(modal_selector);
let imageTag = modal.querySelector('.image-tag-overallmarhun');
},
takePhoto: function () {
let setMarhunPhotoInputToCapturedPhoto = function (blob) {
const modal = document.querySelector(modal_selector);
const marhunPhotoInput = modal.querySelector('#inputGroupFile04');
if ('mediaDevices' in navigator && navigator.mediaDevices.getUserMedia) {
this.getCamera()
.then(this.captureMedia)
.catch(e => { console.error('getUserMedia() failed: ', e); });
}
},
getCamera: function () {
function getCameraList() {
return navigator.mediaDevices.enumerateDevices()
.then(devices => devices.filter(x => x.kind === 'videoinput'))
}
function selectNearWorkingCamera(listOfCameras) {
return listOfCameras.at(0);
}
const marhunPhotoFile = new File([blob], 'marhun_photo.png', {
type: 'image/png',
lastModified: new Date().getTime(),
});
function selectPriorityCameraIfExist(listOfCameras) {
const available_cameras = listOfCameras.map(camera => {
let altered_label = camera.label.split(" ");
altered_label.splice(-1);
altered_label = altered_label.join(" ");
return {
label: altered_label,
deviceId: camera.deviceId,
};
});
const filtered = available_cameras.filter(camera => {
return marhun_camera_config.includes(camera.label);
})
// Get the first available priority referencing to env
return filtered.at(-1);
}
function selectCamera(listOfCameras) {
let priorityCamera = selectPriorityCameraIfExist(listOfCameras);
if (!priorityCamera) {
return selectNearWorkingCamera(listOfCameras)
}
return priorityCamera;
}
function composeConstraint(camera) {
var constraints = { deviceId: { exact: camera.deviceId } };
return navigator.mediaDevices.getUserMedia({ video: constraints });
}
return getCameraList()
.then(selectCamera)
.then(composeConstraint);
},
initiateTakeMarhunPhoto: function () {
if ('mediaDevices' in navigator && navigator.mediaDevices.getUserMedia) {
const dataTransfer = new DataTransfer();
dataTransfer.items.add(marhunPhotoFile);
marhunPhotoInput.files = dataTransfer.files;
function showCaptureMarhunModal() {
let modal = document.querySelector(modal_selector);
};
modal.querySelector('.video-tag-overallmarhun').classList.remove('d-none');
modal.querySelector('.image-tag-overallmarhun').classList.add('d-none');
modal.querySelector('.camera-shutter').classList.add('d-none');
modal.querySelector('.camera-button').classList.remove('d-none');
modal.querySelector('button[type="submit"]').disabled = true;
imageCapturer.takePhoto()
.then((blob) => {
imageTag.src = URL.createObjectURL(blob);
imageTag.classList.add('marhun-uploaded');
$(modal_selector).modal('show');
}
function streamCameraView(stream) {
let modal = document.querySelector(modal_selector);
let videoTag = modal.querySelector('.video-tag-overallmarhun');
modal.querySelector('.video-tag-overallmarhun').classList.add('d-none');
videoTag.srcObject = stream;
}
modal.querySelector('.camera-shutter').classList.remove('d-none');
modal.querySelector('.camera-shutter').classList.add('d-flex');
window.setTimeout(() => {
modal.querySelector('.image-tag-overallmarhun').classList.remove('d-none');
modal.querySelector('.camera-shutter').classList.remove('d-flex');
modal.querySelector('.camera-shutter').classList.add('d-none');
modal.querySelector('.camera-button').classList.add('d-none')
}, 1500);
modal.querySelector('button[type="submit"]').disabled = false;
return blob;
})
.then(blob => setMarhunPhotoInputToCapturedPhoto(blob))
.catch((err) => {
console.error("takePhoto() failed: ", err);
});
},
takePhoto: function () {
navigator.mediaDevices.getUserMedia(this.constraints)
.then(this.captureMedia)
.catch(e => { console.error('getUserMedia() failed: ', e); });
},
viewCapturedPhoto: function () {
let imageTag = document.getElementById('image-tag');
if (!imageTag.classList.contains('marhun-uploaded')) {
Swal.fire({
icon: 'error',
title: 'Amaran!',
text: 'Sila ambil gambar marhun'
});
return;
}
displayInNewTab(imageTag.src);
},
displayInNewTab: function (src) {
let image = new Image();
image.src = src;
let w = window.open("");
w.document.write(image.outerHTML);
},
initiateTakeMarhunPhoto: function () {
navigator.mediaDevices.getUserMedia(this.constraints)
.then(this.gotMedia)
.catch(e => { console.error('getUserMedia() failed: ', e); });
let modal = document.querySelector(modal_selector);
modal.querySelector('.video-tag-overallmarhun').classList.remove('d-none');
modal.querySelector('.image-tag-overallmarhun').classList.add('d-none');
modal.querySelector('.camera-shutter').classList.add('d-none');
modal.querySelector('.camera-button').classList.remove('d-none');
modal.querySelector('button[type="submit"]').disabled = true;
$(modal_selector).modal('show');
},
initiateUploadMarhunPhoto: function () {
let file_marhun_photo = document.getElementById('marhun_photo');
let image_tag = document.getElementById('image-tag');
let displayUploadFileToImageTag = (event) => {
let selectedFile = event.target.files[0];
let reader = new FileReader();
image_tag.title = selectedFile.name;
reader.onload = function (event) {
image_tag.src = event.target.result;
};
reader.readAsDataURL(selectedFile);
this.removeEventListener('change', displayUploadFileToImageTag);
};
file_marhun_photo.addEventListener('change', displayUploadFileToImageTag);
image_tag.classList.add('marhun-uploaded');
file_marhun_photo.click();
this.getCamera()
.then(streamCameraView)
.then(showCaptureMarhunModal);
}
},
}
}
}
+52
View File
@@ -0,0 +1,52 @@
function marhunPhotoViewerFactory(button_selector) {
return {
attachPhotoViewer: function () {
if(! document.querySelector(button_selector)){
return;
};
document.querySelector(button_selector).addEventListener('click', (event) => {
event.preventDefault();
const image = new Image();
image.src = event.target.href
const viewer = new Viewer(image, {
hidden: function () {
viewer.destroy();
},
navbar: false,
title: false,
toolbar: {
zoomIn: {
show: true,
size: 'large',
},
oneToOne: {
show: true,
size: 'large',
},
zoomOut: {
show: true,
size: 'large',
},
},
viewed() {
// Zoom to 50% from the center of the window.
viewer.zoomTo(1.25, {
x: window.innerWidth / 2,
y: viewer.innerHeight / 2,
});
},
});
viewer.show();
})
}
}
}
+2 -1
View File
@@ -1,8 +1,9 @@
try {
window.Popper = require('popper.js').default;
window.$ = window.jQuery = require('jquery');
window.Viewer = require('viewerjs');
require('bootstrap');
require('datatables.net-bs4');
require('jquery-confirm');
} catch (e) {}
} catch (e) {}
+3 -2
View File
@@ -3,7 +3,7 @@
<head>
@include('includes.head')
<script type="text/javascript">
$(document).ready(function() {
$('#sidebarCollapse').on('click', function() {
@@ -64,6 +64,7 @@
</script>
@stack('additional_scripts')
@stack('additional_styles')
</head>
<body onload="startTime()">
@@ -78,4 +79,4 @@
</body>
</html>
</html>
+44 -22
View File
@@ -3,17 +3,25 @@
@push('additional_scripts')
<script src="{{ asset('js/marhun-photo-capture.js') }}"></script>
<script src="{{ asset('js/marhun-photo-capture-reload-https.js') }}"></script>
<script src="{{ asset('js/marhun-photo-capture-debugger.js') }}"></script>
<script src="{{ asset('js/marhun-photo-viewer.js') }}"></script>
<script>
var marhun_camera_config = @json(config('marhun_camera.marhun_cameras'));
let modalOverallPhotoCapture = new marhunPhotoCapturerFactory('#modaloverallphoto-capture');
let modalOverallPhotoCaptureUpdate = new marhunPhotoCapturerFactory('#modaloverallphoto-capture-update');
let modalOverallPhotoCapturePerMarhun = new marhunPhotoCapturerFactory('#modalpermarhunphoto-capture');
let modalOverallPhotoCapturePerMarhunUpdate = new marhunPhotoCapturerFactory('#modalpermarhunphoto-capture-update');
let marhunPhotoCapturerReloadHttps = new marhunPhotoCapturerReloadHttpsFactory();
let marhunPhotoCapturerDebuggerObj = new marhunPhotoCapturerDebugger();
let marhunPhotoViewerOverall = new marhunPhotoViewerFactory('a.btn-view-overall-marhun-photo');
let marhunPhotoViewerPerMarhun = new marhunPhotoViewerFactory('a.viewPhotoEachMarhunLink');
</script>
@endpush
@push('additional_styles')
<link rel="stylesheet" href="{{ asset('css/marhun-registrations-webcam.css') }}">
<link rel="stylesheet" href="{{ asset('css/viewer.min.css') }}">
<link rel="stylesheet" href="{{ asset('css/fix-page-zoom-when-modal-load.css') }}">
@endpush
@section('content')
@@ -75,9 +83,15 @@
<button
data-dismiss="modal"
onclick="modalOverallPhotoCapture.initiateTakeMarhunPhoto()" type="button"
class="btn btn-primary btn-md text-white"
>Ambil Gambar Marhun
</button>
<button type="button" data-toggle="modal" data-target="#modaloverallphoto">Muat Naik Gambar Marhun</button>
<button
type="button"
data-toggle="modal"
data-target="#modaloverallphoto"
class="btn btn-primary btn-md text-white"
>Muat Naik Gambar Marhun</button>
</div>
@endif
</div>
@@ -107,26 +121,31 @@
<td class="p-2 m-2" style="border: 1px solid black; width: 100px; height: 130px">
@if (empty($item->eachmarhun_filename))
<div class="btn-group" role="group" style="width: 100%;">
<button data-toggle="modal" onclick="eachMarhunData(this)"
class="btn btn-lg btn-light" data-lelongid="{{ $lelongbid['lelong_id'] }}"
data-lelongbidid="{{ $lelongbid['id'] }}"
data-loop="{{ $loop->iteration }}"
data-fileid="{{ $item->eachmarhun_id }}"
data-filename="{{ $item->eachmarhun_filename }}"
data-marhun="{{ $item->marhun }}" data-marhunid="{{ $item->id }}"
data-target="#modaleachphoto" style="border-radius: 0 !important">
<i class="fas fa-upload"></i>
</button>
<button data-toggle="modal" onclick="eachMarhunDataCapturePhoto(this)"
class="btn btn-lg btn-light" data-lelongid="{{ $lelongbid['lelong_id'] }}"
data-lelongbidid="{{ $lelongbid['id'] }}"
data-loop="{{ $loop->iteration }}"
data-fileid="{{ $item->eachmarhun_id }}"
data-filename="{{ $item->eachmarhun_filename }}"
data-marhun="{{ $item->marhun }}" data-marhunid="{{ $item->id }}"
style="border-radius: 0 !important">
<i class="fas fa-camera"></i>
</button>
<span data-toggle="tooltip" data-placement="top" title="Muat naik gambar per marhun">
<button data-toggle="modal" onclick="eachMarhunData(this)"
class="btn btn-lg text-" data-lelongid="{{ $lelongbid['lelong_id'] }}"
data-lelongbidid="{{ $lelongbid['id'] }}"
data-loop="{{ $loop->iteration }}"
data-fileid="{{ $item->eachmarhun_id }}"
data-filename="{{ $item->eachmarhun_filename }}"
data-marhun="{{ $item->marhun }}" data-marhunid="{{ $item->id }}"
data-target="#modaleachphoto"
style="border-radius: 0 !important">
<i class="fas fa-upload"></i>
</button>
</span>
<span data-toggle="tooltip" data-placement="top" title="Ambil gambar per marhun">
<button data-toggle="modal" onclick="eachMarhunDataCapturePhoto(this)"
class="btn btn-lg" data-lelongid="{{ $lelongbid['lelong_id'] }}"
data-lelongbidid="{{ $lelongbid['id'] }}"
data-loop="{{ $loop->iteration }}"
data-fileid="{{ $item->eachmarhun_id }}"
data-filename="{{ $item->eachmarhun_filename }}"
data-marhun="{{ $item->marhun }}" data-marhunid="{{ $item->id }}"
style="border-radius: 0 !important">
<i class="fas fa-camera"></i>
</button>
</span>
</div>
<img src="{{ asset('img/no-image.png') }}" alt="Tambah / Padam Gambar"
@@ -432,7 +451,7 @@
@php
$imageLink = route('marhun.showphotomarhun', ['norujukan_sag' => $lelongbid['norujukan'], 'filemarhun_id' => $lelongbid['filemarhun_id']]);
@endphp
<a href="{{ $imageLink }}" target="_blank" class="btn m-2 btn-warning">Lihat gambar</a>
<a href="{{ $imageLink }}" target="_blank" class="btn m-2 btn-warning btn-view-overall-marhun-photo">Lihat gambar</a>
<button data-dismiss="modal" onclick="updatePhoto(1)" type="button"
data-target="#modalupdatephoto" data-toggle="modal" class="btn m-2 btn-warning action-invalid-after-semak">Muat naik gambar baru</button>
<button data-dismiss="modal"
@@ -874,5 +893,8 @@
$("#formkemaskini").submit();
}
marhunPhotoViewerOverall.attachPhotoViewer();
marhunPhotoViewerPerMarhun.attachPhotoViewer();
</script>
@endsection