From 75f48c137aeb9cbf526df2c7d1953548f6008448 Mon Sep 17 00:00:00 2001 From: Darren Date: Thu, 19 Jul 2012 15:50:15 +0100 Subject: [PATCH] Userbox implimented --- client_backbone/index.html | 7 + client_backbone/model.js | 602 +++++++++++++++++++------------------ client_backbone/style.css | 6 +- client_backbone/view.js | 47 ++- 4 files changed, 358 insertions(+), 304 deletions(-) diff --git a/client_backbone/index.html b/client_backbone/index.html index 4f9ecaa..ea3a52a 100644 --- a/client_backbone/index.html +++ b/client_backbone/index.html @@ -31,6 +31,13 @@ + + diff --git a/client_backbone/model.js b/client_backbone/model.js index 3a52344..fdf1973 100644 --- a/client_backbone/model.js +++ b/client_backbone/model.js @@ -1,299 +1,303 @@ -/*jslint white:true, regexp: true, nomen: true, devel: true, undef: true, browser: true, continue: true, sloppy: true, forin: true, newcap: true, plusplus: true, maxerr: 50, indent: 4 */ -/*global kiwi */ -kiwi.model = {}; - -kiwi.model.MemberList = Backbone.Collection.extend({ - model: kiwi.model.Member, - comparator: function (a, b) { - var i, a_modes, b_modes, a_idx, b_idx, a_nick, b_nick; - var user_prefixes = kiwi.gateway.get('user_prefixes'); - a_modes = a.get("modes"); - b_modes = b.get("modes"); - // Try to sort by modes first - if (a_modes.length > 0) { - // a has modes, but b doesn't so a should appear first - if (b_modes.length === 0) { - return -1; - } - a_idx = b_idx = -1; - // Compare the first (highest) mode - for (i = 0; i < user_prefixes.length; i++) { - if (user_prefixes[i].mode === a_modes[0]) { - a_idx = i; - } - } - for (i = 0; i < user_prefixes.length; i++) { - if (user_prefixes[i].mode === b_modes[0]) { - b_idx = i; - } - } - if (a_idx < b_idx) { - return -1; - } else if (a_idx > b_idx) { - return 1; - } - // If we get to here both a and b have the same highest mode so have to resort to lexicographical sorting - - } else if (b_modes.length > 0) { - // b has modes but a doesn't so b should appear first - return 1; - } - a_nick = a.get("nick").toLocaleUpperCase(); - b_nick = b.get("nick").toLocaleUpperCase(); - // Lexicographical sorting - if (a_nick < b_nick) { - return -1; - } else if (a_nick > b_nick) { - return 1; - } else { - // This should never happen; both users have the same nick. - console.log('Something\'s gone wrong somewhere - two users have the same nick!'); - return 0; - } - }, - initialize: function (options) { - this.view = new kiwi.view.MemberList({"model": this}); - }, - getByNick: function (nick) { - return this.find(function (m) { - return nick === m.get("nick"); - }); - } -}); - -kiwi.model.Member = Backbone.Model.extend({ - sortModes: function (modes) { - return modes.sort(function (a, b) { - var a_idx, b_idx, i; - var user_prefixes = kiwi.gateway.get('user_prefixes'); - - for (i = 0; i < user_prefixes.length; i++) { - if (user_prefixes[i].mode === a) { - a_idx = i; - } - } - for (i = 0; i < user_prefixes.length; i++) { - if (user_prefixes[i].mode === b) { - b_idx = i; - } - } - if (a_idx < b_idx) { - return -1; - } else if (a_idx > b_idx) { - return 1; - } else { - return 0; - } - }); - }, - initialize: function (attributes) { - var nick, modes, prefix; - nick = this.stripPrefix(this.get("nick")); - - modes = this.get("modes"); - modes = modes || []; - this.sortModes(modes); - this.set({"nick": nick, "modes": modes, "prefix": this.getPrefix(modes)}, {silent: true}); - }, - addMode: function (mode) { - var modes, prefix; - modes = this.get("modes"); - modes.push(mode); - modes = this.sortModes(modes); - this.set({"prefix": this.getPrefix(modes), "modes": modes}); - }, - removeMode: function (mode) { - var modes, prefix; - modes = this.get("modes"); - modes = _.reject(modes, function (m) { - return m === mode; - }); - this.set({"prefix": this.getPrefix(modes), "modes": modes}); - }, - getPrefix: function (modes) { - var prefix = ''; - var user_prefixes = kiwi.gateway.get('user_prefixes'); - - if (typeof modes[0] !== 'undefined') { - prefix = _.detect(user_prefixes, function (prefix) { - return prefix.mode === modes[0]; - }); - prefix = (prefix) ? prefix.symbol : ''; - } - return prefix; - }, - stripPrefix: function (nick) { - var tmp = nick, i, j, k; - var user_prefixes = kiwi.gateway.get('user_prefixes'); - i = 0; - - for (j = 0; j < nick.length; j++) { - for (k = 0; k < user_prefixes.length; k++) { - if (nick.charAt(j) === user_prefixes[k].symbol) { - i++; - break; - } - } - } - - return tmp.substr(i); - } -}); - -kiwi.model.PanelList = Backbone.Collection.extend({ - model: kiwi.model.Panel, - comparator: function (chan) { - return chan.get("name"); - }, - initialize: function () { - this.view = new kiwi.view.Tabs({"el": $('#toolbar .panellist')[0], "model": this}); - - // Automatically create a server tab - this.server = new kiwi.model.Server({'name': kiwi.gateway.get('name')}); - kiwi.gateway.on('change:name', this.view.render, this.view); - this.add(this.server); - - // Set the default view to the server tab - kiwi.current_panel = this.server; - - }, - getByName: function (name) { - return this.find(function (c) { - return name === c.get("name"); - }); - } -}); - -kiwi.model.Panel = Backbone.Model.extend({ - initialize: function (attributes) { - var name = this.get("name") || ""; - this.view = new kiwi.view.Panel({"model": this, "name": name}); - this.set({ - "scrollback": [], - "name": name - }, {"silent": true}); - - this.isChannel = false; - }, - - addMsg: function (nick, msg, type, opts) { - var message_obj, bs, d; - - opts = opts || {}; - - // Time defaults to now - if (!opts || typeof opts.time === 'undefined') { - d = new Date(); - opts.time = d.getHours().toString().lpad(2, "0") + ":" + d.getMinutes().toString().lpad(2, "0") + ":" + d.getSeconds().toString().lpad(2, "0"); - } - - // CSS style defaults to empty string - if (!opts || typeof opts.style === 'undefined') { - opts.style = ''; - } - - // Escape any HTML that may be in here - // This doesn't seem right to be here.. should be in view (??) - msg = $('
').text(msg).html(); - - // Run through the plugins - message_obj = {"msg": msg, "time": opts.time, "nick": nick, "chan": this.get("name"), "type": type, "style": opts.style}; - //tmp = kiwi.plugs.run('addmsg', message_obj); - if (!message_obj) { - return; - } - - // The CSS class (action, topic, notice, etc) - if (typeof message_obj.type !== "string") { - message_obj.type = ''; - } - - // Make sure we don't have NaN or something - if (typeof message_obj.msg !== "string") { - message_obj.msg = ''; - } - - // Convert IRC formatting into HTML formatting - message_obj.msg = formatIRCMsg(message_obj.msg); - - // Update the scrollback - bs = this.get("scrollback"); - bs.push(message_obj); - - // Keep the scrolback limited - if (bs.length > 250) { - bs.splice(250); - } - this.set({"scrollback": bs}, {silent: true}); - - this.trigger("msg", message_obj); - }, - - close: function () { - this.view.remove(); - delete this.view; - - var members = this.get('members'); - if (members) { - members.reset([]); - this.unset('members'); - } - - this.destroy(); - - if (this.cid === kiwi.current_panel.cid) { - kiwi.app.panels.server.view.show(); - } - } -}); - -kiwi.model.Server = kiwi.model.Panel.extend({ - initialize: function (attributes) { - var name = "Server"; - this.view = new kiwi.view.Panel({"model": this, "name": name}); - this.set({ - "scrollback": [], - "name": name - }, {"silent": true}); - this.isChannel = false; - - this.addMsg(' ', '--> Kiwi IRC: Such an awesome IRC client', '', {style: 'color:#009900;'}); - } -}); - -// TODO: Channel modes -kiwi.model.Channel = kiwi.model.Panel.extend({ - initialize: function (attributes) { - var that = this, - name = this.get("name") || "", - members; - - this.view = new kiwi.view.Channel({"model": this, "name": name}); - this.set({ - "members": new kiwi.model.MemberList(), - "name": name, - "scrollback": [], - "topic": "" - }, {"silent": true}); - - //this.addMsg(' ', '--> You have joined ' + name, 'action join', {style: 'color:#009900;'}); - - members = this.get("members"); - members.bind("add", function (member) { - var disp = member.get("nick") + ' [' + member.get("ident") + '@' + member.get("hostname") + ']'; - this.addMsg(' ', '--> ' + disp + ' has joined', 'action join'); - }, this); - - members.bind("remove", function (member, options) { - var disp = member.get("nick") + ' [' + member.get("ident") + '@' + member.get("hostname") + ']'; - this.addMsg(' ', '<-- ' + disp + ' has left ' + ((options.message) ? '(' + options.message + ')' : ''), 'action part'); - }, this); - - members.bind("quit", function (args) { - var disp = member.get("nick") + ' [' + member.get("ident") + '@' + member.get("hostname") + ']'; - this.addMsg(' ', '<-- ' + disp + ' has quit ' + ((args.message) ? '(' + args.message + ')' : ''), 'action quit'); - }, this); - - this.isChannel = true; - } -}); +/*jslint white:true, regexp: true, nomen: true, devel: true, undef: true, browser: true, continue: true, sloppy: true, forin: true, newcap: true, plusplus: true, maxerr: 50, indent: 4 */ +/*global kiwi */ +kiwi.model = {}; + +kiwi.model.MemberList = Backbone.Collection.extend({ + model: kiwi.model.Member, + comparator: function (a, b) { + var i, a_modes, b_modes, a_idx, b_idx, a_nick, b_nick; + var user_prefixes = kiwi.gateway.get('user_prefixes'); + a_modes = a.get("modes"); + b_modes = b.get("modes"); + // Try to sort by modes first + if (a_modes.length > 0) { + // a has modes, but b doesn't so a should appear first + if (b_modes.length === 0) { + return -1; + } + a_idx = b_idx = -1; + // Compare the first (highest) mode + for (i = 0; i < user_prefixes.length; i++) { + if (user_prefixes[i].mode === a_modes[0]) { + a_idx = i; + } + } + for (i = 0; i < user_prefixes.length; i++) { + if (user_prefixes[i].mode === b_modes[0]) { + b_idx = i; + } + } + if (a_idx < b_idx) { + return -1; + } else if (a_idx > b_idx) { + return 1; + } + // If we get to here both a and b have the same highest mode so have to resort to lexicographical sorting + + } else if (b_modes.length > 0) { + // b has modes but a doesn't so b should appear first + return 1; + } + a_nick = a.get("nick").toLocaleUpperCase(); + b_nick = b.get("nick").toLocaleUpperCase(); + // Lexicographical sorting + if (a_nick < b_nick) { + return -1; + } else if (a_nick > b_nick) { + return 1; + } else { + // This should never happen; both users have the same nick. + console.log('Something\'s gone wrong somewhere - two users have the same nick!'); + return 0; + } + }, + initialize: function (options) { + this.view = new kiwi.view.MemberList({"model": this}); + }, + getByNick: function (nick) { + return this.find(function (m) { + return nick === m.get("nick"); + }); + } +}); + +kiwi.model.Member = Backbone.Model.extend({ + sortModes: function (modes) { + return modes.sort(function (a, b) { + var a_idx, b_idx, i; + var user_prefixes = kiwi.gateway.get('user_prefixes'); + + for (i = 0; i < user_prefixes.length; i++) { + if (user_prefixes[i].mode === a) { + a_idx = i; + } + } + for (i = 0; i < user_prefixes.length; i++) { + if (user_prefixes[i].mode === b) { + b_idx = i; + } + } + if (a_idx < b_idx) { + return -1; + } else if (a_idx > b_idx) { + return 1; + } else { + return 0; + } + }); + }, + initialize: function (attributes) { + var nick, modes, prefix; + nick = this.stripPrefix(this.get("nick")); + + modes = this.get("modes"); + modes = modes || []; + this.sortModes(modes); + this.set({"nick": nick, "modes": modes, "prefix": this.getPrefix(modes)}, {silent: true}); + }, + addMode: function (mode) { + var modes, prefix; + modes = this.get("modes"); + modes.push(mode); + modes = this.sortModes(modes); + this.set({"prefix": this.getPrefix(modes), "modes": modes}); + }, + removeMode: function (mode) { + var modes, prefix; + modes = this.get("modes"); + modes = _.reject(modes, function (m) { + return m === mode; + }); + this.set({"prefix": this.getPrefix(modes), "modes": modes}); + }, + getPrefix: function (modes) { + var prefix = ''; + var user_prefixes = kiwi.gateway.get('user_prefixes'); + + if (typeof modes[0] !== 'undefined') { + prefix = _.detect(user_prefixes, function (prefix) { + return prefix.mode === modes[0]; + }); + prefix = (prefix) ? prefix.symbol : ''; + } + return prefix; + }, + stripPrefix: function (nick) { + var tmp = nick, i, j, k; + var user_prefixes = kiwi.gateway.get('user_prefixes'); + i = 0; + + for (j = 0; j < nick.length; j++) { + for (k = 0; k < user_prefixes.length; k++) { + if (nick.charAt(j) === user_prefixes[k].symbol) { + i++; + break; + } + } + } + + return tmp.substr(i); + } +}); + +kiwi.model.PanelList = Backbone.Collection.extend({ + model: kiwi.model.Panel, + comparator: function (chan) { + return chan.get("name"); + }, + initialize: function () { + this.view = new kiwi.view.Tabs({"el": $('#toolbar .panellist')[0], "model": this}); + + // Automatically create a server tab + this.server = new kiwi.model.Server({'name': kiwi.gateway.get('name')}); + kiwi.gateway.on('change:name', this.view.render, this.view); + this.add(this.server); + + // Set the default view to the server tab + kiwi.current_panel = this.server; + + }, + getByName: function (name) { + return this.find(function (c) { + return name === c.get("name"); + }); + } +}); + +kiwi.model.Panel = Backbone.Model.extend({ + initialize: function (attributes) { + var name = this.get("name") || ""; + this.view = new kiwi.view.Panel({"model": this, "name": name}); + this.set({ + "scrollback": [], + "name": name + }, {"silent": true}); + }, + + addMsg: function (nick, msg, type, opts) { + var message_obj, bs, d; + + opts = opts || {}; + + // Time defaults to now + if (!opts || typeof opts.time === 'undefined') { + d = new Date(); + opts.time = d.getHours().toString().lpad(2, "0") + ":" + d.getMinutes().toString().lpad(2, "0") + ":" + d.getSeconds().toString().lpad(2, "0"); + } + + // CSS style defaults to empty string + if (!opts || typeof opts.style === 'undefined') { + opts.style = ''; + } + + // Escape any HTML that may be in here + // This doesn't seem right to be here.. should be in view (??) + msg = $('
').text(msg).html(); + + // Run through the plugins + message_obj = {"msg": msg, "time": opts.time, "nick": nick, "chan": this.get("name"), "type": type, "style": opts.style}; + //tmp = kiwi.plugs.run('addmsg', message_obj); + if (!message_obj) { + return; + } + + // The CSS class (action, topic, notice, etc) + if (typeof message_obj.type !== "string") { + message_obj.type = ''; + } + + // Make sure we don't have NaN or something + if (typeof message_obj.msg !== "string") { + message_obj.msg = ''; + } + + // Convert IRC formatting into HTML formatting + message_obj.msg = formatIRCMsg(message_obj.msg); + + // Update the scrollback + bs = this.get("scrollback"); + bs.push(message_obj); + + // Keep the scrolback limited + if (bs.length > 250) { + bs.splice(250); + } + this.set({"scrollback": bs}, {silent: true}); + + this.trigger("msg", message_obj); + }, + + close: function () { + this.view.remove(); + delete this.view; + + var members = this.get('members'); + if (members) { + members.reset([]); + this.unset('members'); + } + + this.destroy(); + + if (this.cid === kiwi.current_panel.cid) { + kiwi.app.panels.server.view.show(); + } + }, + + isChannel: function () { + var channel_prefix = kiwi.gateway.get('channel_prefix'), + this_name = this.get('name'); + + if (!this_name) return false; + return (channel_prefix.indexOf(this_name[0]) > -1); + } +}); + +kiwi.model.Server = kiwi.model.Panel.extend({ + initialize: function (attributes) { + var name = "Server"; + this.view = new kiwi.view.Panel({"model": this, "name": name}); + this.set({ + "scrollback": [], + "name": name + }, {"silent": true}); + + this.addMsg(' ', '--> Kiwi IRC: Such an awesome IRC client', '', {style: 'color:#009900;'}); + } +}); + +// TODO: Channel modes +// TODO: Listen to gateway events for anythign related to this channel +kiwi.model.Channel = kiwi.model.Panel.extend({ + initialize: function (attributes) { + var that = this, + name = this.get("name") || "", + members; + + this.view = new kiwi.view.Channel({"model": this, "name": name}); + this.set({ + "members": new kiwi.model.MemberList(), + "name": name, + "scrollback": [], + "topic": "" + }, {"silent": true}); + + //this.addMsg(' ', '--> You have joined ' + name, 'action join', {style: 'color:#009900;'}); + + members = this.get("members"); + members.bind("add", function (member) { + var disp = member.get("nick") + ' [' + member.get("ident") + '@' + member.get("hostname") + ']'; + this.addMsg(' ', '--> ' + disp + ' has joined', 'action join'); + }, this); + + members.bind("remove", function (member, options) { + var disp = member.get("nick") + ' [' + member.get("ident") + '@' + member.get("hostname") + ']'; + this.addMsg(' ', '<-- ' + disp + ' has left ' + ((options.message) ? '(' + options.message + ')' : ''), 'action part'); + }, this); + + members.bind("quit", function (args) { + var disp = member.get("nick") + ' [' + member.get("ident") + '@' + member.get("hostname") + ']'; + this.addMsg(' ', '<-- ' + disp + ' has quit ' + ((args.message) ? '(' + args.message + ')' : ''), 'action quit'); + }, this); + } +}); diff --git a/client_backbone/style.css b/client_backbone/style.css index 774aa31..27d0c6a 100644 --- a/client_backbone/style.css +++ b/client_backbone/style.css @@ -1,5 +1,6 @@ * { margin:0px; padding:0px; } html, body { height:100%; } +a { color:#36C; text-decoration:none; cursor:pointer; } @@ -116,8 +117,9 @@ body { #memberlists ul.active { display:block; } #memberlists ul li { padding: 0.2em 1em; overflow-y:auto; overflow-x:hidden; cursor:pointer; } #memberlists ul li:hover { background-color:#FAF7D3; } +#memberlists ul li a.nick { display:block; color:black; } -#memberlists ul li .userbox { margin:0px 5px 5px 5px; font-size:.9em; } +#memberlists ul li .userbox { margin:0 1em 5px 1em; font-size:.9em; } #memberlists ul li .userbox a { display:block; text-decoration:none; border-bottom: 1px dashed #aaa; } @@ -131,7 +133,7 @@ body { -khtml-border-radius:5px; } #controlbox .input .nick { text-align: right; width:11em; left:0px; position:absolute; padding:2px; } -#controlbox .input .nick a { text-decoration:none; } +#controlbox .input .nick a { text-decoration:none; color:black; } #controlbox .input .input_wrap { position:absolute; right:7px; left: 12.2em; diff --git a/client_backbone/view.js b/client_backbone/view.js index ec70c2f..65158fe 100644 --- a/client_backbone/view.js +++ b/client_backbone/view.js @@ -16,11 +16,19 @@ kiwi.view.MemberList = Backbone.View.extend({ var $this = $(this.el); $this.empty(); this.model.forEach(function (member) { - $('
  • ' + member.get("prefix") + '' + member.get("nick") + '
  • ').appendTo($this).data('member', member); + $('
  • ' + member.get("prefix") + '' + member.get("nick") + '
  • ') + .appendTo($this) + .data('member', member); }); }, nickClick: function (x) { - console.log(x); + var target = $(x.currentTarget).parent('li'), + member = target.data('member'), + userbox = new kiwi.view.UserBox(); + + userbox.member = member; + $('.userbox', this.$el).remove(); + target.append(userbox.$el); }, show: function () { $('#memberlists').children().removeClass('active'); @@ -28,6 +36,32 @@ kiwi.view.MemberList = Backbone.View.extend({ } }); + +kiwi.view.UserBox = Backbone.View.extend({ + // Member this userbox is relating to + member: {}, + + events: { + 'click .query': 'queryClick', + 'click .info': 'infoClick' + }, + + initialize: function () { + this.$el = $($('#tmpl_userbox').html()); + }, + + queryClick: function (event) { + var panel = new kiwi.model.Channel({name: this.member.get('nick')}); + kiwi.app.panels.add(panel); + panel.view.show(); + }, + + infoClick: function (event) { + kiwi.gateway.raw('WHOIS ' + this.member.get('nick')); + } +}); + + kiwi.view.Panel = Backbone.View.extend({ tagName: "div", className: "messages", @@ -45,6 +79,7 @@ kiwi.view.Panel = Backbone.View.extend({ initializePanel: function (options) { this.$el.css('display', 'none'); + // Containing element for this panel if (options.container) { this.$container = $(options.container); } else { @@ -212,7 +247,13 @@ kiwi.view.Tabs = Backbone.View.extend({ partClick: function (e) { var panel = this.model.getByCid($(e.currentTarget).parent().data('panel_id')); - kiwi.gateway.part(panel.get('name')); + + // Only need to part if it's a channel + if (panel.isChannel()) { + kiwi.gateway.part(panel.get('name')); + } else { + panel.close(); + } } }); -- 2.25.1