diff --git a/app/controllers/conversations_controller.rb b/app/controllers/conversations_controller.rb index dd0838602..5806f4358 100644 --- a/app/controllers/conversations_controller.rb +++ b/app/controllers/conversations_controller.rb @@ -4,11 +4,16 @@ class ConversationsController < ApplicationController respond_to :html, :json def index - @all_contacts_and_ids = current_user.contacts.map{|c| {:value => c.id, :name => c.person.name}} - @conversations = Conversation.joins(:conversation_visibilities).where( :conversation_visibilities => {:person_id => current_user.person.id}).paginate( :page => params[:page], :per_page => 15, :order => 'updated_at DESC') + + @visibilities = ConversationVisibility.where( :person_id => current_user.person.id ).paginate( + :page => params[:page], :per_page => 15, :order => 'updated_at DESC') + + @unread_counts = {} + @visibilities.each{|v| @unread_counts[v.conversation_id] = v.unread} + @authors = {} @conversations.each{|c| @authors[c.id] = c.last_author} @@ -17,7 +22,7 @@ class ConversationsController < ApplicationController end def create - person_ids = Contact.where(:id => params[:contact_ids]).map! do |contact| + person_ids = Contact.where(:id => params[:contact_ids].split(',')).map! do |contact| contact.person_id end @@ -40,6 +45,11 @@ class ConversationsController < ApplicationController @conversation = Conversation.joins(:conversation_visibilities).where(:id => params[:id], :conversation_visibilities => {:person_id => current_user.person.id}).first + if @visibility = ConversationVisibility.where(:conversation_id => params[:id], :person_id => current_user.person.id).first + @visibility.unread = 0 + @visibility.save + end + if @conversation render :layout => false else @@ -48,6 +58,7 @@ class ConversationsController < ApplicationController end def new + @all_contacts_and_ids = current_user.contacts.map{|c| {:value => c.id, :name => c.person.name}} @contact = current_user.contacts.find(params[:contact_id]) if params[:contact_id] render :layout => false end diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 73ed1f772..9ab139566 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -3,7 +3,7 @@ # the COPYRIGHT file. class PostsController < ApplicationController - skip_before_filter :set_contacts_notifications_and_status + skip_before_filter :set_contacts_notifications_unread_count_and_status skip_before_filter :count_requests skip_before_filter :set_invites skip_before_filter :set_locale diff --git a/app/controllers/publics_controller.rb b/app/controllers/publics_controller.rb index 64db524f6..85806c76d 100644 --- a/app/controllers/publics_controller.rb +++ b/app/controllers/publics_controller.rb @@ -6,7 +6,7 @@ class PublicsController < ApplicationController require File.join(Rails.root, '/lib/diaspora/parser') include Diaspora::Parser - skip_before_filter :set_contacts_notifications_and_status, :except => [:create, :update] + skip_before_filter :set_contacts_notifications_unread_count_and_status, :except => [:create, :update] skip_before_filter :count_requests skip_before_filter :set_invites skip_before_filter :set_locale diff --git a/app/views/conversations/_conversation.haml b/app/views/conversations/_conversation.haml index bcf865746..604ae5125 100644 --- a/app/views/conversations/_conversation.haml +++ b/app/views/conversations/_conversation.haml @@ -2,7 +2,7 @@ -# licensed under the Affero General Public License version 3 or later. See -# the COPYRIGHT file. -.stream_element.conversation{:data=>{:guid=>conversation.id}} +.stream_element.conversation{:data=>{:guid=>conversation.id}, :class => ('unread' if unread_counts[conversation.id].to_i > 0)} = person_image_tag(authors[conversation.id]) .subject @@ -15,6 +15,7 @@ .timestamp = time_ago_in_words conversation.updated_at = authors[conversation.id].name + - if conversation.participants.size > 2 %span.participant_count = "(+#{conversation.participants.size - 1})" diff --git a/app/views/conversations/_show.haml b/app/views/conversations/_show.haml index 60bee1f3b..85adf3bef 100644 --- a/app/views/conversations/_show.haml +++ b/app/views/conversations/_show.haml @@ -3,7 +3,7 @@ -# the COPYRIGHT file. -.span-15.last +.span-16.last .conversation_participants .span-9 %h3 @@ -22,7 +22,7 @@ %br %br %br -.span-15.last +.span-16.last .stream = render :partial => 'messages/message', :collection => conversation.messages @@ -33,5 +33,5 @@ = form_for [conversation, Message.new] do |message| = message.text_area :text, :rows => 5 .right - = message.submit 'Reply' + = message.submit 'Reply', :class => 'button' = link_to 'Cancel', '#' diff --git a/app/views/conversations/index.haml b/app/views/conversations/index.haml index 870833e92..6fdc0f141 100644 --- a/app/views/conversations/index.haml +++ b/app/views/conversations/index.haml @@ -12,8 +12,6 @@ :css footer{ display:none;} -= hidden_field_tag :contact_json, @all_contacts_and_ids.to_json - #left_pane #left_pane_header %h3 @@ -24,13 +22,13 @@ #conversation_inbox - if @conversations.count > 0 .stream.conversations - = render :partial => 'conversations/conversation', :collection => @conversations, :locals => {:authors => @authors} + = render :partial => 'conversations/conversation', :collection => @conversations, :locals => {:authors => @authors, :unread_counts => @unread_counts} = will_paginate @conversations - else %i You have no messages -#conversation_show.span-15.prepend-8.last +#conversation_show.span-16.prepend-8.last - if @conversation = render 'conversations/show', :conversation => @conversation - else diff --git a/app/views/conversations/new.haml b/app/views/conversations/new.haml index 4eea90612..9be57e181 100644 --- a/app/views/conversations/new.haml +++ b/app/views/conversations/new.haml @@ -4,40 +4,48 @@ :javascript $(document).ready(function () { - var data = $.parseJSON( $('#contact_json').val() ); - $("#contact_autocomplete").autoSuggest(data, { + var data = $.parseJSON( $('#contact_json').val() ), + autocompleteInput = $("#contact_autocomplete"); + + autocompleteInput.autoSuggest(data, { selectedItemProp: "name", searchObjProps: "name", - asHtmlID: "contact_ids" + asHtmlID: "contact_ids", + keyDelay: 0, + startText: '', + preFill: [{ 'name' : "#{params[:name]}", + 'value' : "#{params[:contact_id]}"}] }); + + autocompleteInput.focus(); }); += hidden_field_tag :contact_json, @all_contacts_and_ids.to_json + #new_message_pane - #facebox_header - %h4 - New Message - - = form_for Conversation.new do |conversation| - - - if @contact - send a message to - = @contact.person.name - - = hidden_field_tag "conversation[contact_ids]", @contact.id - = hidden_field_tag "profile", @contact.person.id - - -else + .span-12.last + #facebox_header %h4 - to - = text_field_tag "contact_autocomplete" + New Message - %h4 - subject - = conversation.text_field :subject + = form_for Conversation.new do |conversation| + %br - %h4 - message - = text_area_tag "conversation[text]", '', :rows => 5 + .span-2 + %h4 + to + .span-10.last + = text_field_tag "contact_autocomplete" - = conversation.submit :send - = link_to 'cancel', conversations_path + .span-2 + %h4 + subject + .span-10.last + = conversation.text_field :subject + + .span-10.prepend-2.last + = text_area_tag "conversation[text]", '', :rows => 5 + + .text-right + = conversation.submit :send, :class => 'button' + = link_to 'cancel', conversations_path diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index e83853926..d37df6b7c 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -2,6 +2,10 @@ -# licensed under the Affero General Public License version 3 or later. See -# the COPYRIGHT file. + +- content_for :head do + = include_javascripts :people + - content_for :page_title do = @person.name @@ -41,8 +45,9 @@ - else - .right - = link_to 'Message', new_conversation_path(:contact_id => @contact.id), :class => 'button', :rel => 'facebox' + - if @contact.person + .right + = link_to 'Message', new_conversation_path(:contact_id => @contact.id, :name => @contact.person.name, :contact_id => @contact.id), :class => 'button', :rel => 'facebox' /- if @post_type == :photos / = link_to t('layouts.header.view_profile'), person_path(@person) diff --git a/config/assets.yml b/config/assets.yml index 0f56bf764..4476666a7 100644 --- a/config/assets.yml +++ b/config/assets.yml @@ -53,6 +53,7 @@ javascripts: - public/javascripts/aspect-filters.js - public/javascripts/contact-list.js people: + - public/javascripts/vendor/jquery.autoSuggest.js - public/javascripts/contact-list.js photos: - public/javascripts/photo-show.js diff --git a/public/javascripts/inbox.js b/public/javascripts/inbox.js index 769b6a0c8..1172b61c7 100644 --- a/public/javascripts/inbox.js +++ b/public/javascripts/inbox.js @@ -11,8 +11,9 @@ $(document).ready(function(){ $.get("conversations/"+conversationGuid, function(data){ $('.conversation', '.stream').removeClass('selected'); - conversationSummary.addClass('selected'); + conversationSummary.addClass('selected').removeClass('unread'); $('#conversation_show').html(data); + Diaspora.widgets.timeago.updateTimeAgo(); }); if (typeof(history.pushState) == 'function') { diff --git a/public/javascripts/vendor/jquery.autoSuggest.js b/public/javascripts/vendor/jquery.autoSuggest.js index 01f58111a..bafd35cbc 100644 --- a/public/javascripts/vendor/jquery.autoSuggest.js +++ b/public/javascripts/vendor/jquery.autoSuggest.js @@ -181,7 +181,7 @@ timeout = setTimeout(function(){ keyChange(); }, opts.keyDelay); } break; - case 9: case 188: // tab or comma + /*case 9: case 188: // tab or comma tab_press = true; var i_input = input.val().replace(/(,)/g, ""); if(i_input != "" && values_input.val().search(","+i_input+",") < 0 && i_input.length >= opts.minChars){ @@ -192,8 +192,12 @@ var lis = $("li", selections_holder).length; add_selected_item(n_data, "00"+(lis+1)); input.val(""); - } - case 13: // return + }*/ + case 9: // tab + if(input.val() == ''){ + break; + } + case 13: case 188: // return, comma tab_press = false; var active = $("li.active:first", results_holder); if(active.length > 0){ diff --git a/public/stylesheets/sass/application.sass b/public/stylesheets/sass/application.sass index d017757a5..89045d0bb 100644 --- a/public/stylesheets/sass/application.sass +++ b/public/stylesheets/sass/application.sass @@ -2279,8 +2279,7 @@ ul.show_comments :position relative :top 10px -#aspect_edit_pane, -#new_message_pane +#aspect_edit_pane :width 400px .person_tiles .tile @@ -2305,8 +2304,15 @@ ul.show_comments :width 600px #new_message_pane - input - :width 90% + input:not([type='submit']), + textarea + :width 378px + :margin + :right 0 + + .as-selections + input + :width 200px #facebox_header :padding 1em @@ -2609,6 +2615,10 @@ ul.show_comments &:hover :cursor pointer +.conversation.unread + :background + :color lighten($background,5%) + .conversation.selected :background :color $blue @@ -2653,7 +2663,6 @@ ul.show_comments :border :bottom 1px solid #ddd - #no_conversation_text :font :size 20px @@ -2670,3 +2679,8 @@ ul.show_comments :font :size 12px +.text-right + :text + :align right + :margin + :right 5px diff --git a/public/stylesheets/vendor/autoSuggest.css b/public/stylesheets/vendor/autoSuggest.css index a694cd71b..225d3c410 100644 --- a/public/stylesheets/vendor/autoSuggest.css +++ b/public/stylesheets/vendor/autoSuggest.css @@ -2,17 +2,17 @@ ul.as-selections { list-style-type: none; - border-top: 1px solid #888; - border-bottom: 1px solid #b6b6b6; - border-left: 1px solid #aaa; - border-right: 1px solid #aaa; + border: 1px solid #ccc; padding: 4px 0 4px 4px; margin: 0; overflow: auto; background-color: #fff; - box-shadow:inset 0 1px 2px #888; - -webkit-box-shadow:inset 0 1px 2px #888; - -moz-box-shadow:inset 0 1px 2px #888; + + border-radius: 3px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + + width: 383px; } ul.as-selections.loading { @@ -27,19 +27,21 @@ ul.as-selections li { ul.as-selections li.as-selection-item { color: #2b3840; font-size: 13px; - font-family: "Lucida Grande", arial, sans-serif; text-shadow: 0 1px 1px #fff; background-color: #ddeefe; background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ddeefe), to(#bfe0f1)); border: 1px solid #acc3ec; - border-top-color: #c0d9e9; - padding: 2px 7px 2px 10px; - border-radius: 12px; - -webkit-border-radius: 12px; - -moz-border-radius: 12px; + padding: 0; + padding-left: 6px; + border-radius: 5px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; box-shadow: 0 1px 1px #e4edf2; -webkit-box-shadow: 0 1px 1px #e4edf2; -moz-box-shadow: 0 1px 1px #e4edf2; + line-height: 10px; + margin-top: -1px; + margin-bottom: -1px; } ul.as-selections li.as-selection-item:last-child { @@ -48,8 +50,8 @@ ul.as-selections li.as-selection-item:last-child { ul.as-selections li.as-selection-item a.as-close { float: right; - margin: 1px 0 0 7px; - padding: 0 2px; + margin: 0px 3px 0 0px; + padding: 0 3px; cursor: pointer; color: #5491be; font-family: "Helvetica", helvetica, arial, sans-serif; @@ -107,8 +109,9 @@ ul.as-selections li.as-original input { outline: none; font-size: 13px; width: 120px; - height: 18px; - padding-top: 3px; + height: 14px; + padding: 0; + margin: 0; } ul.as-list { @@ -116,9 +119,8 @@ ul.as-list { list-style-type: none; margin: 2px 0 0 0; padding: 0; - font-size: 14px; + font-size: 13px; color: #000; - font-family: "Lucida Grande", arial, sans-serif; background-color: #fff; background-color: rgba(255,255,255,0.95); z-index: 2; @@ -132,14 +134,14 @@ ul.as-list { li.as-result-item, li.as-message { margin: 0 0 0 0; - padding: 5px 12px; + padding: 5px; background-color: transparent; border: 1px solid #fff; border-bottom: 1px solid #ddd; cursor: pointer; - border-radius: 5px; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; + border-radius: 3px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; } li:first-child.as-result-item { @@ -173,9 +175,6 @@ li.as-result-item.active em { /* Webkit Hacks */ @media screen and (-webkit-min-device-pixel-ratio:0) { - ul.as-selections { - border-top-width: 2px; - } ul.as-selections li.as-selection-item { padding-top: 3px; padding-bottom: 3px; @@ -184,14 +183,14 @@ li.as-result-item.active em { margin-top: -1px; } ul.as-selections li.as-original input { - height: 19px; + height: 15px; } } /* Opera Hacks */ @media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0) { ul.as-list { - border: 1px solid #888; + border: 1px solid #ccc; } ul.as-selections li.as-selection-item a.as-close { margin-left: 4px; @@ -201,7 +200,7 @@ li.as-result-item.active em { /* IE Hacks */ ul.as-list { - border: 1px solid #888\9; + border: 1px solid #ccc\9; } ul.as-selections li.as-selection-item a.as-close { margin-left: 4px\9; @@ -210,7 +209,7 @@ ul.as-selections li.as-selection-item a.as-close { /* Firefox 3.0 Hacks */ ul.as-list, x:-moz-any-link, x:default { - border: 1px solid #888; + border: 1px solid #ccc; } BODY:first-of-type ul.as-list, x:-moz-any-link, x:default { /* Target FF 3.5+ */ border: none;