~cytrogen/masto-fe

3b375ee3952f98278d235fe3fad04ee836169a62 — Renaud Chaput 2 years ago 45d7358
[Glitch] Upgrade to React 18

Port 8d6aea33260dedeacb3d22ac1a6d2f9cc3856a5e to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
M app/javascript/flavours/glitch/components/column.jsx => app/javascript/flavours/glitch/components/column.jsx +6 -4
@@ 3,6 3,8 @@ import PropTypes from 'prop-types';
import { supportsPassiveEvents } from 'detect-passive-events';
import { scrollTop } from '../scroll';

const listenerOptions = supportsPassiveEvents ? { passive: true } : false;

export default class Column extends React.PureComponent {

  static propTypes = {


@@ 37,17 39,17 @@ export default class Column extends React.PureComponent {

  componentDidMount () {
    if (this.props.bindToDocument) {
      document.addEventListener('wheel', this.handleWheel, supportsPassiveEvents ? { passive: true } : false);
      document.addEventListener('wheel', this.handleWheel, listenerOptions);
    } else {
      this.node.addEventListener('wheel', this.handleWheel, supportsPassiveEvents ? { passive: true } : false);
      this.node.addEventListener('wheel', this.handleWheel, listenerOptions);
    }
  }

  componentWillUnmount () {
    if (this.props.bindToDocument) {
      document.removeEventListener('wheel', this.handleWheel);
      document.removeEventListener('wheel', this.handleWheel, listenerOptions);
    } else {
      this.node.removeEventListener('wheel', this.handleWheel);
      this.node.removeEventListener('wheel', this.handleWheel, listenerOptions);
    }
  }


M app/javascript/flavours/glitch/components/dropdown_menu.jsx => app/javascript/flavours/glitch/components/dropdown_menu.jsx +6 -5
@@ 7,7 7,7 @@ import { supportsPassiveEvents } from 'detect-passive-events';
import classNames from 'classnames';
import { CircularProgress } from 'flavours/glitch/components/loading_indicator';

const listenerOptions = supportsPassiveEvents ? { passive: true } : false;
const listenerOptions = supportsPassiveEvents ? { passive: true, capture: true } : true;
let id = 0;

class DropdownMenu extends React.PureComponent {


@@ 35,12 35,13 @@ class DropdownMenu extends React.PureComponent {
  handleDocumentClick = e => {
    if (this.node && !this.node.contains(e.target)) {
      this.props.onClose();
      e.stopPropagation();
    }
  };

  componentDidMount () {
    document.addEventListener('click', this.handleDocumentClick, false);
    document.addEventListener('keydown', this.handleKeyDown, false);
    document.addEventListener('click', this.handleDocumentClick, { capture: true });
    document.addEventListener('keydown', this.handleKeyDown, { capture: true });
    document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);

    if (this.focusedItem && this.props.openedViaKeyboard) {


@@ 49,8 50,8 @@ class DropdownMenu extends React.PureComponent {
  }

  componentWillUnmount () {
    document.removeEventListener('click', this.handleDocumentClick, false);
    document.removeEventListener('keydown', this.handleKeyDown, false);
    document.removeEventListener('click', this.handleDocumentClick, { capture: true });
    document.removeEventListener('keydown', this.handleKeyDown, { capture: true });
    document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions);
  }


M app/javascript/flavours/glitch/components/scrollable_list.jsx => app/javascript/flavours/glitch/components/scrollable_list.jsx +6 -4
@@ 15,6 15,8 @@ import { connect } from 'react-redux';

const MOUSE_IDLE_DELAY = 300;

const listenerOptions = supportsPassiveEvents ? { passive: true } : false;

const mapStateToProps = (state, { scrollKey }) => {
  return {
    preventScroll: scrollKey === state.getIn(['dropdown_menu', 'scroll_key']),


@@ 237,20 239,20 @@ class ScrollableList extends PureComponent {
  attachScrollListener () {
    if (this.props.bindToDocument) {
      document.addEventListener('scroll', this.handleScroll);
      document.addEventListener('wheel', this.handleWheel, supportsPassiveEvents ? { passive: true } : undefined);
      document.addEventListener('wheel', this.handleWheel,  listenerOptions);
    } else {
      this.node.addEventListener('scroll', this.handleScroll);
      this.node.addEventListener('wheel', this.handleWheel, supportsPassiveEvents ? { passive: true } : undefined);
      this.node.addEventListener('wheel', this.handleWheel, listenerOptions);
    }
  }

  detachScrollListener () {
    if (this.props.bindToDocument) {
      document.removeEventListener('scroll', this.handleScroll);
      document.removeEventListener('wheel', this.handleWheel);
      document.removeEventListener('wheel', this.handleWheel, listenerOptions);
    } else {
      this.node.removeEventListener('scroll', this.handleScroll);
      this.node.removeEventListener('wheel', this.handleWheel);
      this.node.removeEventListener('wheel', this.handleWheel, listenerOptions);
    }
  }


M app/javascript/flavours/glitch/containers/media_container.jsx => app/javascript/flavours/glitch/containers/media_container.jsx +2 -2
@@ 1,5 1,5 @@
import React, { PureComponent, Fragment } from 'react';
import ReactDOM from 'react-dom';
import { createPortal } from 'react-dom';
import PropTypes from 'prop-types';
import { IntlProvider, addLocaleData } from 'react-intl';
import { fromJS } from 'immutable';


@@ 95,7 95,7 @@ export default class MediaContainer extends PureComponent {
              }),
            });

            return ReactDOM.createPortal(
            return createPortal(
              <Component {...props} key={`media-${i}`} />,
              component,
            );

M app/javascript/flavours/glitch/features/compose/components/dropdown_menu.jsx => app/javascript/flavours/glitch/features/compose/components/dropdown_menu.jsx +7 -6
@@ 2,12 2,12 @@
import PropTypes from 'prop-types';
import React from 'react';
import classNames from 'classnames';
import { supportsPassiveEvents } from 'detect-passive-events';

//  Components.
import { Icon } from 'flavours/glitch/components/icon';

//  Utils.
import { withPassive } from 'flavours/glitch/utils/dom_helpers';
const listenerOptions = supportsPassiveEvents ? { passive: true, capture: true } : true;

//  The component.
export default class ComposerOptionsDropdownContent extends React.PureComponent {


@@ 41,6 41,7 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent 
  handleDocumentClick = (e) => {
    if (this.node && !this.node.contains(e.target)) {
      this.props.onClose();
      e.stopPropagation();
    }
  };



@@ 51,8 52,8 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent 

  //  On mounting, we add our listeners.
  componentDidMount () {
    document.addEventListener('click', this.handleDocumentClick, false);
    document.addEventListener('touchend', this.handleDocumentClick, withPassive);
    document.addEventListener('click', this.handleDocumentClick, { capture: true });
    document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
    if (this.focusedItem) {
      this.focusedItem.focus({ preventScroll: true });
    } else {


@@ 62,8 63,8 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent 

  //  On unmounting, we remove our listeners.
  componentWillUnmount () {
    document.removeEventListener('click', this.handleDocumentClick, false);
    document.removeEventListener('touchend', this.handleDocumentClick, withPassive);
    document.removeEventListener('click', this.handleDocumentClick, { capture: true });
    document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions);
  }

  handleClick = (e) => {

M app/javascript/flavours/glitch/features/compose/components/emoji_picker_dropdown.jsx => app/javascript/flavours/glitch/features/compose/components/emoji_picker_dropdown.jsx +5 -5
@@ 28,7 28,7 @@ const messages = defineMessages({

let EmojiPicker, Emoji; // load asynchronously

const listenerOptions = supportsPassiveEvents ? { passive: true } : false;
const listenerOptions = supportsPassiveEvents ? { passive: true, capture: true } : true;

const backgroundImageFn = () => `${assetHost}/emoji/sheet_13.png`;



@@ 79,12 79,12 @@ class ModifierPickerMenu extends React.PureComponent {
  };

  attachListeners () {
    document.addEventListener('click', this.handleDocumentClick, false);
    document.addEventListener('click', this.handleDocumentClick, { capture: true });
    document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
  }

  removeListeners () {
    document.removeEventListener('click', this.handleDocumentClick, false);
    document.removeEventListener('click', this.handleDocumentClick, { capture: true });
    document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions);
  }



@@ 177,7 177,7 @@ class EmojiPickerMenuImpl extends React.PureComponent {
  };

  componentDidMount () {
    document.addEventListener('click', this.handleDocumentClick, false);
    document.addEventListener('click', this.handleDocumentClick, { capture: true });
    document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);

    // Because of https://github.com/react-bootstrap/react-bootstrap/issues/2614 we need


@@ 192,7 192,7 @@ class EmojiPickerMenuImpl extends React.PureComponent {
  }

  componentWillUnmount () {
    document.removeEventListener('click', this.handleDocumentClick, false);
    document.removeEventListener('click', this.handleDocumentClick, { capture: true });
    document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions);
  }


M app/javascript/flavours/glitch/features/compose/components/language_dropdown.jsx => app/javascript/flavours/glitch/features/compose/components/language_dropdown.jsx +4 -3
@@ 15,7 15,7 @@ const messages = defineMessages({
  clear: { id: 'emoji_button.clear', defaultMessage: 'Clear' },
});

const listenerOptions = supportsPassiveEvents ? { passive: true } : false;
const listenerOptions = supportsPassiveEvents ? { passive: true, capture: true } : true;

class LanguageDropdownMenu extends React.PureComponent {



@@ 39,11 39,12 @@ class LanguageDropdownMenu extends React.PureComponent {
  handleDocumentClick = e => {
    if (this.node && !this.node.contains(e.target)) {
      this.props.onClose();
      e.stopPropagation();
    }
  };

  componentDidMount () {
    document.addEventListener('click', this.handleDocumentClick, false);
    document.addEventListener('click', this.handleDocumentClick, { capture: true });
    document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);

    // Because of https://github.com/react-bootstrap/react-bootstrap/issues/2614 we need


@@ 57,7 58,7 @@ class LanguageDropdownMenu extends React.PureComponent {
  }

  componentWillUnmount () {
    document.removeEventListener('click', this.handleDocumentClick, false);
    document.removeEventListener('click', this.handleDocumentClick, { capture: true });
    document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions);
  }


M app/javascript/flavours/glitch/main.jsx => app/javascript/flavours/glitch/main.jsx +3 -2
@@ 1,5 1,5 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { createRoot } from 'react-dom/client';
import { setupBrowserNotifications } from 'flavours/glitch/actions/notifications';
import Mastodon from 'flavours/glitch/containers/mastodon';
import { store } from 'flavours/glitch/store';


@@ 18,7 18,8 @@ function main() {
    const mountNode = document.getElementById('mastodon');
    const props = JSON.parse(mountNode.getAttribute('data-props'));

    ReactDOM.render(<Mastodon {...props} />, mountNode);
    const root = createRoot(mountNode);
    root.render(<Mastodon {...props} />);
    store.dispatch(setupBrowserNotifications());

    if (process.env.NODE_ENV === 'production' && me && 'serviceWorker' in navigator) {

M app/javascript/flavours/glitch/packs/admin.jsx => app/javascript/flavours/glitch/packs/admin.jsx +6 -4
@@ 1,7 1,7 @@
import 'packs/public-path';
import ready from 'flavours/glitch/ready';
import React from 'react';
import ReactDOM from 'react-dom';
import { createRoot } from 'react-dom/client';

ready(() => {
  [].forEach.call(document.querySelectorAll('[data-admin-component]'), element => {


@@ 10,11 10,13 @@ ready(() => {

    import('flavours/glitch/containers/admin_component').then(({ default: AdminComponent }) => {
      return import('flavours/glitch/components/admin/' + componentName).then(({ default: Component }) => {
        ReactDOM.render((
        const root = createRoot(element);

        root.render (
          <AdminComponent locale={locale}>
            <Component {...componentProps} />
          </AdminComponent>
        ), element);
          </AdminComponent>,
        );
      });
    }).catch(error => {
      console.error(error);

M app/javascript/flavours/glitch/packs/public.jsx => app/javascript/flavours/glitch/packs/public.jsx +3 -2
@@ 11,7 11,7 @@ import { delegate }  from '@rails/ujs';
import emojify  from 'flavours/glitch/features/emoji/emoji';
import { getLocale }  from 'locales';
import React  from 'react';
import ReactDOM  from 'react-dom';
import { createRoot }  from 'react-dom/client';
import { createBrowserHistory }  from 'history';

const messages = defineMessages({


@@ 130,7 130,8 @@ function main() {

          const content = document.createElement('div');

          ReactDOM.render(<MediaContainer locale={locale} components={reactComponents} />, content);
          const root = createRoot(content);
          root.render(<MediaContainer locale={locale} components={reactComponents} />);
          document.body.appendChild(content);
          scrollToDetailedStatus();
        })

M app/javascript/flavours/glitch/packs/share.jsx => app/javascript/flavours/glitch/packs/share.jsx +4 -3
@@ 1,9 1,9 @@
import 'packs/public-path';
import { loadPolyfills } from 'flavours/glitch/polyfills';
import ready from 'flavours/glitch/ready';
import ComposeContainer from 'flavours/glitch/containers/compose_container';
import React from 'react';
import ReactDOM from 'react-dom';
import ready from 'flavours/glitch/ready';
import { createRoot } from 'react-dom/client';

function loaded() {
  const mountNode = document.getElementById('mastodon-compose');


@@ 13,7 13,8 @@ function loaded() {
    if(!attr) return;

    const props = JSON.parse(attr);
    ReactDOM.render(<ComposeContainer {...props} />, mountNode);
    const root = createRoot(mountNode);
    root.render(<ComposeContainer {...props} />);
  }
}


M app/javascript/flavours/glitch/utils/dom_helpers.js => app/javascript/flavours/glitch/utils/dom_helpers.js +0 -4
@@ 1,10 1,6 @@
//  Package imports.
import { supportsPassiveEvents } from 'detect-passive-events';

//  This will either be a passive lister options object (if passive
//  events are supported), or `false`.
export const withPassive = supportsPassiveEvents ? { passive: true } : false;

//  Focuses the root element.
export function focusRoot () {
  let e;