Logo accreditation
[KiwiIRC.git] / js / front.js
index 619125d2a655b9a16cf5632e96e1625eb7bec023..05591769935d26b0dcef9e765b17054d0c9febd3 100644 (file)
@@ -1,4 +1,4 @@
-/*jslint nomen: true, devel: true, undef: true, browser: true, continue: true, sloppy: true, forin: true, newcap: true, plusplus: true, maxerr: 50, indent: 4 */
+/*jslint 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 gateway, io, $, iScroll, agent, touchscreen, init_data, plugs, plugins, registerTouches, randomString */
 kiwi.front = {
     revision: 38,
@@ -12,6 +12,8 @@ kiwi.front = {
     buffer: [],
     buffer_pos: 0,
 
+    cache: {},
+    
     original_topic: '',
     
     init: function () {
@@ -89,7 +91,6 @@ kiwi.front = {
             new_width = new_width - parseInt($('#kiwi .userlist').css('margin-right'), 10);
 
             // Make sure we don't remove the userlist alltogether
-            console.log(new_width);
             if (new_width < 20) {
                 $(this).data('draggable').offset.click.left = 10;
                 console.log('whoaa');
@@ -101,6 +102,8 @@ kiwi.front = {
 
         $('#kiwi .formconnectwindow').submit(function () {
             var netsel = $('#kiwi .formconnectwindow .network'),
+                netport = $('#kiwi .formconnectwindow .port'),
+                netssl = $('#kiwi .formconnectwindow .ssl'),
                 nick = $('#kiwi .formconnectwindow .nick'),
                 tmp;
             
@@ -117,8 +120,10 @@ kiwi.front = {
 
             kiwi.front.doLayout();
             try {
-                kiwi.front.run('/connect ' + netsel.val());
-            } catch (e) {}
+                kiwi.front.run('/connect ' + netsel.val() + ' ' + netport.val() + ' ' + (netssl.attr('checked') ? 'true' : ''));
+            } catch (e) {
+                console.log(e);
+            }
             
             $('#kiwi .connectwindow').slideUp('', kiwi.front.barsShow);
             $('#windows').click(function () { $('#kiwi_msginput').focus(); });
@@ -279,16 +284,23 @@ kiwi.front = {
                 
             case '/connect':
             case '/server':
-                if (parts[1] === undefined) {
-                    alert('Usage: /connect servername [port]');
+                if (typeof parts[1] === 'undefined') {
+                    alert('Usage: /connect servername [port] [ssl]');
                     break;
                 }
                 
-                if (parts[2] === undefined) {
+                if (typeof parts[2] === 'undefined') {
                     parts[2] = 6667;
                 }
-                kiwi.front.cur_channel.addMsg(null, ' ', '=== Connecting to ' + parts[1] + '...', 'status');
-                kiwi.gateway.connect(parts[1], parts[2], 0);
+                
+                if ((typeof parts[3] === 'undefined') || !parts[3] || (parts[3] === 'false') || (parts[3] === 'no')) {
+                    parts[3] = false;
+                } else {
+                    parts[3] = true;
+                }
+                
+                kiwi.front.cur_channel.addMsg(null, ' ', '=== Connecting to ' + parts[1] + ' on port ' + parts[2] + (parts[3] ? ' using SSL' : '') + '...', 'status');
+                kiwi.gateway.connect(parts[1], parts[2], parts[3]);
                 break;
                 
             case '/nick':
@@ -378,7 +390,7 @@ kiwi.front = {
                 break;
 
             case '/quit':
-                kiwi.gateway.quit(msg.split(" ", 2)[1]);
+                kiwi.gateway.quit(parts.slice(1).join(' '));
                 break;
 
             case '/topic':
@@ -406,7 +418,7 @@ kiwi.front = {
 
             default:
                 //kiwi.front.cur_channel.addMsg(null, ' ', '--> Invalid command: '+parts[0].substring(1));
-                kiwi.gateway.raw(msg.substring(1));
+                kiwi.gateway.raw(msg.substring(1)); 
             }
 
         } else {
@@ -616,30 +628,64 @@ kiwi.front = {
     },
     
     onChannelListStart: function (e, data) {
-        kiwi.data.set('chanList', []);
+        var tab, table;
+        
+        tab = new Utilityview('Channel List');
+        tab.div.css('overflow-y', 'scroll');
+        table = $('<table style="margin:1em 2em;"><thead style="font-weight: bold;"><tr><td>Channel Name</td><td>Members</td><td style="padding-left: 2em;">Topic</td></tr></thead><tbody style="vertical-align: top;"></tbody>');
+        tab.div.append(table);
+        
+        kiwi.front.cache.list = {chans: [], tab: tab, table: table,
+            update: function (newChans) {
+                var body = this.table.children('tbody:first').detach(),
+                    chan,
+                    html;
+                
+                html = '';
+                for (chan in newChans) {
+                    this.chans.push(newChans[chan]);
+                    html += newChans[chan].html;
+                }
+                body.append(html);
+                this.table.append(body);
+                
+            },
+            finalise: function () {
+                var body = this.table.children('tbody:first').detach(),
+                    list,
+                    chan;
+                
+                list = $.makeArray($(body).children());
+                
+                for (chan in list) {
+                    list[chan] = $(list[chan]).detach();
+                }
+                
+                list = _.sortBy(list, function (channel) {
+                    return parseInt(channel.children('.num_users').first().text(), 10);
+                }).reverse();
+                
+                for (chan in list) {
+                    body.append(list[chan]);
+                }
+                
+                this.table.append(body);
+                
+            }};
     },
     onChannelList: function (e, data) {
-        var network_name = kiwi.gateway.network_name,
-            chanList = kiwi.data.get('chanList');
-        chanList.push(data);
-        kiwi.data.set('chanList', chanList);
+        var chans;
+        console.log(data);
+        data = data.chans;
+        //data = [data];
+        for (chans in data) {
+            data[chans] = {data: data[chans], html: '<tr><td><a class="chan">' + data[chans].channel + '</a></td><td class="num_users" style="text-align: center;">' + data[chans].num_users + '</td><td style="padding-left: 2em;">' + kiwi.front.format(data[chans].topic) + '</td></tr>'};
+        }
+        kiwi.front.cache.list.update(data);
     },
     onChannelListEnd: function (e, data) {
-        var chanList, tab, table, body, chan;
-        
-        chanList = kiwi.data.get('chanList');
-        tab = new Utilityview('Channel List');
-        table = $('<table><thead style="font-weight: bold;"><tr><td>Channel Name</td><td>Members</td><td style="padding-left: 2em;">Topic</td></tr></thead><tbody style="vertical-align: top;"></tbody>');
-        body = table.children('tbody:first');
-        chanList = _.sortBy(chanList, function (channel) {
-            return parseInt(channel.num_users, 10);
-        }).reverse();
-        for (chan in chanList) {
-            body.append($('<tr><td><a class="chan">' + chanList[chan].channel + '</a></td><td style="text-align: center;">' + chanList[chan].num_users + '</td><td style="padding-left: 2em;">' + kiwi.front.format(chanList[chan].topic) + '</td></tr>'));
-        }
-        tab.div.append(table);
-        tab.div.css('overflow-y', 'scroll');
-        tab.show();
+        kiwi.front.cache.list.finalise();
+        kiwi.front.cache.list.tab.show();
     },
 
 
@@ -771,12 +817,19 @@ kiwi.front = {
     },
     
     registerKeys: function () {
+        var tabcomplete = {active: false, data: [], prefix: ''};
         $('#kiwi_msginput').bind('keydown', function (e) {
-            var windows, meta, num, msg, data, candidates, word_pos, word, i;
+            var windows, meta, num, msg, data, candidates, word_pos, word, i, self;
             windows = $('#windows');
             //var meta = e.altKey;
             meta = e.ctrlKey;
             
+            if (e.which !== 9) {
+                tabcomplete.active = false;
+                tabcomplete.data = [];
+                tabcomplete.prefix = '';
+            }
+            
             switch (true) {
             case (e.which >= 48) && (e.which <= 57):
                 if (meta) {
@@ -835,40 +888,59 @@ kiwi.front = {
                 break;
                 
             case e.which === 9:                // tab
-                // Get possible autocompletions
-                data = [];
-                kiwi.front.cur_channel.userlist.children().each(function () {
-                    var nick;
-                    nick = kiwi.front.nickStripPrefix($('a.nick', this).text());
-                    data.push(nick);
-                });
+                tabcomplete.active = true;
+                if (_.isEqual(tabcomplete.data, [])) {
+                    // Get possible autocompletions
+                    data = [];
+                    kiwi.front.cur_channel.userlist.children().each(function () {
+                        var nick;
+                        nick = kiwi.front.nickStripPrefix($('a.nick', this).text());
+                        data.push(nick);
+                    });
+                    data = _.sortBy(data, function (nick) {
+                        return nick;
+                    });
+                    tabcomplete.data = data;
+                }
                 
-                // Do the autocomplete
-                if (this.value.length === this.selectionStart && this.value.length === this.selectionEnd) {
-                    candidates = [];
-                    
-                    word_pos = this.value.lastIndexOf(' ');
-                    word = "";
-                    if (word_pos === -1) {
-                        word = this.value;
-                    } else {
-                        word = this.value.substr(word_pos);
+                if (this.value[this.selectionStart - 1] === ' ') {
+                    return false;
+                }
+                self = this;
+                (function () {
+                    var tokens = self.value.substring(0, self.selectionStart).split(" "),
+                        val,
+                        p1,
+                        newnick,
+                        range;
+                    nick = tokens[tokens.length - 1];
+                    if (tabcomplete.prefix === '') {
+                        tabcomplete.prefix = nick;
                     }
-                    word = word.trim();
                     
-                    // filter data to find only strings that start with existing value
-                    for (i = 0; i < data.length; i++) {
-                        if (data[i].indexOf(word) === 0 && data[i].length > word.length) {
-                            candidates.push(data[i]);
-                        }
-                    }
+                    tabcomplete.data = _.select(tabcomplete.data, function (n) {
+                        return (n.toLowerCase().indexOf(tabcomplete.prefix.toLowerCase()) === 0);
+                    });
                     
-                    if (candidates.length > 0) {
-                        // some candidates for autocompletion are found
-                        this.value = this.value.substring(0, word_pos) + ' ' + candidates[0] + ': ';
-                        this.selectionStart = this.value.length;
+                    if (tabcomplete.data.length > 0) {
+                        p1 = self.selectionStart - (nick.length);
+                        val = self.value.substr(0, p1);
+                        newnick = tabcomplete.data.shift();
+                        tabcomplete.data.push(newnick);
+                        val += newnick;
+                        val += self.value.substr(self.selectionStart);
+                        self.value = val;
+                        if (self.setSelectionRange) {
+                            self.setSelectionRange(p1 + newnick.length, p1 + newnick.length);
+                        } else if (self.createTextRange) { // not sure if this bit is actually needed....
+                            range = self.createTextRange();
+                            range.collapse(true);
+                            range.moveEnd('character', p1 + newnick.length);
+                            range.moveStart('character', p1 + newnick.length);
+                            range.select();
+                        }
                     }
-                }
+                }());
                 return false;
             }
         });
@@ -1090,7 +1162,7 @@ kiwi.front = {
     
     setTopicText: function (new_topic) {
         kiwi.front.original_topic = new_topic;
-        $('#kiwi .cur_topic .topic').text(kiwi.front.format(new_topic));
+        $('#kiwi .cur_topic .topic').text(new_topic);
         kiwi.front.doLayoutSize();
     },
     
@@ -1202,6 +1274,10 @@ kiwi.front = {
     format: function (msg) {
         var re;
         
+        if ((!msg) || (typeof msg !== 'string')) {
+            return;
+        }
+        
         // bold
         if (msg.indexOf(String.fromCharCode(2)) !== -1) {
             next = '<b>';
@@ -1271,7 +1347,7 @@ kiwi.front = {
                 };
             fg = col(p1);
             bg = col(p3);
-            return '<span style="' + ((fg !== null) ? 'color: ' + fg +'; ' : '') + ((bg !== null) ? 'background-color: ' + bg + ';' : '') + '">' + p4 + '</span>';
+            return '<span style="' + ((fg !== null) ? 'color: ' + fg + '; ' : '') + ((bg !== null) ? 'background-color: ' + bg + ';' : '') + '">' + p4 + '</span>';
         });
         return msg;
     }
@@ -1306,14 +1382,20 @@ var Utilityview = function (name) {
     this.name = rand_name;
     this.title = name;
     this.topic = ' ';
+    this.panel = $('#panel1');
 
-    $('#kiwi .windows .scroller').append('<div id="' + tmp_divname + '" class="messages"></div>');
+    if (typeof $('.scroller', this.panel)[0] === 'undefined') {
+        this.panel.append('<div id="' + tmp_divname + '" class="messages"></div>');
+    } else {
+        $('.scroller', this.panel).append('<div id="' + tmp_divname + '" class="messages"></div>');
+    }
 
     this.tab = $('<li id="' + tmp_tabname + '">' + this.title + '</li>');
     this.tab.click(function () {
         kiwi.front.utilityviews[rand_name.toLowerCase()].show();
     });
     $('#kiwi .utilityviewlist ul').append(this.tab);
+    kiwi.front.doLayoutSize();
     
     this.div = $('#' + tmp_divname);
     this.div.css('overflow', 'hidden');
@@ -1326,12 +1408,13 @@ Utilityview.prototype.title = null;
 Utilityview.prototype.div = null;
 Utilityview.prototype.tab = null;
 Utilityview.prototype.topic = ' ';
+Utilityview.prototype.panel = null;
 Utilityview.prototype.show = function () {
-    $('#kiwi .messages').removeClass("active");
+    $('.messages', this.panel).removeClass("active");
     $('#kiwi .userlist ul').removeClass("active");
     $('#kiwi .toolbars ul li').removeClass("active");
 
-    $('#windows').css('overflow-y', 'hidden');
+    this.panel.css('overflow-y', 'hidden');
     $('#windows').css('right', 0);
     // Activate this tab!
     this.div.addClass('active');
@@ -1348,6 +1431,13 @@ Utilityview.prototype.show = function () {
     }
 };
 
+Utilityview.prototype.setPanel = function (new_panel) {
+    this.div.detach();
+    this.panel = new_panel;
+    this.panel.append(this.div);
+    this.show();
+};
+
 Utilityview.prototype.close = function () {
     this.div.remove();
     this.tab.remove();
@@ -1391,7 +1481,9 @@ Utilityview.prototype.clearPartImage = function () {
  */
 
 
-var Tabview = function () {};
+var Tabview = function () {
+    this.panel = $('#panel1');
+};
 Tabview.prototype.name = null;
 Tabview.prototype.div = null;
 Tabview.prototype.userlist = null;
@@ -1399,18 +1491,19 @@ Tabview.prototype.userlist_width = 100;     // 0 for disabled
 Tabview.prototype.tab = null;
 Tabview.prototype.topic = "";
 Tabview.prototype.safe_to_close = false;                // If we have been kicked/banned/etc from this channel, don't wait for a part message
+Tabview.prototype.panel = null;
 
 Tabview.prototype.show = function () {
     var w, u;
 
-    $('#kiwi .messages').removeClass("active");
+    $('.messages', this.panel).removeClass("active");
     $('#kiwi .userlist ul').removeClass("active");
     $('#kiwi .toolbars ul li').removeClass("active");
     
     w = $('#windows');
     u = $('#kiwi .userlist');
 
-    w.css('overflow-y', 'scroll');
+    this.panel.css('overflow-y', 'scroll');
 
     // Set the window size accordingly
     this.setUserlistWidth();
@@ -1532,14 +1625,14 @@ Tabview.prototype.addMsg = function (time, nick, msg, type, style) {
         msg = '';
     }
     
-    msg = kiwi.front.format(msg);
-    
     // Make the channels clickable
     re = new RegExp('\\B(' + kiwi.gateway.channel_prefix + '[^ ,.\\007]+)', 'g');
     msg = msg.replace(re, function (match) {
         return '<a class="chan">' + match + '</a>';
     });
 
+    msg = kiwi.front.format(msg);
+    
     // Build up and add the line
     line_msg = $('<div class="msg ' + type + '"><div class="time">' + time + '</div><div class="nick">' + nick + '</div><div class="text" style="' + style + '">' + msg + ' </div></div>');
     this.div.append(line_msg);
@@ -1557,8 +1650,9 @@ Tabview.prototype.addMsg = function (time, nick, msg, type, style) {
 };
 
 Tabview.prototype.scrollBottom = function () {
-    var w = $('#windows');
-    w[0].scrollTop = w[0].scrollHeight;
+    var panel = this.panel;
+    console.log(panel);
+    panel[0].scrollTop = panel[0].scrollHeight;
 };
 
 Tabview.prototype.changeNick = function (newNick, oldNick) {