瀏覽代碼

feat: response notification

Timothy J. Baek 1 年之前
父節點
當前提交
e34b452509
共有 3 個文件被更改,包括 100 次插入33 次删除
  1. 70 33
      src/lib/components/chat/SettingsModal.svelte
  2. 15 0
      src/routes/(app)/+page.svelte
  3. 15 0
      src/routes/(app)/c/[id]/+page.svelte

+ 70 - 33
src/lib/components/chat/SettingsModal.svelte

@@ -49,8 +49,10 @@
 	let pullProgress = null;
 
 	// Addons
+	let responseNotification = false;
 	let titleAutoGenerate = true;
 	let speechAutoSend = false;
+
 	let gravatarEmail = '';
 	let OPENAI_API_KEY = '';
 
@@ -108,6 +110,19 @@
 		saveSettings({ titleAutoGenerate: titleAutoGenerate });
 	};
 
+	const toggleResponseNotification = async () => {
+		const permission = await Notification.requestPermission();
+
+		if (permission === 'granted') {
+			responseNotification = !responseNotification;
+			saveSettings({ responseNotification: responseNotification });
+		} else {
+			toast.error(
+				'Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.'
+			);
+		}
+	};
+
 	const toggleAuthHeader = async () => {
 		authEnabled = !authEnabled;
 	};
@@ -802,44 +817,66 @@
 					>
 						<div class=" space-y-3">
 							<div>
-								<div class=" py-1 flex w-full justify-between">
-									<div class=" self-center text-sm font-medium">Title Auto Generation</div>
+								<div class=" mb-1 text-sm font-medium">WebUI Add-ons</div>
 
-									<button
-										class="p-1 px-3 text-xs flex rounded transition"
-										on:click={() => {
-											toggleTitleAutoGenerate();
-										}}
-										type="button"
-									>
-										{#if titleAutoGenerate === true}
-											<span class="ml-2 self-center">On</span>
-										{:else}
-											<span class="ml-2 self-center">Off</span>
-										{/if}
-									</button>
+								<div>
+									<div class=" py-0.5 flex w-full justify-between">
+										<div class=" self-center text-xs font-medium">Response Notification</div>
+
+										<button
+											class="p-1 px-3 text-xs flex rounded transition"
+											on:click={() => {
+												toggleResponseNotification();
+											}}
+											type="button"
+										>
+											{#if responseNotification === true}
+												<span class="ml-2 self-center">On</span>
+											{:else}
+												<span class="ml-2 self-center">Off</span>
+											{/if}
+										</button>
+									</div>
 								</div>
-							</div>
 
-							<hr class=" dark:border-gray-700" />
+								<div>
+									<div class=" py-0.5 flex w-full justify-between">
+										<div class=" self-center text-xs font-medium">Title Auto Generation</div>
 
-							<div>
-								<div class=" py-1 flex w-full justify-between">
-									<div class=" self-center text-sm font-medium">Voice Input Auto-Send</div>
+										<button
+											class="p-1 px-3 text-xs flex rounded transition"
+											on:click={() => {
+												toggleTitleAutoGenerate();
+											}}
+											type="button"
+										>
+											{#if titleAutoGenerate === true}
+												<span class="ml-2 self-center">On</span>
+											{:else}
+												<span class="ml-2 self-center">Off</span>
+											{/if}
+										</button>
+									</div>
+								</div>
 
-									<button
-										class="p-1 px-3 text-xs flex rounded transition"
-										on:click={() => {
-											toggleSpeechAutoSend();
-										}}
-										type="button"
-									>
-										{#if speechAutoSend === true}
-											<span class="ml-2 self-center">On</span>
-										{:else}
-											<span class="ml-2 self-center">Off</span>
-										{/if}
-									</button>
+								<div>
+									<div class=" py-0.5 flex w-full justify-between">
+										<div class=" self-center text-xs font-medium">Voice Input Auto-Send</div>
+
+										<button
+											class="p-1 px-3 text-xs flex rounded transition"
+											on:click={() => {
+												toggleSpeechAutoSend();
+											}}
+											type="button"
+										>
+											{#if speechAutoSend === true}
+												<span class="ml-2 self-center">On</span>
+											{:else}
+												<span class="ml-2 self-center">Off</span>
+											{/if}
+										</button>
+									</div>
 								</div>
 							</div>
 

+ 15 - 0
src/routes/(app)/+page.svelte

@@ -222,6 +222,21 @@
 									eval_duration: data.eval_duration
 								};
 								messages = messages;
+
+								if ($settings.responseNotification && !document.hasFocus()) {
+									const notification = new Notification(
+										selectedModelfile
+											? `${
+													selectedModelfile.title.charAt(0).toUpperCase() +
+													selectedModelfile.title.slice(1)
+											  }`
+											: `Ollama - ${model}`,
+										{
+											body: responseMessage.content,
+											icon: selectedModelfile?.imageUrl ?? '/favicon.png'
+										}
+									);
+								}
 							}
 						}
 					}

+ 15 - 0
src/routes/(app)/c/[id]/+page.svelte

@@ -234,6 +234,21 @@
 									eval_duration: data.eval_duration
 								};
 								messages = messages;
+
+								if ($settings.responseNotification && !document.hasFocus()) {
+									const notification = new Notification(
+										selectedModelfile
+											? `${
+													selectedModelfile.title.charAt(0).toUpperCase() +
+													selectedModelfile.title.slice(1)
+											  }`
+											: `Ollama - ${model}`,
+										{
+											body: responseMessage.content,
+											icon: selectedModelfile?.imageUrl ?? '/favicon.png'
+										}
+									);
+								}
 							}
 						}
 					}