Merge branch 'remote-follow-feature' into 'develop'
ActionButton: put remote follow behind feature detection See merge request soapbox-pub/soapbox-fe!1381
This commit is contained in:
commit
a6396dd4c5
2 changed files with 59 additions and 28 deletions
|
@ -30,13 +30,21 @@ const messages = defineMessages({
|
||||||
unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
|
unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
|
||||||
});
|
});
|
||||||
|
|
||||||
interface iActionButton {
|
interface IActionButton {
|
||||||
|
/** Target account for the action. */
|
||||||
account: AccountEntity
|
account: AccountEntity
|
||||||
|
/** Type of action to prioritize, eg on Blocks and Mutes pages. */
|
||||||
actionType?: 'muting' | 'blocking'
|
actionType?: 'muting' | 'blocking'
|
||||||
|
/** Displays shorter text on the "Awaiting approval" button. */
|
||||||
small?: boolean
|
small?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const ActionButton = ({ account, actionType, small }: iActionButton) => {
|
/**
|
||||||
|
* Circumstantial action button (usually "Follow") to display on accounts.
|
||||||
|
* May say "Unblock" or something else, depending on the relationship and
|
||||||
|
* `actionType` prop.
|
||||||
|
*/
|
||||||
|
const ActionButton: React.FC<IActionButton> = ({ account, actionType, small }) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const features = useFeatures();
|
const features = useFeatures();
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
@ -45,40 +53,41 @@ const ActionButton = ({ account, actionType, small }: iActionButton) => {
|
||||||
|
|
||||||
const handleFollow = () => {
|
const handleFollow = () => {
|
||||||
if (account.getIn(['relationship', 'following']) || account.getIn(['relationship', 'requested'])) {
|
if (account.getIn(['relationship', 'following']) || account.getIn(['relationship', 'requested'])) {
|
||||||
dispatch(unfollowAccount(account.get('id')));
|
dispatch(unfollowAccount(account.id));
|
||||||
} else {
|
} else {
|
||||||
dispatch(followAccount(account.get('id')));
|
dispatch(followAccount(account.id));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBlock = () => {
|
const handleBlock = () => {
|
||||||
if (account.getIn(['relationship', 'blocking'])) {
|
if (account.getIn(['relationship', 'blocking'])) {
|
||||||
dispatch(unblockAccount(account.get('id')));
|
dispatch(unblockAccount(account.id));
|
||||||
} else {
|
} else {
|
||||||
dispatch(blockAccount(account.get('id')));
|
dispatch(blockAccount(account.id));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMute = () => {
|
const handleMute = () => {
|
||||||
if (account.getIn(['relationship', 'muting'])) {
|
if (account.getIn(['relationship', 'muting'])) {
|
||||||
dispatch(unmuteAccount(account.get('id')));
|
dispatch(unmuteAccount(account.id));
|
||||||
} else {
|
} else {
|
||||||
dispatch(muteAccount(account.get('id')));
|
dispatch(muteAccount(account.id));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRemoteFollow = () => {
|
const handleRemoteFollow = () => {
|
||||||
dispatch(openModal('UNAUTHORIZED', {
|
dispatch(openModal('UNAUTHORIZED', {
|
||||||
action: 'FOLLOW',
|
action: 'FOLLOW',
|
||||||
account: account.get('id'),
|
account: account.id,
|
||||||
ap_id: account.get('url'),
|
ap_id: account.url,
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Handles actionType='muting' */
|
||||||
const mutingAction = () => {
|
const mutingAction = () => {
|
||||||
const isMuted = account.getIn(['relationship', 'muting']);
|
const isMuted = account.getIn(['relationship', 'muting']);
|
||||||
const messageKey = isMuted ? messages.unmute : messages.mute;
|
const messageKey = isMuted ? messages.unmute : messages.mute;
|
||||||
const text = intl.formatMessage(messageKey, { name: account.get('username') });
|
const text = intl.formatMessage(messageKey, { name: account.username });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
|
@ -90,10 +99,11 @@ const ActionButton = ({ account, actionType, small }: iActionButton) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Handles actionType='blocking' */
|
||||||
const blockingAction = () => {
|
const blockingAction = () => {
|
||||||
const isBlocked = account.getIn(['relationship', 'blocking']);
|
const isBlocked = account.getIn(['relationship', 'blocking']);
|
||||||
const messageKey = isBlocked ? messages.unblock : messages.block;
|
const messageKey = isBlocked ? messages.unblock : messages.block;
|
||||||
const text = intl.formatMessage(messageKey, { name: account.get('username') });
|
const text = intl.formatMessage(messageKey, { name: account.username });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
|
@ -105,10 +115,9 @@ const ActionButton = ({ account, actionType, small }: iActionButton) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const empty = <></>;
|
/** Render a remote follow button, depending on features. */
|
||||||
|
const renderRemoteFollow = () => {
|
||||||
if (!me) {
|
// Remote follow through the API.
|
||||||
// Remote follow
|
|
||||||
if (features.remoteInteractionsAPI) {
|
if (features.remoteInteractionsAPI) {
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
|
@ -117,18 +126,34 @@ const ActionButton = ({ account, actionType, small }: iActionButton) => {
|
||||||
text={intl.formatMessage(messages.follow)}
|
text={intl.formatMessage(messages.follow)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
// Pleroma's classic remote follow form.
|
||||||
|
} else if (features.pleromaRemoteFollow) {
|
||||||
|
return (
|
||||||
|
<form method='POST' action='/main/ostatus'>
|
||||||
|
<input type='hidden' name='nickname' value={account.acct} />
|
||||||
|
<input type='hidden' name='profile' value='' />
|
||||||
|
<Button text={intl.formatMessage(messages.remote_follow)} type='submit' />
|
||||||
|
</form>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return null;
|
||||||
<form method='POST' action='/main/ostatus'>
|
};
|
||||||
<input type='hidden' name='nickname' value={account.get('acct')} />
|
|
||||||
<input type='hidden' name='profile' value='' />
|
/** Render remote follow if federating, otherwise hide the button. */
|
||||||
<Button text={intl.formatMessage(messages.remote_follow)} type='submit' />
|
const renderLoggedOut = () => {
|
||||||
</form>
|
if (features.federating) {
|
||||||
);
|
return renderRemoteFollow();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!me) {
|
||||||
|
return renderLoggedOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (me !== account.get('id')) {
|
if (me !== account.id) {
|
||||||
const isFollowing = account.getIn(['relationship', 'following']);
|
const isFollowing = account.getIn(['relationship', 'following']);
|
||||||
const blockedBy = account.getIn(['relationship', 'blocked_by']) as boolean;
|
const blockedBy = account.getIn(['relationship', 'blocked_by']) as boolean;
|
||||||
|
|
||||||
|
@ -140,9 +165,9 @@ const ActionButton = ({ account, actionType, small }: iActionButton) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!account.get('relationship')) {
|
if (account.relationship.isEmpty()) {
|
||||||
// Wait until the relationship is loaded
|
// Wait until the relationship is loaded
|
||||||
return empty;
|
return null;
|
||||||
} else if (account.getIn(['relationship', 'requested'])) {
|
} else if (account.getIn(['relationship', 'requested'])) {
|
||||||
// Awaiting acceptance
|
// Awaiting acceptance
|
||||||
return (
|
return (
|
||||||
|
@ -176,7 +201,7 @@ const ActionButton = ({ account, actionType, small }: iActionButton) => {
|
||||||
<Button
|
<Button
|
||||||
theme='danger'
|
theme='danger'
|
||||||
size='sm'
|
size='sm'
|
||||||
text={intl.formatMessage(messages.unblock, { name: account.get('username') })}
|
text={intl.formatMessage(messages.unblock, { name: account.username })}
|
||||||
onClick={handleBlock}
|
onClick={handleBlock}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -193,7 +218,7 @@ const ActionButton = ({ account, actionType, small }: iActionButton) => {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return empty;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ActionButton;
|
export default ActionButton;
|
||||||
|
|
|
@ -356,6 +356,12 @@ const getInstanceFeatures = (instance: Instance) => {
|
||||||
*/
|
*/
|
||||||
paginatedContext: v.software === TRUTHSOCIAL,
|
paginatedContext: v.software === TRUTHSOCIAL,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a form to follow a user when logged out.
|
||||||
|
* @see POST /main/ostatus
|
||||||
|
*/
|
||||||
|
pleromaRemoteFollow: v.software === PLEROMA,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can add polls to statuses.
|
* Can add polls to statuses.
|
||||||
* @see POST /api/v1/statuses
|
* @see POST /api/v1/statuses
|
||||||
|
|
Loading…
Reference in a new issue