Allow user to enable / disable notifications for a post from stream #5350
This commit is contained in:
parent
ccd7561072
commit
eccab62e32
14 changed files with 165 additions and 6 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 49 KiB |
BIN
app/assets/images/icons-sbcb16d92c7.png
Normal file
BIN
app/assets/images/icons-sbcb16d92c7.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 50 KiB |
BIN
app/assets/images/icons/create_participation.png
Normal file
BIN
app/assets/images/icons/create_participation.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
app/assets/images/icons/destroy_participation.png
Normal file
BIN
app/assets/images/icons/destroy_participation.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -23,10 +23,13 @@ app.views.StreamPost = app.views.Post.extend({
|
||||||
"click .remove_post": "destroyModel",
|
"click .remove_post": "destroyModel",
|
||||||
"click .hide_post": "hidePost",
|
"click .hide_post": "hidePost",
|
||||||
"click .post_report": "report",
|
"click .post_report": "report",
|
||||||
"click .block_user": "blockUser"
|
"click .block_user": "blockUser",
|
||||||
|
|
||||||
|
"click .create_participation": "createParticipation",
|
||||||
|
"click .destroy_participation": "destroyParticipation"
|
||||||
},
|
},
|
||||||
|
|
||||||
tooltipSelector : ".timeago, .post_scope, .block_user, .delete",
|
tooltipSelector : ".timeago, .post_scope, .block_user, .delete, .create_participation, .destroy_participation",
|
||||||
|
|
||||||
initialize : function(){
|
initialize : function(){
|
||||||
var personId = this.model.get('author').id;
|
var personId = this.model.get('author').id;
|
||||||
|
|
@ -113,6 +116,22 @@ app.views.StreamPost = app.views.Post.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
createParticipation: function (evt) {
|
||||||
|
that = this;
|
||||||
|
$.post("/posts/" + this.model.get("id") + "/participation", {}, function () {
|
||||||
|
that.model.set({participation: true});
|
||||||
|
that.render();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
destroyParticipation: function (evt) {
|
||||||
|
that = this;
|
||||||
|
$.post("/posts/" + this.model.get("id") + "/participation", { _method: "delete" }, function () {
|
||||||
|
that.model.set({participation: false});
|
||||||
|
that.render();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
focusCommentTextarea: function(evt){
|
focusCommentTextarea: function(evt){
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
this.$(".new_comment_form_wrapper").removeClass("hidden");
|
this.$(".new_comment_form_wrapper").removeClass("hidden");
|
||||||
|
|
|
||||||
|
|
@ -279,6 +279,22 @@ ul.as-selections {
|
||||||
width: 14px;
|
width: 14px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.create_participation {
|
||||||
|
display: inline-block;
|
||||||
|
.icons-create-participation {
|
||||||
|
height: 14px;
|
||||||
|
width: 14px;
|
||||||
|
background: image-url("icons/create_participation.png") center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.destroy_participation {
|
||||||
|
display: inline-block;
|
||||||
|
.icons-destroy-participation {
|
||||||
|
height: 14px;
|
||||||
|
width: 14px;
|
||||||
|
background: image-url("icons/destroy_participation.png") center;
|
||||||
|
}
|
||||||
|
}
|
||||||
.delete {
|
.delete {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
.icons-deletelabel {
|
.icons-deletelabel {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,15 @@
|
||||||
<a href="#" rel="nofollow" class="block_user" title="{{t "ignore"}}">
|
<a href="#" rel="nofollow" class="block_user" title="{{t "ignore"}}">
|
||||||
<div class="icons-ignoreuser control_icon"></div>
|
<div class="icons-ignoreuser control_icon"></div>
|
||||||
</a>
|
</a>
|
||||||
|
{{#if participation}}
|
||||||
|
<a href="#" rel="nofollow" class="destroy_participation" title="{{t "stream.disable_post_notifications"}}">
|
||||||
|
<div class="icons-destroy-participation control_icon"></div>
|
||||||
|
</a>
|
||||||
|
{{else}}
|
||||||
|
<a href="#" rel="nofollow" class="create_participation" title="{{t "stream.enable_post_notifications"}}">
|
||||||
|
<div class="icons-create-participation control_icon"></div>
|
||||||
|
</a>
|
||||||
|
{{/if}}
|
||||||
<a href="#" rel="nofollow" class="delete hide_post" title="{{t "stream.hide"}}">
|
<a href="#" rel="nofollow" class="delete hide_post" title="{{t "stream.hide"}}">
|
||||||
<div class="icons-deletelabel delete control_icon"/>
|
<div class="icons-deletelabel delete control_icon"/>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
23
app/controllers/participations_controller.rb
Normal file
23
app/controllers/participations_controller.rb
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
class ParticipationsController < ApplicationController
|
||||||
|
before_action :authenticate_user!
|
||||||
|
|
||||||
|
def create
|
||||||
|
post = current_user.find_visible_shareable_by_id(Post, params[:post_id])
|
||||||
|
if post
|
||||||
|
current_user.participate! post
|
||||||
|
render :nothing => true, :status => :created
|
||||||
|
else
|
||||||
|
render :nothing => true, :status => :forbidden
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@participation = current_user.participations.find_by :target_id => params[:post_id]
|
||||||
|
if @participation
|
||||||
|
@participation.destroy
|
||||||
|
render :nothing => true, :status => :no_content
|
||||||
|
else
|
||||||
|
render :nothing => true, :status => :unprocessable_entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -60,7 +60,7 @@ class Comment < ActiveRecord::Base
|
||||||
def notification_type(user, person)
|
def notification_type(user, person)
|
||||||
if self.post.author == user.person
|
if self.post.author == user.person
|
||||||
return Notifications::CommentOnPost
|
return Notifications::CommentOnPost
|
||||||
elsif self.post.comments.where(:author_id => user.person.id) != [] && self.author_id != user.person.id
|
elsif user.participations.where(:target_id => self.post).exists? && self.author_id != user.person.id
|
||||||
return Notifications::AlsoCommented
|
return Notifications::AlsoCommented
|
||||||
else
|
else
|
||||||
return false
|
return false
|
||||||
|
|
|
||||||
|
|
@ -41,13 +41,14 @@ class PostPresenter
|
||||||
:address => @post.address,
|
:address => @post.address,
|
||||||
:poll => @post.poll(),
|
:poll => @post.poll(),
|
||||||
:already_participated_in_poll => already_participated_in_poll,
|
:already_participated_in_poll => already_participated_in_poll,
|
||||||
|
:participation => participate?,
|
||||||
|
|
||||||
:interactions => {
|
:interactions => {
|
||||||
:likes => [user_like].compact,
|
:likes => [user_like].compact,
|
||||||
:reshares => [user_reshare].compact,
|
:reshares => [user_reshare].compact,
|
||||||
:comments_count => @post.comments_count,
|
:comments_count => @post.comments_count,
|
||||||
:likes_count => @post.likes_count,
|
:likes_count => @post.likes_count,
|
||||||
:reshares_count => @post.reshares_count,
|
:reshares_count => @post.reshares_count
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
@ -86,6 +87,10 @@ class PostPresenter
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def participate?
|
||||||
|
user_signed_in? && @current_user.participations.where(:target_id => @post).exists?
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class PostInteractionPresenter
|
class PostInteractionPresenter
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,8 @@ en:
|
||||||
hide_nsfw_posts: "Hide #nsfw posts"
|
hide_nsfw_posts: "Hide #nsfw posts"
|
||||||
follow: "Follow"
|
follow: "Follow"
|
||||||
unfollow: "Unfollow"
|
unfollow: "Unfollow"
|
||||||
|
enable_post_notifications: "Enable notifications for this post"
|
||||||
|
disable_post_notifications: "Disable notifications for this post"
|
||||||
via: "via <%= provider %>"
|
via: "via <%= provider %>"
|
||||||
|
|
||||||
likes:
|
likes:
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ Diaspora::Application.routes.draw do
|
||||||
resources :poll_participations, :only => [:create]
|
resources :poll_participations, :only => [:create]
|
||||||
|
|
||||||
resources :likes, :only => [:create, :destroy, :index ]
|
resources :likes, :only => [:create, :destroy, :index ]
|
||||||
resources :participations, :only => [:create, :destroy, :index]
|
resource :participation, :only => [:create, :destroy]
|
||||||
resources :comments, :only => [:new, :create, :destroy, :index]
|
resources :comments, :only => [:new, :create, :destroy, :index]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
79
spec/controllers/participations_controller_spec.rb
Normal file
79
spec/controllers/participations_controller_spec.rb
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe ParticipationsController, :type => :controller do
|
||||||
|
before do
|
||||||
|
allow(@controller).to receive(:current_user).and_return(alice)
|
||||||
|
sign_in :user, alice
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#create' do
|
||||||
|
let(:stranger) { FactoryGirl.create(:user) }
|
||||||
|
|
||||||
|
shared_examples 'on a visible post' do
|
||||||
|
it 'creates the participation' do
|
||||||
|
post :create, post_id: @post.id
|
||||||
|
expect(alice.participations.where(:target_id => @post.id)).to exist
|
||||||
|
expect(response.code).to eq('201')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'on my own post' do
|
||||||
|
before do
|
||||||
|
aspect_to_post = alice.aspects.where(:name => 'generic').first
|
||||||
|
@post = alice.post :status_message, :text => 'something', :to => aspect_to_post
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'on a visible post'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'on a post from a contact' do
|
||||||
|
before do
|
||||||
|
aspect_to_post = bob.aspects.where(:name => 'generic').first
|
||||||
|
@post = bob.post :status_message, :text => 'something', :to => aspect_to_post
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'on a visible post'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'on a public post from a stranger' do
|
||||||
|
before do
|
||||||
|
@post = stranger.post :status_message, :text => 'something', :public => true, :to => 'all'
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'on a visible post'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'on a non visible post' do
|
||||||
|
before do
|
||||||
|
@post = stranger.post :status_message, :text => 'something', :public => false, :to => 'all'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not create the participation' do
|
||||||
|
post :create, post_id: @post.id
|
||||||
|
expect(alice.participations.where(:target_id => @post.id)).not_to exist
|
||||||
|
expect(response.code).to eq('403')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#destroy' do
|
||||||
|
let(:post) { FactoryGirl.create(:status_message) }
|
||||||
|
|
||||||
|
context 'on a post you partecipate to' do
|
||||||
|
before { alice.participate! post }
|
||||||
|
|
||||||
|
it 'should remove participation' do
|
||||||
|
delete :destroy, post_id: post.id
|
||||||
|
expect(alice.participations.where(:target_id => post.id)).not_to exist
|
||||||
|
expect(response.code).to eq('204')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'on a post you do not partecipate to' do
|
||||||
|
it 'says it is an unprocessable request' do
|
||||||
|
delete :destroy, post_id: post.id
|
||||||
|
expect(response.code).to eq('422')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -12,11 +12,17 @@ describe Comment, :type => :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'comment#notification_type' do
|
describe 'comment#notification_type' do
|
||||||
|
let (:comment) { alice.comment!(@status, "why so formal?") }
|
||||||
|
|
||||||
it "returns 'comment_on_post' if the comment is on a post you own" do
|
it "returns 'comment_on_post' if the comment is on a post you own" do
|
||||||
comment = alice.comment!(@status, "why so formal?")
|
|
||||||
expect(comment.notification_type(bob, alice.person)).to eq(Notifications::CommentOnPost)
|
expect(comment.notification_type(bob, alice.person)).to eq(Notifications::CommentOnPost)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "returns 'also_commented' if the comment is on a post you participate to" do
|
||||||
|
eve.participate! @status
|
||||||
|
expect(comment.notification_type(eve, alice.person)).to eq(Notifications::AlsoCommented)
|
||||||
|
end
|
||||||
|
|
||||||
it 'returns false if the comment is not on a post you own and no one "also_commented"' do
|
it 'returns false if the comment is not on a post you own and no one "also_commented"' do
|
||||||
comment = alice.comment!(@status, "I simply felt like issuing a greeting. Do step off.")
|
comment = alice.comment!(@status, "I simply felt like issuing a greeting. Do step off.")
|
||||||
expect(comment.notification_type(eve, alice.person)).to be false
|
expect(comment.notification_type(eve, alice.person)).to be false
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue