Commit 9698b36c authored by Valery Sizov's avatar Valery Sizov

Subscription

parent 606d24ff
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)
class Projects::IssuesController < Projects::ApplicationController class Projects::IssuesController < Projects::ApplicationController
before_filter :module_enabled before_filter :module_enabled
before_filter :issue, only: [:edit, :update, :show] before_filter :issue, only: [:edit, :update, :show, :set_subscription]
# Allow read any issue # Allow read any issue
before_filter :authorize_read_issue! before_filter :authorize_read_issue!
...@@ -97,6 +97,15 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -97,6 +97,15 @@ class Projects::IssuesController < Projects::ApplicationController
redirect_to :back, notice: "#{result[:count]} issues updated" redirect_to :back, notice: "#{result[:count]} issues updated"
end 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 protected
def issue def issue
......
...@@ -2,7 +2,7 @@ require 'gitlab/satellite/satellite' ...@@ -2,7 +2,7 @@ require 'gitlab/satellite/satellite'
class Projects::MergeRequestsController < Projects::ApplicationController class Projects::MergeRequestsController < Projects::ApplicationController
before_filter :module_enabled 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 :closes_issues, only: [:edit, :update, :show, :diffs]
before_filter :validates_merge_request, only: [:show, :diffs] before_filter :validates_merge_request, only: [:show, :diffs]
before_filter :define_show_vars, only: [:show, :diffs] before_filter :define_show_vars, only: [:show, :diffs]
...@@ -174,6 +174,15 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -174,6 +174,15 @@ class Projects::MergeRequestsController < Projects::ApplicationController
render json: response render json: response
end 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 protected
def selected_target_project def selected_target_project
......
...@@ -15,6 +15,7 @@ module Issuable ...@@ -15,6 +15,7 @@ module Issuable
has_many :notes, as: :noteable, dependent: :destroy has_many :notes, as: :noteable, dependent: :destroy
has_many :label_links, as: :target, dependent: :destroy has_many :label_links, as: :target, dependent: :destroy
has_many :labels, through: :label_links has_many :labels, through: :label_links
has_many :subscribes, dependent: :destroy
validates :author, presence: true validates :author, presence: true
validates :title, presence: true, length: { within: 0..255 } validates :title, presence: true, length: { within: 0..255 }
...@@ -132,6 +133,15 @@ module Issuable ...@@ -132,6 +133,15 @@ module Issuable
users.concat(mentions.reduce([], :|)).uniq users.concat(mentions.reduce([], :|)).uniq
end 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) def to_hook_data(user)
{ {
object_kind: self.class.name.underscore, object_kind: self.class.name.underscore,
......
class Subscribe < ActiveRecord::Base
belongs_to :user
end
...@@ -314,6 +314,13 @@ class NotificationService ...@@ -314,6 +314,13 @@ class NotificationService
end end
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) def new_resource_email(target, project, method)
recipients = build_recipients(target, project) recipients = build_recipients(target, project)
recipients.delete(target.author) recipients.delete(target.author)
...@@ -361,10 +368,21 @@ class NotificationService ...@@ -361,10 +368,21 @@ class NotificationService
recipients = reject_muted_users(recipients, project) recipients = reject_muted_users(recipients, project)
recipients = reject_mention_users(recipients, project) recipients = reject_mention_users(recipients, project)
recipients = add_subscribers(recipients, project)
recipients = recipients.concat(project_watchers(project)).uniq recipients = recipients.concat(project_watchers(project)).uniq
recipients = reject_unsubscribed_users(recipients, target)
recipients recipients
end 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 def mailer
Notify.delay Notify.delay
end end
......
...@@ -26,3 +26,19 @@ ...@@ -26,3 +26,19 @@
= f.select(:milestone_id, milestone_options(@issue), { include_blank: "Select milestone" }, {class: 'select2 select2-compact js-select2 js-milestone'}) = f.select(:milestone_id, milestone_options(@issue), { include_blank: "Select milestone" }, {class: 'select2 select2-compact js-select2 js-milestone'})
= hidden_field_tag :issue_context = hidden_field_tag :issue_context
= f.submit class: 'btn' = 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
...@@ -28,3 +28,19 @@ ...@@ -28,3 +28,19 @@
= f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2 select2-compact js-select2 js-milestone'}) = 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 = hidden_field_tag :merge_request_context
= f.submit class: 'btn' = 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
...@@ -406,6 +406,7 @@ Gitlab::Application.routes.draw do ...@@ -406,6 +406,7 @@ Gitlab::Application.routes.draw do
post :automerge post :automerge
get :automerge_check get :automerge_check
get :ci_status get :ci_status
post :set_subscription
end end
collection do collection do
...@@ -440,6 +441,9 @@ Gitlab::Application.routes.draw do ...@@ -440,6 +441,9 @@ Gitlab::Application.routes.draw do
end end
resources :issues, constraints: { id: /\d+/ }, except: [:destroy] do resources :issues, constraints: { id: /\d+/ }, except: [:destroy] do
member do
post :set_subscription
end
collection do collection do
post :bulk_update post :bulk_update
end end
......
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
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # 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 # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
...@@ -397,6 +397,15 @@ ActiveRecord::Schema.define(version: 20150306023112) do ...@@ -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", ["project_id"], name: "index_snippets_on_project_id", using: :btree
add_index "snippets", ["visibility_level"], name: "index_snippets_on_visibility_level", 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| create_table "taggings", force: true do |t|
t.integer "tag_id" t.integer "tag_id"
t.integer "taggable_id" t.integer "taggable_id"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment