mirror of
https://github.com/ae-utbm/sith.git
synced 2024-11-22 06:03:20 +00:00
move webcam JS to its own file
This commit is contained in:
parent
d47461ba40
commit
3d138d404f
110
core/static/user/js/user_edit.js
Normal file
110
core/static/user/js/user_edit.js
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
function alpine_webcam_builder(
|
||||||
|
default_picture,
|
||||||
|
delete_url,
|
||||||
|
can_delete_picture,
|
||||||
|
) {
|
||||||
|
return () => ({
|
||||||
|
can_edit_picture: false,
|
||||||
|
|
||||||
|
loading: false,
|
||||||
|
is_camera_enabled: false,
|
||||||
|
is_camera_error: false,
|
||||||
|
picture: null,
|
||||||
|
video: null,
|
||||||
|
picture_form: null,
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.video = this.$refs.video;
|
||||||
|
this.picture_form = this.$refs.form.getElementsByTagName("input");
|
||||||
|
if (this.picture_form.length > 0) {
|
||||||
|
this.picture_form = this.picture_form[0];
|
||||||
|
this.can_edit_picture = true;
|
||||||
|
|
||||||
|
// Link the displayed element to the form input
|
||||||
|
this.picture_form.onchange = (event) => {
|
||||||
|
let files = event.srcElement.files;
|
||||||
|
if (files.length > 0) {
|
||||||
|
this.picture = (window.URL || window.webkitURL).createObjectURL(
|
||||||
|
event.srcElement.files[0],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.picture = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
get_picture() {
|
||||||
|
return this.picture || default_picture;
|
||||||
|
},
|
||||||
|
|
||||||
|
delete_picture() {
|
||||||
|
// Only remove currently displayed picture
|
||||||
|
if (!!this.picture) {
|
||||||
|
let list = new DataTransfer();
|
||||||
|
this.picture_form.files = list.files;
|
||||||
|
this.picture_form.dispatchEvent(new Event("change"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!can_delete_picture) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Remove user picture if correct rights are available
|
||||||
|
window.open(delete_url, "_self");
|
||||||
|
},
|
||||||
|
|
||||||
|
enable_camera() {
|
||||||
|
this.picture = null;
|
||||||
|
this.loading = true;
|
||||||
|
this.is_camera_error = false;
|
||||||
|
navigator.mediaDevices
|
||||||
|
.getUserMedia({ video: true, audio: false })
|
||||||
|
.then((stream) => {
|
||||||
|
this.loading = false;
|
||||||
|
this.is_camera_enabled = true;
|
||||||
|
this.video.srcObject = stream;
|
||||||
|
this.video.play();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
this.is_camera_error = true;
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
take_picture() {
|
||||||
|
let canvas = document.createElement("canvas");
|
||||||
|
const context = canvas.getContext("2d");
|
||||||
|
|
||||||
|
/* Create the image */
|
||||||
|
let 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);
|
||||||
|
|
||||||
|
/* Stop camera */
|
||||||
|
this.video.pause();
|
||||||
|
this.video.srcObject.getTracks().forEach((track) => {
|
||||||
|
if (track.readyState === "live") {
|
||||||
|
track.stop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
canvas.toBlob((blob) => {
|
||||||
|
const filename = interpolate(gettext("captured.%s"), ["webp"]);
|
||||||
|
let file = new File([blob], filename, {
|
||||||
|
type: "image/webp",
|
||||||
|
});
|
||||||
|
|
||||||
|
let list = new DataTransfer();
|
||||||
|
list.items.add(file);
|
||||||
|
this.picture_form.files = list.files;
|
||||||
|
|
||||||
|
// No change event is triggered, we trigger it manually #}
|
||||||
|
this.picture_form.dispatchEvent(new Event("change"));
|
||||||
|
}, "image/webp");
|
||||||
|
|
||||||
|
canvas.remove();
|
||||||
|
this.is_camera_enabled = false;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
@ -8,7 +8,12 @@
|
|||||||
<link rel="stylesheet" href="{{ scss('user/user_edit.scss') }}">
|
<link rel="stylesheet" href="{{ scss('user/user_edit.scss') }}">
|
||||||
{%- endblock -%}
|
{%- endblock -%}
|
||||||
|
|
||||||
|
{% block additional_js %}
|
||||||
|
<script defer src="{{ static("user/js/user_edit.js") }}"></script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% macro profile_picture(field_name) %}
|
{% macro profile_picture(field_name) %}
|
||||||
|
{% set this_picture = form.instance[field_name] %}
|
||||||
<div class="profile-picture" x-data="camera_{{ field_name }}" >
|
<div class="profile-picture" x-data="camera_{{ field_name }}" >
|
||||||
<div class="profile-picture-display" :aria-busy="loading" :class="{ 'camera-error': is_camera_error }">
|
<div class="profile-picture-display" :aria-busy="loading" :class="{ 'camera-error': is_camera_error }">
|
||||||
<img
|
<img
|
||||||
@ -50,8 +55,8 @@
|
|||||||
<div>
|
<div>
|
||||||
{{ form[field_name] }}
|
{{ form[field_name] }}
|
||||||
<button class="btn btn-red" @click.prevent="delete_picture()"
|
<button class="btn btn-red" @click.prevent="delete_picture()"
|
||||||
{%- if not (user.is_root and form.instance[field_name]) -%}
|
{%- if not (this_picture and this_picture.is_owned_by(user)) -%}
|
||||||
:disabled="picture == null"
|
:disabled="!picture"
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
x-cloak
|
x-cloak
|
||||||
>
|
>
|
||||||
@ -68,128 +73,22 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
|
{%- if this_picture -%}
|
||||||
|
{% set default_picture = this_picture.get_download_url()|tojson %}
|
||||||
|
{% set delete_url = url('core:file_delete', file_id=this_picture.id, popup='')|tojson %}
|
||||||
|
{%- else -%}
|
||||||
|
{% set default_picture = static('core/img/unknown.jpg')|tojson %}
|
||||||
|
{% set delete_url = "null" %}
|
||||||
|
{%- endif -%}
|
||||||
document.addEventListener("alpine:init", () => {
|
document.addEventListener("alpine:init", () => {
|
||||||
Alpine.data("camera_{{ field_name }}", () => ({
|
Alpine.data(
|
||||||
can_edit_picture: false,
|
"camera_{{ field_name }}",
|
||||||
|
alpine_webcam_builder(
|
||||||
loading: false,
|
{{ default_picture }},
|
||||||
is_camera_enabled: false,
|
{{ delete_url }},
|
||||||
is_camera_error: false,
|
{{ (this_picture and this_picture.is_owned_by(user))|tojson }}
|
||||||
picture: null,
|
)
|
||||||
video: null,
|
);
|
||||||
picture_form: null,
|
|
||||||
|
|
||||||
init() {
|
|
||||||
this.video = this.$refs.video;
|
|
||||||
this.picture_form = this.$refs.form.getElementsByTagName("input");
|
|
||||||
if (this.picture_form.length > 0){
|
|
||||||
this.picture_form = this.picture_form[0];
|
|
||||||
this.can_edit_picture = true;
|
|
||||||
|
|
||||||
{# Link the displayed element to the form input #}
|
|
||||||
this.picture_form.onchange = (event) => {
|
|
||||||
let files = event.srcElement.files;
|
|
||||||
if (files.length > 0){
|
|
||||||
this.picture = (window.URL || window.webkitURL)
|
|
||||||
.createObjectURL(event.srcElement.files[0]);
|
|
||||||
} else {
|
|
||||||
this.picture = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
get_picture() {
|
|
||||||
if (this.picture != null) {
|
|
||||||
return this.picture;
|
|
||||||
}
|
|
||||||
|
|
||||||
{%- if form.instance[field_name] -%}
|
|
||||||
return "{{ form.instance[field_name].get_download_url() }}"
|
|
||||||
{%- else -%}
|
|
||||||
return "{{ static('core/img/unknown.jpg') }}"
|
|
||||||
{%- endif -%}
|
|
||||||
},
|
|
||||||
|
|
||||||
delete_picture() {
|
|
||||||
|
|
||||||
{# Only remove currently displayed picture #}
|
|
||||||
if (this.picture != null){
|
|
||||||
let list = new DataTransfer();
|
|
||||||
this.picture_form.files = list.files;
|
|
||||||
this.picture_form.dispatchEvent(new Event("change"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
{# Remove user picture if correct rights are available #}
|
|
||||||
{%- if user.is_root and form.instance[field_name] -%}
|
|
||||||
window.open(
|
|
||||||
'{{ url(
|
|
||||||
'core:file_delete',
|
|
||||||
file_id=form.instance[field_name].id,
|
|
||||||
popup=''
|
|
||||||
) }}',
|
|
||||||
'_self');
|
|
||||||
{%- endif -%}
|
|
||||||
},
|
|
||||||
|
|
||||||
enable_camera() {
|
|
||||||
this.picture = null;
|
|
||||||
this.loading = true;
|
|
||||||
this.is_camera_error = false;
|
|
||||||
navigator.mediaDevices
|
|
||||||
.getUserMedia({ video: true, audio: false })
|
|
||||||
.then((stream) => {
|
|
||||||
this.loading = false;
|
|
||||||
this.is_camera_enabled = true;
|
|
||||||
this.video.srcObject = stream;
|
|
||||||
this.video.play();
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
this.is_camera_error = true;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
take_picture() {
|
|
||||||
let canvas = document.createElement("canvas")
|
|
||||||
const context = canvas.getContext("2d");
|
|
||||||
|
|
||||||
/* Create the image */
|
|
||||||
let 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);
|
|
||||||
|
|
||||||
/* Stop camera */
|
|
||||||
this.video.pause()
|
|
||||||
this.video.srcObject.getTracks().forEach((track) => {
|
|
||||||
if (track.readyState === 'live') {
|
|
||||||
track.stop();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
canvas.toBlob((blob) => {
|
|
||||||
let file = new File(
|
|
||||||
[blob],
|
|
||||||
"{% trans %}captured{% endtrans %}.webp",
|
|
||||||
{ type: "image/webp" },
|
|
||||||
);
|
|
||||||
|
|
||||||
let list = new DataTransfer();
|
|
||||||
list.items.add(file);
|
|
||||||
this.picture_form.files = list.files;
|
|
||||||
|
|
||||||
{# No change event is triggered, we trigger it manually #}
|
|
||||||
this.picture_form.dispatchEvent(new Event("change"));
|
|
||||||
}, "image/webp");
|
|
||||||
|
|
||||||
|
|
||||||
canvas.remove();
|
|
||||||
this.is_camera_enabled = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
Loading…
Reference in New Issue
Block a user