mastodon.jsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import PropTypes from 'prop-types';
  2. import { PureComponent } from 'react';
  3. import { Helmet } from 'react-helmet';
  4. import { Route } from 'react-router-dom';
  5. import { Provider as ReduxProvider } from 'react-redux';
  6. import { ScrollContext } from 'react-router-scroll-4';
  7. import { fetchCustomEmojis } from 'mastodon/actions/custom_emojis';
  8. import { hydrateStore } from 'mastodon/actions/store';
  9. import { connectUserStream } from 'mastodon/actions/streaming';
  10. import ErrorBoundary from 'mastodon/components/error_boundary';
  11. import { Router } from 'mastodon/components/router';
  12. import UI from 'mastodon/features/ui';
  13. import initialState, { title as siteTitle } from 'mastodon/initial_state';
  14. import { IntlProvider } from 'mastodon/locales';
  15. import { store } from 'mastodon/store';
  16. import { isProduction } from 'mastodon/utils/environment';
  17. const title = isProduction() ? siteTitle : `${siteTitle} (Dev)`;
  18. const hydrateAction = hydrateStore(initialState);
  19. store.dispatch(hydrateAction);
  20. if (initialState.meta.me) {
  21. store.dispatch(fetchCustomEmojis());
  22. }
  23. const createIdentityContext = state => ({
  24. signedIn: !!state.meta.me,
  25. accountId: state.meta.me,
  26. disabledAccountId: state.meta.disabled_account_id,
  27. accessToken: state.meta.access_token,
  28. permissions: state.role ? state.role.permissions : 0,
  29. });
  30. export default class Mastodon extends PureComponent {
  31. static childContextTypes = {
  32. identity: PropTypes.shape({
  33. signedIn: PropTypes.bool.isRequired,
  34. accountId: PropTypes.string,
  35. disabledAccountId: PropTypes.string,
  36. accessToken: PropTypes.string,
  37. }).isRequired,
  38. };
  39. identity = createIdentityContext(initialState);
  40. getChildContext() {
  41. return {
  42. identity: this.identity,
  43. };
  44. }
  45. componentDidMount() {
  46. if (this.identity.signedIn) {
  47. this.disconnect = store.dispatch(connectUserStream());
  48. }
  49. }
  50. componentWillUnmount () {
  51. if (this.disconnect) {
  52. this.disconnect();
  53. this.disconnect = null;
  54. }
  55. }
  56. shouldUpdateScroll (prevRouterProps, { location }) {
  57. return !(location.state?.mastodonModalKey && location.state?.mastodonModalKey !== prevRouterProps?.location?.state?.mastodonModalKey);
  58. }
  59. render () {
  60. return (
  61. <IntlProvider>
  62. <ReduxProvider store={store}>
  63. <ErrorBoundary>
  64. <Router>
  65. <ScrollContext shouldUpdateScroll={this.shouldUpdateScroll}>
  66. <Route path='/' component={UI} />
  67. </ScrollContext>
  68. </Router>
  69. <Helmet defaultTitle={title} titleTemplate={`%s - ${title}`} />
  70. </ErrorBoundary>
  71. </ReduxProvider>
  72. </IntlProvider>
  73. );
  74. }
  75. }