Fix public timelines being broken by new toots when they are not mounted (#10131)

rebase/4.0.0rc2
Eugen Rochko 2019-03-07 22:17:52 +01:00 committed by GitHub
parent 09c042aa10
commit be1c634b2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 28 additions and 7 deletions

View File

@ -158,7 +158,9 @@ export function submitCompose(routerHistory) {
// into the columns // into the columns
const insertIfOnline = timelineId => { const insertIfOnline = timelineId => {
if (getState().getIn(['timelines', timelineId, 'items', 0]) !== null) { const timeline = getState().getIn(['timelines', timelineId]);
if (timeline && timeline.get('items').size > 0 && timeline.getIn(['items', 0]) !== null && timeline.get('online')) {
dispatch(updateTimeline(timelineId, { ...response.data })); dispatch(updateTimeline(timelineId, { ...response.data }));
} }
}; };

View File

@ -3,6 +3,7 @@ import {
updateTimeline, updateTimeline,
deleteFromTimelines, deleteFromTimelines,
expandHomeTimeline, expandHomeTimeline,
connectTimeline,
disconnectTimeline, disconnectTimeline,
} from './timelines'; } from './timelines';
import { updateNotifications, expandNotifications } from './notifications'; import { updateNotifications, expandNotifications } from './notifications';
@ -16,7 +17,12 @@ export function connectTimelineStream (timelineId, path, pollingRefresh = null,
return connectStream (path, pollingRefresh, (dispatch, getState) => { return connectStream (path, pollingRefresh, (dispatch, getState) => {
const locale = getState().getIn(['meta', 'locale']); const locale = getState().getIn(['meta', 'locale']);
return { return {
onConnect() {
dispatch(connectTimeline(timelineId));
},
onDisconnect() { onDisconnect() {
dispatch(disconnectTimeline(timelineId)); dispatch(disconnectTimeline(timelineId));
}, },

View File

@ -12,6 +12,7 @@ export const TIMELINE_EXPAND_FAIL = 'TIMELINE_EXPAND_FAIL';
export const TIMELINE_SCROLL_TOP = 'TIMELINE_SCROLL_TOP'; export const TIMELINE_SCROLL_TOP = 'TIMELINE_SCROLL_TOP';
export const TIMELINE_CONNECT = 'TIMELINE_CONNECT';
export const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT'; export const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT';
export function updateTimeline(timeline, status, accept) { export function updateTimeline(timeline, status, accept) {
@ -143,6 +144,13 @@ export function scrollTopTimeline(timeline, top) {
}; };
}; };
export function connectTimeline(timeline) {
return {
type: TIMELINE_CONNECT,
timeline,
};
};
export function disconnectTimeline(timeline) { export function disconnectTimeline(timeline) {
return { return {
type: TIMELINE_DISCONNECT, type: TIMELINE_DISCONNECT,

View File

@ -6,6 +6,7 @@ import {
TIMELINE_EXPAND_REQUEST, TIMELINE_EXPAND_REQUEST,
TIMELINE_EXPAND_FAIL, TIMELINE_EXPAND_FAIL,
TIMELINE_SCROLL_TOP, TIMELINE_SCROLL_TOP,
TIMELINE_CONNECT,
TIMELINE_DISCONNECT, TIMELINE_DISCONNECT,
} from '../actions/timelines'; } from '../actions/timelines';
import { import {
@ -20,6 +21,7 @@ const initialState = ImmutableMap();
const initialTimeline = ImmutableMap({ const initialTimeline = ImmutableMap({
unread: 0, unread: 0,
online: false,
top: true, top: true,
isLoading: false, isLoading: false,
hasMore: true, hasMore: true,
@ -142,14 +144,13 @@ export default function timelines(state = initialState, action) {
return filterTimeline('home', state, action.relationship, action.statuses); return filterTimeline('home', state, action.relationship, action.statuses);
case TIMELINE_SCROLL_TOP: case TIMELINE_SCROLL_TOP:
return updateTop(state, action.timeline, action.top); return updateTop(state, action.timeline, action.top);
case TIMELINE_CONNECT:
return state.update(action.timeline, initialTimeline, map => map.set('online', true));
case TIMELINE_DISCONNECT: case TIMELINE_DISCONNECT:
return state.update( return state.update(
action.timeline, action.timeline,
initialTimeline, initialTimeline,
map => map.update( map => map.set('online', false).update('items', items => items.first() ? items.unshift(null) : items)
'items',
items => items.first() ? items.unshift(null) : items
)
); );
default: default:
return state; return state;

View File

@ -2,11 +2,11 @@ import WebSocketClient from 'websocket.js';
const randomIntUpTo = max => Math.floor(Math.random() * Math.floor(max)); const randomIntUpTo = max => Math.floor(Math.random() * Math.floor(max));
export function connectStream(path, pollingRefresh = null, callbacks = () => ({ onDisconnect() {}, onReceive() {} })) { export function connectStream(path, pollingRefresh = null, callbacks = () => ({ onConnect() {}, onDisconnect() {}, onReceive() {} })) {
return (dispatch, getState) => { return (dispatch, getState) => {
const streamingAPIBaseURL = getState().getIn(['meta', 'streaming_api_base_url']); const streamingAPIBaseURL = getState().getIn(['meta', 'streaming_api_base_url']);
const accessToken = getState().getIn(['meta', 'access_token']); const accessToken = getState().getIn(['meta', 'access_token']);
const { onDisconnect, onReceive } = callbacks(dispatch, getState); const { onConnect, onDisconnect, onReceive } = callbacks(dispatch, getState);
let polling = null; let polling = null;
@ -28,6 +28,8 @@ export function connectStream(path, pollingRefresh = null, callbacks = () => ({
if (pollingRefresh) { if (pollingRefresh) {
clearPolling(); clearPolling();
} }
onConnect();
}, },
disconnected () { disconnected () {
@ -47,6 +49,8 @@ export function connectStream(path, pollingRefresh = null, callbacks = () => ({
clearPolling(); clearPolling();
pollingRefresh(dispatch); pollingRefresh(dispatch);
} }
onConnect();
}, },
}); });