Refactor <FavouritedStatuses> and <BookmarkedStatuses> into TypeScript (#34356)
				
					
				
			This commit is contained in:
		@@ -1,115 +0,0 @@
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
 | 
			
		||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 | 
			
		||||
 | 
			
		||||
import { Helmet } from 'react-helmet';
 | 
			
		||||
 | 
			
		||||
import ImmutablePropTypes from 'react-immutable-proptypes';
 | 
			
		||||
import ImmutablePureComponent from 'react-immutable-pure-component';
 | 
			
		||||
import { connect } from 'react-redux';
 | 
			
		||||
 | 
			
		||||
import { debounce } from 'lodash';
 | 
			
		||||
 | 
			
		||||
import BookmarksIcon from '@/material-icons/400-24px/bookmarks-fill.svg?react';
 | 
			
		||||
import { fetchBookmarkedStatuses, expandBookmarkedStatuses } from 'mastodon/actions/bookmarks';
 | 
			
		||||
import { addColumn, removeColumn, moveColumn } from 'mastodon/actions/columns';
 | 
			
		||||
import ColumnHeader from 'mastodon/components/column_header';
 | 
			
		||||
import StatusList from 'mastodon/components/status_list';
 | 
			
		||||
import Column from 'mastodon/features/ui/components/column';
 | 
			
		||||
import { getStatusList } from 'mastodon/selectors';
 | 
			
		||||
 | 
			
		||||
const messages = defineMessages({
 | 
			
		||||
  heading: { id: 'column.bookmarks', defaultMessage: 'Bookmarks' },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const mapStateToProps = state => ({
 | 
			
		||||
  statusIds: getStatusList(state, 'bookmarks'),
 | 
			
		||||
  isLoading: state.getIn(['status_lists', 'bookmarks', 'isLoading'], true),
 | 
			
		||||
  hasMore: !!state.getIn(['status_lists', 'bookmarks', 'next']),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
class Bookmarks extends ImmutablePureComponent {
 | 
			
		||||
 | 
			
		||||
  static propTypes = {
 | 
			
		||||
    dispatch: PropTypes.func.isRequired,
 | 
			
		||||
    statusIds: ImmutablePropTypes.list.isRequired,
 | 
			
		||||
    intl: PropTypes.object.isRequired,
 | 
			
		||||
    columnId: PropTypes.string,
 | 
			
		||||
    multiColumn: PropTypes.bool,
 | 
			
		||||
    hasMore: PropTypes.bool,
 | 
			
		||||
    isLoading: PropTypes.bool,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  UNSAFE_componentWillMount () {
 | 
			
		||||
    this.props.dispatch(fetchBookmarkedStatuses());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handlePin = () => {
 | 
			
		||||
    const { columnId, dispatch } = this.props;
 | 
			
		||||
 | 
			
		||||
    if (columnId) {
 | 
			
		||||
      dispatch(removeColumn(columnId));
 | 
			
		||||
    } else {
 | 
			
		||||
      dispatch(addColumn('BOOKMARKS', {}));
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleMove = (dir) => {
 | 
			
		||||
    const { columnId, dispatch } = this.props;
 | 
			
		||||
    dispatch(moveColumn(columnId, dir));
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleHeaderClick = () => {
 | 
			
		||||
    this.column.scrollTop();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  setRef = c => {
 | 
			
		||||
    this.column = c;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleLoadMore = debounce(() => {
 | 
			
		||||
    this.props.dispatch(expandBookmarkedStatuses());
 | 
			
		||||
  }, 300, { leading: true });
 | 
			
		||||
 | 
			
		||||
  render () {
 | 
			
		||||
    const { intl, statusIds, columnId, multiColumn, hasMore, isLoading } = this.props;
 | 
			
		||||
    const pinned = !!columnId;
 | 
			
		||||
 | 
			
		||||
    const emptyMessage = <FormattedMessage id='empty_column.bookmarked_statuses' defaultMessage="You don't have any bookmarked posts yet. When you bookmark one, it will show up here." />;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <Column bindToDocument={!multiColumn} ref={this.setRef} label={intl.formatMessage(messages.heading)}>
 | 
			
		||||
        <ColumnHeader
 | 
			
		||||
          icon='bookmarks'
 | 
			
		||||
          iconComponent={BookmarksIcon}
 | 
			
		||||
          title={intl.formatMessage(messages.heading)}
 | 
			
		||||
          onPin={this.handlePin}
 | 
			
		||||
          onMove={this.handleMove}
 | 
			
		||||
          onClick={this.handleHeaderClick}
 | 
			
		||||
          pinned={pinned}
 | 
			
		||||
          multiColumn={multiColumn}
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
        <StatusList
 | 
			
		||||
          trackScroll={!pinned}
 | 
			
		||||
          statusIds={statusIds}
 | 
			
		||||
          scrollKey={`bookmarked_statuses-${columnId}`}
 | 
			
		||||
          hasMore={hasMore}
 | 
			
		||||
          isLoading={isLoading}
 | 
			
		||||
          onLoadMore={this.handleLoadMore}
 | 
			
		||||
          emptyMessage={emptyMessage}
 | 
			
		||||
          bindToDocument={!multiColumn}
 | 
			
		||||
          timelineId='bookmarks'
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
        <Helmet>
 | 
			
		||||
          <title>{intl.formatMessage(messages.heading)}</title>
 | 
			
		||||
          <meta name='robots' content='noindex' />
 | 
			
		||||
        </Helmet>
 | 
			
		||||
      </Column>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default connect(mapStateToProps)(injectIntl(Bookmarks));
 | 
			
		||||
							
								
								
									
										116
									
								
								app/javascript/mastodon/features/bookmarked_statuses/index.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								app/javascript/mastodon/features/bookmarked_statuses/index.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
			
		||||
import { useEffect, useRef, useCallback } from 'react';
 | 
			
		||||
 | 
			
		||||
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
 | 
			
		||||
 | 
			
		||||
import { Helmet } from 'react-helmet';
 | 
			
		||||
 | 
			
		||||
import BookmarksIcon from '@/material-icons/400-24px/bookmarks-fill.svg?react';
 | 
			
		||||
import {
 | 
			
		||||
  fetchBookmarkedStatuses,
 | 
			
		||||
  expandBookmarkedStatuses,
 | 
			
		||||
} from 'mastodon/actions/bookmarks';
 | 
			
		||||
import { addColumn, removeColumn, moveColumn } from 'mastodon/actions/columns';
 | 
			
		||||
import { Column } from 'mastodon/components/column';
 | 
			
		||||
import type { ColumnRef } from 'mastodon/components/column';
 | 
			
		||||
import { ColumnHeader } from 'mastodon/components/column_header';
 | 
			
		||||
import StatusList from 'mastodon/components/status_list';
 | 
			
		||||
import { getStatusList } from 'mastodon/selectors';
 | 
			
		||||
import { useAppDispatch, useAppSelector } from 'mastodon/store';
 | 
			
		||||
 | 
			
		||||
const messages = defineMessages({
 | 
			
		||||
  heading: { id: 'column.bookmarks', defaultMessage: 'Bookmarks' },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const Bookmarks: React.FC<{
 | 
			
		||||
  columnId: string;
 | 
			
		||||
  multiColumn: boolean;
 | 
			
		||||
}> = ({ columnId, multiColumn }) => {
 | 
			
		||||
  const intl = useIntl();
 | 
			
		||||
  const dispatch = useAppDispatch();
 | 
			
		||||
  const columnRef = useRef<ColumnRef>(null);
 | 
			
		||||
  const statusIds = useAppSelector((state) =>
 | 
			
		||||
    getStatusList(state, 'bookmarks'),
 | 
			
		||||
  );
 | 
			
		||||
  const isLoading = useAppSelector(
 | 
			
		||||
    (state) =>
 | 
			
		||||
      state.status_lists.getIn(['bookmarks', 'isLoading'], true) as boolean,
 | 
			
		||||
  );
 | 
			
		||||
  const hasMore = useAppSelector(
 | 
			
		||||
    (state) => !!state.status_lists.getIn(['bookmarks', 'next']),
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    dispatch(fetchBookmarkedStatuses());
 | 
			
		||||
  }, [dispatch]);
 | 
			
		||||
 | 
			
		||||
  const handlePin = useCallback(() => {
 | 
			
		||||
    if (columnId) {
 | 
			
		||||
      dispatch(removeColumn(columnId));
 | 
			
		||||
    } else {
 | 
			
		||||
      dispatch(addColumn('BOOKMARKS', {}));
 | 
			
		||||
    }
 | 
			
		||||
  }, [dispatch, columnId]);
 | 
			
		||||
 | 
			
		||||
  const handleMove = useCallback(
 | 
			
		||||
    (dir: number) => {
 | 
			
		||||
      dispatch(moveColumn(columnId, dir));
 | 
			
		||||
    },
 | 
			
		||||
    [dispatch, columnId],
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const handleHeaderClick = useCallback(() => {
 | 
			
		||||
    columnRef.current?.scrollTop();
 | 
			
		||||
  }, []);
 | 
			
		||||
 | 
			
		||||
  const handleLoadMore = useCallback(() => {
 | 
			
		||||
    dispatch(expandBookmarkedStatuses());
 | 
			
		||||
  }, [dispatch]);
 | 
			
		||||
 | 
			
		||||
  const pinned = !!columnId;
 | 
			
		||||
 | 
			
		||||
  const emptyMessage = (
 | 
			
		||||
    <FormattedMessage
 | 
			
		||||
      id='empty_column.bookmarked_statuses'
 | 
			
		||||
      defaultMessage="You don't have any bookmarked posts yet. When you bookmark one, it will show up here."
 | 
			
		||||
    />
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <Column
 | 
			
		||||
      bindToDocument={!multiColumn}
 | 
			
		||||
      ref={columnRef}
 | 
			
		||||
      label={intl.formatMessage(messages.heading)}
 | 
			
		||||
    >
 | 
			
		||||
      <ColumnHeader
 | 
			
		||||
        icon='bookmarks'
 | 
			
		||||
        iconComponent={BookmarksIcon}
 | 
			
		||||
        title={intl.formatMessage(messages.heading)}
 | 
			
		||||
        onPin={handlePin}
 | 
			
		||||
        onMove={handleMove}
 | 
			
		||||
        onClick={handleHeaderClick}
 | 
			
		||||
        pinned={pinned}
 | 
			
		||||
        multiColumn={multiColumn}
 | 
			
		||||
      />
 | 
			
		||||
 | 
			
		||||
      <StatusList
 | 
			
		||||
        trackScroll={!pinned}
 | 
			
		||||
        statusIds={statusIds}
 | 
			
		||||
        scrollKey={`bookmarked_statuses-${columnId}`}
 | 
			
		||||
        hasMore={hasMore}
 | 
			
		||||
        isLoading={isLoading}
 | 
			
		||||
        onLoadMore={handleLoadMore}
 | 
			
		||||
        emptyMessage={emptyMessage}
 | 
			
		||||
        bindToDocument={!multiColumn}
 | 
			
		||||
        timelineId='bookmarks'
 | 
			
		||||
      />
 | 
			
		||||
 | 
			
		||||
      <Helmet>
 | 
			
		||||
        <title>{intl.formatMessage(messages.heading)}</title>
 | 
			
		||||
        <meta name='robots' content='noindex' />
 | 
			
		||||
      </Helmet>
 | 
			
		||||
    </Column>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// eslint-disable-next-line import/no-default-export
 | 
			
		||||
export default Bookmarks;
 | 
			
		||||
@@ -1,115 +0,0 @@
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
 | 
			
		||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 | 
			
		||||
 | 
			
		||||
import { Helmet } from 'react-helmet';
 | 
			
		||||
 | 
			
		||||
import ImmutablePropTypes from 'react-immutable-proptypes';
 | 
			
		||||
import ImmutablePureComponent from 'react-immutable-pure-component';
 | 
			
		||||
import { connect } from 'react-redux';
 | 
			
		||||
 | 
			
		||||
import { debounce } from 'lodash';
 | 
			
		||||
 | 
			
		||||
import StarIcon from '@/material-icons/400-24px/star-fill.svg?react';
 | 
			
		||||
import { addColumn, removeColumn, moveColumn } from 'mastodon/actions/columns';
 | 
			
		||||
import { fetchFavouritedStatuses, expandFavouritedStatuses } from 'mastodon/actions/favourites';
 | 
			
		||||
import ColumnHeader from 'mastodon/components/column_header';
 | 
			
		||||
import StatusList from 'mastodon/components/status_list';
 | 
			
		||||
import Column from 'mastodon/features/ui/components/column';
 | 
			
		||||
import { getStatusList } from 'mastodon/selectors';
 | 
			
		||||
 | 
			
		||||
const messages = defineMessages({
 | 
			
		||||
  heading: { id: 'column.favourites', defaultMessage: 'Favorites' },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const mapStateToProps = state => ({
 | 
			
		||||
  statusIds: getStatusList(state, 'favourites'),
 | 
			
		||||
  isLoading: state.getIn(['status_lists', 'favourites', 'isLoading'], true),
 | 
			
		||||
  hasMore: !!state.getIn(['status_lists', 'favourites', 'next']),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
class Favourites extends ImmutablePureComponent {
 | 
			
		||||
 | 
			
		||||
  static propTypes = {
 | 
			
		||||
    dispatch: PropTypes.func.isRequired,
 | 
			
		||||
    statusIds: ImmutablePropTypes.list.isRequired,
 | 
			
		||||
    intl: PropTypes.object.isRequired,
 | 
			
		||||
    columnId: PropTypes.string,
 | 
			
		||||
    multiColumn: PropTypes.bool,
 | 
			
		||||
    hasMore: PropTypes.bool,
 | 
			
		||||
    isLoading: PropTypes.bool,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  UNSAFE_componentWillMount () {
 | 
			
		||||
    this.props.dispatch(fetchFavouritedStatuses());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handlePin = () => {
 | 
			
		||||
    const { columnId, dispatch } = this.props;
 | 
			
		||||
 | 
			
		||||
    if (columnId) {
 | 
			
		||||
      dispatch(removeColumn(columnId));
 | 
			
		||||
    } else {
 | 
			
		||||
      dispatch(addColumn('FAVOURITES', {}));
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleMove = (dir) => {
 | 
			
		||||
    const { columnId, dispatch } = this.props;
 | 
			
		||||
    dispatch(moveColumn(columnId, dir));
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleHeaderClick = () => {
 | 
			
		||||
    this.column.scrollTop();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  setRef = c => {
 | 
			
		||||
    this.column = c;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleLoadMore = debounce(() => {
 | 
			
		||||
    this.props.dispatch(expandFavouritedStatuses());
 | 
			
		||||
  }, 300, { leading: true });
 | 
			
		||||
 | 
			
		||||
  render () {
 | 
			
		||||
    const { intl, statusIds, columnId, multiColumn, hasMore, isLoading } = this.props;
 | 
			
		||||
    const pinned = !!columnId;
 | 
			
		||||
 | 
			
		||||
    const emptyMessage = <FormattedMessage id='empty_column.favourited_statuses' defaultMessage="You don't have any favorite posts yet. When you favorite one, it will show up here." />;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <Column bindToDocument={!multiColumn} ref={this.setRef} label={intl.formatMessage(messages.heading)}>
 | 
			
		||||
        <ColumnHeader
 | 
			
		||||
          icon='star'
 | 
			
		||||
          iconComponent={StarIcon}
 | 
			
		||||
          title={intl.formatMessage(messages.heading)}
 | 
			
		||||
          onPin={this.handlePin}
 | 
			
		||||
          onMove={this.handleMove}
 | 
			
		||||
          onClick={this.handleHeaderClick}
 | 
			
		||||
          pinned={pinned}
 | 
			
		||||
          multiColumn={multiColumn}
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
        <StatusList
 | 
			
		||||
          trackScroll={!pinned}
 | 
			
		||||
          statusIds={statusIds}
 | 
			
		||||
          scrollKey={`favourited_statuses-${columnId}`}
 | 
			
		||||
          hasMore={hasMore}
 | 
			
		||||
          isLoading={isLoading}
 | 
			
		||||
          onLoadMore={this.handleLoadMore}
 | 
			
		||||
          emptyMessage={emptyMessage}
 | 
			
		||||
          bindToDocument={!multiColumn}
 | 
			
		||||
          timelineId='favourites'
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
        <Helmet>
 | 
			
		||||
          <title>{intl.formatMessage(messages.heading)}</title>
 | 
			
		||||
          <meta name='robots' content='noindex' />
 | 
			
		||||
        </Helmet>
 | 
			
		||||
      </Column>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default connect(mapStateToProps)(injectIntl(Favourites));
 | 
			
		||||
							
								
								
									
										116
									
								
								app/javascript/mastodon/features/favourited_statuses/index.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								app/javascript/mastodon/features/favourited_statuses/index.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
			
		||||
import { useEffect, useRef, useCallback } from 'react';
 | 
			
		||||
 | 
			
		||||
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
 | 
			
		||||
 | 
			
		||||
import { Helmet } from 'react-helmet';
 | 
			
		||||
 | 
			
		||||
import StarIcon from '@/material-icons/400-24px/star-fill.svg?react';
 | 
			
		||||
import { addColumn, removeColumn, moveColumn } from 'mastodon/actions/columns';
 | 
			
		||||
import {
 | 
			
		||||
  fetchFavouritedStatuses,
 | 
			
		||||
  expandFavouritedStatuses,
 | 
			
		||||
} from 'mastodon/actions/favourites';
 | 
			
		||||
import { Column } from 'mastodon/components/column';
 | 
			
		||||
import type { ColumnRef } from 'mastodon/components/column';
 | 
			
		||||
import { ColumnHeader } from 'mastodon/components/column_header';
 | 
			
		||||
import StatusList from 'mastodon/components/status_list';
 | 
			
		||||
import { getStatusList } from 'mastodon/selectors';
 | 
			
		||||
import { useAppDispatch, useAppSelector } from 'mastodon/store';
 | 
			
		||||
 | 
			
		||||
const messages = defineMessages({
 | 
			
		||||
  heading: { id: 'column.favourites', defaultMessage: 'Favorites' },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const Favourites: React.FC<{ columnId: string; multiColumn: boolean }> = ({
 | 
			
		||||
  columnId,
 | 
			
		||||
  multiColumn,
 | 
			
		||||
}) => {
 | 
			
		||||
  const dispatch = useAppDispatch();
 | 
			
		||||
  const intl = useIntl();
 | 
			
		||||
  const columnRef = useRef<ColumnRef>(null);
 | 
			
		||||
  const statusIds = useAppSelector((state) =>
 | 
			
		||||
    getStatusList(state, 'favourites'),
 | 
			
		||||
  );
 | 
			
		||||
  const isLoading = useAppSelector(
 | 
			
		||||
    (state) =>
 | 
			
		||||
      state.status_lists.getIn(['favourites', 'isLoading'], true) as boolean,
 | 
			
		||||
  );
 | 
			
		||||
  const hasMore = useAppSelector(
 | 
			
		||||
    (state) => !!state.status_lists.getIn(['favourites', 'next']),
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    dispatch(fetchFavouritedStatuses());
 | 
			
		||||
  }, [dispatch]);
 | 
			
		||||
 | 
			
		||||
  const handlePin = useCallback(() => {
 | 
			
		||||
    if (columnId) {
 | 
			
		||||
      dispatch(removeColumn(columnId));
 | 
			
		||||
    } else {
 | 
			
		||||
      dispatch(addColumn('FAVOURITES', {}));
 | 
			
		||||
    }
 | 
			
		||||
  }, [dispatch, columnId]);
 | 
			
		||||
 | 
			
		||||
  const handleMove = useCallback(
 | 
			
		||||
    (dir: number) => {
 | 
			
		||||
      dispatch(moveColumn(columnId, dir));
 | 
			
		||||
    },
 | 
			
		||||
    [dispatch, columnId],
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const handleHeaderClick = useCallback(() => {
 | 
			
		||||
    columnRef.current?.scrollTop();
 | 
			
		||||
  }, []);
 | 
			
		||||
 | 
			
		||||
  const handleLoadMore = useCallback(() => {
 | 
			
		||||
    dispatch(expandFavouritedStatuses());
 | 
			
		||||
  }, [dispatch]);
 | 
			
		||||
 | 
			
		||||
  const pinned = !!columnId;
 | 
			
		||||
 | 
			
		||||
  const emptyMessage = (
 | 
			
		||||
    <FormattedMessage
 | 
			
		||||
      id='empty_column.favourited_statuses'
 | 
			
		||||
      defaultMessage="You don't have any favorite posts yet. When you favorite one, it will show up here."
 | 
			
		||||
    />
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <Column
 | 
			
		||||
      bindToDocument={!multiColumn}
 | 
			
		||||
      ref={columnRef}
 | 
			
		||||
      label={intl.formatMessage(messages.heading)}
 | 
			
		||||
    >
 | 
			
		||||
      <ColumnHeader
 | 
			
		||||
        icon='star'
 | 
			
		||||
        iconComponent={StarIcon}
 | 
			
		||||
        title={intl.formatMessage(messages.heading)}
 | 
			
		||||
        onPin={handlePin}
 | 
			
		||||
        onMove={handleMove}
 | 
			
		||||
        onClick={handleHeaderClick}
 | 
			
		||||
        pinned={pinned}
 | 
			
		||||
        multiColumn={multiColumn}
 | 
			
		||||
      />
 | 
			
		||||
 | 
			
		||||
      <StatusList
 | 
			
		||||
        trackScroll={!pinned}
 | 
			
		||||
        statusIds={statusIds}
 | 
			
		||||
        scrollKey={`favourited_statuses-${columnId}`}
 | 
			
		||||
        hasMore={hasMore}
 | 
			
		||||
        isLoading={isLoading}
 | 
			
		||||
        onLoadMore={handleLoadMore}
 | 
			
		||||
        emptyMessage={emptyMessage}
 | 
			
		||||
        bindToDocument={!multiColumn}
 | 
			
		||||
        timelineId='favourites'
 | 
			
		||||
      />
 | 
			
		||||
 | 
			
		||||
      <Helmet>
 | 
			
		||||
        <title>{intl.formatMessage(messages.heading)}</title>
 | 
			
		||||
        <meta name='robots' content='noindex' />
 | 
			
		||||
      </Helmet>
 | 
			
		||||
    </Column>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// eslint-disable-next-line import/no-default-export
 | 
			
		||||
export default Favourites;
 | 
			
		||||
@@ -96,6 +96,7 @@ const removeOneFromList = (state, listType, status) => {
 | 
			
		||||
  return state.updateIn([listType, 'items'], (list) => list.delete(status.get('id')));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** @type {import('@reduxjs/toolkit').Reducer<typeof initialState>} */
 | 
			
		||||
export default function statusLists(state = initialState, action) {
 | 
			
		||||
  switch(action.type) {
 | 
			
		||||
  case FAVOURITED_STATUSES_FETCH_REQUEST:
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@ import { me } from '../initial_state';
 | 
			
		||||
import { getFilters } from './filters';
 | 
			
		||||
 | 
			
		||||
export { makeGetAccount } from "./accounts";
 | 
			
		||||
export { getStatusList } from "./statuses";
 | 
			
		||||
 | 
			
		||||
export const makeGetStatus = () => {
 | 
			
		||||
  return createSelector(
 | 
			
		||||
@@ -77,7 +78,3 @@ export const makeGetReport = () => createSelector([
 | 
			
		||||
  (_, base) => base,
 | 
			
		||||
  (state, _, targetAccountId) => state.getIn(['accounts', targetAccountId]),
 | 
			
		||||
], (base, targetAccount) => base.set('target_account', targetAccount));
 | 
			
		||||
 | 
			
		||||
export const getStatusList = createSelector([
 | 
			
		||||
  (state, type) => state.getIn(['status_lists', type, 'items']),
 | 
			
		||||
], (items) => items.toList());
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								app/javascript/mastodon/selectors/statuses.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								app/javascript/mastodon/selectors/statuses.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
import { createSelector } from '@reduxjs/toolkit';
 | 
			
		||||
import type { OrderedSet as ImmutableOrderedSet } from 'immutable';
 | 
			
		||||
 | 
			
		||||
import type { RootState } from 'mastodon/store';
 | 
			
		||||
 | 
			
		||||
export const getStatusList = createSelector(
 | 
			
		||||
  [
 | 
			
		||||
    (
 | 
			
		||||
      state: RootState,
 | 
			
		||||
      type: 'favourites' | 'bookmarks' | 'pins' | 'trending',
 | 
			
		||||
    ) =>
 | 
			
		||||
      state.status_lists.getIn([type, 'items']) as ImmutableOrderedSet<string>,
 | 
			
		||||
  ],
 | 
			
		||||
  (items) => items.toList(),
 | 
			
		||||
);
 | 
			
		||||
		Reference in New Issue
	
	Block a user