Update copy highlighting nonprofit status

This commit is contained in:
trevor-signal
2026-01-27 12:12:36 -05:00
committed by GitHub
parent 721035b821
commit 69f11c7f31
7 changed files with 91 additions and 60 deletions

View File

@@ -1086,6 +1086,10 @@
"messageformat": "See {whatsNew} in this update",
"description": "Shown in the main window"
},
"icu:signalNonProfit": {
"messageformat": "Signal is a 501c3 nonprofit",
"description": "Shown at the bottom of the main window when a chat is not selected"
},
"icu:viewReleaseNotes": {
"messageformat": "what's new",
"description": "Clickable link that displays the latest release notes"
@@ -9698,10 +9702,18 @@
"messageformat": "Privacy over Profit",
"description": "Title shown at the top of the donations preferences page"
},
"icu:PreferencesDonations__title-v2": {
"messageformat": "Proudly nonprofit",
"description": "Title shown at the top of the donations preferences page"
},
"icu:PreferencesDonations__description": {
"messageformat": "Private messaging, funded by you. No ads, no tracking, no compromise. Donate now to support Signal. <readMoreLink>Read more</readMoreLink>",
"description": "Description text explaining Signal's donation model with learn more link"
},
"icu:PreferencesDonations__description-v2": {
"messageformat": "Donate to support private messaging. Keep Signal independent and ad-free. <readMoreLink>Read more</readMoreLink>",
"description": "Description text explaining Signal's donation model with learn more link"
},
"icu:PreferencesDonations__donate-button": {
"messageformat": "Donate",
"description": "Button text to make a donation"

View File

@@ -438,30 +438,6 @@
}
}
.DonationPrivacyInformationModal {
@include donations-modal;
&__footer {
display: flex;
justify-content: space-between;
align-items: center;
gap: 16px;
}
&__faqs-link {
@include mixins.button-reset;
& {
color: variables.$color-ultramarine;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
}
.PreferencesDonations__badge-list {
width: 100%;
margin-block: 4px 8px;

View File

@@ -5,6 +5,7 @@ import React from 'react';
import type { LocalizerType } from '../types/Util.std.js';
import { useEscapeHandling } from '../hooks/useEscapeHandling.dom.js';
import { tw } from '../axo/tw.dom.js';
export type AboutProps = Readonly<{
closeAbout: () => unknown;
@@ -63,6 +64,9 @@ export function About({
{i18n('icu:privacyPolicy')}
</a>
</div>
<div className={tw('text-label-secondary')}>
{i18n('icu:signalNonProfit')}
</div>
</div>
</div>
);

View File

@@ -7,6 +7,7 @@ import type { NavTabPanelProps } from './NavTabs.dom.js';
import { WhatsNewLink } from './WhatsNewLink.dom.js';
import type { UnreadStats } from '../util/countUnreadStats.std.js';
import type { SmartConversationViewProps } from '../state/smart/ConversationView.preload.js';
import { tw } from '../axo/tw.dom.js';
export type ChatsTabProps = Readonly<{
otherTabsUnreadStats: UnreadStats;
@@ -74,6 +75,9 @@ export function ChatsTab({
<WhatsNewLink i18n={i18n} showWhatsNewModal={showWhatsNewModal} />
</p>
<div className="Inbox__padding" />
<div className={tw('absolute bottom-0 p-5 text-label-secondary')}>
{i18n('icu:signalNonProfit')}
</div>
</div>
)}
</div>

View File

@@ -0,0 +1,22 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { action } from '@storybook/addon-actions';
import type { Meta } from '@storybook/react';
import { DonationPrivacyInformationModal } from './DonationPrivacyInformationModal.dom.js';
import type { LocalizerType } from '../types/I18N.std.js';
const { i18n } = window.SignalContext;
export default {
title: 'Components/DonationPrivacyInformationModal',
} satisfies Meta<{ i18n: LocalizerType; onClose: VoidFunction }>;
export function Default(): React.JSX.Element {
return (
<DonationPrivacyInformationModal i18n={i18n} onClose={action('onClose')} />
);
}

View File

@@ -2,11 +2,11 @@
// SPDX-License-Identifier: AGPL-3.0-only
import React, { useCallback } from 'react';
import { Modal } from './Modal.dom.js';
import { Button, ButtonSize } from './Button.dom.js';
import { I18n } from './I18n.dom.js';
import type { LocalizerType } from '../types/Util.std.js';
import { openLinkInWebBrowser } from '../util/openLinkInWebBrowser.dom.js';
import { AxoDialog } from '../axo/AxoDialog.dom.js';
import { I18n } from './I18n.dom.js';
import { tw } from '../axo/tw.dom.js';
export type DonationPrivacyInformationModalProps = {
i18n: LocalizerType;
@@ -23,43 +23,56 @@ export function DonationPrivacyInformationModal({
);
};
const modalFooter = (
<div className="DonationPrivacyInformationModal__footer">
<button
type="button"
className="DonationPrivacyInformationModal__faqs-link"
onClick={handleDonationFAQsClick}
>
{i18n('icu:PreferencesDonations__faqs')}
</button>
<Button onClick={onClose} size={ButtonSize.Small}>
{i18n('icu:PreferencesDonations__privacy-modal-ok')}
</Button>
</div>
);
const paragraphComponent = useCallback(
(parts: Array<string | React.JSX.Element>) => <p>{parts}</p>,
[]
);
return (
<Modal
modalName="DonationPrivacyInformationModal"
moduleClassName="DonationPrivacyInformationModal"
i18n={i18n}
title={i18n('icu:PreferencesDonations__privacy-modal-title')}
onClose={onClose}
modalFooter={modalFooter}
padded={false}
<AxoDialog.Root
open
onOpenChange={open => {
if (!open) {
onClose();
}
}}
>
<I18n
components={{
paragraph: paragraphComponent,
}}
i18n={i18n}
id="icu:PreferencesDonations__privacy-modal-content"
/>
</Modal>
<AxoDialog.Content
size="sm"
escape="cancel-is-noop"
disableMissingAriaDescriptionWarning
>
<AxoDialog.Header>
<AxoDialog.Title>
{i18n('icu:PreferencesDonations__privacy-modal-title')}
</AxoDialog.Title>
<AxoDialog.Close aria-label={i18n('icu:PinMessageDialog__Close')} />
</AxoDialog.Header>
<AxoDialog.Body>
<div className={tw('flex flex-col gap-4 pt-1.5 pb-4')}>
<I18n
components={{
paragraph: paragraphComponent,
}}
i18n={i18n}
id="icu:PreferencesDonations__privacy-modal-content"
/>
</div>
</AxoDialog.Body>
<AxoDialog.Footer>
<AxoDialog.Actions>
<AxoDialog.Action
variant="secondary"
onClick={handleDonationFAQsClick}
>
{i18n('icu:PreferencesDonations__faqs')}
</AxoDialog.Action>
<AxoDialog.Action variant="primary" onClick={onClose}>
{i18n('icu:PreferencesDonations__privacy-modal-ok')}
</AxoDialog.Action>
</AxoDialog.Actions>
</AxoDialog.Footer>
</AxoDialog.Content>
</AxoDialog.Root>
);
}

View File

@@ -189,7 +189,7 @@ function DonationHero({
/>
</div>
<div className="PreferencesDonations__title">
{i18n('icu:PreferencesDonations__title')}
{i18n('icu:PreferencesDonations__title-v2')}
</div>
<div className="PreferencesDonations__description">
<I18n
@@ -197,7 +197,7 @@ function DonationHero({
readMoreLink: privacyReadMoreLink,
}}
i18n={i18n}
id="icu:PreferencesDonations__description"
id="icu:PreferencesDonations__description-v2"
/>
</div>
</>