Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bug with reblogged view on Toots only showing latest reblogging accounts #26574

Merged
merged 2 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
55 changes: 53 additions & 2 deletions app/javascript/mastodon/actions/interactions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ export const REBLOG_REQUEST = 'REBLOG_REQUEST';
export const REBLOG_SUCCESS = 'REBLOG_SUCCESS';
export const REBLOG_FAIL = 'REBLOG_FAIL';

export const REBLOGS_EXPAND_REQUEST = 'REBLOGS_EXPAND_REQUEST';
export const REBLOGS_EXPAND_SUCCESS = 'REBLOGS_EXPAND_SUCCESS';
export const REBLOGS_EXPAND_FAIL = 'REBLOGS_EXPAND_FAIL';

export const FAVOURITE_REQUEST = 'FAVOURITE_REQUEST';
export const FAVOURITE_SUCCESS = 'FAVOURITE_SUCCESS';
export const FAVOURITE_FAIL = 'FAVOURITE_FAIL';
Expand Down Expand Up @@ -278,8 +282,10 @@ export function fetchReblogs(id) {
dispatch(fetchReblogsRequest(id));

api(getState).get(`/api/v1/statuses/${id}/reblogged_by`).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(fetchReblogsSuccess(id, response.data));
dispatch(fetchReblogsSuccess(id, response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map(item => item.id)));
}).catch(error => {
dispatch(fetchReblogsFail(id, error));
});
Expand All @@ -293,17 +299,62 @@ export function fetchReblogsRequest(id) {
};
}

export function fetchReblogsSuccess(id, accounts) {
export function fetchReblogsSuccess(id, accounts, next) {
return {
type: REBLOGS_FETCH_SUCCESS,
id,
accounts,
next,
};
}

export function fetchReblogsFail(id, error) {
return {
type: REBLOGS_FETCH_FAIL,
id,
error,
};
}

export function expandReblogs(id) {
return (dispatch, getState) => {
const url = getState().getIn(['user_lists', 'reblogged_by', id, 'next']);
if (url === null) {
return;
}

dispatch(expandReblogsRequest(id));

api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');

dispatch(importFetchedAccounts(response.data));
dispatch(expandReblogsSuccess(id, response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map(item => item.id)));
}).catch(error => dispatch(expandReblogsFail(id, error)));
};
}

export function expandReblogsRequest(id) {
return {
type: REBLOGS_EXPAND_REQUEST,
id,
};
}

export function expandReblogsSuccess(id, accounts, next) {
return {
type: REBLOGS_EXPAND_SUCCESS,
id,
accounts,
next,
};
}

export function expandReblogsFail(id, error) {
return {
type: REBLOGS_EXPAND_FAIL,
id,
error,
};
}
Expand Down
27 changes: 17 additions & 10 deletions app/javascript/mastodon/features/reblogs/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { connect } from 'react-redux';

import { debounce } from 'lodash';

import { Icon } from 'mastodon/components/icon';

import { fetchReblogs } from '../../actions/interactions';
import { fetchReblogs, expandReblogs } from '../../actions/interactions';
import ColumnHeader from '../../components/column_header';
import { LoadingIndicator } from '../../components/loading_indicator';
import ScrollableList from '../../components/scrollable_list';
Expand All @@ -22,7 +24,9 @@ const messages = defineMessages({
});

const mapStateToProps = (state, props) => ({
accountIds: state.getIn(['user_lists', 'reblogged_by', props.params.statusId]),
accountIds: state.getIn(['user_lists', 'reblogged_by', props.params.statusId, 'items']),
hasMore: !!state.getIn(['user_lists', 'reblogged_by', props.params.statusId, 'next']),
isLoading: state.getIn(['user_lists', 'reblogged_by', props.params.statusId, 'isLoading'], true),
});

class Reblogs extends ImmutablePureComponent {
Expand All @@ -31,6 +35,8 @@ class Reblogs extends ImmutablePureComponent {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
accountIds: ImmutablePropTypes.list,
hasMore: PropTypes.bool,
isLoading: PropTypes.bool,
multiColumn: PropTypes.bool,
intl: PropTypes.object.isRequired,
};
Expand All @@ -39,20 +45,18 @@ class Reblogs extends ImmutablePureComponent {
if (!this.props.accountIds) {
this.props.dispatch(fetchReblogs(this.props.params.statusId));
}
}

UNSAFE_componentWillReceiveProps(nextProps) {
if (nextProps.params.statusId !== this.props.params.statusId && nextProps.params.statusId) {
this.props.dispatch(fetchReblogs(nextProps.params.statusId));
}
}
};

handleRefresh = () => {
this.props.dispatch(fetchReblogs(this.props.params.statusId));
};

handleLoadMore = debounce(() => {
this.props.dispatch(expandReblogs(this.props.params.statusId));
}, 300, { leading: true });

render () {
const { intl, accountIds, multiColumn } = this.props;
const { intl, accountIds, hasMore, isLoading, multiColumn } = this.props;

if (!accountIds) {
return (
Expand All @@ -76,6 +80,9 @@ class Reblogs extends ImmutablePureComponent {

<ScrollableList
scrollKey='reblogs'
onLoadMore={this.handleLoadMore}
hasMore={hasMore}
isLoading={isLoading}
emptyMessage={emptyMessage}
bindToDocument={!multiColumn}
>
Expand Down
15 changes: 14 additions & 1 deletion app/javascript/mastodon/reducers/user_lists.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ import {
BLOCKS_EXPAND_FAIL,
} from '../actions/blocks';
import {
REBLOGS_FETCH_REQUEST,
REBLOGS_FETCH_SUCCESS,
REBLOGS_FETCH_FAIL,
REBLOGS_EXPAND_REQUEST,
REBLOGS_EXPAND_SUCCESS,
REBLOGS_EXPAND_FAIL,
FAVOURITES_FETCH_REQUEST,
FAVOURITES_FETCH_SUCCESS,
FAVOURITES_FETCH_FAIL,
Expand Down Expand Up @@ -139,7 +144,15 @@ export default function userLists(state = initialState, action) {
case FOLLOWING_EXPAND_FAIL:
return state.setIn(['following', action.id, 'isLoading'], false);
case REBLOGS_FETCH_SUCCESS:
return state.setIn(['reblogged_by', action.id], ImmutableList(action.accounts.map(item => item.id)));
return normalizeList(state, ['reblogged_by', action.id], action.accounts, action.next);
case REBLOGS_EXPAND_SUCCESS:
return appendToList(state, ['reblogged_by', action.id], action.accounts, action.next);
case REBLOGS_FETCH_REQUEST:
case REBLOGS_EXPAND_REQUEST:
return state.setIn(['reblogged_by', action.id, 'isLoading'], true);
case REBLOGS_FETCH_FAIL:
case REBLOGS_EXPAND_FAIL:
return state.setIn(['reblogged_by', action.id, 'isLoading'], false);
case FAVOURITES_FETCH_SUCCESS:
return normalizeList(state, ['favourited_by', action.id], action.accounts, action.next);
case FAVOURITES_EXPAND_SUCCESS:
Expand Down