-
-
Save Laurentttrade/cc616be44769473675ae to your computer and use it in GitHub Desktop.
Tutorial code snippets for chat application in rails. Tutorial link http://goo.gl/l3e8zN
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Chat logic | |
| * | |
| * Most of the js functionality is inspired from anatgarg.com | |
| * jQuery tag Module from the tutorial | |
| * http://anantgarg.com/2009/05/13/gmail-facebook-style-jquery-chat/ | |
| * | |
| */ | |
| var chatboxFocus = new Array(); | |
| var chatBoxes = new Array(); | |
| var ready = function () { | |
| chatBox = { | |
| /** | |
| * creates an inline chatbox on the page by calling the | |
| * createChatBox function passing along the unique conversation_id | |
| * | |
| * @param conversation_id | |
| */ | |
| chatWith: function (conversation_id) { | |
| chatBox.createChatBox(conversation_id); | |
| $("#chatbox_" + conversation_id + " .chatboxtextarea").focus(); | |
| }, | |
| /** | |
| * closes the chatbox by essentially hiding it from the page | |
| * | |
| * @param conversation_id | |
| */ | |
| close: function (conversation_id) { | |
| $('#chatbox_' + conversation_id).css('display', 'none'); | |
| chatBox.restructure(); | |
| }, | |
| /** | |
| * Plays a notification sound when a new chat message arrives | |
| */ | |
| notify: function () { | |
| var audioplayer = $('#chatAudio')[0]; | |
| audioplayer.play(); | |
| }, | |
| /** | |
| * Handles 'smart layouts' of the chatboxes. Like when new chatboxes are | |
| * added or removed from the view, it restructures them so that they appear | |
| * neatly aligned on the page | |
| */ | |
| restructure: function () { | |
| align = 0; | |
| for (x in chatBoxes) { | |
| chatbox_id = chatBoxes[x]; | |
| if ($("#chatbox_" + chatbox_id).css('display') != 'none') { | |
| if (align == 0) { | |
| $("#chatbox_" + chatbox_id).css('right', '20px'); | |
| } else { | |
| width = (align) * (280 + 7) + 20; | |
| $("#chatbox_" + chatbox_id).css('right', width + 'px'); | |
| } | |
| align++; | |
| } | |
| } | |
| }, | |
| /** | |
| * Takes in two parameters. It is responsible for fetching the specific conversation's | |
| * html page and appending it to the body of our home page e.g if conversation_id = 1 | |
| * | |
| * $.get("conversations/1, function(data){ | |
| * // rest of the logic here | |
| * }, "html") | |
| * | |
| * @param conversation_id | |
| * @param minimizeChatBox | |
| */ | |
| createChatBox: function (conversation_id, minimizeChatBox) { | |
| if ($("#chatbox_" + conversation_id).length > 0) { | |
| if ($("#chatbox_" + conversation_id).css('display') == 'none') { | |
| $("#chatbox_" + conversation_id).css('display', 'block'); | |
| chatBox.restructure(); | |
| } | |
| $("#chatbox_" + conversation_id + " .chatboxtextarea").focus(); | |
| return; | |
| } | |
| $("body").append('<div id="chatbox_' + conversation_id + '" class="chatbox"></div>') | |
| $.get("conversations/" + conversation_id, function (data) { | |
| $('#chatbox_' + conversation_id).html(data); | |
| $("#chatbox_" + conversation_id + " .chatboxcontent").scrollTop($("#chatbox_" + conversation_id + " .chatboxcontent")[0].scrollHeight); | |
| }, "html"); | |
| $("#chatbox_" + conversation_id).css('bottom', '0px'); | |
| chatBoxeslength = 0; | |
| for (x in chatBoxes) { | |
| if ($("#chatbox_" + chatBoxes[x]).css('display') != 'none') { | |
| chatBoxeslength++; | |
| } | |
| } | |
| if (chatBoxeslength == 0) { | |
| $("#chatbox_" + conversation_id).css('right', '20px'); | |
| } else { | |
| width = (chatBoxeslength) * (280 + 7) + 20; | |
| $("#chatbox_" + conversation_id).css('right', width + 'px'); | |
| } | |
| chatBoxes.push(conversation_id); | |
| if (minimizeChatBox == 1) { | |
| minimizedChatBoxes = new Array(); | |
| if ($.cookie('chatbox_minimized')) { | |
| minimizedChatBoxes = $.cookie('chatbox_minimized').split(/\|/); | |
| } | |
| minimize = 0; | |
| for (j = 0; j < minimizedChatBoxes.length; j++) { | |
| if (minimizedChatBoxes[j] == conversation_id) { | |
| minimize = 1; | |
| } | |
| } | |
| if (minimize == 1) { | |
| $('#chatbox_' + conversation_id + ' .chatboxcontent').css('display', 'none'); | |
| $('#chatbox_' + conversation_id + ' .chatboxinput').css('display', 'none'); | |
| } | |
| } | |
| chatboxFocus[conversation_id] = false; | |
| $("#chatbox_" + conversation_id + " .chatboxtextarea").blur(function () { | |
| chatboxFocus[conversation_id] = false; | |
| $("#chatbox_" + conversation_id + " .chatboxtextarea").removeClass('chatboxtextareaselected'); | |
| }).focus(function () { | |
| chatboxFocus[conversation_id] = true; | |
| $('#chatbox_' + conversation_id + ' .chatboxhead').removeClass('chatboxblink'); | |
| $("#chatbox_" + conversation_id + " .chatboxtextarea").addClass('chatboxtextareaselected'); | |
| }); | |
| $("#chatbox_" + conversation_id).click(function () { | |
| if ($('#chatbox_' + conversation_id + ' .chatboxcontent').css('display') != 'none') { | |
| $("#chatbox_" + conversation_id + " .chatboxtextarea").focus(); | |
| } | |
| }); | |
| $("#chatbox_" + conversation_id).show(); | |
| }, | |
| /** | |
| * Responsible for listening to the keypresses when chatting. If the Enter button is pressed, | |
| * we submit our conversation form to our rails app | |
| * | |
| * @param event | |
| * @param chatboxtextarea | |
| * @param conversation_id | |
| */ | |
| checkInputKey: function (event, chatboxtextarea, conversation_id) { | |
| if (event.keyCode == 13 && event.shiftKey == 0) { | |
| event.preventDefault(); | |
| message = chatboxtextarea.val(); | |
| message = message.replace(/^\s+|\s+$/g, ""); | |
| if (message != '') { | |
| $('#conversation_form_' + conversation_id).submit(); | |
| $(chatboxtextarea).val(''); | |
| $(chatboxtextarea).focus(); | |
| $(chatboxtextarea).css('height', '44px'); | |
| } | |
| } | |
| var adjustedHeight = chatboxtextarea.clientHeight; | |
| var maxHeight = 94; | |
| if (maxHeight > adjustedHeight) { | |
| adjustedHeight = Math.max(chatboxtextarea.scrollHeight, adjustedHeight); | |
| if (maxHeight) | |
| adjustedHeight = Math.min(maxHeight, adjustedHeight); | |
| if (adjustedHeight > chatboxtextarea.clientHeight) | |
| $(chatboxtextarea).css('height', adjustedHeight + 8 + 'px'); | |
| } else { | |
| $(chatboxtextarea).css('overflow', 'auto'); | |
| } | |
| }, | |
| /** | |
| * Responsible for handling minimize and maximize of the chatbox | |
| * | |
| * @param conversation_id | |
| */ | |
| toggleChatBoxGrowth: function (conversation_id) { | |
| if ($('#chatbox_' + conversation_id + ' .chatboxcontent').css('display') == 'none') { | |
| var minimizedChatBoxes = new Array(); | |
| if ($.cookie('chatbox_minimized')) { | |
| minimizedChatBoxes = $.cookie('chatbox_minimized').split(/\|/); | |
| } | |
| var newCookie = ''; | |
| for (i = 0; i < minimizedChatBoxes.length; i++) { | |
| if (minimizedChatBoxes[i] != conversation_id) { | |
| newCookie += conversation_id + '|'; | |
| } | |
| } | |
| newCookie = newCookie.slice(0, -1) | |
| $.cookie('chatbox_minimized', newCookie); | |
| $('#chatbox_' + conversation_id + ' .chatboxcontent').css('display', 'block'); | |
| $('#chatbox_' + conversation_id + ' .chatboxinput').css('display', 'block'); | |
| $("#chatbox_" + conversation_id + " .chatboxcontent").scrollTop($("#chatbox_" + conversation_id + " .chatboxcontent")[0].scrollHeight); | |
| } else { | |
| var newCookie = conversation_id; | |
| if ($.cookie('chatbox_minimized')) { | |
| newCookie += '|' + $.cookie('chatbox_minimized'); | |
| } | |
| $.cookie('chatbox_minimized', newCookie); | |
| $('#chatbox_' + conversation_id + ' .chatboxcontent').css('display', 'none'); | |
| $('#chatbox_' + conversation_id + ' .chatboxinput').css('display', 'none'); | |
| } | |
| } | |
| } | |
| /** | |
| * Cookie plugin | |
| * | |
| * Copyright (c) 2006 Klaus Hartl (stilbuero.de) | |
| * Dual licensed under the MIT and GPL licenses: | |
| * http://www.opensource.org/licenses/mit-license.php | |
| * http://www.gnu.org/licenses/gpl.html | |
| * | |
| */ | |
| jQuery.cookie = function (name, value, options) { | |
| if (typeof value != 'undefined') { // name and value given, set cookie | |
| options = options || {}; | |
| if (value === null) { | |
| value = ''; | |
| options.expires = -1; | |
| } | |
| var expires = ''; | |
| if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) { | |
| var date; | |
| if (typeof options.expires == 'number') { | |
| date = new Date(); | |
| date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); | |
| } else { | |
| date = options.expires; | |
| } | |
| expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE | |
| } | |
| // CAUTION: Needed to parenthesize options.path and options.domain | |
| // in the following expressions, otherwise they evaluate to undefined | |
| // in the packed version for some reason... | |
| var path = options.path ? '; path=' + (options.path) : ''; | |
| var domain = options.domain ? '; domain=' + (options.domain) : ''; | |
| var secure = options.secure ? '; secure' : ''; | |
| document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join(''); | |
| } else { // only name given, get cookie | |
| var cookieValue = null; | |
| if (document.cookie && document.cookie != '') { | |
| var cookies = document.cookie.split(';'); | |
| for (var i = 0; i < cookies.length; i++) { | |
| var cookie = jQuery.trim(cookies[i]); | |
| // Does this cookie string begin with the name we want? | |
| if (cookie.substring(0, name.length + 1) == (name + '=')) { | |
| cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); | |
| break; | |
| } | |
| } | |
| } | |
| return cookieValue; | |
| } | |
| }; | |
| } | |
| $(document).ready(ready); | |
| $(document).on("page:load", ready); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class Conversation < ActiveRecord::Base | |
| belongs_to :sender, :foreign_key => :sender_id, class_name: 'User' | |
| belongs_to :recipient, :foreign_key => :recipient_id, class_name: 'User' | |
| has_many :messages, dependent: :destroy | |
| validates_uniqueness_of :sender_id, :scope => :recipient_id | |
| scope :involving, -> (user) do | |
| where("conversations.sender_id =? OR conversations.recipient_id =?",user.id,user.id) | |
| end | |
| scope :between, -> (sender_id,recipient_id) do | |
| where("(conversations.sender_id = ? AND conversations.recipient_id =?) OR (conversations.sender_id = ? AND conversations.recipient_id =?)", sender_id,recipient_id, recipient_id, sender_id) | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class CreateConversations < ActiveRecord::Migration | |
| def change | |
| create_table :conversations do |t| | |
| t.integer :sender_id | |
| t.integer :recipient_id | |
| t.timestamps | |
| end | |
| add_index :conversations, :sender_id | |
| add_index :conversations, :recipient_id | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class Message < ActiveRecord::Base | |
| belongs_to :conversation | |
| belongs_to :user | |
| validates_presence_of :body, :conversation_id, :user_id | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <% @users.each_with_index do |user, index| %> | |
| <tr> | |
| <td><%= index +=1 %></td> | |
| <td><%= user.name %></td> | |
| <td> | |
| <%= link_to "Send Message", "#", class: "btn btn-success btn-xs start-conversation", | |
| "data-sid" => current_user.id, "data-rip" => user.id %> | |
| </td> | |
| </tr> | |
| <% end %> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class User < ActiveRecord::Base | |
| devise :database_authenticatable, :registerable, | |
| :recoverable, :rememberable, :trackable, :validatable | |
| has_many :conversations, :foreign_key => :sender_id | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment