diff options
author | Eric Davis <edavis@littlestreamsoftware.com> | 2008-10-30 02:58:04 +0000 |
---|---|---|
committer | Eric Davis <edavis@littlestreamsoftware.com> | 2008-10-30 02:58:04 +0000 |
commit | ed314caf7d6e871c214ac1896eaadcb5f5d21ed6 (patch) | |
tree | f05063af03cb962edfdd6d086aad6cc3ed2e2d1b | |
parent | 1399f3dd122f6145d66b912e72dc6186dff884bb (diff) | |
download | redmine-ed314caf7d6e871c214ac1896eaadcb5f5d21ed6.tar.gz redmine-ed314caf7d6e871c214ac1896eaadcb5f5d21ed6.zip |
Gravatar support for issue detai, user grid, and activity stream
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@1962 e93f8b46-1217-0410-a6f0-8f06a7374b81
-rw-r--r-- | app/views/issues/_history.rhtml | 23 | ||||
-rw-r--r-- | app/views/issues/show.rhtml | 23 | ||||
-rw-r--r-- | app/views/projects/activity.rhtml | 5 | ||||
-rw-r--r-- | app/views/users/list.rhtml | 2 | ||||
-rw-r--r-- | public/stylesheets/application.css | 36 | ||||
-rw-r--r-- | vendor/plugins/gravatar/MIT-LICENSE | 20 | ||||
-rw-r--r-- | vendor/plugins/gravatar/README | 52 | ||||
-rw-r--r-- | vendor/plugins/gravatar/Rakefile | 33 | ||||
-rw-r--r-- | vendor/plugins/gravatar/about.yml | 7 | ||||
-rw-r--r-- | vendor/plugins/gravatar/init.rb | 2 | ||||
-rw-r--r-- | vendor/plugins/gravatar/lib/gravatar.rb | 67 | ||||
-rw-r--r-- | vendor/plugins/gravatar/spec/gravatar_spec.rb | 37 |
12 files changed, 283 insertions, 24 deletions
diff --git a/app/views/issues/_history.rhtml b/app/views/issues/_history.rhtml index b8efdb400..896e28027 100644 --- a/app/views/issues/_history.rhtml +++ b/app/views/issues/_history.rhtml @@ -1,14 +1,15 @@ <% reply_links = authorize_for('issues', 'edit') -%> <% for journal in journals %> - <div id="change-<%= journal.id %>" class="journal"> - <h4><div style="float:right;"><%= link_to "##{journal.indice}", :anchor => "note-#{journal.indice}" %></div> - <%= content_tag('a', '', :name => "note-#{journal.indice}")%> - <%= format_time(journal.created_on) %> - <%= journal.user.name %></h4> - <ul> - <% for detail in journal.details %> - <li><%= show_detail(detail) %></li> - <% end %> - </ul> - <%= render_notes(journal, :reply_links => reply_links) unless journal.notes.blank? %> - </div> + <div id="change-<%= journal.id %>" class="journal"> + <%= gravatar(journal.user.mail.blank? ? "" : journal.user.mail, :size => "48") %> + <h4><div style="float:right;"><%= link_to "##{journal.indice}", :anchor => "note-#{journal.indice}" %></div> + <%= content_tag('a', '', :name => "note-#{journal.indice}")%> + <%= format_time(journal.created_on) %> - <%= journal.user.name %></h4> + <ul> + <% for detail in journal.details %> + <li><%= show_detail(detail) %></li> + <% end %> + </ul> + <%= render_notes(journal, :reply_links => reply_links) unless journal.notes.blank? %> + </div> <% end %> diff --git a/app/views/issues/show.rhtml b/app/views/issues/show.rhtml index 463fa6960..88fa1df3d 100644 --- a/app/views/issues/show.rhtml +++ b/app/views/issues/show.rhtml @@ -10,6 +10,7 @@ <h2><%= @issue.tracker.name %> #<%= @issue.id %></h2> <div class="issue <%= "status-#{@issue.status.position} priority-#{@issue.priority.position}" %>"> + <%= gravatar(@issue.author.mail, :size => "64") %> <h3><%=h @issue.subject %></h3> <p class="author"> <%= authoring @issue.created_on, @issue.author %>. @@ -18,28 +19,28 @@ <table width="100%"> <tr> - <td style="width:15%"><b><%=l(:field_status)%>:</b></td><td style="width:35%"><%= @issue.status.name %></td> - <td style="width:15%"><b><%=l(:field_start_date)%>:</b></td><td style="width:35%"><%= format_date(@issue.start_date) %></td> + <td style="width:15%" class="status"><b><%=l(:field_status)%>:</b></td><td style="width:35%" class="status status-<%= @issue.status.name %>"><%= @issue.status.name %></td> + <td style="width:15%" class="start-date"><b><%=l(:field_start_date)%>:</b></td><td style="width:35%"><%= format_date(@issue.start_date) %></td> </tr> <tr> - <td><b><%=l(:field_priority)%>:</b></td><td><%= @issue.priority.name %></td> - <td><b><%=l(:field_due_date)%>:</b></td><td><%= format_date(@issue.due_date) %></td> + <td class="priority"><b><%=l(:field_priority)%>:</b></td><td class="priority priority-<%= @issue.priority.name %>"><%= @issue.priority.name %></td> + <td class="due-date"><b><%=l(:field_due_date)%>:</b></td><td class="due-date"><%= format_date(@issue.due_date) %></td> </tr> <tr> - <td><b><%=l(:field_assigned_to)%>:</b></td><td><%= @issue.assigned_to ? link_to_user(@issue.assigned_to) : "-" %></td> - <td><b><%=l(:field_done_ratio)%>:</b></td><td><%= progress_bar @issue.done_ratio, :width => '80px', :legend => "#{@issue.done_ratio}%" %></td> + <td class="assigned-to"><b><%=l(:field_assigned_to)%>:</b></td><td><%= gravatar(@issue.assigned_to.mail, :size => "24") %><%= @issue.assigned_to ? link_to_user(@issue.assigned_to) : "-" %></td> + <td class="progress"><b><%=l(:field_done_ratio)%>:</b></td><td class="progress"><%= progress_bar @issue.done_ratio, :width => '80px', :legend => "#{@issue.done_ratio}%" %></td> </tr> <tr> - <td><b><%=l(:field_category)%>:</b></td><td><%=h @issue.category ? @issue.category.name : "-" %></td> + <td class="category"><b><%=l(:field_category)%>:</b></td><td><%=h @issue.category ? @issue.category.name : "-" %></td> <% if User.current.allowed_to?(:view_time_entries, @project) %> - <td><b><%=l(:label_spent_time)%>:</b></td> - <td><%= @issue.spent_hours > 0 ? (link_to lwr(:label_f_hour, @issue.spent_hours), {:controller => 'timelog', :action => 'details', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time') : "-" %></td> + <td class="spent-time"><b><%=l(:label_spent_time)%>:</b></td> + <td class="spent-hours"><%= @issue.spent_hours > 0 ? (link_to lwr(:label_f_hour, @issue.spent_hours), {:controller => 'timelog', :action => 'details', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time') : "-" %></td> <% end %> </tr> <tr> - <td><b><%=l(:field_fixed_version)%>:</b></td><td><%= @issue.fixed_version ? link_to_version(@issue.fixed_version) : "-" %></td> + <td class="fixed-version"><b><%=l(:field_fixed_version)%>:</b></td><td><%= @issue.fixed_version ? link_to_version(@issue.fixed_version) : "-" %></td> <% if @issue.estimated_hours %> - <td><b><%=l(:field_estimated_hours)%>:</b></td><td><%= lwr(:label_f_hour, @issue.estimated_hours) %></td> + <td class="estimated-hours"><b><%=l(:field_estimated_hours)%>:</b></td><td><%= lwr(:label_f_hour, @issue.estimated_hours) %></td> <% end %> </tr> <tr> diff --git a/app/views/projects/activity.rhtml b/app/views/projects/activity.rhtml index fa25812ac..47d32e6a3 100644 --- a/app/views/projects/activity.rhtml +++ b/app/views/projects/activity.rhtml @@ -6,7 +6,10 @@ <h3><%= format_activity_day(day) %></h3> <dl> <% @events_by_day[day].sort {|x,y| y.event_datetime <=> x.event_datetime }.each do |e| -%> - <dt class="<%= e.event_type %> <%= User.current.logged? && e.respond_to?(:event_author) && User.current == e.event_author ? 'me' : nil %>"> + <dt class="<%= e.event_type %> <%= User.current.logged? && e.respond_to?(:event_author) && User.current == e.event_author ? 'me' : nil %>"> + <%= gravatar(e.user.mail, :size => "24") if e.respond_to?(:user) rescue nil%> + <%= gravatar(e.author.mail, :size => "24") if e.respond_to?(:author) rescue nil%> + <%= gravatar(e.committer.match('\\<.+?\\>')[0].gsub(/[<>]/, ''), :size => "24") if e.respond_to?(:committer) rescue nil%> <span class="time"><%= format_time(e.event_datetime, false) %></span> <%= content_tag('span', h(e.project), :class => 'project') if @project.nil? || @project != e.project %> <%= link_to format_activity_title(e.event_title), e.event_url %></dt> diff --git a/app/views/users/list.rhtml b/app/views/users/list.rhtml index c41563759..945c9926c 100644 --- a/app/views/users/list.rhtml +++ b/app/views/users/list.rhtml @@ -29,7 +29,7 @@ <tbody> <% for user in @users -%> <tr class="user <%= cycle("odd", "even") %> <%= %w(anon active registered locked)[user.status] %>"> - <td class="username"><%= link_to h(user.login), :action => 'edit', :id => user %></td> + <td class="username"><%= gravatar(user.mail, :size => "24") %><%= link_to h(user.login), :action => 'edit', :id => user %></td> <td class="firstname"><%= h(user.firstname) %></td> <td class="lastname"><%= h(user.lastname) %></td> <td class="email"><%= mail_to(h(user.mail)) %></td> diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css index 6517fdaab..f29e9e6fe 100644 --- a/public/stylesheets/application.css +++ b/public/stylesheets/application.css @@ -615,6 +615,42 @@ vertical-align: middle; .icon22-settings { background-image: url(../images/22x22/settings.png); } .icon22-plugin { background-image: url(../images/22x22/plugin.png); } +img.gravatar { + padding: 2px; + border: solid 1px #d5d5d5; + background: #fff; +} + +div.issue img.gravatar { + float: right; + margin: 0 0 1em 1em; + padding: 5px; +} + +div.issue table img.gravatar { + height: 24px; + width: 24px; + padding: 2px; + float: left; + margin: 0 1em 0 0; +} + +#history img.gravatar { + padding: 3px; + margin: 0 2em 1em 0; + float: left; +} + +td.username img.gravatar { + float: left; + margin: 0 1em 0 0; +} + +#activity dt img.gravatar { + float: left; + margin: 0 1em 1em 0; +} + /***** Media print specific styles *****/ @media print { #top-menu, #header, #main-menu, #sidebar, #footer, .contextual, .other-formats { display:none; } diff --git a/vendor/plugins/gravatar/MIT-LICENSE b/vendor/plugins/gravatar/MIT-LICENSE new file mode 100644 index 000000000..6a222ac4d --- /dev/null +++ b/vendor/plugins/gravatar/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2007 West Arete Computing, Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file diff --git a/vendor/plugins/gravatar/README b/vendor/plugins/gravatar/README new file mode 100644 index 000000000..dc516d367 --- /dev/null +++ b/vendor/plugins/gravatar/README @@ -0,0 +1,52 @@ +== Gravatar Plugin + +This plugin provides a handful of view helpers for displaying gravatars +(globally-recognized avatars). + +Gravatars allow users to configure an avatar to go with their email address at +a central location: http://gravatar.com. Gravatar-aware websites (such +as yours) can then look up and display each user's preferred avatar, without +having to handle avatar management. The user gets the benefit of not having to +set up an avatar for each site that they post on. + +== Installation + + cd ~/myapp + ruby script/plugin install svn://rubyforge.org//var/svn/gravatarplugin/plugins/gravatar + +or, if you're using piston[http://piston.rubyforge.org] (worth it!): + + cd ~/myapp/vendor/plugins + piston import svn://rubyforge.org//var/svn/gravatarplugin/plugins/gravatar + +== Example + +If you represent your users with a model that has an +email+ method (typical +for most rails authentication setups), then you can simply use this method +in your views: + + <%= gravatar_for @user %> + +This will be replaced with the full HTML +img+ tag necessary for displaying +that user's gravatar. + +Other helpers are documented under GravatarHelper::PublicMethods. + +== Acknowledgments + +The following people have also written gravatar-related Ruby libraries: +* Seth Rasmussen created the gravatar gem[http://gravatar.rubyforge.org] +* Matt McCray has also created a gravatar + plugin[http://mattmccray.com/svn/rails/plugins/gravatar_helper] + +== Author + + Scott A. Woods + West Arete Computing, Inc. + http://westarete.com + scott at westarete dot com + +== TODO + +* Get full spec coverage +* Finish rdoc documentation
\ No newline at end of file diff --git a/vendor/plugins/gravatar/Rakefile b/vendor/plugins/gravatar/Rakefile new file mode 100644 index 000000000..5a8d92a8a --- /dev/null +++ b/vendor/plugins/gravatar/Rakefile @@ -0,0 +1,33 @@ +require 'spec/rake/spectask' +require 'rake/rdoctask' + +desc 'Default: run all specs' +task :default => :spec + +desc 'Run all application-specific specs' +Spec::Rake::SpecTask.new(:spec) do |t| + t.warning = true + t.rcov = true +end + +desc "Report code statistics (KLOCs, etc) from the application" +task :stats do + RAILS_ROOT = File.dirname(__FILE__) + STATS_DIRECTORIES = [ + %w(Libraries lib/), + %w(Specs spec/), + ].collect { |name, dir| [ name, "#{RAILS_ROOT}/#{dir}" ] }.select { |name, dir| File.directory?(dir) } + require 'code_statistics' + CodeStatistics.new(*STATS_DIRECTORIES).to_s +end + +namespace :doc do + desc 'Generate documentation for the assert_request plugin.' + Rake::RDocTask.new(:plugin) do |rdoc| + rdoc.rdoc_dir = 'rdoc' + rdoc.title = 'Gravatar Rails Plugin' + rdoc.options << '--line-numbers' << '--inline-source' << '--accessor' << 'cattr_accessor=rw' + rdoc.rdoc_files.include('README') + rdoc.rdoc_files.include('lib/**/*.rb') + end +end diff --git a/vendor/plugins/gravatar/about.yml b/vendor/plugins/gravatar/about.yml new file mode 100644 index 000000000..a801d2582 --- /dev/null +++ b/vendor/plugins/gravatar/about.yml @@ -0,0 +1,7 @@ +author: Scott Woods, West Arete Computing +summary: View helpers for displaying gravatars. +homepage: http://gravatarplugin.rubyforge.org/ +plugin: svn://rubyforge.org//var/svn/gravatarplugin/plugins/gravatar +license: MIT +version: 0.1 +rails_version: 1.0+ diff --git a/vendor/plugins/gravatar/init.rb b/vendor/plugins/gravatar/init.rb new file mode 100644 index 000000000..aab3f75f3 --- /dev/null +++ b/vendor/plugins/gravatar/init.rb @@ -0,0 +1,2 @@ +require 'gravatar' +ActionView::Base.send :include, GravatarHelper::PublicMethods diff --git a/vendor/plugins/gravatar/lib/gravatar.rb b/vendor/plugins/gravatar/lib/gravatar.rb new file mode 100644 index 000000000..58cb4cabe --- /dev/null +++ b/vendor/plugins/gravatar/lib/gravatar.rb @@ -0,0 +1,67 @@ +require 'digest/md5' +require 'cgi' + +module GravatarHelper + + # These are the options that control the default behavior of the public + # methods. They can be overridden during the actual call to the helper, + # or you can set them in your environment.rb as such: + # + # # Allow racier gravatars + # GravatarHelper::DEFAULT_OPTIONS[:rating] = 'R' + # + DEFAULT_OPTIONS = { + # The URL of a default image to display if the given email address does + # not have a gravatar. + :default => nil, + + # The default size in pixels for the gravatar image (they're square). + :size => 50, + + # The maximum allowed MPAA rating for gravatars. This allows you to + # exclude gravatars that may be out of character for your site. + :rating => 'PG', + + # The alt text to use in the img tag for the gravatar. + :alt => 'avatar', + + # The class to assign to the img tag for the gravatar. + :class => 'gravatar', + } + + # The methods that will be made available to your views. + module PublicMethods + + # Return the HTML img tag for the given user's gravatar. Presumes that + # the given user object will respond_to "email", and return the user's + # email address. + def gravatar_for(user, options={}) + gravatar(user.email, options) + end + + # Return the HTML img tag for the given email address's gravatar. + def gravatar(email, options={}) + src = h(gravatar_url(email, options)) + options = DEFAULT_OPTIONS.merge(options) + [:class, :alt, :size].each { |opt| options[opt] = h(options[opt]) } + "<img class=\"#{options[:class]}\" alt=\"#{options[:alt]}\" width=\"#{options[:size]}\" height=\"#{options[:size]}\" src=\"#{src}\" />" + end + + # Return the gravatar URL for the given email address. + def gravatar_url(email, options={}) + email_hash = Digest::MD5.hexdigest(email) + options = DEFAULT_OPTIONS.merge(options) + options[:default] = CGI::escape(options[:default]) unless options[:default].nil? + returning "http://www.gravatar.com/avatar.php?gravatar_id=#{email_hash}" do |url| + [:rating, :size, :default].each do |opt| + unless options[opt].nil? + value = h(options[opt]) + url << "&#{opt}=#{value}" + end + end + end + end + + end + +end
\ No newline at end of file diff --git a/vendor/plugins/gravatar/spec/gravatar_spec.rb b/vendor/plugins/gravatar/spec/gravatar_spec.rb new file mode 100644 index 000000000..a11d2683a --- /dev/null +++ b/vendor/plugins/gravatar/spec/gravatar_spec.rb @@ -0,0 +1,37 @@ +require 'rubygems' +require 'erb' # to get "h" +require 'active_support' # to get "returning" +require File.dirname(__FILE__) + '/../lib/gravatar' +include GravatarHelper, GravatarHelper::PublicMethods, ERB::Util + +context "gravatar_url with a custom default URL" do + setup do + @original_options = DEFAULT_OPTIONS.dup + DEFAULT_OPTIONS[:default] = "no_avatar.png" + @url = gravatar_url("somewhere") + end + + specify "should include the \"default\" argument in the result" do + @url.should match(/&default=no_avatar.png/) + end + + teardown do + DEFAULT_OPTIONS.merge!(@original_options) + end + +end + +context "gravatar_url with default settings" do + setup do + @url = gravatar_url("somewhere") + end + + specify "should have a nil default URL" do + DEFAULT_OPTIONS[:default].should be_nil + end + + specify "should not include the \"default\" argument in the result" do + @url.should_not match(/&default=/) + end + +end
\ No newline at end of file |