nicolium: support quote approval policy on mastodon
Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
@@ -277,10 +277,12 @@ interface ComposeQuoteAction {
|
||||
account: Pick<Account, 'acct'> | undefined;
|
||||
explicitAddressing: boolean;
|
||||
conversationScope: boolean;
|
||||
approvalRequired?: boolean;
|
||||
}
|
||||
|
||||
const quoteCompose =
|
||||
(status: ComposeQuoteAction['status']) => (dispatch: AppDispatch, getState: () => RootState) => {
|
||||
(status: ComposeQuoteAction['status'], approvalRequired?: boolean) =>
|
||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
||||
const state = getState();
|
||||
const { forceImplicitAddressing } = useSettingsStore.getState().settings;
|
||||
const { createStatusConversationScope, createStatusExplicitAddressing } =
|
||||
@@ -294,6 +296,7 @@ const quoteCompose =
|
||||
account: selectOwnAccount(state),
|
||||
explicitAddressing,
|
||||
conversationScope: createStatusConversationScope,
|
||||
approvalRequired,
|
||||
});
|
||||
useModalsStore.getState().actions.openModal('COMPOSE');
|
||||
};
|
||||
|
||||
@@ -26,6 +26,7 @@ type MenuItem = {
|
||||
items?: Menu;
|
||||
onSelectFile?: (files: FileList) => void;
|
||||
accept?: string;
|
||||
disabled?: boolean;
|
||||
} & (LinkOptions | { to?: undefined });
|
||||
|
||||
interface IDropdownMenuItem {
|
||||
@@ -46,6 +47,7 @@ const DropdownMenuItem = ({ index, item, onClick, autoFocus, onSetTab }: IDropdo
|
||||
event.stopPropagation();
|
||||
|
||||
if (!item) return;
|
||||
if (item.disabled) return;
|
||||
|
||||
if (item.items?.length) {
|
||||
event.preventDefault();
|
||||
@@ -74,6 +76,7 @@ const DropdownMenuItem = ({ index, item, onClick, autoFocus, onSetTab }: IDropdo
|
||||
|
||||
const handleAuxClick: React.EventHandler<React.MouseEvent> = (event) => {
|
||||
if (!item) return;
|
||||
if (item.disabled) return;
|
||||
if (item.onSelectFile) fileElement.current?.click();
|
||||
if (onClick) onClick();
|
||||
|
||||
@@ -93,6 +96,7 @@ const DropdownMenuItem = ({ index, item, onClick, autoFocus, onSetTab }: IDropdo
|
||||
event.stopPropagation();
|
||||
|
||||
if (!item) return;
|
||||
if (item.disabled) return;
|
||||
|
||||
if (item.onChange) item.onChange(event.target.checked);
|
||||
};
|
||||
@@ -132,6 +136,7 @@ const DropdownMenuItem = ({ index, item, onClick, autoFocus, onSetTab }: IDropdo
|
||||
'mx-2 my-1 flex cursor-pointer items-center rounded-md px-2 py-1.5 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-800 focus:bg-gray-100 focus:text-gray-800 focus:outline-none black:hover:bg-gray-900 black:focus:bg-gray-900 dark:text-gray-300 dark:hover:bg-gray-800 dark:hover:text-gray-200 dark:focus:bg-gray-800 dark:focus:text-gray-200',
|
||||
{
|
||||
'text-danger-600 dark:text-danger-400': item.destructive,
|
||||
'cursor-not-allowed opacity-50': item.disabled,
|
||||
},
|
||||
)}
|
||||
>
|
||||
@@ -185,6 +190,7 @@ const DropdownMenuItem = ({ index, item, onClick, autoFocus, onSetTab }: IDropdo
|
||||
accept={item.accept}
|
||||
onChange={handleSelectFileChange}
|
||||
className='hidden'
|
||||
disabled={item.disabled}
|
||||
/>
|
||||
</label>
|
||||
)}
|
||||
|
||||
@@ -421,6 +421,7 @@ const ReblogButton: React.FC<IReblogButton> = ({
|
||||
const { boostModal } = useSettings();
|
||||
const { openModal } = useModalsActions();
|
||||
const canReblog = useCanInteract(status, 'can_reblog');
|
||||
const canQuote = useCanInteract(status, 'can_quote');
|
||||
|
||||
const { mutate: reblogStatus } = useReblogStatus(status.id);
|
||||
const { mutate: unreblogStatus } = useUnreblogStatus(status.id);
|
||||
@@ -494,7 +495,7 @@ const ReblogButton: React.FC<IReblogButton> = ({
|
||||
|
||||
const handleQuoteClick: React.EventHandler<React.MouseEvent> = (e) => {
|
||||
if (me) {
|
||||
dispatch(quoteCompose(status));
|
||||
dispatch(quoteCompose(status, canQuote.approvalRequired || false));
|
||||
} else {
|
||||
onOpenUnauthorizedModal('REBLOG');
|
||||
}
|
||||
@@ -510,6 +511,7 @@ const ReblogButton: React.FC<IReblogButton> = ({
|
||||
text: intl.formatMessage(messages.quotePost),
|
||||
action: handleQuoteClick,
|
||||
icon: require('@phosphor-icons/core/regular/quotes.svg'),
|
||||
disabled: !canQuote.canInteract,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -426,13 +426,20 @@ const ComposeForm = <ID extends string>({
|
||||
onClick={handleClick}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
{!!compose.inReplyToId && compose.approvalRequired && (
|
||||
{(compose.inReplyToId || compose.quoteId) && compose.approvalRequired && (
|
||||
<Warning
|
||||
message={
|
||||
<FormattedMessage
|
||||
id='compose_form.approval_required'
|
||||
defaultMessage='The reply needs to be approved by the post author.'
|
||||
/>
|
||||
compose.quoteId ? (
|
||||
<FormattedMessage
|
||||
id='compose_form.approval_required.quote'
|
||||
defaultMessage='The quote needs to be approved by the post author.'
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id='compose_form.approval_required'
|
||||
defaultMessage='The reply needs to be approved by the post author.'
|
||||
/>
|
||||
)
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -6,8 +6,11 @@ import type { MinifiedStatus } from '@/reducers/statuses';
|
||||
import type { InteractionPolicy, InteractionPolicyEntry } from 'pl-api';
|
||||
|
||||
const useCanInteract = (
|
||||
status: Pick<MinifiedStatus, 'account_id' | 'id' | 'interaction_policy' | 'mentions'>,
|
||||
type: keyof InteractionPolicy,
|
||||
status: Pick<
|
||||
MinifiedStatus,
|
||||
'account_id' | 'id' | 'interaction_policy' | 'mentions' | 'quote_approval'
|
||||
>,
|
||||
type: keyof InteractionPolicy | 'can_quote',
|
||||
): {
|
||||
canInteract: boolean;
|
||||
approvalRequired: boolean | null;
|
||||
@@ -16,6 +19,14 @@ const useCanInteract = (
|
||||
const me = useAppSelector((state) => state.me);
|
||||
|
||||
return useMemo(() => {
|
||||
if (type === 'can_quote') {
|
||||
const quoteApproval = status.quote_approval;
|
||||
|
||||
return {
|
||||
canInteract: !quoteApproval || quoteApproval.current_user !== 'denied',
|
||||
approvalRequired: quoteApproval?.current_user === 'manual',
|
||||
};
|
||||
}
|
||||
const interactionPolicy = status.interaction_policy;
|
||||
|
||||
if (me === status.account_id || interactionPolicy[type].always.includes('me'))
|
||||
|
||||
@@ -509,6 +509,7 @@ const compose = (
|
||||
compose.caretPosition = null;
|
||||
compose.contentType = defaultCompose.contentType;
|
||||
compose.spoilerText = '';
|
||||
compose.approvalRequired = action.approvalRequired ?? false;
|
||||
|
||||
if (action.status.visibility === 'group') {
|
||||
compose.groupId = action.status.group_id;
|
||||
|
||||
Reference in New Issue
Block a user