mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-12-13 15:58:50 +00:00
Fix error when visiting non-public hashtag timelines (#36961)
This commit is contained in:
@@ -197,13 +197,16 @@ export const HashtagHeader: React.FC<{
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Button
|
{signedIn && (
|
||||||
onClick={handleFollow}
|
<Button
|
||||||
text={intl.formatMessage(
|
onClick={handleFollow}
|
||||||
tag.following ? messages.unfollowHashtag : messages.followHashtag,
|
text={intl.formatMessage(
|
||||||
)}
|
tag.following
|
||||||
disabled={!signedIn}
|
? messages.unfollowHashtag
|
||||||
/>
|
: messages.followHashtag,
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { expandHashtagTimeline, clearTimeline } from 'mastodon/actions/timelines
|
|||||||
import Column from 'mastodon/components/column';
|
import Column from 'mastodon/components/column';
|
||||||
import ColumnHeader from 'mastodon/components/column_header';
|
import ColumnHeader from 'mastodon/components/column_header';
|
||||||
import { identityContextPropShape, withIdentity } from 'mastodon/identity_context';
|
import { identityContextPropShape, withIdentity } from 'mastodon/identity_context';
|
||||||
import { remoteTopicFeedAccess, me } from 'mastodon/initial_state';
|
import { remoteTopicFeedAccess, me, localTopicFeedAccess } from 'mastodon/initial_state';
|
||||||
|
|
||||||
import StatusListContainer from '../ui/containers/status_list_container';
|
import StatusListContainer from '../ui/containers/status_list_container';
|
||||||
|
|
||||||
@@ -25,9 +25,11 @@ import ColumnSettingsContainer from './containers/column_settings_container';
|
|||||||
|
|
||||||
const mapStateToProps = (state, props) => {
|
const mapStateToProps = (state, props) => {
|
||||||
const local = props.params.local || (!me && remoteTopicFeedAccess !== 'public');
|
const local = props.params.local || (!me && remoteTopicFeedAccess !== 'public');
|
||||||
|
const hasFeedAccess = !!me || localTopicFeedAccess === 'public';
|
||||||
|
|
||||||
return ({
|
return ({
|
||||||
local,
|
local,
|
||||||
|
hasFeedAccess,
|
||||||
hasUnread: state.getIn(['timelines', `hashtag:${props.params.id}${local ? ':local' : ''}`, 'unread']) > 0,
|
hasUnread: state.getIn(['timelines', `hashtag:${props.params.id}${local ? ':local' : ''}`, 'unread']) > 0,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -127,11 +129,13 @@ class HashtagTimeline extends PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_load() {
|
_load() {
|
||||||
const { dispatch, local } = this.props;
|
const { dispatch, local, hasFeedAccess } = this.props;
|
||||||
const { id, tags } = this.props.params;
|
const { id, tags } = this.props.params;
|
||||||
|
|
||||||
this._subscribe(dispatch, id, tags, local);
|
if (hasFeedAccess) {
|
||||||
dispatch(expandHashtagTimeline(id, { tags, local }));
|
this._subscribe(dispatch, id, tags, local);
|
||||||
|
dispatch(expandHashtagTimeline(id, { tags, local }));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
@@ -164,7 +168,7 @@ class HashtagTimeline extends PureComponent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { hasUnread, columnId, multiColumn, local } = this.props;
|
const { hasUnread, columnId, multiColumn, local, hasFeedAccess } = this.props;
|
||||||
const { id } = this.props.params;
|
const { id } = this.props.params;
|
||||||
const pinned = !!columnId;
|
const pinned = !!columnId;
|
||||||
|
|
||||||
@@ -192,7 +196,20 @@ class HashtagTimeline extends PureComponent {
|
|||||||
scrollKey={`hashtag_timeline-${columnId}`}
|
scrollKey={`hashtag_timeline-${columnId}`}
|
||||||
timelineId={`hashtag:${id}${local ? ':local' : ''}`}
|
timelineId={`hashtag:${id}${local ? ':local' : ''}`}
|
||||||
onLoadMore={this.handleLoadMore}
|
onLoadMore={this.handleLoadMore}
|
||||||
emptyMessage={<FormattedMessage id='empty_column.hashtag' defaultMessage='There is nothing in this hashtag yet.' />}
|
initialLoadingState={hasFeedAccess}
|
||||||
|
emptyMessage={
|
||||||
|
hasFeedAccess ? (
|
||||||
|
<FormattedMessage
|
||||||
|
id='empty_column.hashtag'
|
||||||
|
defaultMessage='There is nothing in this hashtag yet.'
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<FormattedMessage
|
||||||
|
id='error.no_hashtag_feed_access'
|
||||||
|
defaultMessage='Join or log in to view and follow this hashtag.'
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
bindToDocument={!multiColumn}
|
bindToDocument={!multiColumn}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@@ -40,10 +40,10 @@ const makeMapStateToProps = () => {
|
|||||||
const getStatusIds = makeGetStatusIds();
|
const getStatusIds = makeGetStatusIds();
|
||||||
const getPendingStatusIds = makeGetStatusIds(true);
|
const getPendingStatusIds = makeGetStatusIds(true);
|
||||||
|
|
||||||
const mapStateToProps = (state, { timelineId }) => ({
|
const mapStateToProps = (state, { timelineId, initialLoadingState = true }) => ({
|
||||||
statusIds: getStatusIds(state, { type: timelineId }),
|
statusIds: getStatusIds(state, { type: timelineId }),
|
||||||
lastId: state.getIn(['timelines', timelineId, 'items'])?.last(),
|
lastId: state.getIn(['timelines', timelineId, 'items'])?.last(),
|
||||||
isLoading: state.getIn(['timelines', timelineId, 'isLoading'], true),
|
isLoading: state.getIn(['timelines', timelineId, 'isLoading'], initialLoadingState),
|
||||||
isPartial: state.getIn(['timelines', timelineId, 'isPartial'], false),
|
isPartial: state.getIn(['timelines', timelineId, 'isPartial'], false),
|
||||||
hasMore: state.getIn(['timelines', timelineId, 'hasMore']),
|
hasMore: state.getIn(['timelines', timelineId, 'hasMore']),
|
||||||
numPending: getPendingStatusIds(state, { type: timelineId }).size,
|
numPending: getPendingStatusIds(state, { type: timelineId }).size,
|
||||||
|
|||||||
@@ -357,6 +357,7 @@
|
|||||||
"empty_column.notification_requests": "All clear! There is nothing here. When you receive new notifications, they will appear here according to your settings.",
|
"empty_column.notification_requests": "All clear! There is nothing here. When you receive new notifications, they will appear here according to your settings.",
|
||||||
"empty_column.notifications": "You don't have any notifications yet. When other people interact with you, you will see it here.",
|
"empty_column.notifications": "You don't have any notifications yet. When other people interact with you, you will see it here.",
|
||||||
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up",
|
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up",
|
||||||
|
"error.no_hashtag_feed_access": "Join or log in to view and follow this hashtag.",
|
||||||
"error.unexpected_crash.explanation": "Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.",
|
"error.unexpected_crash.explanation": "Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.",
|
||||||
"error.unexpected_crash.explanation_addons": "This page could not be displayed correctly. This error is likely caused by a browser add-on or automatic translation tools.",
|
"error.unexpected_crash.explanation_addons": "This page could not be displayed correctly. This error is likely caused by a browser add-on or automatic translation tools.",
|
||||||
"error.unexpected_crash.next_steps": "Try refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.",
|
"error.unexpected_crash.next_steps": "Try refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.",
|
||||||
|
|||||||
Reference in New Issue
Block a user