diff --git a/app/soapbox/components/profile_hover_card.js b/app/soapbox/components/profile_hover_card.js
index 202be475d..c9d1024e7 100644
--- a/app/soapbox/components/profile_hover_card.js
+++ b/app/soapbox/components/profile_hover_card.js
@@ -4,7 +4,8 @@ import { useSelector, useDispatch } from 'react-redux';
import { makeGetAccount } from 'soapbox/selectors';
import { injectIntl, FormattedMessage } from 'react-intl';
import ImmutablePropTypes from 'react-immutable-proptypes';
-import UserPanel from 'soapbox/features/ui/components/user_panel';
+import BundleContainer from 'soapbox/features/ui/containers/bundle_container';
+import { UserPanel } from 'soapbox/features/ui/util/async-components';
import ActionButton from 'soapbox/features/ui/components/action_button';
import { isAdmin, isModerator } from 'soapbox/utils/accounts';
import Badge from 'soapbox/components/badge';
@@ -74,7 +75,9 @@ export const ProfileHoverCard = ({ visible }) => {
}
{badges}
diff --git a/app/soapbox/containers/soapbox.js b/app/soapbox/containers/soapbox.js
index bc53d5c9d..1bde94db0 100644
--- a/app/soapbox/containers/soapbox.js
+++ b/app/soapbox/containers/soapbox.js
@@ -15,8 +15,6 @@ import UI from '../features/ui';
// import Introduction from '../features/introduction';
import { preload } from '../actions/preload';
import { IntlProvider } from 'react-intl';
-import { previewState as previewMediaState } from 'soapbox/features/ui/components/media_modal';
-import { previewState as previewVideoState } from 'soapbox/features/ui/components/video_modal';
import ErrorBoundary from '../components/error_boundary';
import { fetchInstance } from 'soapbox/actions/instance';
import { fetchSoapboxConfig } from 'soapbox/actions/soapbox';
@@ -30,6 +28,9 @@ import { FE_SUBDIRECTORY } from 'soapbox/build_config';
const validLocale = locale => Object.keys(messages).includes(locale);
+const previewMediaState = 'previewMediaModal';
+const previewVideoState = 'previewVideoModal';
+
export const store = configureStore();
store.dispatch(preload());
diff --git a/app/soapbox/features/account/components/header.js b/app/soapbox/features/account/components/header.js
index 633fea01f..de3e74a1d 100644
--- a/app/soapbox/features/account/components/header.js
+++ b/app/soapbox/features/account/components/header.js
@@ -20,7 +20,8 @@ import {
import classNames from 'classnames';
import Avatar from 'soapbox/components/avatar';
import DropdownMenuContainer from 'soapbox/containers/dropdown_menu_container';
-import ProfileInfoPanel from '../../ui/components/profile_info_panel';
+import BundleContainer from 'soapbox/features/ui/containers/bundle_container';
+import { ProfileInfoPanel } from 'soapbox/features/ui/util/async-components';
import { debounce } from 'lodash';
import StillImage from 'soapbox/components/still_image';
import ActionButton from 'soapbox/features/ui/components/action_button';
@@ -301,12 +302,13 @@ class Header extends ImmutablePureComponent {
- {
- isSmallScreen &&
+ {isSmallScreen && (
- }
+ )}
);
@@ -343,12 +345,13 @@ class Header extends ImmutablePureComponent {
diff --git a/app/soapbox/features/follow_recommendations/components/follow_recommendations_container.js b/app/soapbox/features/follow_recommendations/components/follow_recommendations_container.js
new file mode 100644
index 000000000..657780f43
--- /dev/null
+++ b/app/soapbox/features/follow_recommendations/components/follow_recommendations_container.js
@@ -0,0 +1,36 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { FormattedMessage } from 'react-intl';
+import Button from 'soapbox/components/button';
+import FollowRecommendationsList from './follow_recommendations_list';
+
+export default class FollowRecommendationsContainer extends React.Component {
+
+ static propTypes = {
+ onDone: PropTypes.func.isRequired,
+ }
+
+ handleDone = () => {
+ this.props.onDone();
+ }
+
+ render() {
+ return (
+
+ );
+ }
+
+}
diff --git a/app/soapbox/features/follow_recommendations/index.js b/app/soapbox/features/follow_recommendations/index.js
index 6e043c9f2..b3aa44ea6 100644
--- a/app/soapbox/features/follow_recommendations/index.js
+++ b/app/soapbox/features/follow_recommendations/index.js
@@ -1,9 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { FormattedMessage } from 'react-intl';
import Column from 'soapbox/features/ui/components/column';
-import Button from 'soapbox/components/button';
-import FollowRecommendationsList from './components/follow_recommendations_list';
+import FollowRecommendationsContainer from './components/follow_recommendations_container';
export default class FollowRecommendations extends React.Component {
@@ -11,7 +9,7 @@ export default class FollowRecommendations extends React.Component {
router: PropTypes.object.isRequired,
};
- handleDone = () => {
+ onDone = () => {
const { router } = this.context;
router.history.push('/');
@@ -20,20 +18,7 @@ export default class FollowRecommendations extends React.Component {
render() {
return (
-
+
);
}
diff --git a/app/soapbox/features/home_timeline/index.js b/app/soapbox/features/home_timeline/index.js
index 9b63b6d83..d6c9340b7 100644
--- a/app/soapbox/features/home_timeline/index.js
+++ b/app/soapbox/features/home_timeline/index.js
@@ -7,12 +7,11 @@ import Column from '../../components/column';
import BundleContainer from 'soapbox/features/ui/containers/bundle_container';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { Link } from 'react-router-dom';
-import Button from 'soapbox/components/button';
import { OrderedSet as ImmutableOrderedSet } from 'immutable';
import { getFeatures } from 'soapbox/utils/features';
-function FollowRecommendationsList() {
- return import(/* webpackChunkName: "features/follow_recommendations" */'soapbox/features/follow_recommendations/components/follow_recommendations_list');
+function FollowRecommendationsContainer() {
+ return import(/* webpackChunkName: "features/follow_recommendations" */'soapbox/features/follow_recommendations/components/follow_recommendations_container');
}
const messages = defineMessages({
@@ -27,6 +26,7 @@ const mapStateToProps = state => {
hasUnread: state.getIn(['timelines', 'home', 'unread']) > 0,
isPartial: state.getIn(['timelines', 'home', 'isPartial']),
siteTitle: state.getIn(['instance', 'title']),
+ isLoading: state.getIn(['timelines', 'home', 'isLoading'], true),
isEmpty: state.getIn(['timelines', 'home', 'items'], ImmutableOrderedSet()).isEmpty(),
features,
};
@@ -42,6 +42,7 @@ class HomeTimeline extends React.PureComponent {
hasUnread: PropTypes.bool,
isPartial: PropTypes.bool,
siteTitle: PropTypes.string,
+ isLoading: PropTypes.bool,
isEmpty: PropTypes.bool,
features: PropTypes.object.isRequired,
};
@@ -92,35 +93,16 @@ class HomeTimeline extends React.PureComponent {
this.setState({ done: true });
}
- renderFollowRecommendations = () => {
- return (
-
-
-
-
- {Component => }
-
-
-
-
-
-
- );
- }
-
render() {
- const { intl, siteTitle, isEmpty, features } = this.props;
+ const { intl, siteTitle, isLoading, isEmpty, features } = this.props;
const { done } = this.state;
return (
- {(features.suggestions && isEmpty && !done) ? (
- this.renderFollowRecommendations()
+ {(features.suggestions && isEmpty && !isLoading && !done) ? (
+
+ {Component => }
+
) : (