summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/subscription.js.coffee18
-rw-r--r--app/controllers/projects/issues_controller.rb11
-rw-r--r--app/controllers/projects/merge_requests_controller.rb11
-rw-r--r--app/models/concerns/issuable.rb10
-rw-r--r--app/models/subscribe.rb3
-rw-r--r--app/services/notification_service.rb18
-rw-r--r--app/views/projects/issues/_issue_context.html.haml16
-rw-r--r--app/views/projects/merge_requests/show/_context.html.haml16
-rw-r--r--config/routes.rb4
-rw-r--r--db/migrate/20150313012111_create_subscribes_table.rb12
-rw-r--r--db/schema.rb11
11 files changed, 127 insertions, 3 deletions
diff --git a/app/assets/javascripts/subscription.js.coffee b/app/assets/javascripts/subscription.js.coffee
new file mode 100644
index 00000000000..f457622fc3a
--- /dev/null
+++ b/app/assets/javascripts/subscription.js.coffee
@@ -0,0 +1,18 @@
+class @Subscription
+ constructor: (url) ->
+ $(".subscribe-button").click (event)=>
+ self = @
+ btn = $(event.currentTarget)
+ action = btn.prop("value")
+ current_status = $(".sub_status").text().trim()
+ $(".fa-spinner.subscription").removeClass("hidden")
+ $(".sub_status").empty()
+
+ $.post url, subscription: action, =>
+ $(".fa-spinner.subscription").addClass("hidden")
+ status = if current_status == "subscribed" then "unsubscribed" else "subscribed"
+ $(".sub_status").text(status)
+ action = if status == "subscribed" then "Unsubscribe" else "Subscribe"
+ btn.prop("value", action)
+
+
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 4266bcaef16..4eb5092b9d9 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -1,6 +1,6 @@
class Projects::IssuesController < Projects::ApplicationController
before_filter :module_enabled
- before_filter :issue, only: [:edit, :update, :show]
+ before_filter :issue, only: [:edit, :update, :show, :set_subscription]
# Allow read any issue
before_filter :authorize_read_issue!
@@ -97,6 +97,15 @@ class Projects::IssuesController < Projects::ApplicationController
redirect_to :back, notice: "#{result[:count]} issues updated"
end
+ def set_subscription
+ subscribed = params[:subscription] == "Subscribe"
+
+ sub = @issue.subscribes.find_or_create_by(user_id: current_user.id)
+ sub.update(subscribed: subscribed)
+
+ render nothing: true
+ end
+
protected
def issue
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 93d79d81661..5613eee35c0 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -2,7 +2,7 @@ require 'gitlab/satellite/satellite'
class Projects::MergeRequestsController < Projects::ApplicationController
before_filter :module_enabled
- before_filter :merge_request, only: [:edit, :update, :show, :diffs, :automerge, :automerge_check, :ci_status]
+ before_filter :merge_request, only: [:edit, :update, :show, :diffs, :automerge, :automerge_check, :ci_status, :set_subscription]
before_filter :closes_issues, only: [:edit, :update, :show, :diffs]
before_filter :validates_merge_request, only: [:show, :diffs]
before_filter :define_show_vars, only: [:show, :diffs]
@@ -174,6 +174,15 @@ class Projects::MergeRequestsController < Projects::ApplicationController
render json: response
end
+ def set_subscription
+ subscribed = params[:subscription] == "Subscribe"
+
+ sub = @merge_request.subscribes.find_or_create_by(user_id: current_user.id)
+ sub.update(subscribed: subscribed)
+
+ render nothing: true
+ end
+
protected
def selected_target_project
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index f5e23e9dc2d..e89dcbf9acb 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -15,6 +15,7 @@ module Issuable
has_many :notes, as: :noteable, dependent: :destroy
has_many :label_links, as: :target, dependent: :destroy
has_many :labels, through: :label_links
+ has_many :subscribes, dependent: :destroy
validates :author, presence: true
validates :title, presence: true, length: { within: 0..255 }
@@ -132,6 +133,15 @@ module Issuable
users.concat(mentions.reduce([], :|)).uniq
end
+ def subscribe_status(user)
+ sub = subscribes.find_by_user_id(user.id)
+ if sub
+ return sub.subscribed
+ end
+
+ participants.include?(user)
+ end
+
def to_hook_data(user)
{
object_kind: self.class.name.underscore,
diff --git a/app/models/subscribe.rb b/app/models/subscribe.rb
new file mode 100644
index 00000000000..a68546667f1
--- /dev/null
+++ b/app/models/subscribe.rb
@@ -0,0 +1,3 @@
+class Subscribe < ActiveRecord::Base
+ belongs_to :user
+end
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb
index 0063b7ce40c..4fa775a28ce 100644
--- a/app/services/notification_service.rb
+++ b/app/services/notification_service.rb
@@ -314,6 +314,13 @@ class NotificationService
end
end
+ def reject_unsubscribed_users(recipients, target)
+ recipients.reject do |user|
+ subscribe = target.subscribes.find_by_user_id(user.id)
+ subscribe && !subscribe.subscribed
+ end
+ end
+
def new_resource_email(target, project, method)
recipients = build_recipients(target, project)
recipients.delete(target.author)
@@ -361,10 +368,21 @@ class NotificationService
recipients = reject_muted_users(recipients, project)
recipients = reject_mention_users(recipients, project)
+ recipients = add_subscribers(recipients, project)
recipients = recipients.concat(project_watchers(project)).uniq
+ recipients = reject_unsubscribed_users(recipients, target)
recipients
end
+ def add_subscribers(recipients, target)
+ subs = target.subscribes
+ if subs.any?
+ recipients.merge(subs.where("subscribed is true").map(&:user))
+ else
+ recipients
+ end
+ end
+
def mailer
Notify.delay
end
diff --git a/app/views/projects/issues/_issue_context.html.haml b/app/views/projects/issues/_issue_context.html.haml
index 4c7654354f4..09c531ac7fc 100644
--- a/app/views/projects/issues/_issue_context.html.haml
+++ b/app/views/projects/issues/_issue_context.html.haml
@@ -26,3 +26,19 @@
= f.select(:milestone_id, milestone_options(@issue), { include_blank: "Select milestone" }, {class: 'select2 select2-compact js-select2 js-milestone'})
= hidden_field_tag :issue_context
= f.submit class: 'btn'
+
+ %div.prepend-top-20.clearfix
+ .issuable-context-title
+ %label
+ Subscription:
+ %i.fa.fa-spinner.fa-spin.hidden.subscription
+ %span.sub_status
+ = @issue.subscribe_status(current_user) ? "subscribed" : "unsubscribed"
+ - subscribe_action = @issue.subscribe_status(current_user) ? "Unsubscribe" : "Subscribe"
+ %input.btn.subscribe-button{:type => "button", :value => subscribe_action}
+
+:coffeescript
+ $ ->
+ new Subscription("#{set_subscription_namespace_project_issue_path(@issue.project.namespace, @project, @issue)}")
+
+ \ No newline at end of file
diff --git a/app/views/projects/merge_requests/show/_context.html.haml b/app/views/projects/merge_requests/show/_context.html.haml
index a74f3fb24e7..aae0aa24ed7 100644
--- a/app/views/projects/merge_requests/show/_context.html.haml
+++ b/app/views/projects/merge_requests/show/_context.html.haml
@@ -28,3 +28,19 @@
= f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2 select2-compact js-select2 js-milestone'})
= hidden_field_tag :merge_request_context
= f.submit class: 'btn'
+
+ %div.prepend-top-20.clearfix
+ .issuable-context-title
+ %label
+ Subscription:
+ %i.fa.fa-spinner.fa-spin.hidden.subscription
+ %span.sub_status
+ = @merge_request.subscribe_status(current_user) ? "subscribed" : "unsubscribed"
+ - subscribe_action = @merge_request.subscribe_status(current_user) ? "Unsubscribe" : "Subscribe"
+ %input.btn.subscribe-button{:type => "button", :value => subscribe_action}
+
+:coffeescript
+ $ ->
+ new Subscription("#{set_subscription_namespace_project_issue_path(@merge_request.project.namespace, @project, @merge_request)}")
+
+ \ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index 889995e92a6..a976ba9d593 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -406,6 +406,7 @@ Gitlab::Application.routes.draw do
post :automerge
get :automerge_check
get :ci_status
+ post :set_subscription
end
collection do
@@ -440,6 +441,9 @@ Gitlab::Application.routes.draw do
end
resources :issues, constraints: { id: /\d+/ }, except: [:destroy] do
+ member do
+ post :set_subscription
+ end
collection do
post :bulk_update
end
diff --git a/db/migrate/20150313012111_create_subscribes_table.rb b/db/migrate/20150313012111_create_subscribes_table.rb
new file mode 100644
index 00000000000..706cf77118c
--- /dev/null
+++ b/db/migrate/20150313012111_create_subscribes_table.rb
@@ -0,0 +1,12 @@
+class CreateSubscribesTable < ActiveRecord::Migration
+ def change
+ create_table :subscribes do |t|
+ t.integer :user_id
+ t.integer :merge_request_id
+ t.integer :issue_id
+ t.boolean :subscribed
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 3afbc082b70..6afb79069e4 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20150306023112) do
+ActiveRecord::Schema.define(version: 20150313012111) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -397,6 +397,15 @@ ActiveRecord::Schema.define(version: 20150306023112) do
add_index "snippets", ["project_id"], name: "index_snippets_on_project_id", using: :btree
add_index "snippets", ["visibility_level"], name: "index_snippets_on_visibility_level", using: :btree
+ create_table "subscribes", force: true do |t|
+ t.integer "user_id"
+ t.integer "merge_request_id"
+ t.integer "issue_id"
+ t.boolean "subscribed"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
create_table "taggings", force: true do |t|
t.integer "tag_id"
t.integer "taggable_id"