diff --git a/src/lib/components/chat/MessageInput/VoiceRecording.svelte b/src/lib/components/chat/MessageInput/VoiceRecording.svelte index 726e26bbb..941c814d7 100644 --- a/src/lib/components/chat/MessageInput/VoiceRecording.svelte +++ b/src/lib/components/chat/MessageInput/VoiceRecording.svelte @@ -10,6 +10,8 @@ export let recording = false; export let transcribe = true; + export let displayMedia = false; + export let className = ' p-2.5 w-full max-w-full'; export let onCancel = () => {}; @@ -175,13 +177,34 @@ const startRecording = async () => { loading = true; - stream = await navigator.mediaDevices.getUserMedia({ - audio: { - echoCancellation: true, - noiseSuppression: true, - autoGainControl: true + try { + if (displayMedia) { + stream = await navigator.mediaDevices.getDisplayMedia({ + video: { + mediaSource: 'screen' + }, + audio: { + echoCancellation: true, + noiseSuppression: true, + autoGainControl: true + } + }); + } else { + stream = await navigator.mediaDevices.getUserMedia({ + audio: { + echoCancellation: true, + noiseSuppression: true, + autoGainControl: true + } + }); } - }); + } catch (err) { + console.error('Error accessing media devices.', err); + toast.error($i18n.t('Error accessing media devices.')); + loading = false; + recording = false; + return; + } mediaRecorder = new MediaRecorder(stream); mediaRecorder.onstart = () => { diff --git a/src/lib/components/icons/CursorArrowRays.svelte b/src/lib/components/icons/CursorArrowRays.svelte new file mode 100644 index 000000000..801626838 --- /dev/null +++ b/src/lib/components/icons/CursorArrowRays.svelte @@ -0,0 +1,19 @@ + + + + + diff --git a/src/lib/components/icons/Mic.svelte b/src/lib/components/icons/Mic.svelte index 7967b6da2..dbfc11126 100644 --- a/src/lib/components/icons/Mic.svelte +++ b/src/lib/components/icons/Mic.svelte @@ -1,10 +1,19 @@ - - + diff --git a/src/lib/components/icons/MicSolid.svelte b/src/lib/components/icons/MicSolid.svelte new file mode 100644 index 000000000..7967b6da2 --- /dev/null +++ b/src/lib/components/icons/MicSolid.svelte @@ -0,0 +1,10 @@ + + + + + + diff --git a/src/lib/components/notes/NoteEditor.svelte b/src/lib/components/notes/NoteEditor.svelte index 067715e50..93f5d65b4 100644 --- a/src/lib/components/notes/NoteEditor.svelte +++ b/src/lib/components/notes/NoteEditor.svelte @@ -38,7 +38,7 @@ import RichTextInput from '../common/RichTextInput.svelte'; import Spinner from '../common/Spinner.svelte'; - import Mic from '../icons/Mic.svelte'; + import MicSolid from '../icons/MicSolid.svelte'; import VoiceRecording from '../chat/MessageInput/VoiceRecording.svelte'; import Tooltip from '../common/Tooltip.svelte'; @@ -49,6 +49,7 @@ import Image from '../common/Image.svelte'; import FileItem from '../common/FileItem.svelte'; import FilesOverlay from '../chat/MessageInput/FilesOverlay.svelte'; + import RecordMenu from './RecordMenu.svelte'; export let id: null | string = null; @@ -67,7 +68,8 @@ }; let files = []; - let voiceInput = false; + let recording = false; + let displayMediaRecord = false; let dragged = false; let loading = false; @@ -380,64 +382,71 @@ - {#if voiceInput} + {#if recording} { - voiceInput = false; + recording = false; + displayMediaRecord = false; }} onConfirm={(data) => { if (data?.file) { uploadFileHandler(data?.file); } + + recording = false; + displayMediaRecord = false; }} /> {:else} - + { + displayMediaRecord = false; + + try { + let stream = await navigator.mediaDevices + .getUserMedia({ audio: true }) + .catch(function (err) { + toast.error( + $i18n.t(`Permission denied when accessing microphone: {{error}}`, { + error: err + }) + ); + return null; + }); + + if (stream) { + recording = true; + const tracks = stream.getTracks(); + tracks.forEach((track) => track.stop()); + } + stream = null; + } catch { + toast.error($i18n.t('Permission denied when accessing microphone')); + } + }} + onCaptureAudio={async () => { + displayMediaRecord = true; + + recording = true; + }} + > { - try { - let stream = await navigator.mediaDevices - .getUserMedia({ audio: true }) - .catch(function (err) { - toast.error( - $i18n.t(`Permission denied when accessing microphone: {{error}}`, { - error: err - }) - ); - return null; - }); - - if (stream) { - voiceInput = true; - const tracks = stream.getTracks(); - tracks.forEach((track) => track.stop()); - } - stream = null; - } catch { - toast.error($i18n.t('Permission denied when accessing microphone')); - } - }} > - + - + {/if} - - diff --git a/src/lib/components/notes/RecordMenu.svelte b/src/lib/components/notes/RecordMenu.svelte new file mode 100644 index 000000000..4ab195497 --- /dev/null +++ b/src/lib/components/notes/RecordMenu.svelte @@ -0,0 +1,70 @@ + + + { + dispatch('change', state); + }} +> + + + + + + fade(e, { duration: 100 })} + > + { + onRecord(); + show = false; + }} + > + + + + {$i18n.t('Record')} + + + { + onCaptureAudio(); + show = false; + }} + > + + + + {$i18n.t('Capture Audio')} + + + + diff --git a/src/lib/components/workspace/Knowledge/KnowledgeBase/AddTextContentModal.svelte b/src/lib/components/workspace/Knowledge/KnowledgeBase/AddTextContentModal.svelte index 4762d5d97..2e288c6d7 100644 --- a/src/lib/components/workspace/Knowledge/KnowledgeBase/AddTextContentModal.svelte +++ b/src/lib/components/workspace/Knowledge/KnowledgeBase/AddTextContentModal.svelte @@ -9,7 +9,7 @@ import Modal from '$lib/components/common/Modal.svelte'; import RichTextInput from '$lib/components/common/RichTextInput.svelte'; import XMark from '$lib/components/icons/XMark.svelte'; - import Mic from '$lib/components/icons/Mic.svelte'; + import MicSolid from '$lib/components/icons/MicSolid.svelte'; import Tooltip from '$lib/components/common/Tooltip.svelte'; import VoiceRecording from '$lib/components/chat/MessageInput/VoiceRecording.svelte'; export let show = false; @@ -125,7 +125,7 @@ } }} > - + {/if}