2024-10-08 15:14:22 +00:00
|
|
|
// biome-ignore lint/correctness/noUnusedVariables: used in user_edit.jinja
|
|
|
|
function alpineWebcamBuilder(defaultPicture, deleteUrl, canDeletePicture) {
|
2024-10-08 11:54:44 +00:00
|
|
|
return () => ({
|
2024-10-08 15:14:22 +00:00
|
|
|
canEditPicture: false,
|
2024-09-19 20:16:39 +00:00
|
|
|
|
2024-10-08 11:54:44 +00:00
|
|
|
loading: false,
|
2024-10-08 15:14:22 +00:00
|
|
|
isCameraEnabled: false,
|
|
|
|
isCameraError: false,
|
2024-10-08 11:54:44 +00:00
|
|
|
picture: null,
|
|
|
|
video: null,
|
2024-10-08 15:14:22 +00:00
|
|
|
pictureForm: null,
|
2024-09-19 20:16:39 +00:00
|
|
|
|
2024-10-08 11:54:44 +00:00
|
|
|
init() {
|
|
|
|
this.video = this.$refs.video;
|
2024-10-08 15:14:22 +00:00
|
|
|
this.pictureForm = this.$refs.form.getElementsByTagName("input");
|
|
|
|
if (this.pictureForm.length > 0) {
|
|
|
|
this.pictureForm = this.pictureForm[0];
|
|
|
|
this.canEditPicture = true;
|
2024-09-19 20:16:39 +00:00
|
|
|
|
2024-10-08 11:54:44 +00:00
|
|
|
// Link the displayed element to the form input
|
2024-10-08 15:14:22 +00:00
|
|
|
this.pictureForm.onchange = (event) => {
|
2024-10-08 11:54:44 +00:00
|
|
|
const files = event.srcElement.files;
|
|
|
|
if (files.length > 0) {
|
|
|
|
this.picture = (window.URL || window.webkitURL).createObjectURL(
|
|
|
|
event.srcElement.files[0],
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
this.picture = null;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
},
|
2024-09-19 20:16:39 +00:00
|
|
|
|
2024-10-08 15:14:22 +00:00
|
|
|
getPicture() {
|
|
|
|
return this.picture || defaultPicture;
|
2024-10-08 11:54:44 +00:00
|
|
|
},
|
2024-09-19 20:16:39 +00:00
|
|
|
|
2024-10-08 15:14:22 +00:00
|
|
|
deletePicture() {
|
2024-10-08 11:54:44 +00:00
|
|
|
// Only remove currently displayed picture
|
|
|
|
if (this.picture) {
|
|
|
|
const list = new DataTransfer();
|
2024-10-08 15:14:22 +00:00
|
|
|
this.pictureForm.files = list.files;
|
|
|
|
this.pictureForm.dispatchEvent(new Event("change"));
|
2024-10-08 11:54:44 +00:00
|
|
|
return;
|
|
|
|
}
|
2024-10-08 15:14:22 +00:00
|
|
|
if (!canDeletePicture) {
|
2024-10-08 11:54:44 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Remove user picture if correct rights are available
|
2024-10-08 15:14:22 +00:00
|
|
|
window.open(deleteUrl, "_self");
|
2024-10-08 11:54:44 +00:00
|
|
|
},
|
2024-09-19 20:16:39 +00:00
|
|
|
|
2024-10-08 15:14:22 +00:00
|
|
|
enableCamera() {
|
2024-10-08 11:54:44 +00:00
|
|
|
this.picture = null;
|
|
|
|
this.loading = true;
|
2024-10-08 15:14:22 +00:00
|
|
|
this.isCameraError = false;
|
2024-10-08 11:54:44 +00:00
|
|
|
navigator.mediaDevices
|
|
|
|
.getUserMedia({ video: true, audio: false })
|
|
|
|
.then((stream) => {
|
|
|
|
this.loading = false;
|
2024-10-08 15:14:22 +00:00
|
|
|
this.isCameraEnabled = true;
|
2024-10-08 11:54:44 +00:00
|
|
|
this.video.srcObject = stream;
|
|
|
|
this.video.play();
|
|
|
|
})
|
|
|
|
.catch((err) => {
|
2024-10-08 15:14:22 +00:00
|
|
|
this.isCameraError = true;
|
2024-10-08 11:54:44 +00:00
|
|
|
this.loading = false;
|
|
|
|
throw err;
|
|
|
|
});
|
|
|
|
},
|
2024-09-19 20:16:39 +00:00
|
|
|
|
2024-10-08 15:14:22 +00:00
|
|
|
takePicture() {
|
2024-10-08 11:54:44 +00:00
|
|
|
const canvas = document.createElement("canvas");
|
|
|
|
const context = canvas.getContext("2d");
|
2024-09-19 20:16:39 +00:00
|
|
|
|
2024-10-08 11:54:44 +00:00
|
|
|
/* Create the image */
|
|
|
|
const settings = this.video.srcObject.getTracks()[0].getSettings();
|
|
|
|
canvas.width = settings.width;
|
|
|
|
canvas.height = settings.height;
|
|
|
|
context.drawImage(this.video, 0, 0, canvas.width, canvas.height);
|
2024-09-19 20:16:39 +00:00
|
|
|
|
2024-10-08 11:54:44 +00:00
|
|
|
/* Stop camera */
|
|
|
|
this.video.pause();
|
|
|
|
for (const track of this.video.srcObject.getTracks()) {
|
|
|
|
if (track.readyState === "live") {
|
|
|
|
track.stop();
|
|
|
|
}
|
|
|
|
}
|
2024-09-19 20:16:39 +00:00
|
|
|
|
2024-10-08 11:54:44 +00:00
|
|
|
canvas.toBlob((blob) => {
|
|
|
|
const filename = interpolate(gettext("captured.%s"), ["webp"]);
|
|
|
|
const file = new File([blob], filename, {
|
|
|
|
type: "image/webp",
|
|
|
|
});
|
2024-09-19 20:16:39 +00:00
|
|
|
|
2024-10-08 11:54:44 +00:00
|
|
|
const list = new DataTransfer();
|
|
|
|
list.items.add(file);
|
2024-10-08 15:14:22 +00:00
|
|
|
this.pictureForm.files = list.files;
|
2024-09-19 20:16:39 +00:00
|
|
|
|
2024-10-08 11:54:44 +00:00
|
|
|
// No change event is triggered, we trigger it manually #}
|
2024-10-08 15:14:22 +00:00
|
|
|
this.pictureForm.dispatchEvent(new Event("change"));
|
2024-10-08 11:54:44 +00:00
|
|
|
}, "image/webp");
|
2024-09-19 20:16:39 +00:00
|
|
|
|
2024-10-08 11:54:44 +00:00
|
|
|
canvas.remove();
|
2024-10-08 15:14:22 +00:00
|
|
|
this.isCameraEnabled = false;
|
2024-10-08 11:54:44 +00:00
|
|
|
},
|
|
|
|
});
|
2024-09-19 20:16:39 +00:00
|
|
|
}
|