Change home timeline to reload after follow recommendations in web UI (#16160)
parent
74081433d0
commit
0ad240cb6b
|
@ -18,17 +18,26 @@ export const TIMELINE_LOAD_PENDING = 'TIMELINE_LOAD_PENDING';
|
||||||
export const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT';
|
export const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT';
|
||||||
export const TIMELINE_CONNECT = 'TIMELINE_CONNECT';
|
export const TIMELINE_CONNECT = 'TIMELINE_CONNECT';
|
||||||
|
|
||||||
|
export const TIMELINE_MARK_AS_PARTIAL = 'TIMELINE_MARK_AS_PARTIAL';
|
||||||
|
|
||||||
export const loadPending = timeline => ({
|
export const loadPending = timeline => ({
|
||||||
type: TIMELINE_LOAD_PENDING,
|
type: TIMELINE_LOAD_PENDING,
|
||||||
timeline,
|
timeline,
|
||||||
});
|
});
|
||||||
|
|
||||||
export function updateTimeline(timeline, status, accept) {
|
export function updateTimeline(timeline, status, accept) {
|
||||||
return dispatch => {
|
return (dispatch, getState) => {
|
||||||
if (typeof accept === 'function' && !accept(status)) {
|
if (typeof accept === 'function' && !accept(status)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getState().getIn(['timelines', timeline, 'isPartial'])) {
|
||||||
|
// Prevent new items from being added to a partial timeline,
|
||||||
|
// since it will be reloaded anyway
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dispatch(importFetchedStatus(status));
|
dispatch(importFetchedStatus(status));
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
|
@ -183,3 +192,8 @@ export const disconnectTimeline = timeline => ({
|
||||||
timeline,
|
timeline,
|
||||||
usePendingItems: preferPendingItems,
|
usePendingItems: preferPendingItems,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const markAsPartial = timeline => ({
|
||||||
|
type: TIMELINE_MARK_AS_PARTIAL,
|
||||||
|
timeline,
|
||||||
|
});
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { FormattedMessage } from 'react-intl';
|
||||||
import { fetchSuggestions } from 'mastodon/actions/suggestions';
|
import { fetchSuggestions } from 'mastodon/actions/suggestions';
|
||||||
import { changeSetting, saveSettings } from 'mastodon/actions/settings';
|
import { changeSetting, saveSettings } from 'mastodon/actions/settings';
|
||||||
import { requestBrowserPermission } from 'mastodon/actions/notifications';
|
import { requestBrowserPermission } from 'mastodon/actions/notifications';
|
||||||
|
import { markAsPartial } from 'mastodon/actions/timelines';
|
||||||
import Column from 'mastodon/features/ui/components/column';
|
import Column from 'mastodon/features/ui/components/column';
|
||||||
import Account from './components/account';
|
import Account from './components/account';
|
||||||
import Logo from 'mastodon/components/logo';
|
import Logo from 'mastodon/components/logo';
|
||||||
|
@ -42,6 +43,15 @@ class FollowRecommendations extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillUnmount () {
|
||||||
|
const { dispatch } = this.props;
|
||||||
|
|
||||||
|
// Force the home timeline to be reloaded when the user navigates
|
||||||
|
// to it; if the user is new, it would've been empty before
|
||||||
|
|
||||||
|
dispatch(markAsPartial('home'));
|
||||||
|
}
|
||||||
|
|
||||||
handleDone = () => {
|
handleDone = () => {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
const { router } = this.context;
|
const { router } = this.context;
|
||||||
|
|
|
@ -73,7 +73,7 @@ class HomeTimeline extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
this.props.dispatch(fetchAnnouncements());
|
setTimeout(() => this.props.dispatch(fetchAnnouncements()), 700);
|
||||||
this._checkIfReloadNeeded(false, this.props.isPartial);
|
this._checkIfReloadNeeded(false, this.props.isPartial);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ class HomeTimeline extends React.PureComponent {
|
||||||
scrollKey={`home_timeline-${columnId}`}
|
scrollKey={`home_timeline-${columnId}`}
|
||||||
onLoadMore={this.handleLoadMore}
|
onLoadMore={this.handleLoadMore}
|
||||||
timelineId='home'
|
timelineId='home'
|
||||||
emptyMessage={<FormattedMessage id='empty_column.home' defaultMessage='Your home timeline is empty! Visit {public} or use search to get started and meet other users.' values={{ public: <Link to='/timelines/public'><FormattedMessage id='empty_column.home.public_timeline' defaultMessage='the public timeline' /></Link> }} />}
|
emptyMessage={<FormattedMessage id='empty_column.home' defaultMessage='Your home timeline is empty! Follow more people to fill it up. {suggestions}' values={{ suggestions: <Link to='/start'><FormattedMessage id='empty_column.home.suggestions' defaultMessage='See some suggestions' /></Link> }} />}
|
||||||
shouldUpdateScroll={shouldUpdateScroll}
|
shouldUpdateScroll={shouldUpdateScroll}
|
||||||
bindToDocument={!multiColumn}
|
bindToDocument={!multiColumn}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -178,7 +178,7 @@ class Notifications extends React.PureComponent {
|
||||||
render () {
|
render () {
|
||||||
const { intl, notifications, shouldUpdateScroll, isLoading, isUnread, columnId, multiColumn, hasMore, numPending, showFilterBar, lastReadId, canMarkAsRead, needsNotificationPermission } = this.props;
|
const { intl, notifications, shouldUpdateScroll, isLoading, isUnread, columnId, multiColumn, hasMore, numPending, showFilterBar, lastReadId, canMarkAsRead, needsNotificationPermission } = this.props;
|
||||||
const pinned = !!columnId;
|
const pinned = !!columnId;
|
||||||
const emptyMessage = <FormattedMessage id='empty_column.notifications' defaultMessage="You don't have any notifications yet. Interact with others to start the conversation." />;
|
const emptyMessage = <FormattedMessage id='empty_column.notifications' defaultMessage="You don't have any notifications yet. When other people interact with you, you will see it here." />;
|
||||||
|
|
||||||
let scrollableContent = null;
|
let scrollableContent = null;
|
||||||
|
|
||||||
|
|
|
@ -361,10 +361,9 @@ class UI extends React.PureComponent {
|
||||||
this.props.dispatch(closeOnboarding());
|
this.props.dispatch(closeOnboarding());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.props.dispatch(fetchMarkers());
|
|
||||||
this.props.dispatch(expandHomeTimeline());
|
this.props.dispatch(expandHomeTimeline());
|
||||||
this.props.dispatch(expandNotifications());
|
this.props.dispatch(expandNotifications());
|
||||||
|
setTimeout(() => this.props.dispatch(fetchMarkers()), 500);
|
||||||
setTimeout(() => this.props.dispatch(fetchFilters()), 500);
|
setTimeout(() => this.props.dispatch(fetchFilters()), 500);
|
||||||
|
|
||||||
this.hotkeys.__mousetrap__.stopCallback = (e, element) => {
|
this.hotkeys.__mousetrap__.stopCallback = (e, element) => {
|
||||||
|
|
|
@ -161,12 +161,12 @@
|
||||||
"empty_column.favourites": "No one has favourited this post yet. When someone does, they will show up here.",
|
"empty_column.favourites": "No one has favourited this post yet. When someone does, they will show up here.",
|
||||||
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
|
||||||
"empty_column.hashtag": "There is nothing in this hashtag yet.",
|
"empty_column.hashtag": "There is nothing in this hashtag yet.",
|
||||||
"empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.",
|
"empty_column.home": "Your home timeline is empty! Follow more people to fill it up. {suggestions}",
|
||||||
"empty_column.home.public_timeline": "the public timeline",
|
"empty_column.home.suggestions": "See some suggestions",
|
||||||
"empty_column.list": "There is nothing in this list yet. When members of this list publish new posts, they will appear here.",
|
"empty_column.list": "There is nothing in this list yet. When members of this list publish new posts, they will appear here.",
|
||||||
"empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
|
"empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
|
||||||
"empty_column.mutes": "You haven't muted any users yet.",
|
"empty_column.mutes": "You haven't muted any users yet.",
|
||||||
"empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
|
"empty_column.notifications": "You don't have any notifications yet. When other people interact with you, you will see it here.",
|
||||||
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up",
|
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up",
|
||||||
"error.unexpected_crash.explanation": "Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.",
|
"error.unexpected_crash.explanation": "Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.",
|
||||||
"error.unexpected_crash.explanation_addons": "This page could not be displayed correctly. This error is likely caused by a browser add-on or automatic translation tools.",
|
"error.unexpected_crash.explanation_addons": "This page could not be displayed correctly. This error is likely caused by a browser add-on or automatic translation tools.",
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
TIMELINE_CONNECT,
|
TIMELINE_CONNECT,
|
||||||
TIMELINE_DISCONNECT,
|
TIMELINE_DISCONNECT,
|
||||||
TIMELINE_LOAD_PENDING,
|
TIMELINE_LOAD_PENDING,
|
||||||
|
TIMELINE_MARK_AS_PARTIAL,
|
||||||
} from '../actions/timelines';
|
} from '../actions/timelines';
|
||||||
import {
|
import {
|
||||||
ACCOUNT_BLOCK_SUCCESS,
|
ACCOUNT_BLOCK_SUCCESS,
|
||||||
|
@ -168,6 +169,12 @@ export default function timelines(state = initialState, action) {
|
||||||
initialTimeline,
|
initialTimeline,
|
||||||
map => map.set('online', false).update(action.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(null) : items),
|
map => map.set('online', false).update(action.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(null) : items),
|
||||||
);
|
);
|
||||||
|
case TIMELINE_MARK_AS_PARTIAL:
|
||||||
|
return state.update(
|
||||||
|
action.timeline,
|
||||||
|
initialTimeline,
|
||||||
|
map => map.set('isPartial', true).set('items', ImmutableList()).set('pendingItems', ImmutableList()).set('unread', 0),
|
||||||
|
);
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue