Update preview on change in image and audio inputs (#1807)

This commit is contained in:
Jonatan Kłosko 2023-03-20 20:09:41 +01:00 committed by GitHub
parent 7059aa235c
commit 8be942590a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 37 deletions

View file

@ -32,14 +32,21 @@ const AudioInput = {
this.mediaRecorder = null; this.mediaRecorder = null;
// Render initial value // Render updated value
this.handleEvent(`audio_input_init:${this.props.id}`, (audioInfo) => { this.handleEvent(
this.updatePreview({ `audio_input_change:${this.props.id}`,
data: this.decodeAudio(base64ToBuffer(audioInfo.data)), ({ audio_info: audioInfo }) => {
numChannels: audioInfo.num_channels, if (audioInfo) {
samplingRate: audioInfo.sampling_rate, this.updatePreview({
}); data: this.decodeAudio(base64ToBuffer(audioInfo.data)),
}); numChannels: audioInfo.num_channels,
samplingRate: audioInfo.sampling_rate,
});
} else {
this.clearPreview();
}
}
);
// File selection // File selection
@ -173,7 +180,6 @@ const AudioInput = {
context.decodeAudioData(buffer, (audioBuffer) => { context.decodeAudioData(buffer, (audioBuffer) => {
const audioInfo = audioBufferToAudioInfo(audioBuffer); const audioInfo = audioBufferToAudioInfo(audioBuffer);
this.updatePreview(audioInfo);
this.pushAudio(audioInfo); this.pushAudio(audioInfo);
}); });
}, },
@ -185,6 +191,12 @@ const AudioInput = {
oldUrl && URL.revokeObjectURL(oldUrl); oldUrl && URL.revokeObjectURL(oldUrl);
}, },
clearPreview() {
const oldUrl = this.audioEl.src;
this.audioEl.src = "";
oldUrl && URL.revokeObjectURL(oldUrl);
},
pushAudio(audioInfo) { pushAudio(audioInfo) {
this.pushEventTo(this.props.phxTarget, "change", { this.pushEventTo(this.props.phxTarget, "change", {
data: bufferToBase64(this.encodeAudio(audioInfo)), data: bufferToBase64(this.encodeAudio(audioInfo)),

View file

@ -32,6 +32,8 @@ const ImageInput = {
this.inputEl = this.el.querySelector(`[data-input]`); this.inputEl = this.el.querySelector(`[data-input]`);
this.previewEl = this.el.querySelector(`[data-preview]`); this.previewEl = this.el.querySelector(`[data-preview]`);
this.initialPreviewContentEl = this.previewEl.firstElementChild;
this.cameraPreviewEl = this.el.querySelector(`[data-camera-preview]`); this.cameraPreviewEl = this.el.querySelector(`[data-camera-preview]`);
this.cameraListEl = this.el.querySelector(`[data-camera-list]`); this.cameraListEl = this.el.querySelector(`[data-camera-list]`);
this.cameraItemTemplateEl = this.cameraListEl.firstElementChild; this.cameraItemTemplateEl = this.cameraListEl.firstElementChild;
@ -48,11 +50,18 @@ const ImageInput = {
this.cameraVideoEl = null; this.cameraVideoEl = null;
this.cameraStream = null; this.cameraStream = null;
// Render initial value // Render updated value
this.handleEvent(`image_input_init:${this.props.id}`, (imageInfo) => { this.handleEvent(
const canvas = imageInfoToElement(imageInfo, this.props.format); `image_input_change:${this.props.id}`,
this.setPreview(canvas); ({ image_info: imageInfo }) => {
}); if (imageInfo) {
const canvas = imageInfoToElement(imageInfo, this.props.format);
this.setPreview(canvas);
} else {
this.setPreview(this.initialPreviewContentEl);
}
}
);
// File selection // File selection
@ -119,7 +128,6 @@ const ImageInput = {
this.cameraVideoEl.videoWidth, this.cameraVideoEl.videoWidth,
this.cameraVideoEl.videoHeight this.cameraVideoEl.videoHeight
); );
this.setPreview(canvas);
this.pushImage(canvas); this.pushImage(canvas);
this.closeCameraView(); this.closeCameraView();
}); });
@ -152,7 +160,6 @@ const ImageInput = {
imgEl.addEventListener("load", (loadEvent) => { imgEl.addEventListener("load", (loadEvent) => {
const canvas = this.toCanvas(imgEl, imgEl.width, imgEl.height); const canvas = this.toCanvas(imgEl, imgEl.width, imgEl.height);
this.setPreview(canvas);
this.pushImage(canvas); this.pushImage(canvas);
}); });
@ -379,11 +386,13 @@ const ImageInput = {
setPreview(element) { setPreview(element) {
element.style.maxHeight = "300px"; element.style.maxHeight = "300px";
element.style.maxWidth = "100%";
this.previewEl.replaceChildren(element); this.previewEl.replaceChildren(element);
}, },
setCameraPreview(element) { setCameraPreview(element) {
element.style.maxHeight = "300px"; element.style.maxHeight = "300px";
element.style.maxWidth = "100%";
this.cameraPreviewEl.replaceChildren(element); this.cameraPreviewEl.replaceChildren(element);
}, },
}; };

View file

@ -3,7 +3,7 @@ defmodule LivebookWeb.Output.AudioInputComponent do
@impl true @impl true
def mount(socket) do def mount(socket) do
{:ok, assign(socket, endianness: System.endianness(), initialized: false)} {:ok, assign(socket, endianness: System.endianness(), value: nil)}
end end
@impl true @impl true
@ -13,24 +13,22 @@ defmodule LivebookWeb.Output.AudioInputComponent do
socket = assign(socket, assigns) socket = assign(socket, assigns)
socket = socket =
if socket.assigns.initialized do if value == socket.assigns.value do
socket socket
else else
socket = audio_info =
if value do if value do
push_event(socket, "audio_input_init:#{socket.assigns.id}", %{ %{
data: Base.encode64(value.data), data: Base.encode64(value.data),
num_channels: value.num_channels, num_channels: value.num_channels,
sampling_rate: value.sampling_rate sampling_rate: value.sampling_rate
}) }
else
socket
end end
assign(socket, initialized: true) push_event(socket, "audio_input_change:#{socket.assigns.id}", %{audio_info: audio_info})
end end
{:ok, socket} {:ok, assign(socket, value: value)}
end end
@impl true @impl true

View file

@ -3,7 +3,7 @@ defmodule LivebookWeb.Output.ImageInputComponent do
@impl true @impl true
def mount(socket) do def mount(socket) do
{:ok, assign(socket, initialized: false)} {:ok, assign(socket, value: nil)}
end end
@impl true @impl true
@ -13,24 +13,18 @@ defmodule LivebookWeb.Output.ImageInputComponent do
socket = assign(socket, assigns) socket = assign(socket, assigns)
socket = socket =
if socket.assigns.initialized do if value == socket.assigns.value do
socket socket
else else
socket = image_info =
if value do if value do
push_event(socket, "image_input_init:#{socket.assigns.id}", %{ %{data: Base.encode64(value.data), height: value.height, width: value.width}
data: Base.encode64(value.data),
height: value.height,
width: value.width
})
else
socket
end end
assign(socket, initialized: true) push_event(socket, "image_input_change:#{socket.assigns.id}", %{image_info: image_info})
end end
{:ok, socket} {:ok, assign(socket, value: value)}
end end
@impl true @impl true