162 lines
4.9 KiB
TypeScript
162 lines
4.9 KiB
TypeScript
import { defineMessages } from 'react-intl';
|
|
import type { MessageDescriptor } from 'react-intl';
|
|
|
|
import type { Status, StatusVisibility } from '@/mastodon/models/status';
|
|
import { createAppSelector } from '@/mastodon/store';
|
|
import FormatQuote from '@/material-icons/400-24px/format_quote-fill.svg?react';
|
|
import FormatQuoteOff from '@/material-icons/400-24px/format_quote_off-fill.svg?react';
|
|
import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react';
|
|
import RepeatActiveIcon from '@/svg-icons/repeat_active.svg?react';
|
|
import RepeatDisabledIcon from '@/svg-icons/repeat_disabled.svg?react';
|
|
import RepeatPrivateIcon from '@/svg-icons/repeat_private.svg?react';
|
|
import RepeatPrivateActiveIcon from '@/svg-icons/repeat_private_active.svg?react';
|
|
|
|
import type { IconProp } from '../icon';
|
|
|
|
export const messages = defineMessages({
|
|
all_disabled: {
|
|
id: 'status.all_disabled',
|
|
defaultMessage: 'Boosts and quotes are disabled',
|
|
},
|
|
quote: { id: 'status.quote', defaultMessage: 'Quote' },
|
|
quote_cannot: {
|
|
id: 'status.cannot_quote',
|
|
defaultMessage: 'Quotes are disabled on this post',
|
|
},
|
|
quote_followers_only: {
|
|
id: 'status.quote_followers_only',
|
|
defaultMessage: 'Only followers can quote this post',
|
|
},
|
|
quote_manual_review: {
|
|
id: 'status.quote_manual_review',
|
|
defaultMessage: 'Author will manually review',
|
|
},
|
|
quote_private: {
|
|
id: 'status.quote_private',
|
|
defaultMessage: 'Private posts cannot be quoted',
|
|
},
|
|
reblog: { id: 'status.reblog', defaultMessage: 'Boost' },
|
|
reblog_or_quote: {
|
|
id: 'status.reblog_or_quote',
|
|
defaultMessage: 'Boost or quote',
|
|
},
|
|
reblog_cancel: {
|
|
id: 'status.cancel_reblog_private',
|
|
defaultMessage: 'Unboost',
|
|
},
|
|
reblog_private: {
|
|
id: 'status.reblog_private',
|
|
defaultMessage: 'Share again with your followers',
|
|
},
|
|
reblog_cannot: {
|
|
id: 'status.cannot_reblog',
|
|
defaultMessage: 'This post cannot be boosted',
|
|
},
|
|
request_quote: {
|
|
id: 'status.request_quote',
|
|
defaultMessage: 'Request to quote',
|
|
},
|
|
});
|
|
|
|
export const selectStatusState = createAppSelector(
|
|
[
|
|
(state) => state.meta.get('me') as string | undefined,
|
|
(_, status: Status) => status,
|
|
],
|
|
(userId, status) => {
|
|
const isPublic = ['public', 'unlisted'].includes(
|
|
status.get('visibility') as StatusVisibility,
|
|
);
|
|
const isMineAndPrivate =
|
|
userId === status.getIn(['account', 'id']) &&
|
|
status.get('visibility') === 'private';
|
|
return {
|
|
isLoggedIn: !!userId,
|
|
isPublic,
|
|
isMine: userId === status.getIn(['account', 'id']),
|
|
isPrivateReblog:
|
|
userId === status.getIn(['account', 'id']) &&
|
|
status.get('visibility') === 'private',
|
|
isReblogged: !!status.get('reblogged'),
|
|
isReblogAllowed: isPublic || isMineAndPrivate,
|
|
isQuoteAutomaticallyAccepted:
|
|
status.getIn(['quote_approval', 'current_user']) === 'automatic' &&
|
|
(isPublic || isMineAndPrivate),
|
|
isQuoteManuallyAccepted:
|
|
status.getIn(['quote_approval', 'current_user']) === 'manual' &&
|
|
(isPublic || isMineAndPrivate),
|
|
isQuoteFollowersOnly:
|
|
status.getIn(['quote_approval', 'automatic', 0]) === 'followers' ||
|
|
status.getIn(['quote_approval', 'manual', 0]) === 'followers',
|
|
};
|
|
},
|
|
);
|
|
|
|
export type StatusState = ReturnType<typeof selectStatusState>;
|
|
|
|
export interface MenuItemState {
|
|
title: MessageDescriptor;
|
|
meta?: MessageDescriptor;
|
|
iconComponent: IconProp;
|
|
disabled?: boolean;
|
|
}
|
|
|
|
export function boostItemState({
|
|
isPublic,
|
|
isPrivateReblog,
|
|
isReblogged,
|
|
}: StatusState): MenuItemState {
|
|
if (isReblogged) {
|
|
return {
|
|
title: messages.reblog_cancel,
|
|
iconComponent: isPublic ? RepeatActiveIcon : RepeatPrivateActiveIcon,
|
|
};
|
|
}
|
|
const iconText: MenuItemState = {
|
|
title: messages.reblog,
|
|
iconComponent: RepeatIcon,
|
|
};
|
|
|
|
if (isPrivateReblog) {
|
|
iconText.meta = messages.reblog_private;
|
|
iconText.iconComponent = RepeatPrivateIcon;
|
|
} else if (!isPublic) {
|
|
iconText.meta = messages.reblog_cannot;
|
|
iconText.iconComponent = RepeatDisabledIcon;
|
|
iconText.disabled = true;
|
|
}
|
|
return iconText;
|
|
}
|
|
|
|
export function quoteItemState({
|
|
isMine,
|
|
isQuoteAutomaticallyAccepted,
|
|
isQuoteManuallyAccepted,
|
|
isQuoteFollowersOnly,
|
|
isPublic,
|
|
}: StatusState): MenuItemState {
|
|
const iconText: MenuItemState = {
|
|
title: messages.quote,
|
|
iconComponent: FormatQuote,
|
|
};
|
|
|
|
if (!isPublic && !isMine) {
|
|
iconText.disabled = true;
|
|
iconText.iconComponent = FormatQuoteOff;
|
|
iconText.meta = messages.quote_private;
|
|
} else if (isQuoteAutomaticallyAccepted) {
|
|
iconText.title = messages.quote;
|
|
} else if (isQuoteManuallyAccepted) {
|
|
iconText.title = messages.request_quote;
|
|
iconText.meta = messages.quote_manual_review;
|
|
} else {
|
|
iconText.disabled = true;
|
|
iconText.iconComponent = FormatQuoteOff;
|
|
iconText.meta = isQuoteFollowersOnly
|
|
? messages.quote_followers_only
|
|
: messages.quote_cannot;
|
|
}
|
|
|
|
return iconText;
|
|
}
|