feat(settings): remove the platform mails switch

Broadcasts go to every active user, so the settings switch and its API
call are gone. Admin broadcast texts no longer mention an opt-out.
This commit is contained in:
lobo committed 2026-10-02 07:53:35 +02:00
1 parent 6dda186bdf
commit 80259cb0e9
8 files changed
+19 -60

No files matched your search

-1
View File
@@ -115,7 +115,6 @@ To Be Played is split into three repositories:
(menu) lists all entries and marks them seen. Admins publish, preview, edit and delete entries on `/admin/news`. (menu) lists all entries and marks them seen. Admins publish, preview, edit and delete entries on `/admin/news`.
- **Broadcast mail**: admins write a mail in both languages on `/admin/broadcasts`, send it to all active users or to - **Broadcast mail**: admins write a mail in both languages on `/admin/broadcasts`, send it to all active users or to
picked ones, send a test to themselves, confirm with the real recipient count, and see the history with the counts. picked ones, send a test to themselves, confirm with the real recipient count, and see the history with the counts.
Users turn platform mails off in the settings; account mails always come.
- **Welcome page**: `/welcome` opens once after the first login (Auth `settings.welcomeSeenAt` is null; only the - **Welcome page**: `/welcome` opens once after the first login (Auth `settings.welcomeSeenAt` is null; only the
dashboard redirects, deep links stay). Feature cards with links, two next steps (Steam, import) with checks from dashboard redirects, deep links stay). Feature cards with links, two next steps (Steam, import) with checks from
`/me` and the library summary. "Let's go" and "Skip" stamp it in Auth and open the dashboard. The settings page `/me` and the library summary. "Let's go" and "Skip" stamp it in Auth and open the dashboard. The settings page
+3 -5
View File
@@ -143,9 +143,7 @@
"PROFILE_TILES_HINT": "Wähle, was dein Profil zeigt und wo: öffne dein Profil und klicke auf \"Anpassen\".", "PROFILE_TILES_HINT": "Wähle, was dein Profil zeigt und wo: öffne dein Profil und klicke auf \"Anpassen\".",
"FAVORITE_PLATFORM": "Lieblingsplattform", "FAVORITE_PLATFORM": "Lieblingsplattform",
"FAVORITE_PLATFORM_HINT": "Wird zuerst gewählt, wenn du ein Spiel für mehrere Plattformen hinzufügst.", "FAVORITE_PLATFORM_HINT": "Wird zuerst gewählt, wenn du ein Spiel für mehrere Plattformen hinzufügst.",
"FAVORITE_PLATFORM_NONE": "Keine", "FAVORITE_PLATFORM_NONE": "Keine"
"PLATFORM_MAILS": "Mails von der Plattform",
"PLATFORM_MAILS_HINT": "Neuigkeiten und Ankündigungen per Mail. Mails zu deinem Konto kommen immer."
}, },
"VALIDATION": { "VALIDATION": {
"EMAIL_REQUIRED": "Email ist erforderlich.", "EMAIL_REQUIRED": "Email ist erforderlich.",
@@ -718,7 +716,7 @@
"SUBJECT_DE": "Betreff (Deutsch)", "SUBJECT_DE": "Betreff (Deutsch)",
"BODY_EN": "Text (Englisch)", "BODY_EN": "Text (Englisch)",
"BODY_DE": "Text (Deutsch)", "BODY_DE": "Text (Deutsch)",
"TEXT_HELP": "Nur Text, in beiden Sprachen. Betreff höchstens 150, Text höchstens 5000 Zeichen. Eine Fußzeile mit dem Link zum Abschalten wird angehängt.", "TEXT_HELP": "Nur Text, in beiden Sprachen. Betreff höchstens 150, Text höchstens 5000 Zeichen. Eine Fußzeile wird angehängt.",
"RECIPIENTS": "Empfänger", "RECIPIENTS": "Empfänger",
"ALL": "Alle aktiven Nutzer", "ALL": "Alle aktiven Nutzer",
"PICKED": "Ausgewählte Nutzer", "PICKED": "Ausgewählte Nutzer",
@@ -732,7 +730,7 @@
"CONFIRM_TEXT": "An {{count}} Nutzer senden? Das kann nicht rückgängig gemacht werden.", "CONFIRM_TEXT": "An {{count}} Nutzer senden? Das kann nicht rückgängig gemacht werden.",
"CONFIRM": "Senden", "CONFIRM": "Senden",
"CANCEL": "Abbrechen", "CANCEL": "Abbrechen",
"NO_RECIPIENTS": "Kein Empfänger: niemand ist aktiv und hat Mails an.", "NO_RECIPIENTS": "Kein Empfänger: niemand davon ist aktiv.",
"SENT": "Mail für {{count}} Nutzer eingereiht.", "SENT": "Mail für {{count}} Nutzer eingereiht.",
"ERROR": "Die Aktion ist fehlgeschlagen.", "ERROR": "Die Aktion ist fehlgeschlagen.",
"LIST": "Gesendete Mails", "LIST": "Gesendete Mails",
+3 -5
View File
@@ -143,9 +143,7 @@
"PROFILE_TILES_HINT": "Choose what your profile shows, and where: open your profile and click \"Customize\".", "PROFILE_TILES_HINT": "Choose what your profile shows, and where: open your profile and click \"Customize\".",
"FAVORITE_PLATFORM": "Favorite platform", "FAVORITE_PLATFORM": "Favorite platform",
"FAVORITE_PLATFORM_HINT": "Selected first when you add a game on more than one platform.", "FAVORITE_PLATFORM_HINT": "Selected first when you add a game on more than one platform.",
"FAVORITE_PLATFORM_NONE": "None", "FAVORITE_PLATFORM_NONE": "None"
"PLATFORM_MAILS": "Mails from the platform",
"PLATFORM_MAILS_HINT": "News and announcements by mail. Mails about your account always come."
}, },
"VALIDATION": { "VALIDATION": {
"EMAIL_REQUIRED": "Email is required.", "EMAIL_REQUIRED": "Email is required.",
@@ -718,7 +716,7 @@
"SUBJECT_DE": "Subject (German)", "SUBJECT_DE": "Subject (German)",
"BODY_EN": "Text (English)", "BODY_EN": "Text (English)",
"BODY_DE": "Text (German)", "BODY_DE": "Text (German)",
"TEXT_HELP": "Plain text, both languages. Subject max 150, text max 5000 characters. A footer with the opt-out link is added.", "TEXT_HELP": "Plain text, both languages. Subject max 150, text max 5000 characters. A footer is added.",
"RECIPIENTS": "Recipients", "RECIPIENTS": "Recipients",
"ALL": "All active users", "ALL": "All active users",
"PICKED": "Picked users", "PICKED": "Picked users",
@@ -732,7 +730,7 @@
"CONFIRM_TEXT": "Send to {{count}} users? This cannot be undone.", "CONFIRM_TEXT": "Send to {{count}} users? This cannot be undone.",
"CONFIRM": "Send", "CONFIRM": "Send",
"CANCEL": "Cancel", "CANCEL": "Cancel",
"NO_RECIPIENTS": "No recipient: nobody active with mails on.", "NO_RECIPIENTS": "No recipient: nobody active among them.",
"SENT": "Mail queued for {{count}} users.", "SENT": "Mail queued for {{count}} users.",
"ERROR": "The action failed.", "ERROR": "The action failed.",
"LIST": "Sent mails", "LIST": "Sent mails",
+1 -16
View File
@@ -11,7 +11,7 @@ import {usePreferences} from '../context/PreferencesContext.jsx';
import usePersistSettings from '../hooks/usePersistSettings.js'; import usePersistSettings from '../hooks/usePersistSettings.js';
import useSaveResponse from '../hooks/useSaveResponse.js'; import useSaveResponse from '../hooks/useSaveResponse.js';
import {FAVORITE_PLATFORMS, saveFavoritePlatform} from '../utils/platforms.js'; import {FAVORITE_PLATFORMS, saveFavoritePlatform} from '../utils/platforms.js';
import {LANGUAGES, savePlatformMails, saveSettings} from '../utils/settings.js'; import {LANGUAGES, saveSettings} from '../utils/settings.js';
// Radix Select has no empty value. // Radix Select has no empty value.
const NO_FAVORITE = 'NONE'; const NO_FAVORITE = 'NONE';
@@ -41,13 +41,6 @@ export default function PreferencesCard() {
} }
}; };
const handlePlatformMailsChange = async (next) => {
if (await runSave(() => savePlatformMails(next))) {
updateProfile((p) => ({...p, settings: {...p.settings, platformMails: next}}));
toast.success(t('SETTINGS.SAVED'));
}
};
return ( return (
<Card> <Card>
<CardHeader> <CardHeader>
@@ -90,14 +83,6 @@ export default function PreferencesCard() {
</SelectContent> </SelectContent>
</Select> </Select>
</div> </div>
<div className="flex items-center justify-between gap-4">
<div className="space-y-1">
<Label htmlFor="platformMails">{t('SETTINGS.PLATFORM_MAILS')}</Label>
<p className="text-xs text-muted-foreground">{t('SETTINGS.PLATFORM_MAILS_HINT')}</p>
</div>
<Switch id="platformMails" checked={profile?.settings?.platformMails ?? true}
onCheckedChange={handlePlatformMailsChange}/>
</div>
</CardContent> </CardContent>
</Card> </Card>
); );
+11
View File
@@ -20,3 +20,14 @@ describe('translation files', () => {
expect(loadPath).toBe(`/i18n/{{lng}}.json?v=${hash.digest('hex').slice(0, 12)}`); expect(loadPath).toBe(`/i18n/{{lng}}.json?v=${hash.digest('hex').slice(0, 12)}`);
}); });
}); });
describe('admin broadcast texts', () => {
it('adminBroadcastTexts_DoNotMentionAnOptOut', () => {
const dir = path.resolve(import.meta.dirname, '../public/i18n');
for (const file of ['en.json', 'de.json']) {
const texts = JSON.parse(readFileSync(path.join(dir, file), 'utf8')).ADMIN_BROADCAST;
expect(texts.TEXT_HELP, file).not.toMatch(/opt-out|Abschalten/i);
expect(texts.NO_RECIPIENTS, file).not.toMatch(/mails on|Mails an/i);
}
});
});
-24
View File
@@ -31,7 +31,6 @@ const authRoutes = (me) => ({
'PUT /api/users/settings/appearance': noBody, 'PUT /api/users/settings/appearance': noBody,
'PUT /api/users/settings/profile-style': noBody, 'PUT /api/users/settings/profile-style': noBody,
'PUT /api/users/settings/favorite-platform': noBody, 'PUT /api/users/settings/favorite-platform': noBody,
'PUT /api/users/settings/platform-mails': noBody,
'GET /api/version': json(404, {}), 'GET /api/version': json(404, {}),
}); });
@@ -257,29 +256,6 @@ describe('SettingsPage favorite platform', () => {
}); });
}); });
describe('SettingsPage platform mails', () => {
beforeEach(() => localStorage.setItem('tbp_session', '1'));
afterEach(() => {
cleanup();
localStorage.clear();
});
it('is on by default and saves the opt-out', async () => {
toast.success.mockClear();
renderPage(profile());
const mails = await screen.findByRole('switch', {name: 'SETTINGS.PLATFORM_MAILS'});
expect(mails.getAttribute('aria-checked')).toBe('true');
fireEvent.click(mails);
await waitFor(() => expect(puts()).toEqual([{enabled: false}]));
expect(fetch.mock.calls.find(([, init]) => init?.method === 'PUT')[0]).toContain('/api/users/settings/platform-mails');
await waitFor(() => expect(toast.success).toHaveBeenCalledWith('SETTINGS.SAVED'));
expect(mails.getAttribute('aria-checked')).toBe('false');
});
});
describe('SettingsPage session', () => { describe('SettingsPage session', () => {
beforeEach(() => localStorage.setItem('tbp_session', '1')); beforeEach(() => localStorage.setItem('tbp_session', '1'));
+1 -1
View File
@@ -10,7 +10,7 @@ const JSON_HEADERS = {'Content-Type': 'application/json'};
export const fetchBroadcasts = () => apiFetch(`${AUTH()}/api/admin/broadcasts`); export const fetchBroadcasts = () => apiFetch(`${AUTH()}/api/admin/broadcasts`);
/** /**
* {count}: the active users with platform mails on, among `userIds`; all of them when `userIds` is null. * {count}: the active users among `userIds`; all of them when `userIds` is null.
*/ */
export const fetchRecipientCount = (userIds) => export const fetchRecipientCount = (userIds) =>
apiFetch(`${AUTH()}/api/admin/broadcasts/recipient-count${userIds ? `?userIds=${userIds.join(',')}` : ''}`); apiFetch(`${AUTH()}/api/admin/broadcasts/recipient-count${userIds ? `?userIds=${userIds.join(',')}` : ''}`);
-8
View File
@@ -58,11 +58,3 @@ export const markWelcomeSeen = () =>
method: 'PUT', method: 'PUT',
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS), signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
}); });
/** PUT on Auth, 204: turns the broadcast mails on or off. The caller handles the response status. */
export const savePlatformMails = (enabled) =>
apiFetch(`${import.meta.env.VITE_API_URL}/api/users/settings/platform-mails`, {
method: 'PUT',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({enabled}),
});