From 0ad240cb6b8662e31dfae6279cbee07a4c75b231 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 7 May 2021 14:33:57 +0200 Subject: [PATCH] Change home timeline to reload after follow recommendations in web UI (#16160) --- app/javascript/mastodon/actions/timelines.js | 16 +++++++++++++++- .../features/follow_recommendations/index.js | 10 ++++++++++ .../mastodon/features/home_timeline/index.js | 4 ++-- .../mastodon/features/notifications/index.js | 2 +- app/javascript/mastodon/features/ui/index.js | 3 +-- app/javascript/mastodon/locales/en.json | 6 +++--- app/javascript/mastodon/reducers/timelines.js | 7 +++++++ 7 files changed, 39 insertions(+), 9 deletions(-) diff --git a/app/javascript/mastodon/actions/timelines.js b/app/javascript/mastodon/actions/timelines.js index de1725acf..31ae09e4a 100644 --- a/app/javascript/mastodon/actions/timelines.js +++ b/app/javascript/mastodon/actions/timelines.js @@ -18,17 +18,26 @@ export const TIMELINE_LOAD_PENDING = 'TIMELINE_LOAD_PENDING'; export const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT'; export const TIMELINE_CONNECT = 'TIMELINE_CONNECT'; +export const TIMELINE_MARK_AS_PARTIAL = 'TIMELINE_MARK_AS_PARTIAL'; + export const loadPending = timeline => ({ type: TIMELINE_LOAD_PENDING, timeline, }); export function updateTimeline(timeline, status, accept) { - return dispatch => { + return (dispatch, getState) => { if (typeof accept === 'function' && !accept(status)) { 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({ @@ -183,3 +192,8 @@ export const disconnectTimeline = timeline => ({ timeline, usePendingItems: preferPendingItems, }); + +export const markAsPartial = timeline => ({ + type: TIMELINE_MARK_AS_PARTIAL, + timeline, +}); diff --git a/app/javascript/mastodon/features/follow_recommendations/index.js b/app/javascript/mastodon/features/follow_recommendations/index.js index 5b30a206e..a35ff3e82 100644 --- a/app/javascript/mastodon/features/follow_recommendations/index.js +++ b/app/javascript/mastodon/features/follow_recommendations/index.js @@ -7,6 +7,7 @@ import { FormattedMessage } from 'react-intl'; import { fetchSuggestions } from 'mastodon/actions/suggestions'; import { changeSetting, saveSettings } from 'mastodon/actions/settings'; import { requestBrowserPermission } from 'mastodon/actions/notifications'; +import { markAsPartial } from 'mastodon/actions/timelines'; import Column from 'mastodon/features/ui/components/column'; import Account from './components/account'; 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 = () => { const { dispatch } = this.props; const { router } = this.context; diff --git a/app/javascript/mastodon/features/home_timeline/index.js b/app/javascript/mastodon/features/home_timeline/index.js index 577ff33bb..b85c69af7 100644 --- a/app/javascript/mastodon/features/home_timeline/index.js +++ b/app/javascript/mastodon/features/home_timeline/index.js @@ -73,7 +73,7 @@ class HomeTimeline extends React.PureComponent { } componentDidMount () { - this.props.dispatch(fetchAnnouncements()); + setTimeout(() => this.props.dispatch(fetchAnnouncements()), 700); this._checkIfReloadNeeded(false, this.props.isPartial); } @@ -153,7 +153,7 @@ class HomeTimeline extends React.PureComponent { scrollKey={`home_timeline-${columnId}`} onLoadMore={this.handleLoadMore} timelineId='home' - emptyMessage={ }} />} + emptyMessage={ }} />} shouldUpdateScroll={shouldUpdateScroll} bindToDocument={!multiColumn} /> diff --git a/app/javascript/mastodon/features/notifications/index.js b/app/javascript/mastodon/features/notifications/index.js index cf8fd7127..1a621eca9 100644 --- a/app/javascript/mastodon/features/notifications/index.js +++ b/app/javascript/mastodon/features/notifications/index.js @@ -178,7 +178,7 @@ class Notifications extends React.PureComponent { render () { const { intl, notifications, shouldUpdateScroll, isLoading, isUnread, columnId, multiColumn, hasMore, numPending, showFilterBar, lastReadId, canMarkAsRead, needsNotificationPermission } = this.props; const pinned = !!columnId; - const emptyMessage = ; + const emptyMessage = ; let scrollableContent = null; diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js index 078a69f0f..2b9fe1603 100644 --- a/app/javascript/mastodon/features/ui/index.js +++ b/app/javascript/mastodon/features/ui/index.js @@ -361,10 +361,9 @@ class UI extends React.PureComponent { this.props.dispatch(closeOnboarding()); } - this.props.dispatch(fetchMarkers()); this.props.dispatch(expandHomeTimeline()); this.props.dispatch(expandNotifications()); - + setTimeout(() => this.props.dispatch(fetchMarkers()), 500); setTimeout(() => this.props.dispatch(fetchFilters()), 500); this.hotkeys.__mousetrap__.stopCallback = (e, element) => { diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 6ef9c7922..d426b5082 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -161,12 +161,12 @@ "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.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.public_timeline": "the public timeline", + "empty_column.home": "Your home timeline is empty! Follow more people to fill it up. {suggestions}", + "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.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.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", "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.", diff --git a/app/javascript/mastodon/reducers/timelines.js b/app/javascript/mastodon/reducers/timelines.js index 9156db021..b66c19fd5 100644 --- a/app/javascript/mastodon/reducers/timelines.js +++ b/app/javascript/mastodon/reducers/timelines.js @@ -9,6 +9,7 @@ import { TIMELINE_CONNECT, TIMELINE_DISCONNECT, TIMELINE_LOAD_PENDING, + TIMELINE_MARK_AS_PARTIAL, } from '../actions/timelines'; import { ACCOUNT_BLOCK_SUCCESS, @@ -168,6 +169,12 @@ export default function timelines(state = initialState, action) { initialTimeline, 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: return state; }