forked from treehouse/mastodon
RemoveStatusService fleshed out, still doesn't send Salmon slaps though
parent
413e700fe0
commit
926eea89b5
|
@ -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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
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';
|
||||||
|
|
||||||
const store = configureStore();
|
const store = configureStore();
|
||||||
|
|
||||||
|
@ -32,7 +32,11 @@ const Root = React.createClass({
|
||||||
disconnected: function() {},
|
disconnected: function() {},
|
||||||
|
|
||||||
received: function(data) {
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue