// SPDX-License-Identifier: AGPL-3.0-or-later
import {PRODUCT_NAME} from '@app/features/app/config/I18nDisplayConstants';
import {openClaimAccountModal} from '@app/features/auth/components/modals/ClaimAccountModal';
import styles from '@app/features/channel/components/barriers/BarrierComponents.module.css';
import wrapperStyles from '@app/features/channel/components/textarea/InputWrapper.module.css';
import textareaStyles from '@app/features/channel/components/textarea/TextareaInput.module.css';
import {CLAIM_ACCOUNT_DESCRIPTOR, VERIFY_EMAIL_DESCRIPTOR} from '@app/features/i18n/utils/CommonMessageDescriptors';
import {unblockUser} from '@app/features/relationship/utils/RelationshipActionUtils';
import {remFromPx} from '@app/features/theme/layout/RemFromPx';
import {Button} from '@app/features/ui/button/Button';
import * as ModalCommands from '@app/features/ui/commands/ModalCommands';
import {modal} from '@app/features/ui/commands/ModalCommands';
import {PhoneAddModal} from '@app/features/user/components/modals/PhoneAddModal';
import {UserSettingsModal} from '@app/features/user/components/modals/UserSettingsModal';
import {msg} from '@lingui/core/macro';
import {Trans, useLingui} from '@lingui/react/macro';
import {
ClockIcon,
EnvelopeSimpleIcon,
InfoIcon,
PhoneIcon,
ProhibitIcon,
ShieldWarningIcon,
TimerIcon,
WarningCircleIcon,
} from '@phosphor-icons/react';
import {clsx} from 'clsx';
import {observer} from 'mobx-react-lite';
import {useEffect, useState} from 'react';
interface BarrierProps {
onAction?: () => void;
}
interface TimedBarrierProps extends BarrierProps {
initialTimeRemaining?: number;
}
interface BarrierBaseProps {
message: React.ReactNode;
action?: React.ReactNode;
icon: React.ReactElement;
}
const SYSTEM_ANNOUNCEMENTS_FROM_STAFF_DESCRIPTOR = msg({
message: "System announcements from {productName} staff. You can't reply here.",
comment: 'Read-only system DM barrier message. productName is the Fluxer product name.',
});
const BarrierBase = observer(({message, action, icon}: BarrierBaseProps) => {
const hasAction = Boolean(action);
return (
{hasAction && (
{action}
)}
);
});
const CountdownTimer = observer(({initialTime}: {initialTime: number}) => {
const [timeRemaining, setTimeRemaining] = useState(initialTime);
useEffect(() => {
if (timeRemaining <= 0) return;
const interval = setInterval(() => {
setTimeRemaining((prev) => {
if (prev <= 1000) {
clearInterval(interval);
return 0;
}
return prev - 1000;
});
}, 1000);
return () => clearInterval(interval);
}, []);
const formatTime = (ms: number): string => {
const totalSeconds = Math.ceil(ms / 1000);
const minutes = Math.floor(totalSeconds / 60);
const seconds = totalSeconds % 60;
return `${minutes}:${seconds.toString().padStart(2, '0')}`;
};
if (timeRemaining <= 0) {
return null;
}
return (
{formatTime(timeRemaining)}
);
});
export const UnclaimedAccountBarrier = observer(({onAction}: BarrierProps) => {
const {i18n} = useLingui();
return (
You need to claim your account to send messages in this community.}
icon={
}
action={
}
data-flx="channel.barriers.barrier-components.unclaimed-account-barrier.barrier-base"
/>
);
});
export const UnverifiedEmailBarrier = observer(({onAction}: BarrierProps) => {
const {i18n} = useLingui();
return (
You need to verify your email to send messages in this community.}
icon={
}
action={
}
data-flx="channel.barriers.barrier-components.unverified-email-barrier.barrier-base"
/>
);
});
export const AccountTooNewBarrier = observer(({initialTimeRemaining = 5 * 60 * 1000}: TimedBarrierProps) => {
return (
Your account is too new to send messages in this community.}
icon={
}
action={
initialTimeRemaining > 0 ? (
) : null
}
data-flx="channel.barriers.barrier-components.account-too-new-barrier.barrier-base"
/>
);
});
export const NotMemberLongEnoughBarrier = observer(({initialTimeRemaining = 10 * 60 * 1000}: TimedBarrierProps) => {
return (
You haven't been a member of this community long enough to send messages.}
icon={
}
action={
initialTimeRemaining > 0 ? (
) : null
}
data-flx="channel.barriers.barrier-components.not-member-long-enough-barrier.barrier-base"
/>
);
});
export const NoPhoneNumberBarrier = observer(({onAction}: BarrierProps) => {
return (
You need to verify a phone number to send messages in this community.}
icon={
}
action={
}
data-flx="channel.barriers.barrier-components.no-phone-number-barrier.barrier-base"
/>
);
});
export const SendMessageDisabledBarrier = observer(() => {
return (
Messaging is temporarily paused in this community.}
icon={
}
action={null}
data-flx="channel.barriers.barrier-components.send-message-disabled-barrier.barrier-base"
/>
);
});
export const TimeoutBarrier = observer(({initialTimeRemaining = 0}: TimedBarrierProps) => {
return (
You're timed out. Messaging, reactions, and voice are paused until the timeout expires.}
icon={
}
action={
initialTimeRemaining > 0 ? (
) : null
}
data-flx="channel.barriers.barrier-components.timeout-barrier.barrier-base"
/>
);
});
export const DefaultBarrier = observer(() => {
return (
You can't send messages in this community.}
icon={
}
action={null}
data-flx="channel.barriers.barrier-components.default-barrier.barrier-base"
/>
);
});
export const SystemDmBarrier = observer(() => {
const {i18n} = useLingui();
return (
}
action={null}
data-flx="channel.barriers.barrier-components.system-dm-barrier.barrier-base"
/>
);
});
interface BlockedUserBarrierProps extends BarrierProps {
userId: string;
username: string;
}
export const BlockedUserBarrier = observer(({userId, username, onAction}: BlockedUserBarrierProps) => {
const {i18n} = useLingui();
const handleUnblock = async () => {
await unblockUser(i18n, userId);
onAction?.();
};
return (
You have blocked {username}. Unblock them to send messages.}
icon={
}
action={
}
data-flx="channel.barriers.barrier-components.blocked-user-barrier.barrier-base"
/>
);
});
export const UnclaimedDMBarrier = observer(({onAction}: BarrierProps) => {
const {i18n} = useLingui();
return (
You need to claim your account to send direct messages.}
icon={
}
action={
}
data-flx="channel.barriers.barrier-components.unclaimed-dm-barrier.barrier-base"
/>
);
});