notifications: Handle exception when trying to play audio.

Safari denies user from playing audio without an interactive
trigger like a button by default. So, when user received a
notification in Zulip via Safari, it triggers an error when
trying to play the notification sound.

Our goal for this commit is to simply handle the error.
This commit is contained in:
Aman Agrawal
2023-03-21 10:57:40 +00:00
committed by Tim Abbott
parent 95bdfa8ff8
commit f5f79048fe
3 changed files with 23 additions and 2 deletions

View File

@@ -22,6 +22,7 @@ import * as spoilers from "./spoilers";
import * as stream_data from "./stream_data";
import * as stream_ui_updates from "./stream_ui_updates";
import * as ui from "./ui";
import * as ui_util from "./ui_util";
import * as unread from "./unread";
import * as unread_ops from "./unread_ops";
import {user_settings} from "./user_settings";
@@ -508,7 +509,7 @@ export function received_messages(messages) {
});
}
if (should_send_audible_notification(message)) {
$("#user-notification-sound-audio")[0].play();
ui_util.play_audio($("#user-notification-sound-audio")[0]);
}
}
}

View File

@@ -14,6 +14,7 @@ import * as stream_edit from "./stream_edit";
import * as stream_settings_data from "./stream_settings_data";
import * as stream_settings_ui from "./stream_settings_ui";
import * as sub_store from "./sub_store";
import * as ui_util from "./ui_util";
import * as unread_ui from "./unread_ui";
import {user_settings} from "./user_settings";
@@ -123,7 +124,7 @@ export function set_up(settings_panel) {
$container.find(".play_notification_sound").on("click", () => {
if (settings_object.notification_sound !== "none") {
$notification_sound_elem[0].play();
ui_util.play_audio($notification_sound_elem[0]);
}
});

View File

@@ -1,5 +1,6 @@
import $ from "jquery";
import * as blueslip from "./blueslip";
import * as keydown_util from "./keydown_util";
// Add functions to this that have no non-trivial
@@ -75,3 +76,21 @@ export function parse_html(html: string): DocumentFragment {
template.innerHTML = html;
return template.content;
}
/*
* Handle permission denied to play audio by the browser.
* This can happen due to two reasons: user denied permission to play audio
* unconditionally and browser denying permission to play audio without
* any interactive trigger like a button. See
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play for more details.
*/
export async function play_audio(elem: HTMLVideoElement): Promise<void> {
try {
await elem.play();
} catch (error) {
if (!(error instanceof DOMException)) {
throw error;
}
blueslip.debug(`Unable to play audio. ${error.name}: ${error.message}`);
}
}