diff --git a/README.md b/README.md index 7b4266c..c3be0e1 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ This is the official plugin repository for [Candy](http://candy-chat.github.com/ * __Inline Videos__ - If a user posts a URL to youtube video, it embeds the youtube video iframe into Candy. * __join__ A plugin that allows to type `/join room [password]` to join a room. * __jQuery-Ui__ - jQuery UI lightness theme +* __Keyboard Shortcuts__ - Gives the user keyboard shortcuts to navigate Candy with. * __Left Tabs__ - Moves the tabs to the left side and uses a bit of Bootstrap3-friendly theme elements. * __Modify Role__ - Adds **add moderator** and **remove moderator** context menu links. * __Namecomplete__ - Autocompletes names of users within room diff --git a/keyboardshortcuts/LICENSE b/keyboardshortcuts/LICENSE new file mode 100644 index 0000000..c8d3f9e --- /dev/null +++ b/keyboardshortcuts/LICENSE @@ -0,0 +1,20 @@ +Copyright (C) 2014 Mojo Lingo LLC + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/keyboardshortcuts/README.md b/keyboardshortcuts/README.md new file mode 100644 index 0000000..5a74745 --- /dev/null +++ b/keyboardshortcuts/README.md @@ -0,0 +1,32 @@ +# Keyboard Shortcuts + +A plugin for Candy Chat to allow keyboard shortcuts for interacting with Candy. + +## Usage + +Include the JavaScript file: + +```HTML + +``` + +To enable this plugin, add its `init` method after you `init` Candy, but before `Candy.connect()`: + +```JavaScript +CandyShop.KeyboardShortcuts.init(); +``` + +You could also pass in your own keyboard shortcuts: + +```JavaScript +var options = { + uniqueShortcutName: { + altKey: (boolean), + ctrlKey: (boolean), + shiftKey: (boolean), + keyCode: (integer) + } +} +``` + +The plugin will then match the name of the `uniqueShortcutName` provided as the key to an identically named function inside itself, so you'll need to add a matching function inside the plugin itself. diff --git a/keyboardshortcuts/keyboardshortcuts.js b/keyboardshortcuts/keyboardshortcuts.js new file mode 100644 index 0000000..3783a88 --- /dev/null +++ b/keyboardshortcuts/keyboardshortcuts.js @@ -0,0 +1,178 @@ +/** File: keyboardshortcuts.js + * Candy Plugin Keyboard Shortcuts + * Author: Melissa Adamaitis + */ + +var CandyShop = (function(self) { return self; }(CandyShop || {})); + +CandyShop.KeyboardShortcuts = (function(self, Candy, $) { + var _options = { + joinNewRoom: { + altKey: true, + ctrlKey: false, + shiftKey: false, + keyCode: 78 // 'n' + }, + toggleSound: { + altKey: true, + ctrlKey: false, + shiftKey: false, + keyCode: 83 // 's' + }, + changeTopic: { + altKey: true, + ctrlKey: false, + shiftKey: false, + keyCode: 84 // 't' + }, + closeCurrentTab: { + altKey: true, + ctrlKey: false, + shiftKey: false, + keyCode: 87 // 'w' + }, + nextTab: { + altKey: true, + ctrlKey: false, + shiftKey: false, + keyCode: 40 // down arrow + }, + previousTab: { + altKey: true, + ctrlKey: false, + shiftKey: false, + keyCode: 38 // up arrow + }, + helpScreen: { + altKey: true, + ctrlKey: false, + shiftKey: false, + keyCode: 191 // '/' + } + }; + + /** Object: about + * + * Contains: + * (String) name - Candy Plugin Keyboard Shortcuts + * (Float) version - Candy Plugin Keyboard Shortcuts + */ + self.about = { + name: 'Candy Plugin Keyboard Shortcuts', + version: '1.0' + }; + + /** + * Initializes the KeyboardShortcuts plugin with the default settings. + */ + self.init = function(options){ + // apply the supplied options to the defaults specified + $.extend(true, _options, options); + + $(window).keydown(function(ev) { + var keystrokes = { + altKey: ev.altKey, + ctrlKey: ev.ctrlKey, + shiftKey: ev.shiftKey, + keyCode: ev.keyCode + }; + for (var option in _options) { + if (self.isEquivalent(_options[option], keystrokes)) { + window['CandyShop']['KeyboardShortcuts'][option](); + ev.preventDefault(); + } + } + }); + }; + + self.closeCurrentTab = function() { + Candy.View.Pane.Room.close(Candy.View.getCurrent().roomJid); + }; + + self.joinNewRoom = function() { + CandyShop.CreateRoom.showModal(); + }; + + self.toggleSound = function() { + Candy.View.Pane.Chat.Toolbar.onSoundControlClick(); + }; + + self.changeTopic = function() { + var currentJid = Candy.View.getCurrent().roomJid, + element = Candy.View.Pane.Room.getPane(Candy.View.getCurrent().roomJid), + currentTopic = element.find('.roombar .topic').html(); + CandyShop.RoomBar.updateRoomTopic(currentJid, $(element).attr('id'), currentTopic); + }; + + self.nextTab = function() { + this.showPane('+1'); + }; + + self.previousTab = function() { + this.showPane('-1'); + }; + + self.helpScreen = function() { + var html = "

Keyboard Shortcuts

"; + Candy.View.Pane.Chat.Modal.show(html, true, false); + }; + + // Used to find and show room pane relative to current. + self.showPane = function(number) { + var rooms = Candy.Core.getRooms(), + room_names = Object.keys(rooms); + + // Push the lobby to the front of the room_names. + room_names.unshift(CandyShop.StaticLobby.getLobbyFakeJid()); + + var currentIndex = room_names.indexOf(Candy.View.getCurrent().roomJid), + newIndex = currentIndex; + + if (number === '+1') { + if ((currentIndex + 1) < room_names.length) { + newIndex = currentIndex + 1; + } else { + newIndex = 0; + } + } else if (number === '-1') { + if ((currentIndex - 1) >= 0) { + newIndex = currentIndex - 1; + } else { + newIndex = room_names.length - 1; + } + } else { + newIndex = number; + } + + Candy.View.Pane.Room.show(room_names[newIndex]); + }; + + // Used to help JavaScript determine if two objects are identical. + self.isEquivalent = function(a, b) { + // Create arrays of property names + var aProps = Object.getOwnPropertyNames(a), + bProps = Object.getOwnPropertyNames(b); + + // If number of properties is different, objects are not equivalent + if (aProps.length !== bProps.length) { + return false; + } + + for (var i = 0; i < aProps.length; i++) { + var propName = aProps[i]; + + // If values of same property are not equal, objects are not equivalent + if (a[propName] !== b[propName]) { + return false; + } + } + + // If we made it this far, objects are considered equivalent + return true; + }; + + return self; +}(CandyShop.KeyboardShortcuts || {}, Candy, jQuery));