NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name dAway System // @namespace http://djordjeungar.com/js/dAway/ // @description Lets you define your own custom away message for every channel // @copyright 2007, ArtBIT (http://artbit.deviantart.com) // @oujs:author artbit // @homepageURL http://fav.me/dwkgi5 // @homeURL https://openuserjs.org/scripts/artbit/dAway_System // @include http://chat.deviantart.com* // @grant none // @version 0.7 // ==/UserScript== function script_wrapper() { // start script source var SCRIPT_NAME = "dAway System"; var SCRIPT_VERSION = "0.7"; function initDawaySystem() { //Catch and rewire(tm) dAmn functions var DJO_HELP_WIN_STR = '<div style="background:#88938D; color:#DAE4DA; padding: 4px; margin: 4px; font-size:1.1em;"><a href="http://www.deviantart.com/deviation/54702221/" style="color:inherit !important;"><b>' + SCRIPT_NAME + '</b> v' + SCRIPT_VERSION + '</a> by <a title="Visit ArtBIT\'s page" href="http://artbit.deviantart.com" style="color:inherit !important;">ArtBIT</a></span></div>' + '<div style="padding:10px;">' + '<br /><u><b>Here is the list of commands: </b></u><br />' + '<table style="padding:5px;"><thead></thead>' + '<tr><td><b>/awayhelp</b></td><td> - This screen</td></tr>' + '<tr><td><b>/awayall</b></td><td> - Sets the away message for all channels the user is in (similar to dAx\'/setaway),</td></tr>' + '<tr><td><b>/awayhere</b></td><td> - Sets the away message for the current channel (ONLY).</td></tr>' + '<tr><td><b>/awaysummary</b></td><td> - Displays a detailed view of all the channels in which you\'re away.</td></tr>' + '<tr><td><b>/backall</b></td><td> - Clears the away message for all the channels the user is in (similar to dAx\' /setback),</td></tr>' + '<tr><td><b>/backhere</b></td><td> - Clears the away message for the current channel (ONLY).</td></tr>' + '</tbody></table>' + '<br /><u><b>Here is the list of macros that can be used anywhere in your away messages: </b></u><br />' + '<table style="padding:5px;"><thead></thead>' + '<tr><td><b>%ME%</b></td><td> - your username. (similar to /me)</td></tr>' + '<tr><td><b>%TO%</b></td><td> - the username of a person who triggered the away message.</td></tr>' + '<tr><td><b>%CHANNEL%</b></td><td> - the name of the channel in which the trigger occured (i.e. #flashers).</td></tr>' + '<tr><td><b>%NO_MSGS%</b></td><td> - the number of messages (the number of times someone tried to contact you) since you started being away.</td></tr>' + '<tr><td><b>%AWAY_TIME%</b></td><td> - this is the time when you started being away (i.e. 17:08)</td></tr>' + '<tr><td><b>%AWAY_DURATION%</b></td><td> - this is the duration since you started being away (i.e. 45mins)</td></tr>' + '<tr><td><b>%RANDOMXX-YY%</b></td><td> - where XX and YY are numerical values, generates a random number betwen XX and YY.</td></tr>' + '</tbody></table>' + '<br /><u><b>Example usage:</b></u><br /><br />' + '<div style="color:#555555;">' + ' <span class="colblk">/awayall</span> I\'m sorry <span class="colblk">%TO%</span>, but <span class="colblk">%ME%</span> is not in the <span class="colblk">%CHANNEL%</span>. Reason: Busy.<br />' + ' <i>result: I\'m sorry <span class="colblk">Someone123</span>, but <span class="colblk">ArtBIT</span> is not in the <span class="colblk">#Flashers</span>. Reason: Busy.</i><br /><br />' + ' <span class="colblk">/awayall</span> <span class="colblk">%TO%</span>: I\'m sorry, but I\'m away atm. I\'ve been away since <span class="colblk">%AWAY_TIME%</span>h and I\'ll be back in <span class="colblk">%RANDOM2-5%</span>h.<br />' + ' <i>result: <span class="colblk">Someone123</span>: I\'m sorry, but I\'m away atm. I\'ve been away since <span class="colblk">17:53</span>h and I\'ll be back in <span class="colblk">3</span>h.</i><br />' + '</div>' + '<br /><u><b>Notes: </b></u><br />' + '<table style="padding:5px;"><thead></thead>' + '<tr><td>If you use the /awayall and /awayhere commands with no parameters, the default message will be used ("Sorry %TO%, but %ME% is away right now.")</td></tr>' + '<tr><td>If you use /awayall <b>+</b>some_message or /awayhere <b>+</b>some_message, then some_message will be applied to the end of default message as a reason ("Sorry %TO%, but %ME% is away right now. Reason: <b>some_message</b>")</td></tr>' + '</tbody></table>' + '</div>'; var trigger_time_out = 10000; showInfoWin = function(title, content) { //alert(content); var page = '<html>\n<head>\n\t<title>' + title + '</title>\n' + '<style type="text/css">\n' + '.colblk {color:#000000;}\n' + '.winheader {background:#88938D; color:#DAE4DA; padding: 4px; margin: 4px; font-size:1.1em;}\n' + '.rowlight {background-color:#C3C9C3;}\n' + '.rownorm {background-color:#CDD2CD;}\n' + '.timestamp {color:#88938d; fontWeight:bold; fontSize:0.8em; fontStyle:normal;margin:0 5px;}\n' + 'a {color: inherit !important}\n' + 'input.button { border:1px solid; padding:0 .1em; cursor:pointer; border-radius:.4em; -moz-border-radius:.4em }\n' + 'input.button:hover{ background:#dddddd; } \n' + '.minimized { display:none; visibility:hidden;} \n' + '.maximized { display:block ; visibility:inherit; }\n' + '</style>\n' + '<script type="text/javascript">\n' + 'toggleElementVisibility = function(elem_id) { \n' + 'var e = document.getElementById(elem_id); \n' + 'if(!e) return 0; \n' + 'var b=e.parentNode.firstChild; \n' + 'if(e.className=="minimized") {\n' + ' e.className="maximized" \n' + ' b.value="hide" \n' + ' } else {\n' + ' e.className="minimized" \n' + ' b.value="show" \n' + ' }' + '}' + '</script>\n' + '</head><body style="background-color:#D2D8D2; width:100%; margin:0px auto;">' + content + '</body></html>'; var newWindow = window.open('.', '_blank'); newWindow.document.open(); newWindow.document.write(page); newWindow.document.close(); //newWindow.callerWindow = this.unsafeWindow; newWindow.focus(); }; //A tweak of the dAmnChanMainChat.prototype.onUserInfo( user, body ) function something like siebenzehn's (http://siebenzehn.deviantart.com/) makeResultBox from dAx showInfoBox = function(channel, body) { var o = dAmn_MakeDiv("userinfo-outer"); var i = dAmn_AddDiv(o, "userinfo-inner"); var u = dAmn_AddDiv(i, "userinfo alt0"); var t = this; dAmnChat_AddImgBox(u, "damncr-close", 'close', 'close', function(el) { dAmn_DeleteSelf(el); t.scroll_once = true; dAmn_InvalidateLayout(); }, o); var r = dAmn_AddDiv(u, 'bodyarea alt1-left-border'); var b = dAmn_AddDiv(r, 'b read pcusers'); dAmn_AddDiv(b, 'read', body); channel.addDiv(o, null, 0); }; randRange = function(min, max) { return (Math.floor(Math.random() * (max - min + 1)) + min); }; parseSpecialWords = function(channel, from) { var msg = String(channel.away_msg); //alert(msg); msg = msg.replace(/%TO%/g, from); msg = msg.replace(/%ME%/g, dAmn_Client_Username); msg = msg.replace(/%AWAY_TIME%/g, channel.away_time); msg = msg.replace(/%CHANNEL%/g, dAmn_formatNS(channel.cr.ns)); msg = msg.replace(/%NO_MSGS%/g, channel.no_missed_msgs); var now = new Date().getTime(); var duration = now - channel.away_time_ms; msg = msg.replace(/%AWAY_DURATION%/g, milisecondsToString(duration)); var re = new RegExp("%RANDOM(\\d+)-(\\d+)%", "g"); var randomSet = msg.match(re); if (randomSet !== null) { for (var i = 0; i < randomSet.length; i++) { re = new RegExp("%RANDOM(\\d+)-(\\d+)%", "g"); var range = re.exec(randomSet[i]); var min = Number(range[1]); var max = Number(range[2]); var randValue = String(randRange(min, max)); if (null !== range) msg = msg.replace(/%RANDOM\d+-\d+%/, randValue); } } return msg; }; sSuffix = function(num) { return ((num % 10 != 1) || (num % 100 == 11)) ? "s": ""; }; milisecondsToString = function(mil) { var period = Math.floor(mil / 1000); var strPeriod = ""; if (period > 60) { period = Math.floor(period / 60); if (period > 60) { period = Math.floor(period / 60); strPeriod = "over " + period + " hour" + sSuffix(period); } else { strPeriod = "over " + period + " minute" + sSuffix(period); } } else { strPeriod = period + " second" + sSuffix(period); } return strPeriod; }; customAwayAll = function(msg) { dAmn_objForEach(dAmnChats, function(chan, name) { customAwayHere(chan.channels.main, msg); }); }; customAwayHere = function(channel, msg) { var noAwayChans = []; noAwayChans["chat:IdleRPG"] = 1; noAwayChans["chat:help"] = 1; noAwayChans["chat:devart"] = 1; noAwayChans["chat:Trivia"] = 1; noAwayChans["debug:conn"] = 1; noAwayChans["chat:photographers"] = 1; if (msg === "" || msg === undefined) msg = "Sorry %TO%, but %ME% is away right now."; if (msg.charAt(0) == '+') msg = "Sorry %TO%, but %ME% is away right now. Reason: " + msg.substring(1); if (!noAwayChans[channel.cr.ns]) { channel.is_away = true; var d = new Date(); var h = d.getHours(); var m = d.getMinutes(); var s = d.getSeconds(); if (h < 10) h = '0' + h; if (m < 10) m = '0' + m; if (s < 10) s = '0' + s; channel.away_time_ms = d.getTime(); channel.away_time = h + ':' + m + ':' + s; channel.away_msg = msg; channel.missed_messages = []; channel.silent_away = false; channel.no_missed_msgs = 0; var parsed_msg = parseSpecialWords(channel, 'all'); channel.cr.Send('action', 'main', ' is now away: ' + parsed_msg); } }; deleteAllMessages = function(channel) { alert("Deleting all messages for channel: " + channel); channel.missed_messages = []; channel.no_missed_msgs = 0; }; timestamp = function() { var d = new Date(); var h = d.getHours(); var m = d.getMinutes(); var s = d.getSeconds(); if (h < 10) h = '0' + h; if (m < 10) m = '0' + m; if (s < 10) s = '0' + s; return (h + ':' + m + ':' + s); }; onAway = function(channel, from, body) { //alert(from); if (channel.silent_away) return; window.clearTimeout(channel.away_timeout); channel.silent_away = true; channel.away_timeout = window.setTimeout((function() { channel.silent_away = false; }), trigger_time_out); if (from == dAmn_Client_Username) return; var noAwayChans = []; noAwayChans["chat:IdleRPG"] = 1; noAwayChans["chat:help"] = 1; noAwayChans["chat:devart"] = 1; noAwayChans["chat:Trivia"] = 1; noAwayChans["debug:conn"] = 1; noAwayChans["chat:photographers"] = 1; if (!noAwayChans[channel.cr.ns]) { var msg = parseSpecialWords(channel, from); channel.no_missed_msgs++; var missed_msg = '<span class="timestamp">' + timestamp() + ' <b><<a title="Visit ' + from + '\'s page" href="http://' + from + '.deviantart.com">' + from + '</a>></b></span> ' + dAmnChanChat.prototype.FormatMsg(body, 'alpha'); channel.missed_messages.push(missed_msg); channel.cr.Send('msg', 'main', msg); } }; customBackHere = function(channel) { if (channel.is_away) { channel.is_away = false; channel.cr.Send('action', 'main', ' is now back.'); } }; userLink = function(da_username) { return '<a title="Visit ' + da_username + '\'s page" target="_blank" href="http://' + da_username + '.deviantart.com/">' + da_username + '</a>'; }; customBackAll = function() { for (var e in dAmnChats) //dAmn_objForEach(dAmnChats[e].channels,function(chan,name) { dAmn_objForEach(dAmnChats, function(chan, name) { customBackHere(chan.channels.main); }); }; getChannelInfo = function(channel) { var m = channel.missed_messages.length; if (channel.away_msg === '' && !m) return ''; var away_msg = (channel.away_msg === '') ? " is not currently away in this channel ": channel.away_msg; var msg = "<table><tbody>"; msg += "<tr><td> - away since: </td><td> " + channel.away_time + "</td></tr>"; msg += "<tr><td> - away message: </td><td> " + away_msg + "</td></tr>"; msg += "<tr><td valign='top'> - " + channel.no_missed_msgs + " personal msg" + sSuffix(channel.no_missed_msgs) + "</td>"; var i = 0; if (m) { var channelID = dAmn_formatNS(channel.cr.ns); var b = "<input value='show' type='button' class='button' onclick='toggleElementVisibility(\"" + channelID + "\")'/>"; //var btndel = "<input value='delete all' type='button' class='button' onclick='javascript: alert(opener.document.deleteAllMessages)'/>"; //msg+="<td>"+b+btndel+"<br />"; msg += "<td>" + b + "<br />"; msg += "<div id='" + channelID + "' class='minimized'>"; while (i < m) { msg += channel.missed_messages[i] + "<br />"; i++; } msg += "</div></td></tr>"; } else { msg += "<td></td></tr>"; } msg += "</tbody></table>"; return msg; }; getSummary = function(channel) { //{var info ='<span style="font-size:1.1em;">'+userlink(dAmn_Client_Username,≣)+'</span> - is away in the following rooms:<br /><br />' var info = '<div class="winheader"><span style="font-size:1.1em;"><b>[' + userLink(dAmn_Client_Username) + ']</b></span> - is away in the following rooms:</div>' + '<table width="100%"><tbody><tr><td align="center">' + '<table style="padding:0px;" width="98%"><thead style="font-size:1.1em;font-weight:bold;"><td style="width:100px;">Channel:</td><td>Info:</td><td></td></thead><tbody>'; var infoList = ''; var row_id = 0; dAmn_objForEach(dAmnChats, function(chan, name) { var chan_info = getChannelInfo(chan.channels.main); if (chan_info !== '') { var imgShoutbox = ''; var rowClass = 'rowlight'; if (row_id++ % 2 === 0) rowClass = 'rownorm'; if (chan.channels.main.no_missed_msgs) imgShoutbox = '<br /><br /><div align="center"><img src="http://e.deviantart.com/emoticons/s/shoutbox.gif" alt="Message" /></div>'; infoList += '<tr class="' + rowClass + '"><td valign="top"><b> ' + name.match(/^chat:(.*)$/)[1] + imgShoutbox + '</b></td><td>' + chan_info + '</td></tr>'; } }); if (infoList === '') infoList = '<tr><td valign="top">none</td><td>none</td></tr>'; info += infoList; info += '<tr><td colspan="3"><div style="font-size:0.8em; text-align:right; padding-right: 5px;color:#000000 !important;""><a href="http://www.deviantart.com/deviation/54702221/" title="Go to deviation page" ><b>' + SCRIPT_NAME + '</b> v' + SCRIPT_VERSION + '</a> by <a title="Visit ArtBIT\'s page" href="http://artbit.deviantart.com" >ArtBIT</a></div></td></tr>'; info += '</tbody></table>'; info += '</td></tr></tbody></table>'; return info; }; /*************************** dAmn - REWIRED ****************************/ dAmnChanChat.prototype.Init_customAway_rewire = dAmnChanChat.prototype.Init; dAmnChanChat.prototype.Init = function(cr, name, parent_el) { this.Init_customAway_rewire(cr, name, parent_el); this.is_away = false; this.away_time_ms = this.away_time = - 1; this.away_msg = ""; this.missed_messages = []; this.no_missed_msgs = 0; this.away_timeout = - 1; this.silent_away = false; var cie = this.input; cie.cmds['awayhere'] = [0, '']; cie.cmds['backhere'] = [0, '']; cie.cmds['awayall'] = [0, '']; cie.cmds['backall'] = [0, '']; cie.cmds['awaysummary'] = [0, '']; cie.cmds['awayhelp'] = [0, '']; } dAmnChanChat.prototype.onMsg_customAway_rewire = dAmnChanChat.prototype.onMsg; dAmnChanChat.prototype.onMsg = function(from, body) { //alert(from); if ( - 1 != body.search(RegExp("([^A-Za-z0-9]+|^)" + dAmn_Client_Username, "im"))) //and it has awaystats word in the message, and the user is away if (0 === body.search(RegExp("(awaysummary)", "im")) && this.is_away) { showAwaySummary(this); } else { if (this.is_away) { onAway(this, from, body); } } this.onMsg_customAway_rewire(from, body); }; dAmnChatInput_onKey_customAway_rewire = dAmnChatInput_onKey; dAmnChatInput_onKey = function(e, kc, force) { var el = this.chatinput_el; var didsmth = false; if (kc == 13 && (force || ! this.multiline || e.shiftKey || e.ctrlKey)) { var input = el.value; var rex = /^\/(\S*)\s*(.*)$/i.exec(input); if (rex) { var cmd = rex[1]; var param = rex.slice(2).join(' '); var show_help = false; if (cmd) { switch (cmd) { case 'awayhere': didsmth = true; show_help = (param == '?'); if (!show_help) customAwayHere(this.channel, param); break; case 'backhere': didsmth = true; show_help = (param == '?'); if (!show_help) customBackHere(this.channel); break; case 'awayall': didsmth = true; show_help = (param == '?'); if (!show_help) customAwayAll(param); break; case 'backall': didsmth = true; show_help = (param == '?'); if (!show_help) customBackAll(); break; case 'awaysummary': didsmth = true; show_help = (param == '?'); //alert(getSummary(this.channel)); if (!show_help) showInfoWin("dAmn awayMessages by ArtBIT - summary for " + dAmn_Client_Username, getSummary(this.channel)); break; case 'awayhelp': didsmth = true; show_help = (param == '?'); showInfoWin("dAmn awayMessages by ArtBIT - HELP", DJO_HELP_WIN_STR); //showInfoBox(this.channel,DJO_HELP_WIN_STR); break; } //end case if (didsmth) { //if(show_help) showInfoBox(this.channel,'Type <b>/awayhelp</b> for more info.<br />'); if (el.value) { //add to history array if (this.history_pos != - 1 && this.history[this.history_pos] == el.value) { // posting from history.. move to the end var before = this.history.slice(0, this.history_pos); var after = this.history.slice(this.history_pos + 1); this.history = before.concat(after).concat(this.history[this.history_pos]); } else { // add to history -- limit to 300 this.history = this.history.concat(el.value); if (this.history.length > 300) this.history = this.history.slice(1); } this.history_pos = - 1; el.value = ''; el.focus(); } } } } } if (!didsmth) return this.onKey_customAway_rewire(e, kc, force) ? true: false; else return false; } dAmnChatInput.prototype.onKey = dAmnChatInput_onKey; dAmnChatInput.prototype.onKey_customAway_rewire = dAmnChatInput_onKey_customAway_rewire; } var tries = 0; var maxTries = 100; function tryInit() { //alert(unsafeWindow.dAmnChanChat.prototype); if (dAmnChanChat && dAmnChanChat.prototype) { initDawaySystem(); } else { if (tries++ < maxTries) setTimeout(tryInit, 100); } } tryInit(); } var script = document.createElement('script'); script.appendChild(document.createTextNode('(' + script_wrapper + ')();')); document.body.appendChild(script);