Skip to content

Instantly share code, notes, and snippets.

@Laurentttrade
Forked from Joseph-N/_message.html.erb
Created February 2, 2016 15:59
Show Gist options
  • Select an option

  • Save Laurentttrade/cc616be44769473675ae to your computer and use it in GitHub Desktop.

Select an option

Save Laurentttrade/cc616be44769473675ae to your computer and use it in GitHub Desktop.

Revisions

  1. @Joseph-N Joseph-N revised this gist Jul 31, 2014. 1 changed file with 21 additions and 8 deletions.
    29 changes: 21 additions & 8 deletions application.html.erb
    Original file line number Diff line number Diff line change
    @@ -1,19 +1,32 @@
    <!DOCTYPE html>
    <html lang="en">

    <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <meta content='<%= user_signed_in? ? current_user.id : "" %>' name='user-id'/>


    <!-- Other markup -->
    <title>Chatty</title>
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
    <%= stylesheet_link_tag '//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
    <%= csrf_meta_tags %>

    <!-- more markup -->
    <body>
    <audio id="chatAudio"><source src="/sounds/notification.mp3" type="audio/mpeg"></audio>
    </body>
    </body>
    <!-- shiv here -->

    </head>

    <body>

    <%= render 'layouts/nav' %>

    <div class="container">
    <!-- flash messages here -->
    <%= yield %>
    </div>
    <audio id="chatAudio"><source src="/sounds/notification.mp3" type="audio/mpeg"></audio>
    </body>

    </html>
  2. @Joseph-N Joseph-N revised this gist Jul 30, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion chat.css
    Original file line number Diff line number Diff line change
    @@ -123,7 +123,7 @@
    }

    .chatboxmessagecontent time {
    font-size: 0.7rem;
    font-size: 9px;
    color: #ccc;
    }

  3. @Joseph-N Joseph-N revised this gist Jul 30, 2014. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions application.html.erb
    Original file line number Diff line number Diff line change
    @@ -11,5 +11,9 @@
    <%= csrf_meta_tags %>

    <!-- more markup -->
    <body>
    <audio id="chatAudio"><source src="/sounds/notification.mp3" type="audio/mpeg"></audio>
    </body>
    </body>

    </html>
  4. @Joseph-N Joseph-N revised this gist Jul 30, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion chat.css
    Original file line number Diff line number Diff line change
    @@ -110,7 +110,7 @@
    }

    .chatboxmessagecontent p {
    font-size: 0.8rem;
    font-size: 12px;
    margin: 0 0 0.2rem 0;
    -ms-word-break: break-all;

  5. @Joseph-N Joseph-N revised this gist Jul 30, 2014. 1 changed file with 15 additions and 0 deletions.
    15 changes: 15 additions & 0 deletions application.html.erb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,15 @@
    <!DOCTYPE html>
    <html lang="en">

    <head>


    <!-- Other markup -->
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
    <%= stylesheet_link_tag '//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
    <%= csrf_meta_tags %>

    <!-- more markup -->

    </html>
  6. @Joseph-N Joseph-N revised this gist Jul 30, 2014. 2 changed files with 8 additions and 17 deletions.
    2 changes: 0 additions & 2 deletions routes.rb
    Original file line number Diff line number Diff line change
    @@ -15,6 +15,4 @@
    resources :conversations do
    resources :messages
    end


    end
    23 changes: 8 additions & 15 deletions users.js
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    var ready = function(){
    var ready = function () {

    /**
    * When the send message link on our home page is clicked
    @@ -12,35 +12,30 @@ var ready = function(){
    var sender_id = $(this).data('sid');
    var recipient_id = $(this).data('rip');


    $.post( "/conversations", { sender_id: sender_id, recipient_id: recipient_id }, function(data){
    $.post("/conversations", { sender_id: sender_id, recipient_id: recipient_id }, function (data) {
    chatBox.chatWith(data.conversation_id);
    } );


    });
    });

    /**
    * Used to minimize the chatbox
    */

    $(document).on('click','.toggleChatBox', function(e){
    $(document).on('click', '.toggleChatBox', function (e) {
    e.preventDefault();

    var id = $(this).data('cid');

    chatBox.toggleChatBoxGrowth(id);
    });

    /**
    * Used to close the chatbox
    */

    $(document).on('click','.closeChat', function(e){
    $(document).on('click', '.closeChat', function (e) {
    e.preventDefault();

    var id = $(this).data('cid');

    chatBox.close(id);
    });

    @@ -50,10 +45,9 @@ var ready = function(){
    * chatInputKey in chat.js for inspection
    */

    $(document).on('keydown', '.chatboxtextarea', function(event){
    $(document).on('keydown', '.chatboxtextarea', function (event) {

    var id = $(this).data('cid');

    chatBox.checkInputKey(event, $(this), id);
    });

    @@ -62,16 +56,15 @@ var ready = function(){
    * conversation chatbox
    */

    $('a.conversation').click(function(e){
    $('a.conversation').click(function (e) {
    e.preventDefault();

    var conversation_id = $(this).data('cid');

    chatBox.chatWith(conversation_id);
    });


    }

    $(document).ready(ready);
    $(document).on("page:load",ready);
    $(document).on("page:load", ready);
  7. @Joseph-N Joseph-N revised this gist Jul 30, 2014. 2 changed files with 2 additions and 2 deletions.
    2 changes: 1 addition & 1 deletion chat.css
    Original file line number Diff line number Diff line change
    @@ -36,7 +36,7 @@
    .chatboxcontent {
    font-family: arial, sans-serif;
    height: 280px;
    width: 264px;
    width: 280px;
    overflow-y: auto;
    padding: 7px;
    border-left: 1px solid #cccccc;
    2 changes: 1 addition & 1 deletion conversations_controller.rb
    Original file line number Diff line number Diff line change
    @@ -15,7 +15,7 @@ def create

    def show
    @conversation = Conversation.find(params[:id])
    @reciever = interlocutor(@conversation).name
    @reciever = interlocutor(@conversation)
    @messages = @conversation.messages
    @message = Message.new
    end
  8. @Joseph-N Joseph-N revised this gist Jul 30, 2014. 1 changed file with 175 additions and 0 deletions.
    175 changes: 175 additions & 0 deletions chat.css
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,175 @@
    /**
    * GMAIL Like chat css
    * CREDITS: http://css-tricks.com/replicating-google-hangouts-chat/
    *
    */

    .chatbox {
    position: fixed;
    position: expression("absolute");
    width: 280px;
    display: none;
    }

    .chatboxhead {
    background: #666;
    color: white;
    padding: 0.5rem;
    overflow: hidden;

    border-right: 1px solid rgba(85, 85, 85, 0.87);
    border-left: 1px solid rgba(85, 85, 85, 0.87);
    }

    .chatboxhead h1 {
    display: inline;
    font-size: 17px;
    font-weight: 700;
    }

    .chatboxblink {
    background-color: #176689;
    border-right: 1px solid #176689;
    border-left: 1px solid #176689;
    }

    .chatboxcontent {
    font-family: arial, sans-serif;
    height: 280px;
    width: 264px;
    overflow-y: auto;
    padding: 7px;
    border-left: 1px solid #cccccc;
    border-right: 1px solid #cccccc;
    border-bottom: 1px solid #eeeeee;
    background: #e5e5e5;
    line-height: 1.3em;
    list-style: none;
    }

    .chatboxcontent li {
    padding: 0.5rem;
    overflow: hidden;
    display: flex;
    }

    .chatboxcontent .avatar {
    width: 40px;
    position: relative;
    }

    .chatboxcontent .avatar img {
    display: block;
    width: 100%;
    }

    .other .avatar:after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    width: 0;
    height: 0;
    border: 5px solid white;
    border-left-color: transparent;
    border-bottom-color: transparent;
    }

    .self {
    justify-content: flex-end;
    align-items: flex-end;
    }

    .self .chatboxmessagecontent {
    order: 1;
    border-bottom-right-radius: 0;
    }

    .self .avatar {
    order: 2;
    }

    .self .avatar:after {
    content: "";
    position: absolute;
    bottom: 0;
    left: 0;
    width: 0;
    height: 0;
    border: 5px solid white;
    border-right-color: transparent;
    border-top-color: transparent;
    box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
    }

    .chatboxmessagecontent {
    background: white;
    padding: 10px;
    border-radius: 2px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
    }

    .chatboxmessagecontent p {
    font-size: 0.8rem;
    margin: 0 0 0.2rem 0;
    -ms-word-break: break-all;

    /* Non standard for webkit */
    word-break: break-word;

    -webkit-hyphens: auto;
    -moz-hyphens: auto;
    hyphens: auto;
    }

    .chatboxmessagecontent time {
    font-size: 0.7rem;
    color: #ccc;
    }

    .chatboxinput {
    padding: 5px;
    background-color: #ffffff;
    border-left: 1px solid #cccccc;
    border-right: 1px solid #cccccc;
    border-bottom: 1px solid #cccccc;
    }

    .chatboxtextarea {
    width: 262px;
    height: 44px;
    padding: 3px 0pt 3px 3px;
    border: 1px solid #eeeeee;
    margin: 1px;
    overflow: hidden;
    resize: none !important;
    }

    .chatboxtextareaselected {
    border: 2px solid #878787;
    margin: 0;
    }

    .chatboxmessage {
    margin-left: 1em;
    }

    .chatboxinfo {
    margin-left: -1em;
    color: #666666;

    }

    .chatboxoptions {
    float: right;
    }

    .chatboxoptions a {
    text-decoration: none;
    color: white;
    font-weight: bold;
    }

    .chatboxtitle {
    float: left;
    }
  9. @Joseph-N Joseph-N revised this gist Jul 30, 2014. 2 changed files with 21 additions and 0 deletions.
    1 change: 1 addition & 0 deletions meta.html.erb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    <meta content='<%= user_signed_in? ? current_user.id : "" %>' name='user-id'/>
    20 changes: 20 additions & 0 deletions routes.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,20 @@
    Rails.application.routes.draw do

    devise_for :users

    authenticated :user do
    root 'users#index'
    end

    unauthenticated :user do
    devise_scope :user do
    get "/" => "devise/sessions#new"
    end
    end

    resources :conversations do
    resources :messages
    end


    end
  10. @Joseph-N Joseph-N revised this gist Jul 30, 2014. 7 changed files with 188 additions and 0 deletions.
    11 changes: 11 additions & 0 deletions _message.html.erb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,11 @@
    <li class="<%= self_or_other(message) %>">
    <div class="avatar">
    <img src="http://placehold.it/50x50" />
    </div>
    <div class="chatboxmessagecontent">
    <p><%= message.body %></p>
    <time datetime="<%= message.created_at %>" title="<%= message.created_at.strftime("%d %b %Y at %I:%M%p") %>">
    <%= message_interlocutor(message).name %><%= message.created_at.strftime("%H:%M %p") %>
    </time>
    </div>
    </li>
    31 changes: 31 additions & 0 deletions conversations_controller.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,31 @@
    class ConversationsController < ApplicationController
    before_filter :authenticate_user!

    layout false

    def create
    if Conversation.between(params[:sender_id],params[:recipient_id]).present?
    @conversation = Conversation.between(params[:sender_id],params[:recipient_id]).first
    else
    @conversation = Conversation.create!(conversation_params)
    end

    render json: { conversation_id: @conversation.id }
    end

    def show
    @conversation = Conversation.find(params[:id])
    @reciever = interlocutor(@conversation).name
    @messages = @conversation.messages
    @message = Message.new
    end

    private
    def conversation_params
    params.permit(:sender_id, :recipient_id)
    end

    def interlocutor(conversation)
    current_user == conversation.recipient ? conversation.sender : conversation.recipient
    end
    end
    16 changes: 16 additions & 0 deletions create.js.erb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,16 @@
    <% publish_to @path do %>
    var id = "<%= @conversation.id %>";
    var chatbox = $("#chatbox_" + id + " .chatboxcontent");
    var sender_id = "<%= @message.user.id %>";
    var reciever_id = $('meta[name=user-id]').attr("content");

    chatbox.append("<%= j render( partial: @message ) %>");
    chatbox.scrollTop(chatbox[0].scrollHeight);

    if(sender_id != reciever_id){
    chatBox.chatWith(id);
    chatbox.children().last().removeClass("self").addClass("other");
    chatbox.scrollTop(chatbox[0].scrollHeight);
    chatBox.notify();
    }
    <% end %>
    18 changes: 18 additions & 0 deletions messages_controller.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,18 @@
    class MessagesController < ApplicationController
    before_filter :authenticate_user!

    def create
    @conversation = Conversation.find(params[:conversation_id])
    @message = @conversation.messages.build(message_params)
    @message.user_id = current_user.id
    @message.save!

    @path = conversation_path(@conversation)
    end

    private

    def message_params
    params.require(:message).permit(:body)
    end
    end
    10 changes: 10 additions & 0 deletions messages_helper.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,10 @@
    module MessagesHelper
    def self_or_other(message)
    message.user == current_user ? "self" : "other"
    end

    def message_interlocutor(message)
    message.user == message.conversation.sender ? message.conversation.sender : message.conversation.recipient
    end
    end

    25 changes: 25 additions & 0 deletions show.html.erb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,25 @@
    <div class="chatboxhead">
    <div class="chatboxtitle">
    <i class="fa fa-comments"></i>

    <h1><%= @reciever.name %> </h1>
    </div>
    <div class="chatboxoptions">
    <%= link_to "<i class='fa fa-minus'></i> ".html_safe, "#", class: "toggleChatBox", "data-cid" => @conversation.id %>
    &nbsp;&nbsp;
    <%= link_to "<i class='fa fa-times'></i> ".html_safe, "#", class: "closeChat", "data-cid" => @conversation.id %>
    </div>
    <br clear="all"/>
    </div>
    <div class="chatboxcontent">
    <% if @messages.any? %>
    <%= render @messages %>
    <% end %>
    </div>
    <div class="chatboxinput">
    <%= form_for([@conversation, @message], :remote => true, :html => {id: "conversation_form_#{@conversation.id}"}) do |f| %>
    <%= f.text_area :body, class: "chatboxtextarea", "data-cid" => @conversation.id %>
    <% end %>
    </div>

    <%= subscribe_to conversation_path(@conversation) %>
    77 changes: 77 additions & 0 deletions users.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,77 @@
    var ready = function(){

    /**
    * When the send message link on our home page is clicked
    * send an ajax request to our rails app with the sender_id and
    * recipient_id
    */

    $('.start-conversation').click(function (e) {
    e.preventDefault();

    var sender_id = $(this).data('sid');
    var recipient_id = $(this).data('rip');


    $.post( "/conversations", { sender_id: sender_id, recipient_id: recipient_id }, function(data){
    chatBox.chatWith(data.conversation_id);
    } );


    });

    /**
    * Used to minimize the chatbox
    */

    $(document).on('click','.toggleChatBox', function(e){
    e.preventDefault();

    var id = $(this).data('cid');

    chatBox.toggleChatBoxGrowth(id);
    });

    /**
    * Used to close the chatbox
    */

    $(document).on('click','.closeChat', function(e){
    e.preventDefault();

    var id = $(this).data('cid');

    chatBox.close(id);
    });


    /**
    * Listen on keypress' in our chat textarea and call the
    * chatInputKey in chat.js for inspection
    */

    $(document).on('keydown', '.chatboxtextarea', function(event){

    var id = $(this).data('cid');

    chatBox.checkInputKey(event, $(this), id);
    });

    /**
    * When a conversation link is clicked show up the respective
    * conversation chatbox
    */

    $('a.conversation').click(function(e){
    e.preventDefault();

    var conversation_id = $(this).data('cid');

    chatBox.chatWith(conversation_id);
    });


    }

    $(document).ready(ready);
    $(document).on("page:load",ready);
  11. @Joseph-N Joseph-N revised this gist Jul 30, 2014. 1 changed file with 1 addition and 2 deletions.
    3 changes: 1 addition & 2 deletions chat.js
    Original file line number Diff line number Diff line change
    @@ -200,8 +200,7 @@ var ready = function () {
    },

    /**
    * Responsible for handling the growth of chatboxes as they increase on the page
    * Keeps track of the minimized chatboxes etc
    * Responsible for handling minimize and maximize of the chatbox
    *
    * @param conversation_id
    */
  12. @Joseph-N Joseph-N revised this gist Jul 30, 2014. 3 changed files with 326 additions and 0 deletions.
    310 changes: 310 additions & 0 deletions chat.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,310 @@
    /**
    * 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 the growth of chatboxes as they increase on the page
    * Keeps track of the minimized chatboxes etc
    *
    * @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);
    6 changes: 6 additions & 0 deletions message.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,6 @@
    class Message < ActiveRecord::Base
    belongs_to :conversation
    belongs_to :user

    validates_presence_of :body, :conversation_id, :user_id
    end
    10 changes: 10 additions & 0 deletions user.html.erb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,10 @@
    <% @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 %>
  13. @Joseph-N Joseph-N revised this gist Jul 30, 2014. 2 changed files with 23 additions and 0 deletions.
    16 changes: 16 additions & 0 deletions conversation.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,16 @@
    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
    7 changes: 7 additions & 0 deletions user.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    class User < ActiveRecord::Base

    devise :database_authenticatable, :registerable,
    :recoverable, :rememberable, :trackable, :validatable

    has_many :conversations, :foreign_key => :sender_id
    end
  14. @Joseph-N Joseph-N created this gist Jul 30, 2014.
    13 changes: 13 additions & 0 deletions create_conversations.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,13 @@
    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