Skip to content
Permalink
Browse files

Add notifications, settings dialog.

  • Loading branch information...
Shinmera committed Nov 23, 2017
1 parent e423829 commit 49fab07c27bbadf1fb5739d5703c447352590a0d
Showing with 126 additions and 21 deletions.
  1. BIN favicon.ico
  2. +12 −1 index.html
  3. +23 −1 index.js
  4. +1 −1 lichat.css
  5. +37 −1 lichat.js
  6. +17 −17 lichat.lass
  7. BIN notify.mp3
  8. +36 −0 ui.js
BIN +4.19 KB favicon.ico
Binary file not shown.
@@ -43,6 +43,7 @@ <h2>Channels</h2>
<a data-action="create" title="Create a new channel.">Create</a>
<a data-action="join" title="Join a channel.">Join</a>
<a data-action="leave" title="Leave this channel.">Leave</a>
<a data-action="settings" title="Change some options.">Settings</a>
<a data-action="about" title="About Lichat-JS">About</a>
</nav>
<div class="lichat-output">
@@ -61,8 +62,18 @@ <h2>Users</h2>
<div class="lichat-user-list">
</div>
</div>
<audio class="lichat-notify">
<source src="notify.mp3" type="audio/mp3"/>
</audio>
</main>
<div class="about">
<div class="settings popup">
<h3>Settings</h3>
<div><label>Notifications</label><input type="checkbox" name="notifyBy" value="desktop"/></div>
<div><label>Sounds</label><input type="checkbox" name="notifyBy" value="sound"/></div>
<div><label>Volume</label><input type="range" name="volume" min="0.0" max="1.0" step="0.1" /></div>
<button>Ok</button>
</div>
<div class="about popup">
<h3>This is Lichat-JS, a JavaScript client for Lichat.</h3>
<p>
Lichat is a light-weight, text-based chat protocol. It is aimed at mid-sized group chats, with many simplifications and improvements over alternative protocols such as IRC and XMPP.
@@ -3,6 +3,7 @@ var stat = document.querySelector(".status");
var chat = document.querySelector(".chat");
var menu = document.querySelector(".menu");
var about = document.querySelector(".about");
var settings = document.querySelector(".settings");
var client = new LichatClient();
var ui = new LichatUI(chat, client);

@@ -53,6 +54,12 @@ var setup = ()=>{
login.querySelector("input[name=hostname]").value = load("hostname", login.querySelector("input[name=hostname]").value);
login.querySelector("input[name=port]").value = load("port", defaultPort);
login.querySelector("input[name=channel]").value = load("channel", login.querySelector("input[name=channel]").value);
ui.notifyBy = load("notifyBy", []);
ui.notifySound.volume = load("volume", 0.5);
for(var value of ui.notifyBy){
settings.querySelector("[name=notifyBy][value="+value+"]").checked = true;
}
settings.querySelector("[name=volume]").value = ""+ui.notifySound.volume;
changeTheme(load("theme", "light"));
};

@@ -64,6 +71,17 @@ about.querySelector("button").addEventListener("click", (ev)=>{
about.style.display = "none";
});

settings.querySelector("button").addEventListener("click", (ev)=>{
if(settings.querySelector("[name=notifyBy][value=desktop]").checked){
ui.requestNotifyPermissions();
}
ui.notifyBy = Array.from(settings.querySelectorAll("[name=notifyBy]")).filter((e)=>e.checked).map((e)=>e.value);
ui.notifySound.volume = parseFloat(settings.querySelector("[name=volume]").value);
save("notifyBy", ui.notifyBy);
save("volume", ui.notifySound.volume);
settings.style.display = "none";
});

