commit: 7b9a4af3112dc4edcd378dc94190e2eb8e041f56
parent: 2c9e672ee2437677d6e39383e5f8e8e0837024b9
Author: Eugen Rochko <eugen@zeonfederated.com>
Date: Mon, 3 Oct 2016 18:17:06 +0200
API for blocking and unblocking
Diffstat:
10 files changed, 106 insertions(+), 8 deletions(-)
diff --git a/app/assets/javascripts/components/components/status_content.jsx b/app/assets/javascripts/components/components/status_content.jsx
@@ -26,7 +26,7 @@ const StatusContent = React.createClass({
} else {
link.setAttribute('target', '_blank');
link.setAttribute('rel', 'noopener');
- link.addEventListener('click', this.onNormalClick);
+ link.addEventListener('click', this.onNormalClick.bind(this));
}
}
},
@@ -36,7 +36,7 @@ const StatusContent = React.createClass({
e.preventDefault();
this.context.router.push(`/accounts/${mention.get('id')}`);
}
-
+
e.stopPropagation();
},
diff --git a/app/assets/javascripts/components/containers/mastodon.jsx b/app/assets/javascripts/components/containers/mastodon.jsx
@@ -40,11 +40,15 @@ const Mastodon = React.createClass({
if (typeof App !== 'undefined') {
App.timeline = App.cable.subscriptions.create("TimelineChannel", {
- connected: function() {},
+ connected () {
- disconnected: function() {},
+ },
- received: function(data) {
+ disconnected () {
+
+ },
+
+ received (data) {
switch(data.type) {
case 'update':
return store.dispatch(updateTimeline(data.timeline, JSON.parse(data.message)));
@@ -53,6 +57,8 @@ const Mastodon = React.createClass({
case 'merge':
case 'unmerge':
return store.dispatch(refreshTimeline('home'));
+ case 'block':
+ return store.dispatch(refreshTimeline('mentions'));
}
}
});
diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb
@@ -24,13 +24,25 @@ class Api::V1::AccountsController < ApiController
end
def follow
- @follow = FollowService.new.call(current_user.account, @account.acct)
+ FollowService.new.call(current_user.account, @account.acct)
+ set_relationship
+ render action: :relationship
+ end
+
+ def block
+ BlockService.new.call(current_user.account, @account)
set_relationship
render action: :relationship
end
def unfollow
- @unfollow = UnfollowService.new.call(current_user.account, @account)
+ UnfollowService.new.call(current_user.account, @account)
+ set_relationship
+ render action: :relationship
+ end
+
+ def unblock
+ UnblockService.new.call(current_user.account, @account)
set_relationship
render action: :relationship
end
diff --git a/app/services/block_service.rb b/app/services/block_service.rb
@@ -0,0 +1,25 @@
+class BlockService < BaseService
+ def call(account, target_account)
+ return if account.id == target_account.id
+
+ UnfollowService.new.call(account, target_account) if account.following?(target_account)
+ account.block!(target_account)
+ clear_mentions(account, target_account)
+ end
+
+ private
+
+ def clear_mentions(account, target_account)
+ timeline_key = FeedManager.instance.key(:mentions, account.id)
+
+ target_account.statuses.select('id').find_each do |status|
+ redis.zrem(timeline_key, status.id)
+ end
+
+ FeedManager.instance.broadcast(account.id, type: 'block', id: target_account.id)
+ end
+
+ def redis
+ $redis
+ end
+end
diff --git a/app/services/unblock_service.rb b/app/services/unblock_service.rb
@@ -0,0 +1,5 @@
+class UnblockService < BaseService
+ def call(account, target_account)
+ account.unblock!(target_account) if account.blocking?(target_account)
+ end
+end
diff --git a/app/services/unfollow_service.rb b/app/services/unfollow_service.rb
@@ -13,7 +13,7 @@ class UnfollowService < BaseService
def unmerge_from_timeline(from_account, into_account)
timeline_key = FeedManager.instance.key(:home, into_account.id)
- from_account.statuses.find_each do |status|
+ from_account.statuses.select('id').find_each do |status|
redis.zrem(timeline_key, status.id)
end
diff --git a/config/routes.rb b/config/routes.rb
@@ -74,6 +74,8 @@ Rails.application.routes.draw do
post :follow
post :unfollow
+ post :block
+ post :unblock
end
end
end
diff --git a/spec/controllers/api/v1/accounts_controller_spec.rb b/spec/controllers/api/v1/accounts_controller_spec.rb
@@ -79,6 +79,44 @@ RSpec.describe Api::V1::AccountsController, type: :controller do
end
end
+ describe 'POST #block' do
+ let(:other_account) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob')).account }
+
+ before do
+ user.account.follow!(other_account)
+ post :block, params: { id: other_account.id }
+ end
+
+ it 'returns http success' do
+ expect(response).to have_http_status(:success)
+ end
+
+ it 'removes the following relation between user and target user' do
+ expect(user.account.following?(other_account)).to be false
+ end
+
+ it 'creates a blocking relation' do
+ expect(user.account.blocking?(other_account)).to be true
+ end
+ end
+
+ describe 'POST #unblock' do
+ let(:other_account) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob')).account }
+
+ before do
+ user.account.block!(other_account)
+ post :unblock, params: { id: other_account.id }
+ end
+
+ it 'returns http success' do
+ expect(response).to have_http_status(:success)
+ end
+
+ it 'removes the blocking relation between user and target user' do
+ expect(user.account.blocking?(other_account)).to be false
+ end
+ end
+
describe 'GET #relationships' do
let(:simon) { Fabricate(:user, email: 'simon@example.com', account: Fabricate(:account, username: 'simon')).account }
let(:lewis) { Fabricate(:user, email: 'lewis@example.com', account: Fabricate(:account, username: 'lewis')).account }
diff --git a/spec/services/block_service_spec.rb b/spec/services/block_service_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe BlockService do
+ subject { BlockService.new }
+end
diff --git a/spec/services/unblock_service_spec.rb b/spec/services/unblock_service_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe UnblockService do
+ subject { UnblockService.new }
+end