File size: 3,504 Bytes
bc27e65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<script>

	import { getContext } from 'svelte';

	const i18n = getContext('i18n');



	import RichTextInput from '../common/RichTextInput.svelte';

	import Spinner from '../common/Spinner.svelte';

	import Sparkles from '../icons/Sparkles.svelte';

	import SparklesSolid from '../icons/SparklesSolid.svelte';

	import Mic from '../icons/Mic.svelte';

	import VoiceRecording from '../chat/MessageInput/VoiceRecording.svelte';

	import Tooltip from '../common/Tooltip.svelte';

	import { toast } from 'svelte-sonner';



	let name = '';

	let content = '';



	let voiceInput = false;

	let loading = false;

</script>

<div class="relative flex-1 w-full h-full flex justify-center overflow-auto px-5">

	{#if loading}

		<div class=" absolute top-0 bottom-0 left-0 right-0 flex">

			<div class="m-auto">

				<Spinner />

			</div>

		</div>

	{/if}



	<div class=" w-full flex flex-col gap-2 {loading ? 'opacity-20' : ''}">

		<div class="shrink-0 w-full flex justify-between items-center">

			<div class="w-full">

				<input

					class="w-full text-2xl font-medium bg-transparent outline-hidden"

					type="text"

					bind:value={name}

					placeholder={$i18n.t('Title')}

					required

				/>

			</div>

		</div>



		<div class=" flex-1 w-full h-full">

			<RichTextInput

				className="input-prose-sm"

				bind:value={content}

				placeholder={$i18n.t('Write something...')}

				preserveBreaks={true}

			/>

		</div>

	</div>



	<div class="absolute bottom-0 left-0 right-0 p-5 max-w-full flex justify-end">

		<div class="flex gap-0.5 justify-end w-full">

			{#if voiceInput}

				<div class="flex-1 w-full">

					<VoiceRecording

						bind:recording={voiceInput}

						className="p-1 w-full max-w-full"

						on:cancel={() => {

							voiceInput = false;

						}}

						on:confirm={(e) => {

							const { text, filename } = e.detail;



							// url is hostname + /cache/audio/transcription/ + filename

							const url = `${window.location.origin}/cache/audio/transcription/${filename}`;



							// Open in new tab



							if (content.trim() !== '') {

								content = `${content}\n\n${text}\n\nRecording: ${url}\n\n`;

							} else {

								content = `${content}${text}\n\nRecording: ${url}\n\n`;

							}



							voiceInput = false;

						}}

					/>

				</div>

			{:else}

				<Tooltip content={$i18n.t('Voice Input')}>

					<button

						class="cursor-pointer p-2.5 flex rounded-full hover:bg-gray-100 dark:hover:bg-gray-850 transition shadow-xl"

						type="button"

						on:click={async () => {

							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'));

							}

						}}

					>

						<Mic className="size-4" />

					</button>

				</Tooltip>

			{/if}



			<!-- <button

				class="cursor-pointer p-2.5 flex rounded-full hover:bg-gray-100 dark:hover:bg-gray-850 transition shadow-xl"

			>

				<SparklesSolid className="size-4" />

			</button> -->
		</div>
	</div>
</div>