refac: play sound only in last active tab

This commit is contained in:
Timothy Jaeryang Baek 2025-01-04 02:30:51 -08:00
parent afcbf2cafb
commit f31e2af349
3 changed files with 43 additions and 14 deletions

View File

@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import { settings, playingNotificationSound } from '$lib/stores'; import { settings, playingNotificationSound, isLastActiveTab } from '$lib/stores';
import DOMPurify from 'dompurify'; import DOMPurify from 'dompurify';
import { marked } from 'marked'; import { marked } from 'marked';
@ -17,7 +17,7 @@
} }
if ($settings?.notificationSound ?? true) { if ($settings?.notificationSound ?? true) {
if (!$playingNotificationSound) { if (!$playingNotificationSound && $isLastActiveTab) {
playingNotificationSound.set(true); playingNotificationSound.set(true);
const audio = new Audio(`/audio/notification.mp3`); const audio = new Audio(`/audio/notification.mp3`);

View File

@ -69,7 +69,7 @@ export const temporaryChatEnabled = writable(false);
export const scrollPaginationEnabled = writable(false); export const scrollPaginationEnabled = writable(false);
export const currentChatPage = writable(1); export const currentChatPage = writable(1);
export const isLastActiveTab = writable(true);
export const playingNotificationSound = writable(false); export const playingNotificationSound = writable(false);
export type Model = OpenAIModel | OllamaModel; export type Model = OpenAIModel | OllamaModel;

View File

@ -21,7 +21,8 @@
chats, chats,
currentChatPage, currentChatPage,
tags, tags,
temporaryChatEnabled temporaryChatEnabled,
isLastActiveTab
} from '$lib/stores'; } from '$lib/stores';
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import { page } from '$app/stores'; import { page } from '$app/stores';
@ -43,7 +44,10 @@
setContext('i18n', i18n); setContext('i18n', i18n);
const bc = new BroadcastChannel('active-tab-channel');
let loaded = false; let loaded = false;
const BREAKPOINT = 768; const BREAKPOINT = 768;
const setupSocket = async (enableWebsocket) => { const setupSocket = async (enableWebsocket) => {
@ -108,12 +112,14 @@
const { done, content, title } = data; const { done, content, title } = data;
if (done) { if (done) {
if ($isLastActiveTab) {
if ($settings?.notificationEnabled ?? false) { if ($settings?.notificationEnabled ?? false) {
const notification = new Notification(`${title} | Open WebUI`, { new Notification(`${title} | Open WebUI`, {
body: content, body: content,
icon: `${WEBUI_BASE_URL}/static/favicon.png` icon: `${WEBUI_BASE_URL}/static/favicon.png`
}); });
} }
}
toast.custom(NotificationToast, { toast.custom(NotificationToast, {
componentProps: { componentProps: {
@ -146,12 +152,14 @@
const data = event?.data?.data ?? null; const data = event?.data?.data ?? null;
if (type === 'message') { if (type === 'message') {
if ($isLastActiveTab) {
if ($settings?.notificationEnabled ?? false) { if ($settings?.notificationEnabled ?? false) {
new Notification(`#${event?.channel?.name} | Open WebUI`, { new Notification(`#${event?.channel?.name} | Open WebUI`, {
body: data?.content, body: data?.content,
icon: `${WEBUI_BASE_URL}/static/favicon.png` icon: `${WEBUI_BASE_URL}/static/favicon.png`
}); });
} }
}
toast.custom(NotificationToast, { toast.custom(NotificationToast, {
componentProps: { componentProps: {
@ -169,6 +177,27 @@
}; };
onMount(async () => { onMount(async () => {
// Listen for messages on the BroadcastChannel
bc.onmessage = (event) => {
if (event.data === 'active') {
isLastActiveTab.set(false); // Another tab became active
}
};
// Set yourself as the last active tab when this tab is focused
const handleVisibilityChange = () => {
if (document.visibilityState === 'visible') {
isLastActiveTab.set(true); // This tab is now the active tab
bc.postMessage('active'); // Notify other tabs that this tab is active
}
};
// Add event listener for visibility state changes
document.addEventListener('visibilitychange', handleVisibilityChange);
// Call visibility change handler initially to set state on load
handleVisibilityChange();
theme.set(localStorage.theme); theme.set(localStorage.theme);
mobile.set(window.innerWidth < BREAKPOINT); mobile.set(window.innerWidth < BREAKPOINT);