gearheads
/
mastodon
Archived
2
0
Fork 0

RemoveStatusService fleshed out, still doesn't send Salmon slaps though

gh/stable
Eugen Rochko 2016-09-05 01:59:46 +02:00
parent 413e700fe0
commit 926eea89b5
5 changed files with 84 additions and 19 deletions

View File

@ -1,6 +1,6 @@
export const TIMELINE_SET = 'TIMELINE_SET'; export const TIMELINE_SET = 'TIMELINE_SET';
export const TIMELINE_UPDATE = 'TIMELINE_UPDATE'; export const TIMELINE_UPDATE = 'TIMELINE_UPDATE';
export const TIMELINE_DELETE = 'TIMELINE_DELETE';
export function setTimeline(timeline, statuses) { export function setTimeline(timeline, statuses) {
return { return {
@ -17,3 +17,10 @@ export function updateTimeline(timeline, status) {
status: status status: status
}; };
} }
export function deleteFromTimeline(id) {
return {
type: TIMELINE_DELETE,
id: id
};
}

View File

@ -1,7 +1,7 @@
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import configureStore from '../store/configureStore'; import configureStore from '../store/configureStore';
import Frontend from '../components/frontend'; import Frontend from '../components/frontend';
import { setTimeline, updateTimeline } from '../actions/timelines'; import { setTimeline, updateTimeline, deleteFromTimelines } from '../actions/timelines';
import { setAccessToken } from '../actions/meta'; import { setAccessToken } from '../actions/meta';
import PureRenderMixin from 'react-addons-pure-render-mixin'; import PureRenderMixin from 'react-addons-pure-render-mixin';
@ -32,7 +32,11 @@ const Root = React.createClass({
disconnected: function() {}, disconnected: function() {},
received: function(data) { received: function(data) {
if (data.type === 'update') {
return store.dispatch(updateTimeline(data.timeline, JSON.parse(data.message))); return store.dispatch(updateTimeline(data.timeline, JSON.parse(data.message)));
} else if (data.type === 'delete') {
return store.dispatch(deleteFromTimelines(data.id));
}
} }
}); });
} }

View File

@ -1,10 +1,10 @@
import { TIMELINE_SET, TIMELINE_UPDATE } from '../actions/timelines'; import { TIMELINE_SET, TIMELINE_UPDATE, TIMELINE_DELETE } from '../actions/timelines';
import { REBLOG_SUCCESS, FAVOURITE_SUCCESS } from '../actions/interactions'; import { REBLOG_SUCCESS, FAVOURITE_SUCCESS } from '../actions/interactions';
import Immutable from 'immutable'; import Immutable from 'immutable';
const initialState = Immutable.Map({ const initialState = Immutable.Map({
home: Immutable.List(), home: Immutable.List([]),
mentions: Immutable.List(), mentions: Immutable.List([]),
statuses: Immutable.Map(), statuses: Immutable.Map(),
accounts: Immutable.Map() accounts: Immutable.Map()
}); });
@ -44,12 +44,22 @@ function updateTimelineWithMaps(state, timeline, status) {
return state; 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) { export default function timelines(state = initialState, action) {
switch(action.type) { switch(action.type) {
case TIMELINE_SET: case TIMELINE_SET:
return timelineToMaps(state, action.timeline, Immutable.fromJS(action.statuses)); return timelineToMaps(state, action.timeline, Immutable.fromJS(action.statuses));
case TIMELINE_UPDATE: 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 REBLOG_SUCCESS:
case FAVOURITE_SUCCESS: case FAVOURITE_SUCCESS:
return statusToMaps(state, Immutable.fromJS(action.response)); return statusToMaps(state, Immutable.fromJS(action.response));

View File

@ -31,7 +31,7 @@ class FanOutOnWriteService < BaseService
def push(type, receiver, status) def push(type, receiver, status)
redis.zadd(FeedManager.key(type, receiver.id), status.id, status.id) redis.zadd(FeedManager.key(type, receiver.id), status.id, status.id)
trim(type, receiver) 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 end
def trim(type, receiver) def trim(type, receiver)

View File

@ -1,10 +1,54 @@
class RemoveStatusService < BaseService class RemoveStatusService < BaseService
def call(status) def call(status)
status.destroy! 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 # TODO
# Remove from timelines of self, followers, and mentioned accounts end
# For remote mentioned accounts, send delete Salmon
# Push delete event through ActionCable 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
end end