From 53e4968cb48f06393d0d5d1263a8cce549e2d406 Mon Sep 17 00:00:00 2001 From: Roslot Date: Thu, 9 May 2019 02:37:13 -0400 Subject: Added notifications and sound alerts in client.js --- client/audio/notify.ogg | Bin 0 -> 65732 bytes client/client.js | 151 ++++++++++++++++++++++++++++++++++++++++++++---- client/index.html | 13 ++++- package.json | 2 +- 4 files changed, 152 insertions(+), 14 deletions(-) create mode 100644 client/audio/notify.ogg diff --git a/client/audio/notify.ogg b/client/audio/notify.ogg new file mode 100644 index 0000000..20c1a35 Binary files /dev/null and b/client/audio/notify.ogg differ diff --git a/client/client.js b/client/client.js index 2e9a255..26974e3 100644 --- a/client/client.js +++ b/client/client.js @@ -67,13 +67,126 @@ var myChannel = window.location.search.replace(/^\?/, ''); var lastSent = [""]; var lastSentPos = 0; + +/** Notification switch and local storage behavior **/ +var notifySwitch = document.getElementById("notify-switch") +var notifySetting = localStorageGet("notify-api") + +// Update localStorage with value of checkbox +notifySwitch.addEventListener('change', () => { + localStorageSet("notify-api", notifySwitch.checked) +}) +// Check if localStorage value is set, defaults to ON +if (notifySetting === null) { + localStorageSet("notify-api", "true") + notifySwitch.checked = true +} +// Configure notifySwitch checkbox element +if (notifySetting === "true" || notifySetting === true) { + notifySwitch.checked = true +} else if (notifySetting === "false" || notifySetting === false) { + notifySwitch.checked = false +} + + +/** Sound switch and local storage behavior **/ +var soundSwitch = document.getElementById("sound-switch") +var notifySetting = localStorageGet("notify-sound") + +// Update localStorage with value of checkbox +soundSwitch.addEventListener('change', () => { + localStorageSet("notify-sound", soundSwitch.checked) +}) +// Check if localStorage value is set, defaults to OFF +if (notifySetting === null) { + localStorageSet("notify-sound", "false") + soundSwitch.checked = false +} +// Configure soundSwitch checkbox element +if (notifySetting === "true" || notifySetting === true) { + soundSwitch.checked = true +} else if (notifySetting === "false" || notifySetting === false) { + soundSwitch.checked = false +} + + + +// Create a new notification after checking if permission has been granted +function spawnNotification(title, body) { + // Let's check if the browser supports notifications + if (!("Notification" in window)) { + console.error("This browser does not support desktop notification"); + } + // Let's check whether notification permissions have already been granted + else if (Notification.permission === "granted") { + // If it's okay let's create a notification + var options = { + body: body, + icon: "/favicon-96x96.png" + }; + var n = new Notification(title, options); + } + // Otherwise, we need to ask the user for permission + else if (Notification.permission !== "denied") { + Notification.requestPermission().then(function (permission) { + // If the user accepts, let's create a notification + if (permission === "granted") { + var options = { + body: body, + icon: "/favicon-96x96.png" + }; + var n = new Notification(title, options); + } + }); + } + // At last, if the user has denied notifications, and you + // want to be respectful, there is no need to bother them any more. +} + +// Inital request for notifications permission +try { + Notification.requestPermission().then(function (result) { + console.log("Hack.Chat notification permission: " + result); + if (result === "granted") { + pushMessage({ + cmd: "chat", + nick: "*", + text: "Notifications enabled.", + time: null + }); + } else { + pushMessage({ + cmd: "chat", + nick: "*", + text: "Notifications disabled. You will not be notified if someone @'s you.", + time: null + }); + } + }); +} catch (error) { + console.error("An error occured trying to request notification permissions. This browser might not support desktop notifications.\nDetails:") + console.error(error) +} + +function notify(args) { + // Spawn notification if enabled + if (notifySwitch.checked) { + spawnNotification("?" + myChannel + " — " + args.nick, args.text) + } + + // Play sound if enabled + if (soundSwitch.checked) { + document.getElementById("notify-sound").play() + } +} + function join(channel) { if (document.domain == 'hack.chat') { // For https://hack.chat/ ws = new WebSocket('wss://hack.chat/chat-ws'); } else { // for local installs - var protocol = location.protocol === 'https:' ? 'wss:' : 'ws:' + var protocol = location.protocol === 'https:' ? 'wss:' : 'ws:' // if you changed the port during the server config, change 'wsPath' // to the new port (example: ':8080') // if you are reverse proxying, change 'wsPath' to the new location @@ -125,18 +238,32 @@ var COMMANDS = { return; } - pushMessage(args); + if (args.text.toLowerCase().includes("@" + myNick.toLowerCase().split("#")[0])) { + notify(args); + pushMessage(args); + // Indicate the message which was just added via style + document.getElementById("messages").lastChild.style.fontWeight = "bold" + } else { + pushMessage(args); + } }, info: function (args) { args.nick = '*'; - pushMessage(args); + if (args.from != null && (args.type.toLowerCase() == "whisper" || args.type.toLowerCase() == "invite")) { + notify(args); + pushMessage(args); + // Make the message bold to stand out as a @mention + document.getElementById("messages").lastChild.style.fontWeight = "bold" + } else { + pushMessage(args); + } }, warn: function (args) { args.nick = '!'; - + notify(args); pushMessage(args); }, @@ -177,7 +304,7 @@ function pushMessage(args) { // Message container var messageEl = document.createElement('div'); - if (typeof(myNick) === 'string' && args.text.includes('@' + myNick.split('#')[0] + ' ')) { + if (typeof (myNick) === 'string' && args.text.includes('@' + myNick.split('#')[0] + ' ')) { messageEl.classList.add('refmessage'); } else { messageEl.classList.add('message'); @@ -396,18 +523,18 @@ $('#chatinput').onkeydown = function (e) { updateInputSize(); } else if (e.keyCode == 9 /* TAB */) { // Tab complete nicknames starting with @ - + if (e.ctrlKey) { // Skip autocompletion and tab insertion if user is pressing ctrl // ctrl-tab is used by browsers to cycle through tabs - return; + return; } e.preventDefault(); var pos = e.target.selectionStart || 0; var text = e.target.value; var index = text.lastIndexOf('@', pos); - + var autocompletedNick = false; if (index >= 0) { @@ -416,7 +543,7 @@ $('#chatinput').onkeydown = function (e) { var nicks = onlineUsers.filter(function (nick) { return nick.toLowerCase().indexOf(stub) == 0 }); - + if (nicks.length > 0) { autocompletedNick = true; if (nicks.length == 1) { @@ -424,7 +551,7 @@ $('#chatinput').onkeydown = function (e) { } } } - + // Since we did not insert a nick, we insert a tab character if (!autocompletedNick) { insertAtCursor('\t'); @@ -456,14 +583,14 @@ updateInputSize(); $('#sidebar').onmouseenter = $('#sidebar').ontouchstart = function (e) { $('#sidebar-content').classList.remove('hidden'); - $('#sidebar').classList.add('expand'); + $('#sidebar').classList.add('expand'); e.stopPropagation(); } $('#sidebar').onmouseleave = document.ontouchstart = function () { if (!$('#pin-sidebar').checked) { $('#sidebar-content').classList.add('hidden'); - $('#sidebar').classList.remove('expand'); + $('#sidebar').classList.remove('expand'); } } diff --git a/client/index.html b/client/index.html index 9238c66..86a4c29 100644 --- a/client/index.html +++ b/client/index.html @@ -16,6 +16,9 @@ +
@@ -33,6 +36,14 @@

Settings

+

+ + +

+

+ + +

@@ -42,7 +53,7 @@

- +

Color scheme

diff --git a/package.json b/package.json index 3dbd932..19fee8c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hack.chat-v2", - "version": "2.1.9", + "version": "2.1.10", "description": "a minimal distraction free chat application", "main": "index.js", "repository": { -- cgit v1.2.1