浏览代码

Add create and new actions to Conversation controller

Frans Bergman 7 年之前
父节点
当前提交
2aa11b4ffe

+ 53 - 6
app/assets/stylesheets/custom.scss

@@ -42,6 +42,57 @@ textarea {
   max-width: 100%;
 }
 
+
+// --Chips
+
+.chip-container {
+  display: inline-block;
+
+  div {
+    display: inline-block;
+    border-radius: 5px;
+    border: 1px dotted #c5c5c5;
+    background-color: #fff;
+    padding: 2px;
+    font-size: 11px;
+    cursor: pointer;
+    margin-right: 2px;
+  }
+}
+
+.chips {
+
+  &:hover {
+    cursor: text;
+  }
+
+  input {
+    background: none;
+    border: 0;
+    display: inline-block;
+    padding: 0 !important;
+    width: 300px !important;
+  }
+
+  // Search
+  .results {
+    position: absolute;
+    margin-top: 6px;
+    margin-left: -6px;
+
+    width: 500px;
+    background-color: #fff;
+    overflow: hidden;
+    border: 1px solid #ccc;
+    border-top: none;
+    list-style: none;
+    padding-left: 5px;
+    cursor: pointer;
+    z-index: 1;
+  }
+}
+
+
 // Navigation
 
 // --Topbar
@@ -91,12 +142,8 @@ textarea {
     margin-left: 5px;
 }
 
-.navbar-top-links .dropdown-tasks {
-    margin-left: -59px;
-}
-
-.navbar-top-links .dropdown-alerts {
-    margin-left: -123px;
+.unread-messages {
+  color: red;
 }
 
 .navbar-top-links .dropdown-user {

+ 27 - 0
app/controllers/conversations_controller.rb

@@ -12,6 +12,33 @@ class ConversationsController < ApplicationController
   def show
   end
 
+  def new
+    @conversation = Conversation.new
+    @conversation.messages.build
+  end
+
+  def create
+    @conversation = Conversation.new(conversation_params)
+    @conversation.messages.each{ |message| message.user = current_user }
+    if @conversation.save
+      for id in params[:conversation][:user_ids].uniq
+        @conversation.users << User.find(id)
+      end
+      unless @conversation.users.include? current_user
+        @conversation.users << current_user
+      end
+
+      if @conversation.save
+        flash[:success] = "Created conversation"
+        redirect_to @conversation
+      else
+        render :new
+      end
+    else
+      render :new
+    end
+  end
+
   private
     def set_conversation
       @conversation = Conversation.find(params[:id])

+ 97 - 0
app/views/conversations/_form.html.erb

@@ -0,0 +1,97 @@
+<%= bootstrap_form_for(@conversation) do |f| %>
+  <%= render 'shared/error_messages', object: f.object %>
+
+  <%= f.text_field :name, label: "Topic" %>
+  
+  <%= f.label :participants %>
+  <div class="chips form-control">
+    <div class="chip-container">
+
+    </div>
+    <input class="search" type="text" />
+    <ul class="results">
+
+    </ul>
+  </div>
+
+  <%= f.fields_for :messages do |m| %>
+    <%= m.text_area :content %>
+  <% end %>
+
+  <%= f.submit "Submit", class: "btn btn-primary" %>
+<% end %>
+<script>
+  function getArray() {
+    var elements = $(".chip-container").find("input");
+    var result = [];
+    for (var i = 0; i < elements.length; i++) {
+      result.push(parseInt(elements[i].value));
+    }
+    return result;
+  }
+
+  function addChip(user) {
+    $(".chip-container").append("<div id='" + user.id + "'>" + user.name + "</div>");
+    $("#" + user.id).append("<input type='hidden' name='conversation[user_ids][]' value='" + user.id + "' />");
+    $(".chip-container div").click(function() {
+      $(this).remove();
+    });
+    $(".search").val("");
+    $(".search").keyup();
+  }
+
+  var lastVal;
+
+  $(document).ready(function() {
+    $.get("/users.json", function(users) {
+
+      $(".chips").click(function() {
+        $(".search").focus();
+      });
+
+      $(".search").keydown(function(e) {
+        if (e.which === 13) {
+          e.preventDefault();
+        }
+        lastVal = $(this).val();
+      });
+
+      $(".search").keyup(function(e) {
+        $(".results").empty();
+        var val = $(this).val();
+
+        var filtered = users.filter(function(user) {
+          return user.name.toLowerCase().includes(val.toLowerCase())
+                  && getArray().indexOf(user.id) === -1;
+        });
+
+        if (e.which === 8) { // Backspace
+          if (!lastVal) {
+            $(".chip-container").children().last().remove();
+          }
+        }
+
+        if (val.length < 2) {
+          $(".results").hide();
+        } else if (e.which === 13) { // Return
+          if (filtered.length > 0) {
+            addChip(filtered[0]);
+          }
+        } else {
+          $(".results").show();
+          filtered.forEach(function(user) {
+            $(".results").append("<li user-id='" + user.id + "'>" + user.name + "</li>");
+          });
+
+          $(".results li").click(function() {
+            var id = $(this).attr("user-id");
+            var user = users.find(function(user) {
+              return user.id === parseInt(id);
+            });
+            addChip(user);
+          });
+        }
+      });
+    });
+  });
+</script>

+ 1 - 0
app/views/conversations/index.html.erb

@@ -18,3 +18,4 @@
     <%= render @conversations %>
   </tbody>
 </table>
+<%= link_to "New conversation", new_conversation_path, class: "btn btn-primary btn-lg btn-block" %>

+ 3 - 0
app/views/conversations/new.html.erb

@@ -0,0 +1,3 @@
+<%= provide(:title, "New conversation") %>
+<h1>New conversation</h1>
+<%= render 'form' %>

+ 11 - 0
test/controllers/conversations_controller_test.rb

@@ -7,6 +7,17 @@ class ConversationsControllerTest < ActionDispatch::IntegrationTest
     log_in_as @user
   end
 
+  test "should create valid conversation" do
+    get new_conversation_path
+    assert_response :success
+    assert_difference '@user.conversations.count', 1 do
+      post conversations_path, params: { conversation: {
+                               name: "Example conversation",
+                               user_ids: [@user.id, @other_user.id],
+                               messages_attributes: { "0" => { content: "Content" }}}}
+    end
+  end
+
   test "should redirect conversation which user is not participating in" do
     get conversation_path conversations(:two)
     assert_redirected_to root_path