feat(app): guide privacy review with dots and an inline alert (#3356)

This commit is contained in:
Hampus authored and GitHub committed 2026-10-10 00:57:26 +02:00
1 parent ec681e6061
commit 2f6201bcbd
60 files changed
+2975 -2500

No files matched your search

@@ -11,7 +11,9 @@ 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 {Switch} from '@app/features/ui/components/form/FormSwitch';
import {WarningAlert} from '@app/features/ui/warning_alert/WarningAlert';
import * as UserSettingsCommands from '@app/features/user/commands/UserSettingsCommands';
import {PrivacySetupModal} from '@app/features/user/components/modals/PrivacySetupModal';
import styles from '@app/features/user/components/modals/tabs/privacy_safety_tab/ConnectionsTab.module.css';
import UserSettings from '@app/features/user/state/UserSettings';
import {FriendSourceFlags} from '@fluxer/constants/src/UserConstants';
@@ -62,6 +64,22 @@ const BLOCK_FOR_ALL_COMMUNITIES_DESCRIPTOR = msg({
comment: 'Button or menu action label in the connections tab. Keep it concise. Keep the tone plain and specific.',
});
const PRIVACY_REVIEW_TITLE_DESCRIPTOR = msg({
message: 'Review who can message you',
comment:
'Title of the inline alert in Privacy > Friends & direct messages, shown until the user reviews their direct message setting.',
});
const PRIVACY_REVIEW_BODY_DESCRIPTOR = msg({
message:
'Choose whether people who share a community with you can send you direct messages without being friends first.',
comment:
'Body of the inline alert in Privacy > Friends & direct messages, shown until the user reviews their direct message setting.',
});
const REVIEW_PRIVACY_SETTINGS_DESCRIPTOR = msg({
message: 'Review privacy settings',
comment: 'Button in the inline privacy review alert. Opens the privacy setup modal.',
});
interface DirectMessagesConfirmModalProps {
allowMessages: boolean;
onApplyToAll: () => Promise<void>;
@@ -156,6 +174,37 @@ const DirectMessagesConfirmModal = observer(
);
},
);
const PrivacyReviewAlert = observer(() => {
const {i18n} = useLingui();
const handleReview = useCallback(() => {
ModalCommands.push(
modal(() => (
<PrivacySetupModal data-flx="user.privacy-safety-tab.connections-tab.privacy-review-alert.privacy-setup-modal" />
)),
);
}, []);
if (!UserSettings.isPrivacySetupPending()) {
return null;
}
return (
<WarningAlert
title={i18n._(PRIVACY_REVIEW_TITLE_DESCRIPTOR)}
actions={
<Button
variant="primary"
small
onClick={handleReview}
data-flx="user.privacy-safety-tab.connections-tab.privacy-review-alert.button.review"
>
{i18n._(REVIEW_PRIVACY_SETTINGS_DESCRIPTOR)}
</Button>
}
data-flx="user.privacy-safety-tab.connections-tab.privacy-review-alert"
>
{i18n._(PRIVACY_REVIEW_BODY_DESCRIPTOR)}
</WarningAlert>
);
});
export const ConnectionsTabContent: React.FC = observer(() => {
const {i18n} = useLingui();
const friendSourceFlags = UserSettings.getFriendSourceFlags();
@@ -251,6 +300,7 @@ export const ConnectionsTabContent: React.FC = observer(() => {
data-flx="user.privacy-safety-tab.connections-tab.connections-tab-content.switch.friend-request-toggle--3"
/>
</SettingsTabSection>
<PrivacyReviewAlert data-flx="user.privacy-safety-tab.connections-tab.connections-tab-content.privacy-review-alert" />
<SettingsTabSection
title={<Trans>Direct messages</Trans>}
data-flx="user.privacy-safety-tab.connections-tab.connections-tab-content.settings-tab-section--2"
@@ -316,6 +316,15 @@ export const USER_SETTINGS_LABEL_DESCRIPTOR = msg({
message: 'User settings',
comment: 'Root label for the current user settings modal and settings search paths.',
});
export const USER_SETTINGS_PRIVACY_REVIEW_NEEDED_DESCRIPTOR = msg({
message: 'User settings, privacy review needed',
comment: 'Accessible label for the user settings button while the user has not yet reviewed who can message them.',
});
export const PRIVACY_REVIEW_NEEDED_DESCRIPTOR = msg({
message: 'Review needed',
comment:
'Screen reader text read after the Privacy item in the settings sidebar while the user has not yet reviewed who can message them. A red dot marks the item visually.',
});
export function getUserSettingsTabLabel(i18n: I18n, tabType: UserSettingsTabType): string {
const tab = ALL_TABS_DESCRIPTORS.find((candidate) => candidate.type === tabType);