Implement Auto-AFK (#192)

- Channel-configurable delay
- User is marked AFK if no chat messages are received before the delay expires
- User is marked un-AFK if a chat message is received or if the user voteskips
This commit is contained in:
calzoneman 2013-07-28 17:58:22 -04:00
parent 1150d03474
commit 77a57d24c1
6 changed files with 60 additions and 20 deletions

View File

@ -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];
}
}

View File

@ -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) {

39
user.js
View File

@ -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));

View File

@ -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())
});
});

View File

@ -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() {

View File

@ -56,6 +56,13 @@
<input type="text" id="opt_maxlength" placeholder="HH:MM:SS">
</div>
</div>
<!-- auto afk -->
<div class="control-group">
<label class="control-label" for="opt_afktimeout">Auto AFK Delay (0 to disable)</label>
<div class="controls">
<input type="text" id="opt_afktimeout" placeholder="0">
</div>
</div>
<hr>
<strong>Admin-Only Controls</strong>
<!-- page title -->