فهرست منبع

Add message dropdown to navigation bar

Frans Bergman 7 سال پیش
والد
کامیت
ac310ccff3

+ 3 - 0
app/controllers/conversations_controller.rb

@@ -10,6 +10,9 @@ class ConversationsController < ApplicationController
   end
 
   def show
+    ConversationParticipation
+      .where(user: current_user, conversation: @conversation)
+      .update_all(viewed_at: Time.now)
   end
 
   def new

+ 9 - 0
app/helpers/messages_helper.rb

@@ -1,2 +1,11 @@
 module MessagesHelper
+  def unread_messages_count(user)
+    counter = 0
+    for conversation_participation in user.conversation_participations
+      counter += conversation_participation.conversation.messages.select do |message|
+        message.created_at > conversation_participation.viewed_at
+      end.count
+    end
+    counter
+  end
 end

+ 6 - 0
app/models/conversation_participation.rb

@@ -3,4 +3,10 @@ class ConversationParticipation < ApplicationRecord
   belongs_to :conversation
   validates :user_id, presence: true
   validates :conversation_id, presence: true
+
+  before_save :set_viewed_at_to_now
+
+  def set_viewed_at_to_now
+    self.viewed_at = Time.now
+  end
 end

+ 34 - 0
app/views/layouts/_navigation.html.erb

@@ -10,6 +10,40 @@
     </div>
 
     <ul class="nav navbar-top-links navbar-right">
+        <li class="dropdown">
+            <a class="dropdown-toggle" data-toggle="dropdown" href="#">
+              <%= fa_icon "envelope fw" %>
+              <% count = unread_messages_count current_user %>
+              <% if count > 0 %>
+                (<span class="unread-messages"><%= count %></span>)
+              <% end %>
+              <%= fa_icon "caret-down" %>
+            </a>
+            <ul class="dropdown-menu dropdown-messages">
+                <% for conversation in current_user.conversations.sort_by{ |conversation| conversation.messages.last.created_at }[0..1] %>
+                  <% message = conversation.messages.last %>
+                  <li>
+                      <%= link_to "#{conversation_path conversation}#message-#{message.id}" do %>
+                          <div>
+                            <span class="pull-right text-muted">
+                                <em><%= time_ago_in_words(message.created_at) %> ago</em>
+                            </span>
+                              <strong><%= message.user.name %></strong>
+
+                          </div>
+                          <div><%= truncate(message.content, length: 100) %></div>
+                      <% end %>
+                  </li>
+                  <li class="divider"></li>
+                <% end %>
+                <li>
+                    <%= link_to conversations_path, class: 'text-center' do %>
+                        <strong>Read All Messages</strong>
+                        <%= fa_icon("angle-right") %>
+                    <% end %>
+                </li>
+            </ul>
+        </li>
         <li class="dropdown">
             <a class="dropdown-toggle" data-toggle="dropdown" href="#">
               <%= fa_icon "user fw" %><%= fa_icon "caret-down" %>

+ 1 - 1
app/views/messages/_message.html.erb

@@ -1,4 +1,4 @@
-<div class="panel panel-default">
+<div class="panel panel-default" id="message-<%= message.id %>">
   <div class="panel-heading">
     <%= render message.user %>
   </div>

+ 5 - 2
test/controllers/conversations_controller_test.rb

@@ -23,11 +23,14 @@ class ConversationsControllerTest < ActionDispatch::IntegrationTest
     assert_redirected_to root_path
   end
 
-  test "last message should be shown in index" do
+  test "last message should be shown in index and dropdown" do
     message = @user.messages.build(content: "Hello, world!",
                                    conversation: conversations(:one))
     message.save
     get conversations_path
-    assert_match message.content, response.body
+    assert_select "tbody" do
+      assert_select "tr:nth-child(1)", text: /#{message.content}/
+    end
+    assert_select ".dropdown-messages li:nth-child(1)", text: /#{message.content}/
   end
 end