Sith/core/static/user/js/user_edit.js

109 lines
3.0 KiB
JavaScript
Raw Normal View History

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
}