commit: 926eea89b51196821d49c7216f38faf0aedb4b09
parent: 413e700fe027ed7a4fdac325a9369d1481d52458
Author: Eugen Rochko <eugen@zeonfederated.com>
Date: Mon, 5 Sep 2016 01:59:46 +0200
RemoveStatusService fleshed out, still doesn't send Salmon slaps though
Diffstat:
5 files changed, 83 insertions(+), 18 deletions(-)
diff --git a/app/assets/javascripts/components/actions/timelines.jsx b/app/assets/javascripts/components/actions/timelines.jsx
@@ -1,6 +1,6 @@
export const TIMELINE_SET = 'TIMELINE_SET';
export const TIMELINE_UPDATE = 'TIMELINE_UPDATE';
-
+export const TIMELINE_DELETE = 'TIMELINE_DELETE';
export function setTimeline(timeline, statuses) {
return {
@@ -17,3 +17,10 @@ export function updateTimeline(timeline, status) {
status: status
};
}
+
+export function deleteFromTimeline(id) {
+ return {
+ type: TIMELINE_DELETE,
+ id: id
+ };
+}
diff --git a/app/assets/javascripts/components/containers/root.jsx b/app/assets/javascripts/components/containers/root.jsx
@@ -1,9 +1,9 @@
-import { Provider } from 'react-redux';
-import configureStore from '../store/configureStore';
-import Frontend from '../components/frontend';
-import { setTimeline, updateTimeline } from '../actions/timelines';
-import { setAccessToken } from '../actions/meta';
-import PureRenderMixin from 'react-addons-pure-render-mixin';
+import { Provider } from 'react-redux';
+import configureStore from '../store/configureStore';
+import Frontend from '../components/frontend';
+import { setTimeline, updateTimeline, deleteFromTimelines } from '../actions/timelines';
+import { setAccessToken } from '../actions/meta';
+import PureRenderMixin from 'react-addons-pure-render-mixin';
const store = configureStore();
@@ -32,7 +32,11 @@ const Root = React.createClass({
disconnected: function() {},
received: function(data) {
- return store.dispatch(updateTimeline(data.timeline, JSON.parse(data.message)));
+ if (data.type === 'update') {
+ return store.dispatch(updateTimeline(data.timeline, JSON.parse(data.message)));
+ } else if (data.type === 'delete') {
+ return store.dispatch(deleteFromTimelines(data.id));
+ }
}
});
}
diff --git a/app/assets/javascripts/components/reducers/timelines.jsx b/app/assets/javascripts/components/reducers/timelines.jsx
@@ -1,10 +1,10 @@
-import { TIMELINE_SET, TIMELINE_UPDATE } from '../actions/timelines';
-import { REBLOG_SUCCESS, FAVOURITE_SUCCESS } from '../actions/interactions';
-import Immutable from 'immutable';
+import { TIMELINE_SET, TIMELINE_UPDATE, TIMELINE_DELETE } from '../actions/timelines';
+import { REBLOG_SUCCESS, FAVOURITE_SUCCESS } from '../actions/interactions';
+import Immutable from 'immutable';
const initialState = Immutable.Map({
- home: Immutable.List(),
- mentions: Immutable.List(),
+ home: Immutable.List([]),
+ mentions: Immutable.List([]),
statuses: Immutable.Map(),
accounts: Immutable.Map()
});
@@ -44,12 +44,22 @@ function updateTimelineWithMaps(state, timeline, status) {
return state;
};
+function deleteStatus(state, id) {
+ ['home', 'mentions'].forEach(function (timeline) {
+ state = state.update(timeline, list => list.filterNot(item => item === id));
+ });
+
+ return state.deleteIn(['statuses', id]);
+};
+
export default function timelines(state = initialState, action) {
switch(action.type) {
case TIMELINE_SET:
return timelineToMaps(state, action.timeline, Immutable.fromJS(action.statuses));
case TIMELINE_UPDATE:
- return updateTimelineWithMaps(state, action.timeline,Immutable.fromJS(action.status));
+ return updateTimelineWithMaps(state, action.timeline, Immutable.fromJS(action.status));
+ case TIMELINE_DELETE:
+ return deleteStatus(state, action.id);
case REBLOG_SUCCESS:
case FAVOURITE_SUCCESS:
return statusToMaps(state, Immutable.fromJS(action.response));
diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb
@@ -31,7 +31,7 @@ class FanOutOnWriteService < BaseService
def push(type, receiver, status)
redis.zadd(FeedManager.key(type, receiver.id), status.id, status.id)
trim(type, receiver)
- ActionCable.server.broadcast("timeline:#{receiver.id}", timeline: type, message: inline_render(receiver, status))
+ ActionCable.server.broadcast("timeline:#{receiver.id}", type: 'update', timeline: type, message: inline_render(receiver, status))
end
def trim(type, receiver)
diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb
@@ -1,10 +1,54 @@
class RemoveStatusService < BaseService
def call(status)
+ remove_from_self(status) if status.account.local?
+ remove_from_followers(status)
+ remove_from_mentioned(status)
+ remove_reblogs(status)
+
status.destroy!
+ end
+
+ private
+
+ def remove_from_self(status)
+ unpush(:home, status.account, status)
+ end
+
+ def remove_from_followers(status)
+ status.account.followers.each do |follower|
+ next unless follower.local?
+ unpush(:home, follower, status)
+ end
+ end
+
+ def remove_from_mentioned(status)
+ status.mentions.each do |mention|
+ mentioned_account = mention.account
+ if mentioned_account.local?
+ unpush(:mentions, mentioned_account, status)
+ else
+ send_delete_salmon(mentioned_account, status)
+ end
+ end
+ end
+
+ def send_delete_salmon(account, status)
# TODO
- # Remove from timelines of self, followers, and mentioned accounts
- # For remote mentioned accounts, send delete Salmon
- # Push delete event through ActionCable
+ end
+
+ def remove_reblogs(status)
+ status.reblogs.each do |reblog|
+ RemoveStatusService.new.(reblog)
+ end
+ end
+
+ def unpush(type, receiver, status)
+ redis.zremrangebyscore(FeedManager.key(type, receiver.id), status.id, status.id)
+ ActionCable.server.broadcast("timeline:#{receiver.id}", type: 'delete', id: status.id)
+ end
+
+ def redis
+ $redis
end
end