client.handleFailure = (e)=>{
if(console)
console.log("Failure:",e);
@@ -132,7 +150,11 @@ menu.querySelector("[data-action=leave]").addEventListener("click", (ev)=>{
}, false);

menu.querySelector("[data-action=about]").addEventListener("click", (ev)=>{
about.style.display = "block";
about.style.display = "flex";
}, false);

menu.querySelector("[data-action=settings]").addEventListener("click", (ev)=>{
settings.style.display = "flex";
}, false);

ui.addCommand("theme", (theme)=>{

Large diffs are not rendered by default.

@@ -594,7 +594,7 @@ cl.defclass("PULL", ["CHANNEL-UPDATE", "TARGET-UPDATE"]);
cl.defclass("PERMISSIONS", ["CHANNEL-UPDATE"], {
permissions: []
});
cl.defclass("MESSAGE", ["CHANNEL-UPDATE"]);
cl.defclass("MESSAGE", ["CHANNEL-UPDATE", "TEXT-UPDATE"]);
cl.defclass("USERS", ["CHANNEL-UPDATE"], {
users: []
});
@@ -1191,7 +1191,11 @@ var LichatUI = function(chat,client){

self.commandPrefix = "/";
self.channel = null;
self.notifyBy = [];
self.commands = {};
self.notifySound = chat.querySelector(".lichat-notify");
self.icon = document.querySelector("head link[rel=\"shortcut icon\"]");
self.icon = (self.icon)?self.icon.getAttribute("href"):"/favicon.ico";

self.objectColor = (object)=>{
var hash = cl.sxhash(object);
@@ -1561,6 +1565,35 @@ var LichatUI = function(chat,client){
self.notify = (update)=>{
updates++;
document.title = "("+updates+") "+title;
if(cl.find("sound", self.notifyBy) && self.notifySound){
self.notifySound.play();
}
if(cl.find("desktop", self.notifyBy) && window.Notification && Notification.permission === "granted"){
if(cl.typep(update, "TEXT-UPDATE")){
new Notification(title, {
body: update.from+": "+update.text,
icon: self.icon,
tag: "lichat"
});
}else if(cl.typep(update, "DATA") && cl.find(update["content-type"], ["image/gif", "image/jpeg", "image/png", "image/svg+xml"])){
new Notification(title, {
image: "data:"+update["content-type"]+";base64,"+update["payload"],
icon: self.icon,
tag: "lichat"
});
}
}
};

self.requestNotifyPermissions = ()=>{
if(Notification.permission === "granted"){
return true;
}else if(Notification.permission === "denied"){
return false;
}else{
Notification.requestPermission((p)=>{});
return null;
}
};

document.addEventListener("visibilitychange", (ev)=>{
@@ -1609,6 +1642,9 @@ var LichatUI = function(chat,client){
default:
update.html = "<div class=\"data unsupported\">Unsupported data of type "+update["content-type"]+"</div>";
}
if(document.hidden){
self.notify(update);
}
self.showMessage(update);
});

@@ -12,7 +12,7 @@
(body.light
:background #(primary-bg)
:color #(primary-fg)
(.about
(.popup
:background #(primary-bg)
:color #(primary-fg)
:border-color #(border)
@@ -83,7 +83,7 @@
(body.dark
:background #(primary-bg)
:color #(primary-fg)
(.about
(.popup
:background #(primary-bg)
:color #(primary-fg)
:border-color #(border)
@@ -145,18 +145,6 @@
(.input-area
:border-color #(flavor-bg))))))

(.about
:display none
:position absolute
:left 50% :top 50px
:margin-left -250px
:width 500px
:background white
:padding 10px
:border 3px solid black
:box-shadow 0 0 50px black
(button :width 100%))

(body
:font-family sans-serif
:font-size 14pt
@@ -177,12 +165,12 @@
:border none)
((:or "input[type=submit]:hover" "button:hover")
:cursor pointer)
(.login
((:or .login .settings)
:display flex
:flex-direction column
:margin 10px auto 0 auto
:padding 10px
:max-width 300px
:width 300px
(h1 :text-align center
:margin 0)
(div
@@ -194,9 +182,21 @@
(input :flex-grow 1
:min-width 0
:box-sizing border-box))
(input[type=submit]
((:or input[type=submit] button)
:margin 5px 0 0 0
:width 100%))
(.popup
:display none
:position absolute
:left 50% :top 50px
:margin-left -250px
:width 500px
:background white
:padding 10px
:border 3px solid black
:box-shadow 0 0 50px black)
(.lichat-notify
:display none)
(.chat
:height 100vh
:display flex
BIN +4.49 KB notify.mp3
Binary file not shown.
36 ui.js
@@ -9,7 +9,11 @@ var LichatUI = function(chat,client){

self.commandPrefix = "/";
self.channel = null;
self.notifyBy = [];
self.commands = {};
self.notifySound = chat.querySelector(".lichat-notify");
self.icon = document.querySelector("head link[rel=\"shortcut icon\"]");
self.icon = (self.icon)?self.icon.getAttribute("href"):"/favicon.ico";

self.objectColor = (object)=>{
var hash = cl.sxhash(object);
@@ -379,6 +383,35 @@ var LichatUI = function(chat,client){
self.notify = (update)=>{
updates++;
document.title = "("+updates+") "+title;
if(cl.find("sound", self.notifyBy) && self.notifySound){
self.notifySound.play();
}
if(cl.find("desktop", self.notifyBy) && window.Notification && Notification.permission === "granted"){
if(cl.typep(update, "TEXT-UPDATE")){
new Notification(title, {
body: update.from+": "+update.text,
icon: self.icon,
tag: "lichat"
});
}else if(cl.typep(update, "DATA") && cl.find(update["content-type"], ["image/gif", "image/jpeg", "image/png", "image/svg+xml"])){
new Notification(title, {
image: "data:"+update["content-type"]+";base64,"+update["payload"],
icon: self.icon,
tag: "lichat"
});
}
}
};

self.requestNotifyPermissions = ()=>{
if(Notification.permission === "granted"){
return true;
}else if(Notification.permission === "denied"){
return false;
}else{
Notification.requestPermission((p)=>{});
return null;
}
};

document.addEventListener("visibilitychange", (ev)=>{
@@ -427,6 +460,9 @@ var LichatUI = function(chat,client){
default:
update.html = "<div class=\"data unsupported\">Unsupported data of type "+update["content-type"]+"</div>";
}
if(document.hidden){
self.notify(update);
}
self.showMessage(update);
});

0 comments on commit 49fab07

Please sign in to comment.
You can’t perform that action at this time.