summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Sørensen <johan@johansorensen.com>2009-12-17 13:52:54 +0100
committerJohan Sørensen <johan@johansorensen.com>2010-01-07 13:37:55 +0100
commit7abd7a06e801678dc1c4a1cf996f11ec31aad318 (patch)
tree4d27dc63c8d9a8803c7b51801ca18ae664af8186
parent51d1119f89552f3bd97d446f0f98ecf4f4355f7d (diff)
downloadgitorious-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.rb16
-rw-r--r--app/controllers/users_controller.rb2
-rw-r--r--app/helpers/favorites_helper.rb27
-rw-r--r--app/views/favorites/index.html.erb54
-rw-r--r--app/views/users/show.html.erb6
-rw-r--r--db/migrate/20091217110558_add_mail_flag_to_favorites.rb9
-rw-r--r--db/schema.rb12
-rw-r--r--public/javascripts/application.js34
-rw-r--r--public/stylesheets/base.css30
-rw-r--r--test/functional/favorites_controller_test.rb65
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