Merge branch 'ircv3' of https://github.com/M2Ys4U/KiwiIRC into M2Ys4U-ircv3
[KiwiIRC.git] / client / assets / dev / model_application.js
index fef90644f681697efb305bb12182927e76dbb9b4..262383b4567929d8959b194ee9ce6b4a526d2def 100644 (file)
@@ -1,4 +1,4 @@
-kiwi.model.Application = function () {\r
+_kiwi.model.Application = function () {\r
     // Set to a reference to this object within initialize()\r
     var that = null;\r
 \r
@@ -7,13 +7,13 @@ kiwi.model.Application = function () {
 \r
 \r
     var model = function () {\r
-        /** Instance of kiwi.model.PanelList */\r
+        /** Instance of _kiwi.model.PanelList */\r
         this.panels = null;\r
 \r
-        /** kiwi.view.Application */\r
+        /** _kiwi.view.Application */\r
         this.view = null;\r
 \r
-        /** kiwi.view.StatusMessage */\r
+        /** _kiwi.view.StatusMessage */\r
         this.message = null;\r
 \r
         /* Address for the kiwi server */\r
@@ -27,7 +27,10 @@ kiwi.model.Application = function () {
             }\r
 \r
             // The base url to the kiwi server\r
-            this.set('base_path', options[0].base_path ? options[0].base_path : '/client');\r
+            this.set('base_path', options[0].base_path ? options[0].base_path : '/kiwi');\r
+\r
+            // Any options sent down from the server\r
+            this.server_settings = options[0].server_settings || {};\r
 \r
             // Best guess at where the kiwi server is\r
             this.detectKiwiServer();\r
@@ -42,8 +45,8 @@ kiwi.model.Application = function () {
             }\r
             \r
             // Set the gateway up\r
-            kiwi.gateway = new kiwi.model.Gateway();\r
-            this.bindGatewayCommands(kiwi.gateway);\r
+            _kiwi.gateway = new _kiwi.model.Gateway();\r
+            this.bindGatewayCommands(_kiwi.gateway);\r
 \r
             this.initializeClient();\r
             this.initializeGlobals();\r
@@ -51,27 +54,35 @@ kiwi.model.Application = function () {
             this.view.barsHide(true);\r
 \r
             this.panels.server.server_login.bind('server_connect', function (event) {\r
-                var server_login = this;\r
+                var server_login = this,\r
+                    transport_path = '';\r
                 auto_connect_details = event;\r
 \r
                 server_login.networkConnecting();\r
                 \r
-                $script(that.kiwi_server + '/socket.io/socket.io.js?ts='+(new Date().getTime()), function () {\r
+                // Path to get the socket.io transport code\r
+                transport_path = that.kiwi_server + that.get('base_path') + '/transport/socket.io.js?ts='+(new Date().getTime());\r
+                \r
+                $script(transport_path, function () {\r
                     if (!window.io) {\r
                         kiwiServerNotFound();\r
                         return;\r
                     }\r
-                    kiwi.gateway.set('kiwi_server', that.kiwi_server + '/kiwi');\r
-                    kiwi.gateway.set('nick', event.nick);\r
+                    _kiwi.gateway.set('kiwi_server', that.kiwi_server + '/kiwi');\r
+                    _kiwi.gateway.set('nick', event.nick);\r
                     \r
-                    kiwi.gateway.connect(event.server, event.port, event.ssl, event.password, function () {});\r
+                    _kiwi.gateway.connect(event.server, event.port, event.ssl, event.password, function (error) {\r
+                        if (error) {\r
+                            kiwiServerNotFound();\r
+                        }\r
+                    });\r
                 });\r
             });\r
 \r
             // TODO: Shouldn't really be here but it's not working in the view.. :/\r
             // Hack for firefox browers: Focus is not given on this event loop iteration\r
             setTimeout(function(){\r
-                kiwi.app.panels.server.server_login.$el.find('.nick').select();\r
+                _kiwi.app.panels.server.server_login.$el.find('.nick').select();\r
             }, 0);\r
         };\r
 \r
@@ -93,21 +104,23 @@ kiwi.model.Application = function () {
 \r
 \r
         this.initializeClient = function () {\r
-            this.view = new kiwi.view.Application({model: this, el: this.get('container')});\r
+            this.view = new _kiwi.view.Application({model: this, el: this.get('container')});\r
             \r
             /**\r
              * Set the UI components up\r
              */\r
-            this.panels = new kiwi.model.PanelList();\r
+            this.panels = new _kiwi.model.PanelList();\r
 \r
-            this.controlbox = new kiwi.view.ControlBox({el: $('#controlbox')[0]});\r
+            this.controlbox = new _kiwi.view.ControlBox({el: $('#controlbox')[0]});\r
             this.bindControllboxCommands(this.controlbox);\r
 \r
-            this.topicbar = new kiwi.view.TopicBar({el: $('#topic')[0]});\r
+            this.topicbar = new _kiwi.view.TopicBar({el: $('#topic')[0]});\r
 \r
-            this.message = new kiwi.view.StatusMessage({el: $('#status_message')[0]});\r
+            new _kiwi.view.AppToolbar({el: $('#toolbar .app_tools')[0]});\r
 \r
-            this.resize_handle = new kiwi.view.ResizeHandler({el: $('#memberlists_resize_handle')[0]});\r
+            this.message = new _kiwi.view.StatusMessage({el: $('#status_message')[0]});\r
+\r
+            this.resize_handle = new _kiwi.view.ResizeHandler({el: $('#memberlists_resize_handle')[0]});\r
             \r
             this.panels.server.view.show();\r
 \r
@@ -119,7 +132,14 @@ kiwi.model.Application = function () {
 \r
 \r
         this.initializeGlobals = function () {\r
-            kiwi.global.control = this.controlbox;\r
+            _kiwi.global.control = this.controlbox;\r
+            _kiwi.global.gateway = _kiwi.gateway;\r
+            _kiwi.global.panels = this.panels;\r
+            \r
+            _kiwi.global.components = {\r
+                Applet: _kiwi.model.Applet,\r
+                Panel: _kiwi.model.Panel\r
+            };\r
         };\r
 \r
 \r
@@ -130,8 +150,10 @@ kiwi.model.Application = function () {
                 server: 'irc.kiwiirc.com',\r
                 port: 6667,\r
                 ssl: false,\r
-                channel: window.location.hash || '#kiwiirc'\r
+                channel: window.location.hash || '#kiwiirc',\r
+                channel_key: ''\r
             };\r
+            var uricheck;\r
 \r
             // Process the URL part by part, extracting as we go\r
             parts = window.location.pathname.toString().replace(this.get('base_path'), '').split('/');\r
@@ -140,22 +162,56 @@ kiwi.model.Application = function () {
                 parts.shift();\r
 \r
                 if (parts.length > 0 && parts[0]) {\r
-                    // Extract the port+ssl if we find one\r
-                    if (parts[0].search(/:/) > 0) {\r
-                        defaults.port = parts[0].substring(parts[0].search(/:/) + 1);\r
-                        defaults.server = parts[0].substring(0, parts[0].search(/:/));\r
-                        if (defaults.port[0] === '+') {\r
-                            defaults.port = parseInt(defaults.port.substring(1), 10);\r
-                            defaults.ssl = true;\r
+                    // Check to see if we're dealing with an irc: uri, or whether we need to extract the server/channel info from the HTTP URL path.\r
+                    uricheck = parts[0].substr(0, 7).toLowerCase();\r
+                    if ((uricheck === 'ircs%3a') || (uricheck.substr(0,6) === 'irc%3a')) {\r
+                        parts[0] = decodeURIComponent(parts[0]);\r
+                        // irc[s]://<host>[:<port>]/[<channel>[?<password>]]\r
+                        uricheck = /^irc(s)?:(?:\/\/?)?([^:\/]+)(?::([0-9]+))?(?:(?:\/)([^\?]*)(?:(?:\?)(.*))?)?$/.exec(parts[0]);\r
+                        /*\r
+                            uricheck[1] = ssl (optional)\r
+                            uricheck[2] = host\r
+                            uricheck[3] = port (optional)\r
+                            uricheck[4] = channel (optional)\r
+                            uricheck[5] = channel key (optional, channel must also be set)\r
+                        */\r
+                        if (uricheck) {\r
+                            if (typeof uricheck[1] !== 'undefined') {\r
+                                defaults.ssl = true;\r
+                                if (defaults.port === 6667) {\r
+                                    defaults.port = 6697;\r
+                                }\r
+                            }\r
+                            defaults.server = uricheck[2];\r
+                            if (typeof uricheck[3] !== 'undefined') {\r
+                                defaults.port = uricheck[3];\r
+                            }\r
+                            if (typeof uricheck[4] !== 'undefined') {\r
+                                defaults.channel = '#' + uricheck[4];\r
+                                if (typeof uricheck[5] !== 'undefined') {\r
+                                    defaults.channel_key = uricheck[5];\r
+                                }\r
+                            }\r
+                        }\r
+                        parts = [];\r
+                    } else {\r
+                        // Extract the port+ssl if we find one\r
+                        if (parts[0].search(/:/) > 0) {\r
+                            defaults.port = parts[0].substring(parts[0].search(/:/) + 1);\r
+                            defaults.server = parts[0].substring(0, parts[0].search(/:/));\r
+                            if (defaults.port[0] === '+') {\r
+                                defaults.port = parseInt(defaults.port.substring(1), 10);\r
+                                defaults.ssl = true;\r
+                            } else {\r
+                                defaults.ssl = false;\r
+                            }\r
+\r
                         } else {\r
-                            defaults.ssl = false;\r
+                            defaults.server = parts[0];\r
                         }\r
 \r
-                    } else {\r
-                        defaults.server = parts[0];\r
+                        parts.shift();\r
                     }\r
-\r
-                    parts.shift();\r
                 }\r
 \r
                 if (parts.length > 0 && parts[0]) {\r
@@ -164,6 +220,29 @@ kiwi.model.Application = function () {
                 }\r
             }\r
 \r
+            // If any settings have been given by the server.. override any auto detected settings\r
+            if (this.server_settings && this.server_settings.connection) {\r
+                if (this.server_settings.connection.server) {\r
+                    defaults.server = this.server_settings.connection.server;\r
+                }\r
+\r
+                if (this.server_settings.connection.port) {\r
+                    defaults.port = this.server_settings.connection.port;\r
+                }\r
+\r
+                if (this.server_settings.connection.ssl) {\r
+                    defaults.ssl = this.server_settings.connection.ssl;\r
+                }\r
+\r
+                if (this.server_settings.connection.channel) {\r
+                    defaults.channel = this.server_settings.connection.channel;\r
+                }\r
+\r
+                if (this.server_settings.connection.nick) {\r
+                    defaults.nick = this.server_settings.connection.nick;\r
+                }\r
+            }\r
+\r
             // Set any random numbers if needed\r
             defaults.nick = defaults.nick.replace('?', Math.floor(Math.random() * 100000).toString());\r
 \r
@@ -174,7 +253,7 @@ kiwi.model.Application = function () {
 \r
         this.bindGatewayCommands = function (gw) {\r
             gw.on('onmotd', function (event) {\r
-                that.panels.server.addMsg(kiwi.gateway.get('name'), event.msg, 'motd');\r
+                that.panels.server.addMsg(_kiwi.gateway.get('name'), event.msg, 'motd');\r
             });\r
 \r
 \r
@@ -182,7 +261,7 @@ kiwi.model.Application = function () {
                 that.view.barsShow();\r
                 \r
                 if (auto_connect_details.channel) {\r
-                    that.controlbox.processInput('/JOIN ' + auto_connect_details.channel);\r
+                    that.controlbox.processInput('/JOIN ' + auto_connect_details.channel + ' ' + auto_connect_details.channel_key);\r
                 }\r
             });\r
 \r
@@ -195,17 +274,17 @@ kiwi.model.Application = function () {
                     that.message.text(msg, {timeout: 10000});\r
 \r
                     // Mention the disconnection on every channel\r
-                    $.each(kiwi.app.panels.models, function (idx, panel) {\r
+                    $.each(_kiwi.app.panels.models, function (idx, panel) {\r
                         if (!panel || !panel.isChannel()) return;\r
                         panel.addMsg('', msg, 'action quit');\r
                     });\r
-                    kiwi.app.panels.server.addMsg('', msg, 'action quit');\r
+                    _kiwi.app.panels.server.addMsg('', msg, 'action quit');\r
 \r
                     gw_stat = 1;\r
                 });\r
                 gw.on('reconnecting', function (event) {\r
                     msg = 'You have been disconnected. Attempting to reconnect again in ' + (event.delay/1000) + ' seconds..';\r
-                    kiwi.app.panels.server.addMsg('', msg, 'action quit');\r
+                    _kiwi.app.panels.server.addMsg('', msg, 'action quit');\r
                 });\r
                 gw.on('connect', function (event) {\r
                     if (gw_stat !== 1) return;\r
@@ -214,11 +293,11 @@ kiwi.model.Application = function () {
                     that.message.text(msg, {timeout: 5000});\r
 \r
                     // Mention the disconnection on every channel\r
-                    $.each(kiwi.app.panels.models, function (idx, panel) {\r
+                    $.each(_kiwi.app.panels.models, function (idx, panel) {\r
                         if (!panel || !panel.isChannel()) return;\r
                         panel.addMsg('', msg, 'action join');\r
                     });\r
-                    kiwi.app.panels.server.addMsg('', msg, 'action join');\r
+                    _kiwi.app.panels.server.addMsg('', msg, 'action join');\r
 \r
                     gw_stat = 0;\r
                 });\r
@@ -229,14 +308,14 @@ kiwi.model.Application = function () {
                 var c, members, user;\r
                 c = that.panels.getByName(event.channel);\r
                 if (!c) {\r
-                    c = new kiwi.model.Channel({name: event.channel});\r
+                    c = new _kiwi.model.Channel({name: event.channel});\r
                     that.panels.add(c);\r
                 }\r
 \r
                 members = c.get('members');\r
                 if (!members) return;\r
 \r
-                user = new kiwi.model.Member({nick: event.nick, ident: event.ident, hostname: event.hostname});\r
+                user = new _kiwi.model.Member({nick: event.nick, ident: event.ident, hostname: event.hostname});\r
                 members.add(user);\r
                 // TODO: highlight the new channel in some way\r
             });\r
@@ -253,7 +332,7 @@ kiwi.model.Application = function () {
                 if (!channel) return;\r
 \r
                 // If this is us, close the panel\r
-                if (event.nick === kiwi.gateway.get('nick')) {\r
+                if (event.nick === _kiwi.gateway.get('nick')) {\r
                     channel.close();\r
                     return;\r
                 }\r
@@ -305,7 +384,7 @@ kiwi.model.Application = function () {
 \r
                 members.remove(user, part_options);\r
 \r
-                if (event.kicked === kiwi.gateway.get('nick')) {\r
+                if (event.kicked === _kiwi.gateway.get('nick')) {\r
                     members.reset([]);\r
                 }\r
                 \r
@@ -314,13 +393,13 @@ kiwi.model.Application = function () {
 \r
             gw.on('onmsg', function (event) {\r
                 var panel,\r
-                    is_pm = (event.channel == kiwi.gateway.get('nick'));\r
+                    is_pm = (event.channel == _kiwi.gateway.get('nick'));\r
 \r
                 if (is_pm) {\r
                     // If a panel isn't found for this PM, create one\r
                     panel = that.panels.getByName(event.nick);\r
                     if (!panel) {\r
-                        panel = new kiwi.model.Channel({name: event.nick});\r
+                        panel = new _kiwi.model.Query({name: event.nick});\r
                         that.panels.add(panel);\r
                     }\r
 \r
@@ -352,13 +431,13 @@ kiwi.model.Application = function () {
 \r
             gw.on('onaction', function (event) {\r
                 var panel,\r
-                    is_pm = (event.channel == kiwi.gateway.get('nick'));\r
+                    is_pm = (event.channel == _kiwi.gateway.get('nick'));\r
 \r
                 if (is_pm) {\r
                     // If a panel isn't found for this PM, create one\r
                     panel = that.panels.getByName(event.nick);\r
                     if (!panel) {\r
-                        panel = new kiwi.model.Channel({name: event.nick});\r
+                        panel = new _kiwi.model.Channel({name: event.nick});\r
                         that.panels.add(panel);\r
                     }\r
 \r
@@ -384,7 +463,7 @@ kiwi.model.Application = function () {
                 c.set('topic', event.topic);\r
 \r
                 // If this is the active channel, update the topic bar too\r
-                if (c.get('name') === kiwi.app.panels.active.get('name')) {\r
+                if (c.get('name') === _kiwi.app.panels.active.get('name')) {\r
                     that.topicbar.setCurrentTopic(event.topic);\r
                 }\r
             });\r
@@ -409,7 +488,7 @@ kiwi.model.Application = function () {
 \r
                 channel.temp_userlist = channel.temp_userlist || [];\r
                 _.each(event.users, function (item) {\r
-                    var user = new kiwi.model.Member({nick: item.nick, modes: item.modes});\r
+                    var user = new _kiwi.model.Member({nick: item.nick, modes: item.modes});\r
                     channel.temp_userlist.push(user);\r
                 });\r
             });\r
@@ -471,7 +550,7 @@ kiwi.model.Application = function () {
 \r
                 channel = that.panels.getByName(event.target);\r
                 if (channel) {\r
-                    prefixes = kiwi.gateway.get('user_prefixes');\r
+                    prefixes = _kiwi.gateway.get('user_prefixes');\r
                     find_prefix = function (p) {\r
                         return event.modes[i].mode[1] === p.mode;\r
                     };\r
@@ -503,7 +582,7 @@ kiwi.model.Application = function () {
                     channel.addMsg('', '== ' + event.nick + ' sets mode ' + friendlyModeString(), 'action mode');\r
                 } else {\r
                     // This is probably a mode being set on us.\r
-                    if (event.target.toLowerCase() === kiwi.gateway.get("nick").toLowerCase()) {\r
+                    if (event.target.toLowerCase() === _kiwi.gateway.get("nick").toLowerCase()) {\r
                         that.panels.server.addMsg('', '== ' + event.nick + ' set mode ' + friendlyModeString(), 'action mode');\r
                     } else {\r
                        console.log('MODE command recieved for unknown target %s: ', event.target, event);\r
@@ -540,12 +619,12 @@ kiwi.model.Application = function () {
                     idle_time = idle_time.h.toString().lpad(2, "0") + ':' + idle_time.m.toString().lpad(2, "0") + ':' + idle_time.s.toString().lpad(2, "0");\r
                 }\r
 \r
-                panel = kiwi.app.panels.active;\r
+                panel = _kiwi.app.panels.active;\r
                 if (event.ident) {\r
                     panel.addMsg(event.nick, 'is ' + event.nick + '!' + event.ident + '@' + event.host + ' * ' + event.msg, 'whois');\r
                 } else if (event.chans) {\r
                     panel.addMsg(event.nick, 'on ' + event.chans, 'whois');\r
-                } else if (event.server) {\r
+                } else if (event.irc_server) {\r
                     panel.addMsg(event.nick, 'using ' + event.server, 'whois');\r
                 } else if (event.msg) {\r
                     panel.addMsg(event.nick, event.msg, 'whois');\r
@@ -560,88 +639,99 @@ kiwi.model.Application = function () {
                 }\r
             });\r
 \r
+            gw.on('onaway', function (event) {\r
+                $.each(that.panels.models, function (index, panel) {\r
+                    if (!panel.isChannel()) return;\r
+\r
+                    member = panel.get('members').getByNick(event.nick);\r
+                    if (member) {\r
+                        member.set('away', !(!event.trailing));\r
+                    }\r
+                });\r
+            });
+\r
 \r
             gw.on('onlist_start', function (data) {\r
-                if (kiwi.app.channel_list) {\r
-                    kiwi.app.channel_list.close();\r
-                    delete kiwi.app.channel_list;\r
+                if (_kiwi.app.channel_list) {\r
+                    _kiwi.app.channel_list.close();\r
+                    delete _kiwi.app.channel_list;\r
                 }\r
 \r
-                var panel = new kiwi.model.Applet(),\r
-                    applet = new kiwi.applets.Chanlist();\r
+                var panel = new _kiwi.model.Applet(),\r
+                    applet = new _kiwi.applets.Chanlist();\r
 \r
                 panel.load(applet);\r
                 \r
-                kiwi.app.panels.add(panel);\r
+                _kiwi.app.panels.add(panel);\r
                 panel.view.show();\r
                 \r
-                kiwi.app.channel_list = applet;\r
+                _kiwi.app.channel_list = applet;\r
             });\r
 \r
 \r
             gw.on('onlist_channel', function (data) {\r
                 // TODO: Put this listener within the applet itself\r
-                kiwi.app.channel_list.addChannel(data.chans);\r
+                _kiwi.app.channel_list.addChannel(data.chans);\r
             });\r
 \r
 \r
             gw.on('onlist_end', function (data) {\r
                 // TODO: Put this listener within the applet itself\r
-                delete kiwi.app.channel_list;\r
+                delete _kiwi.app.channel_list;\r
             });\r
 \r
 \r
             gw.on('onirc_error', function (data) {\r
                 var panel, tmp;\r
 \r
-                if (data.channel !== undefined && !(panel = kiwi.app.panels.getByName(data.channel))) {\r
-                    panel = kiwi.app.panels.server;\r
+                if (data.channel !== undefined && !(panel = _kiwi.app.panels.getByName(data.channel))) {\r
+                    panel = _kiwi.app.panels.server;\r
                 }\r
 \r
                 switch (data.error) {\r
                 case 'banned_from_channel':\r
                     panel.addMsg(' ', '== You are banned from ' + data.channel + '. ' + data.reason, 'status');\r
-                    kiwi.app.message.text('You are banned from ' + data.channel + '. ' + data.reason);\r
+                    _kiwi.app.message.text('You are banned from ' + data.channel + '. ' + data.reason);\r
                     break;\r
                 case 'bad_channel_key':\r
                     panel.addMsg(' ', '== Bad channel key for ' + data.channel, 'status');\r
-                    kiwi.app.message.text('Bad channel key or password for ' + data.channel);\r
+                    _kiwi.app.message.text('Bad channel key or password for ' + data.channel);\r
                     break;\r
                 case 'invite_only_channel':\r
                     panel.addMsg(' ', '== ' + data.channel + ' is invite only.', 'status');\r
-                    kiwi.app.message.text(data.channel + ' is invite only');\r
+                    _kiwi.app.message.text(data.channel + ' is invite only');\r
                     break;\r
                 case 'channel_is_full':\r
                     panel.addMsg(' ', '== ' + data.channel + ' is full.', 'status');\r
-                    kiwi.app.message.text(data.channel + ' is full');\r
+                    _kiwi.app.message.text(data.channel + ' is full');\r
                     break;\r
                 case 'chanop_privs_needed':\r
                     panel.addMsg(' ', '== ' + data.reason, 'status');\r
-                    kiwi.app.message.text(data.reason + ' (' + data.channel + ')');\r
+                    _kiwi.app.message.text(data.reason + ' (' + data.channel + ')');\r
                     break;\r
                 case 'no_such_nick':\r
-                    tmp = kiwi.app.panels.getByName(data.nick);\r
+                    tmp = _kiwi.app.panels.getByName(data.nick);\r
                     if (tmp) {\r
                         tmp.addMsg(' ', '== ' + data.nick + ': ' + data.reason, 'status');\r
                     } else {\r
-                        kiwi.app.panels.server.addMsg(' ', '== ' + data.nick + ': ' + data.reason, 'status');\r
+                        _kiwi.app.panels.server.addMsg(' ', '== ' + data.nick + ': ' + data.reason, 'status');\r
                     }\r
                     break;\r
                 case 'nickname_in_use':\r
-                    kiwi.app.panels.server.addMsg(' ', '== The nickname ' + data.nick + ' is already in use. Please select a new nickname', 'status');\r
-                    if (kiwi.app.panels.server !== kiwi.app.panels.active) {\r
-                        kiwi.app.message.text('The nickname "' + data.nick + '" is already in use. Please select a new nickname');\r
+                    _kiwi.app.panels.server.addMsg(' ', '== The nickname ' + data.nick + ' is already in use. Please select a new nickname', 'status');\r
+                    if (_kiwi.app.panels.server !== _kiwi.app.panels.active) {\r
+                        _kiwi.app.message.text('The nickname "' + data.nick + '" is already in use. Please select a new nickname');\r
                     }\r
 \r
                     // Only show the nickchange component if the controlbox is open\r
                     if (that.controlbox.$el.css('display') !== 'none') {\r
-                        (new kiwi.view.NickChangeBox()).render();\r
+                        (new _kiwi.view.NickChangeBox()).render();\r
                     }\r
 \r
                     break;\r
                 default:\r
                     // We don't know what data contains, so don't do anything with it.\r
-                    //kiwi.front.tabviews.server.addMsg(null, ' ', '== ' + data, 'status');\r
+                    //_kiwi.front.tabviews.server.addMsg(null, ' ', '== ' + data, 'status');\r
                 }\r
             });\r
         };\r
@@ -667,11 +757,10 @@ kiwi.model.Application = function () {
                 '/dehop': '/quote mode $channel -h $1+',\r
                 '/voice': '/quote mode $channel +v $1+',\r
                 '/devoice': '/quote mode $channel -v $1+',\r
-                '/k': '/kick $1+',\r
+                '/k': '/kick $channel $1+',\r
 \r
                 // Misc aliases\r
-                '/slap': '/me throws the juciest, sweetest kiwi at $1. Hits right in the kisser!',\r
-                '/throw': '/slap $1+'\r
+                '/slap': '/me slaps $1 around a bit with a large trout'\r
             });\r
 \r
             controlbox.on('unknown_command', unknownCommand);\r
@@ -686,7 +775,7 @@ kiwi.model.Application = function () {
             controlbox.on('command_part', partCommand);\r
 \r
             controlbox.on('command_nick', function (ev) {\r
-                kiwi.gateway.changeNick(ev.params[0]);\r
+                _kiwi.gateway.changeNick(ev.params[0]);\r
             });\r
 \r
             controlbox.on('command_query', queryCommand);\r
@@ -712,13 +801,39 @@ kiwi.model.Application = function () {
                 $script(ev.params[0] + '?' + (new Date().getTime()));\r
             });\r
 \r
+            \r
+            controlbox.on('command_set', function (ev) {\r
+                if (!ev.params[0]) return;\r
+\r
+                var setting = ev.params[0],\r
+                    value;\r
+\r
+                // Do we have a second param to set a value?\r
+                if (ev.params[1]) {\r
+                    ev.params.shift();\r
+\r
+                    value = ev.params.join(' ');\r
+                    _kiwi.global.settings.set(setting, value);\r
+                }\r
+\r
+                // Read the value to the user\r
+                _kiwi.app.panels.active.addMsg('', setting + ' = ' + _kiwi.global.settings.get(setting));\r
+            });\r
+\r
+\r
+            controlbox.on('command_save', function (ev) {\r
+                _kiwi.global.settings.save();\r
+                _kiwi.app.panels.active.addMsg('', 'Settings have been saved');\r
+            });\r
+\r
+\r
             controlbox.on('command_alias', function (ev) {\r
                 var name, rule;\r
 \r
                 // No parameters passed so list them\r
                 if (!ev.params[1]) {\r
                     $.each(controlbox.preprocessor.aliases, function (name, rule) {\r
-                        kiwi.app.panels.server.addMsg(' ', name + '   =>   ' + rule);\r
+                        _kiwi.app.panels.server.addMsg(' ', name + '   =>   ' + rule);\r
                     });\r
                     return;\r
                 }\r
@@ -751,7 +866,7 @@ kiwi.model.Application = function () {
         function unknownCommand (ev) {\r
             var raw_cmd = ev.command + ' ' + ev.params.join(' ');\r
             console.log('RAW: ' + raw_cmd);\r
-            kiwi.gateway.raw(raw_cmd);\r
+            _kiwi.gateway.raw(raw_cmd);\r
         }\r
 \r
         function allCommands (ev) {}\r
@@ -768,11 +883,11 @@ kiwi.model.Application = function () {
                 // Check if we have the panel already. If not, create it\r
                 channel = that.panels.getByName(channel_name);\r
                 if (!channel) {\r
-                    channel = new kiwi.model.Channel({name: channel_name});\r
-                    kiwi.app.panels.add(channel);\r
+                    channel = new _kiwi.model.Channel({name: channel_name});\r
+                    _kiwi.app.panels.add(channel);\r
                 }\r
 \r
-                kiwi.gateway.join(channel_name);\r
+                _kiwi.gateway.join(channel_name);\r
             });\r
 \r
             if (channel) channel.view.show();\r
@@ -787,9 +902,8 @@ kiwi.model.Application = function () {
             // Check if we have the panel already. If not, create it\r
             panel = that.panels.getByName(destination);\r
             if (!panel) {\r
-                panel = new kiwi.model.Channel({name: destination});\r
-                panel.set('members', undefined);\r
-                kiwi.app.panels.add(panel);\r
+                panel = new _kiwi.model.Query({name: destination});\r
+                _kiwi.app.panels.add(panel);\r
             }\r
 \r
             if (panel) panel.view.show();\r
@@ -802,30 +916,30 @@ kiwi.model.Application = function () {
 \r
             ev.params.shift();\r
 \r
-            panel.addMsg(kiwi.gateway.get('nick'), ev.params.join(' '));\r
-            kiwi.gateway.privmsg(destination, ev.params.join(' '));\r
+            panel.addMsg(_kiwi.gateway.get('nick'), ev.params.join(' '));\r
+            _kiwi.gateway.privmsg(destination, ev.params.join(' '));\r
         }\r
 \r
         function actionCommand (ev) {\r
-            if (kiwi.app.panels.active === kiwi.app.panels.server) {\r
+            if (_kiwi.app.panels.active === _kiwi.app.panels.server) {\r
                 return;\r
             }\r
 \r
-            var panel = kiwi.app.panels.active;\r
-            panel.addMsg('', '* ' + kiwi.gateway.get('nick') + ' ' + ev.params.join(' '), 'action');\r
-            kiwi.gateway.action(panel.get('name'), ev.params.join(' '));\r
+            var panel = _kiwi.app.panels.active;\r
+            panel.addMsg('', '* ' + _kiwi.gateway.get('nick') + ' ' + ev.params.join(' '), 'action');\r
+            _kiwi.gateway.action(panel.get('name'), ev.params.join(' '));\r
         }\r
 \r
         function partCommand (ev) {\r
             if (ev.params.length === 0) {\r
-                kiwi.gateway.part(kiwi.app.panels.active.get('name'));\r
+                _kiwi.gateway.part(_kiwi.app.panels.active.get('name'));\r
             } else {\r
                 _.each(ev.params, function (channel) {\r
-                    kiwi.gateway.part(channel);\r
+                    _kiwi.gateway.part(channel);\r
                 });\r
             }\r
             // TODO: More responsive = close tab now, more accurate = leave until part event\r
-            //kiwi.app.panels.remove(kiwi.app.panels.active);\r
+            //_kiwi.app.panels.remove(_kiwi.app.panels.active);\r
         }\r
 \r
         function topicCommand (ev) {\r
@@ -837,10 +951,10 @@ kiwi.model.Application = function () {
                 channel_name = ev.params[0];\r
                 ev.params.shift();\r
             } else {\r
-                channel_name = kiwi.app.panels.active.get('name');\r
+                channel_name = _kiwi.app.panels.active.get('name');\r
             }\r
 \r
-            kiwi.gateway.topic(channel_name, ev.params.join(' '));\r
+            _kiwi.gateway.topic(channel_name, ev.params.join(' '));\r
         }\r
 \r
         function noticeCommand (ev) {\r
@@ -852,16 +966,16 @@ kiwi.model.Application = function () {
             destination = ev.params[0];\r
             ev.params.shift();\r
 \r
-            kiwi.gateway.notice(destination, ev.params.join(' '));\r
+            _kiwi.gateway.notice(destination, ev.params.join(' '));\r
         }\r
 \r
         function quoteCommand (ev) {\r
             var raw = ev.params.join(' ');\r
-            kiwi.gateway.raw(raw);\r
+            _kiwi.gateway.raw(raw);\r
         }\r
 \r
         function kickCommand (ev) {\r
-            var nick, panel = kiwi.app.panels.active;\r
+            var nick, panel = _kiwi.app.panels.active;\r
 \r
             if (!panel.isChannel()) return;\r
 \r
@@ -871,36 +985,36 @@ kiwi.model.Application = function () {
             nick = ev.params[0];\r
             ev.params.shift();\r
 \r
-            kiwi.gateway.kick(panel.get('name'), nick, ev.params.join(' '));\r
+            _kiwi.gateway.kick(panel.get('name'), nick, ev.params.join(' '));\r
         }\r
 \r
         function settingsCommand (ev) {\r
-            var panel = new kiwi.model.Applet();\r
-            panel.load(new kiwi.applets.Settings());\r
+            var panel = new _kiwi.model.Applet();\r
+            panel.load(new _kiwi.applets.Settings());\r
             \r
-            kiwi.app.panels.add(panel);\r
+            _kiwi.app.panels.add(panel);\r
             panel.view.show();\r
         }\r
 \r
         function appletCommand (ev) {\r
             if (!ev.params[0]) return;\r
 \r
-            var panel = new kiwi.model.Applet();\r
+            var panel = new _kiwi.model.Applet();\r
 \r
             if (ev.params[1]) {\r
                 // Url and name given\r
                 panel.load(ev.params[0], ev.params[1]);\r
             } else {\r
                 // Load a pre-loaded applet\r
-                if (kiwi.applets[ev.params[0]]) {\r
-                    panel.load(new kiwi.applets[ev.params[0]]());\r
+                if (_kiwi.applets[ev.params[0]]) {\r
+                    panel.load(new _kiwi.applets[ev.params[0]]());\r
                 } else {\r
-                    kiwi.app.panels.server.addMsg('', 'Applet "' + ev.params[0] + '" does not exist');\r
+                    _kiwi.app.panels.server.addMsg('', 'Applet "' + ev.params[0] + '" does not exist');\r
                     return;\r
                 }\r
             }\r
             \r
-            kiwi.app.panels.add(panel);\r
+            _kiwi.app.panels.add(panel);\r
             panel.view.show();\r
         }\r
 \r
@@ -909,7 +1023,7 @@ kiwi.model.Application = function () {
 \r
 \r
         this.isChannelName = function (channel_name) {\r
-            var channel_prefix = kiwi.gateway.get('channel_prefix');\r
+            var channel_prefix = _kiwi.gateway.get('channel_prefix');\r
 \r
             if (!channel_name || !channel_name.length) return false;\r
             return (channel_prefix.indexOf(channel_name[0]) > -1);\r