diff --git a/channel.js b/channel.js index e16201b1..a212b364 100644 --- a/channel.js +++ b/channel.js @@ -77,6 +77,7 @@ var Channel = function(name, Server) { this.opts = { allow_voteskip: true, voteskip_ratio: 0.5, + afk_timeout: 180, pagetitle: this.name, maxlength: 0, externalcss: "", @@ -202,6 +203,9 @@ Channel.prototype.loadDump = function() { } this.sendAll("setPermissions", this.permissions); this.broadcastOpts(); + this.users.forEach(function (u) { + u.autoAFK(); + }); if(data.filters) { for(var i = 0; i < data.filters.length; i++) { var f = data.filters[i]; @@ -1540,9 +1544,7 @@ Channel.prototype.tryVoteskip = function(user) { } // Voteskip = auto-unafk if(user.meta.afk) { - user.meta.afk = false; - this.broadcastUserUpdate(user); - this.afkcount--; + user.setAFK(false); } if(!this.voteskip) { this.voteskip = new Poll("voteskip", "voteskip", ["yes"]); @@ -1691,6 +1693,11 @@ Channel.prototype.tryUpdateOptions = function(user, data) { if(key in adminonly && user.rank < Rank.Owner) { continue; } + if(key === "afk_timeout" && this.opts[key] != data[key]) { + this.users.forEach(function (u) { + u.autoAFK(); + }); + } this.opts[key] = data[key]; } } diff --git a/chatcommand.js b/chatcommand.js index bef06d9a..388bee42 100644 --- a/chatcommand.js +++ b/chatcommand.js @@ -24,22 +24,7 @@ function handle(chan, user, msg, data) { } } else if(msg.indexOf("/afk") == 0) { - user.meta.afk = !user.meta.afk; - if(user.meta.afk) - chan.afkcount++; - else - chan.afkcount--; - if(chan.voteskip) { - var need = parseInt(chan.users.length * chan.opts.voteskip_ratio); - need -= chan.afkcount; - if(chan.voteskip.counts[0] >= need) { - chan.playNext(); - } - else { - chan.broadcastVoteskipUpdate(); - } - } - chan.broadcastUserUpdate(user); + user.setAFK(!user.meta.afk); } else if(msg.indexOf("/m ") == 0) { if(user.rank >= Rank.Moderator) { diff --git a/user.js b/user.js index 6772118d..64315a8a 100644 --- a/user.js +++ b/user.js @@ -37,6 +37,8 @@ var User = function(socket, Server) { image: "", text: "" }; + this.awaytimer = false; + this.autoAFK(); this.initCallbacks(); if(Server.announcement != null) { @@ -78,6 +80,41 @@ User.prototype.noflood = function(name, hz) { } } +User.prototype.setAFK = function (afk) { + if(this.channel === null) + return; + var chan = this.channel; + this.meta.afk = afk; + if(this.meta.afk) + chan.afkcount++; + else + chan.afkcount--; + if(chan.voteskip) { + chan.voteskip.unvote(this.ip); + var need = parseInt(chan.users.length * chan.opts.voteskip_ratio); + need -= chan.afkcount; + if(chan.voteskip.counts[0] >= need) { + chan.playNext(); + } + else { + chan.broadcastVoteskipUpdate(); + } + } + chan.broadcastUserUpdate(this); +} + +User.prototype.autoAFK = function () { + if(this.awaytimer) + clearTimeout(this.awaytimer); + + if(this.channel === null || this.channel.opts.afk_timeout == 0) + return; + + this.awaytimer = setTimeout(function () { + this.setAFK(true); + }.bind(this), this.channel.opts.afk_timeout * 1000); +} + User.prototype.initCallbacks = function() { this.socket.on("disconnect", function() { if(this.channel != null) @@ -165,6 +202,8 @@ User.prototype.initCallbacks = function() { this.socket.on("chatMsg", function(data) { if(this.channel != null) { + this.setAFK(false); + this.autoAFK(); this.channel.tryChat(this, data); } }.bind(this)); diff --git a/www/assets/js/channelsettings.js b/www/assets/js/channelsettings.js index f222578f..c7919efe 100644 --- a/www/assets/js/channelsettings.js +++ b/www/assets/js/channelsettings.js @@ -69,7 +69,8 @@ externaljs: $("#opt_externaljs").val(), chat_antiflood: $("#opt_chat_antiflood").prop("checked"), show_public: $("#opt_show_public").prop("checked"), - enable_link_regex: $("#opt_enable_link_regex").prop("checked") + enable_link_regex: $("#opt_enable_link_regex").prop("checked"), + afk_timeout: parseInt($("#opt_afktimeout").val()) }); }); diff --git a/www/assets/js/util.js b/www/assets/js/util.js index b1898d4a..36712689 100644 --- a/www/assets/js/util.js +++ b/www/assets/js/util.js @@ -779,6 +779,7 @@ function handleModPermissions() { $("#opt_show_public").prop("checked", CHANNEL.opts.show_public); $("#opt_show_public").attr("disabled", CLIENT.rank < 3); $("#opt_enable_link_regex").prop("checked", CHANNEL.opts.enable_link_regex); + $("#opt_afktimeout").val(CHANNEL.opts.afk_timeout); $("#opt_allow_voteskip").prop("checked", CHANNEL.opts.allow_voteskip); $("#opt_voteskip_ratio").val(CHANNEL.opts.voteskip_ratio); (function() { diff --git a/www/channeloptions.html b/www/channeloptions.html index 87a3d4b7..b3df2ebe 100644 --- a/www/channeloptions.html +++ b/www/channeloptions.html @@ -56,6 +56,13 @@ + +