diff options
author | Johan Sørensen <johan@johansorensen.com> | 2009-12-17 13:52:54 +0100 |
---|---|---|
committer | Johan Sørensen <johan@johansorensen.com> | 2010-01-07 13:37:55 +0100 |
commit | 7abd7a06e801678dc1c4a1cf996f11ec31aad318 (patch) | |
tree | 4d27dc63c8d9a8803c7b51801ca18ae664af8186 | |
parent | 51d1119f89552f3bd97d446f0f98ecf4f4355f7d (diff) | |
download | gitorious-mainline-outdated-7abd7a06e801678dc1c4a1cf996f11ec31aad318.zip gitorious-mainline-outdated-7abd7a06e801678dc1c4a1cf996f11ec31aad318.tar.gz gitorious-mainline-outdated-7abd7a06e801678dc1c4a1cf996f11ec31aad318.tar.bz2 |
Added a UI for managing whether to receive email when a feed item appears or not
Flagging this is a per favorite setting and is opt-in
-rw-r--r-- | app/controllers/favorites_controller.rb | 16 | ||||
-rw-r--r-- | app/controllers/users_controller.rb | 2 | ||||
-rw-r--r-- | app/helpers/favorites_helper.rb | 27 | ||||
-rw-r--r-- | app/views/favorites/index.html.erb | 54 | ||||
-rw-r--r-- | app/views/users/show.html.erb | 6 | ||||
-rw-r--r-- | db/migrate/20091217110558_add_mail_flag_to_favorites.rb | 9 | ||||
-rw-r--r-- | db/schema.rb | 12 | ||||
-rw-r--r-- | public/javascripts/application.js | 34 | ||||
-rw-r--r-- | public/stylesheets/base.css | 30 | ||||
-rw-r--r-- | test/functional/favorites_controller_test.rb | 65 |
10 files changed, 232 insertions, 23 deletions
diff --git a/app/controllers/favorites_controller.rb b/app/controllers/favorites_controller.rb index c2775e8..5a91781 100644 --- a/app/controllers/favorites_controller.rb +++ b/app/controllers/favorites_controller.rb @@ -20,6 +20,20 @@ class FavoritesController < ApplicationController before_filter :login_required before_filter :find_watchable, :only => [:create] + def index + @favorites = current_user.favorites.all(:include => :watchable) + end + + def update + @favorite = current_user.favorites.find(params[:id]) + @favorite.notify_by_email = params[:favorite][:notify_by_email] + @favorite.save + respond_to do |wants| + wants.html { redirect_to favorites_path } + wants.js { head :ok } + end + end + def create @favorite = @watchable.watched_by!(current_user) @favorite.create_event @@ -61,4 +75,4 @@ class FavoritesController < ApplicationController @watchable = watchable_class.find(params[:watchable_id]) end end -
\ No newline at end of file + diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index dcb805a..33e6eab 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -54,7 +54,7 @@ class UsersController < ApplicationController :include => [:user, :project]) end @messages = @user.messages_in_inbox(3) if @user == current_user - @favorites = @user.watched_objects + @favorites = @user.favorites.all(:include => :watchable) @atom_auto_discovery_url = feed_user_path(@user, :format => :atom) @atom_auto_discovery_title = "Public activity feed" diff --git a/app/helpers/favorites_helper.rb b/app/helpers/favorites_helper.rb index dedf78f..7c08941 100644 --- a/app/helpers/favorites_helper.rb +++ b/app/helpers/favorites_helper.rb @@ -37,13 +37,28 @@ module FavoritesHelper ) end - def destroy_favorite_link_to(favorite, watchable) - link_to("Stop watching", - favorite_path(favorite), + def destroy_favorite_link_to(favorite, watchable, options = {}) + label = options[:label] || "Stop watching" + link_to(label, favorite_path(favorite), :method => :delete, :"data-request-method" => "delete", :class => "watch-link enabled round-10") end + def link_to_notification_toggle(favorite) + link_classes = %w[toggle round-10] + link_classes << (favorite.notify_by_email? ? "enabled" : "disabled") + link = link_to(favorite.notify_by_email? ? "on" : "off", favorite, + :class => link_classes.join(" ")) + content_tag(:div, link, + :class => "white-button round-10 small-button update favorite") + end + + def link_to_unwatch_favorite(favorite) + link = link_to("Unwatch", favorite, :class => "watch-link enabled round-10") + content_tag(:div, link, + :class => "white-button round-10 small-button favorite") + end + # Builds a link to the target of a favorite event def link_to_watchable(watchable) case watchable @@ -66,9 +81,13 @@ module FavoritesHelper @favorites.include?(watchable) end + def css_class_for_watchable(watchable) + watchable.class.name.underscore + end + def css_classes_for(watchable) css_classes = ["favorite"] - css_classes << watchable.class.name.underscore + css_classes << css_class_for_watchable(watchable) if current_user == watchable.user css_classes << "mine" else diff --git a/app/views/favorites/index.html.erb b/app/views/favorites/index.html.erb new file mode 100644 index 0000000..d713c9f --- /dev/null +++ b/app/views/favorites/index.html.erb @@ -0,0 +1,54 @@ +<% +#-- +# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +#++ +%> + +<% @page_title = "Your favorites" -%> +<%= breadcrumbs_from(current_user) -%> + +<h1>Your favorites</h1> + +<% help_box do %> +<p> +Here you can manage the watch settings for the objects you're +watching. Use the checkbox to toggle email settings. Turning email +notifications on will send you an email each time something from the +favorite is put in +<%= link_to "your newsfeed", current_user -%> +</p> +<% end %> + +<table class="listing" id="favorite-listing"> + <thead> + <tr> + <th></th> + <th>Email notifications</th> + <th>Unwatch</th> + </tr> + </thead> + <tbody> + <% @favorites.each do |favorite| -%> + <tr> + <td><%= link_to_watchable(favorite.watchable) -%></td> + <td class="notification"><%= link_to_notification_toggle(favorite) -%></td> + <td class="unwatch"> + <%= link_to_unwatch_favorite(favorite) -%> + </td> + </tr> + <% end -%> + </tbody> +</table> diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index e5b4819..55b334a 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -191,9 +191,9 @@ <div class="clear"></div> </div> <ul class="with_icons"> - <% @favorites.each do |watchable| %> - <li class="<%= css_classes_for(watchable) -%>"> - <%= link_to_watchable(watchable) -%> + <% @favorites.each do |favorite| %> + <li class="<%= css_classes_for(favorite.watchable) -%>"> + <%= link_to_watchable(favorite.watchable) -%> </li> <% end %> <p class="hint"><%= no_watchings_notice_for(@user) if @favorites.blank? %></p> diff --git a/db/migrate/20091217110558_add_mail_flag_to_favorites.rb b/db/migrate/20091217110558_add_mail_flag_to_favorites.rb new file mode 100644 index 0000000..3148944 --- /dev/null +++ b/db/migrate/20091217110558_add_mail_flag_to_favorites.rb @@ -0,0 +1,9 @@ +class AddMailFlagToFavorites < ActiveRecord::Migration + def self.up + add_column :favorites, :notify_by_email, :boolean, :default => false + end + + def self.down + remove_column :favorites, :notify_by_email + end +end diff --git a/db/schema.rb b/db/schema.rb index 923007b..0385b90 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1,4 +1,4 @@ -# This file is auto-generated from the current state of the database. Instead of editing this file, +# This file is auto-generated from the current state of the database. Instead of editing this file, # please use the migrations feature of Active Record to incrementally modify your database, and # then regenerate this schema definition. # @@ -9,7 +9,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20091210132746) do +ActiveRecord::Schema.define(:version => 20091217110558) do create_table "cloners", :force => true do |t| t.string "ip" @@ -102,6 +102,7 @@ ActiveRecord::Schema.define(:version => 20091210132746) do t.string "action" t.datetime "created_at" t.datetime "updated_at" + t.boolean "notify_by_email", :default => false end add_index "favorites", ["watchable_type", "watchable_id", "user_id"], :name => "index_favorites_on_watchable_type_and_watchable_id_and_user_id" @@ -374,11 +375,4 @@ ActiveRecord::Schema.define(:version => 20091210132746) do add_index "users", ["password_key"], :name => "index_users_on_password_key" add_index "users", ["ssh_key_id"], :name => "index_users_on_ssh_key_id" - create_table "watchlist", :id => false, :force => true do |t| - t.string "fullname" - t.string "data" - t.text "body" - t.integer "project_id", :null => false - end - end diff --git a/public/javascripts/application.js b/public/javascripts/application.js index 0f11fb6..25fe896 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -227,6 +227,40 @@ $(document).ready(function() { }); }); + // Favorite toggling and deletion on the /favorites page + $("#favorite-listing tr:odd").addClass("odd"); + $("#favorite-listing td.notification .favorite.update a").click(function() { + $this = $(this); + payload = "_method=put&favorite[notify_by_email]=1"; + $.post($this.attr("href"), payload, function(data, respTxt){ + if ("success" === respTxt) { + if ("off" === $this.text()) { + $this.text("on").removeClass("disabled").addClass("enabled"); + } else { + $this.text("off").removeClass("enabled").addClass("disabled") + } + } + }); + + return false; + }); + + $("#favorite-listing td.unwatch .favorite a.watch-link").click(function() { + $this = $(this); + payload = "_method=delete"; + $.post($this.attr("href"), payload, function(data, respTxt){ + if ("success" === respTxt) { + $this.parents("tr").fadeOut("normal", function(){ + $(this).remove(); + $("#favorite-listing tr").removeClass("odd"); + $("#favorite-listing tr:odd").addClass("odd"); + }); + } + }); + + return false; + }); + }); if (!Gitorious) diff --git a/public/stylesheets/base.css b/public/stylesheets/base.css index 9af5a9c..e24a78c 100644 --- a/public/stylesheets/base.css +++ b/public/stylesheets/base.css @@ -729,6 +729,11 @@ li.merge_requests a.selected { color: #09460F;} float: right; background: #fff url('../images/dialog_bg_bottom.png') repeat-x bottom left; } +ul.with_icons .white-button { + float: none; + display: inline-block; +} + #new-project-button a, .white-button a { font-size: 18px; display: block; @@ -763,7 +768,7 @@ ul.buttons .white-button.small-button a { padding:2px 5px 2px 10px; } -/* white favorite button */ +/* favorite buttons */ .white-button.favorite { width: inherit; margin: 0 0 2px 0; @@ -772,12 +777,18 @@ ul.buttons .white-button.small-button a { padding: 2px 5px 1px 25px; background-position: 5px center; } -.white-button.favorite a.enabled { +.white-button.favorite a.watch-link.enabled { background-image: url("../images/silk/star.png"); } -.white-button.favorite a.disabled { +.white-button.favorite a.watch-link.disabled { background-image: url("../images/silk/star_deselected.png"); } +.white-button.favorite a.toggle.enabled { + background-image: url("../images/silk/email_delete.png"); +} +.white-button.favorite a.toggle.disabled { + background-image: url("../images/silk/email_add.png"); +} .white-button.favorite a.waiting { background-image: url("../images/spinner.gif"); } @@ -3426,4 +3437,17 @@ body#users h2.activities small { #watchable-list .filters ul li a:hover { text-decoration: none; color: #390; +} + +#favorite-listing { width: 500px; } + +#favorite-listing th { + text-align: center; +} +#favorite-listing td.notification { width: 120px; } +#favorite-listing td.notification { width: 150px; } +#favorite-listing td.notification .white-button{ + width: 50px; + margin: 0 auto 0 auto; + float:none; }
\ No newline at end of file diff --git a/test/functional/favorites_controller_test.rb b/test/functional/favorites_controller_test.rb index fc58185..83f36e7 100644 --- a/test/functional/favorites_controller_test.rb +++ b/test/functional/favorites_controller_test.rb @@ -21,14 +21,14 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. #++ -require 'test_helper' +require File.dirname(__FILE__) + '/../test_helper' class FavoritesControllerTest < ActionController::TestCase def do_create_post(type, id, extra_options={}) post :create, extra_options.merge(:watchable_type => type, :watchable_id => id) end - + context "Creating a new favorite" do setup { login_as :johan @@ -140,6 +140,67 @@ class FavoritesControllerTest < ActionController::TestCase Favorite.find(@favorite.id) end end + end + + context "listing a users own favorites" do + setup do + @user = users(:mike) + repositories(:johans).watched_by!(@user) + login_as :mike + end + should "require login" do + login_as nil + get :index + assert_redirected_to new_sessions_path + end + + should "only list the users favorites" do + assert @user.favorites.count > 0, "user has no favs" + other_fav = Favorite.create!({:user => users(:johan), + :watchable => Repository.last}) + get :index + assert !assigns(:favorites).include?(other_fav) + assert_equal @user.favorites, assigns(:favorites) + assert_response :success + end + + should_eventually "have a button to toggle the mail flag" do + flunk + end + + should_eventually "have a button to delete the favorite" do + flunk + end + end + + context "editing a favorite" do + setup do + @user = users(:mike) + login_as @user + @favorite = Repository.last.watched_by!(@user) + end + + should "scope the find to the user" do + fav = Favorite.create!({:user => users(:johan), + :watchable => Repository.last}) + put :update, :id => fav.id + assert_response :not_found + end + + should_eventually "be able to add the mail flag" do + assert !@favorite.notify_by_email? + get :update, :id => @favorite.id, :favorite => {:notify_by_email => true} + assert_response :redirect + assert_redirected to favorites_path + assert @favorite.reload.notify_by_email? + end + + should "only be able to change the mail flag" do + assert !@favorite.notify_by_email? + get :update, :id => @favorite.id, :favorite => {:user_id => users(:johan).id} + assert_response :redirect + assert_equal @user, @favorite.reload.user + end end end |