fix: read the year on the calendar's month button also in the current year

This commit is contained in:
Linus Rath
2026-10-31 20:17:11 +01:00
parent 305b836001
commit db1fac4085
3 changed files with 30 additions and 6 deletions
+24 -1
View File
@@ -14,6 +14,8 @@ import {
participantRemoveAccessibilityLabel,
} from '../calendar-a11y';
import { useSettingsStore } from '../../stores/settings-store';
import { gregorianCalendar, jalaliCalendar } from '../calendar-system';
import { displayNow } from '../calendar-timezone';
const t = (_key: string, fallback?: string, params?: Record<string, string | number>) =>
formatMessage(fallback ?? '', params, 'en');
@@ -54,7 +56,28 @@ describe('eventAccessibilityLabel', () => {
describe('header and chip buttons', () => {
it('names the month button by the month it shows, not "Click to change month"', () => {
expect(monthButtonAccessibilityLabel('October 2026', t)).toBe('October 2026, change month');
expect(monthButtonAccessibilityLabel(new Date(2026, 9, 15), gregorianCalendar, enUS, t)).toBe('October 2026, change month');
});
it('reads the year also in the current year, where the header leaves it out', () => {
const now = displayNow();
const month = new Intl.DateTimeFormat('en-US', { month: 'long' }).format(now);
expect(monthButtonAccessibilityLabel(now, gregorianCalendar, enUS, t)).toBe(`${month} ${now.getFullYear()}, change month`);
expect(monthButtonAccessibilityLabel(now, jalaliCalendar, enUS, t)).toMatch(/ \d{4}, change month$/);
});
it('has "change month" translated in every app overlay', async () => {
const fs = await import('node:fs');
const path = await import('node:path');
const dir = path.resolve(__dirname, '../../../locales/rn');
const files = fs.readdirSync(dir).filter((f) => f.endsWith('.json'));
expect(files.length).toBeGreaterThanOrEqual(29);
for (const file of files) {
const overlay = JSON.parse(fs.readFileSync(path.join(dir, file), 'utf8'));
const value = overlay.calendar?.change_month_named as string | undefined;
expect(value, file).toContain('{month}');
if (file !== 'en.json') expect(value, file).not.toContain('change month');
}
});
it('names the cross on a participant chip by the person it removes', () => {
+5 -4
View File
@@ -3,7 +3,7 @@ import type { Locale } from 'date-fns';
import type { Calendar, CalendarEvent } from '../api/types';
import { getEventDisplayEndDate, getEventStartDate, getPrimaryCalendarId, timePattern } from './calendar-utils';
import { isDeclinedByUser } from './calendar-participants';
import { formatCalendarDay } from './calendar-system';
import { formatCalendarDay, monthTitle, type CalendarSystem } from './calendar-system';
type Translate = (key: string, fallback?: string, params?: Record<string, string | number>) => string;
@@ -14,10 +14,11 @@ type Translate = (key: string, fallback?: string, params?: Record<string, string
/**
* "October 2026, change month" for the header button that opens the month
* panel: the month shown first, then what the button does. Not the
* webmail's "Click to change month" (calendar.mini_calendar_change).
* webmail's "Click to change month" (calendar.mini_calendar_change). The
* year is always read, also where the header leaves it out (this year).
*/
export function monthButtonAccessibilityLabel(title: string, t: Translate): string {
return t('calendar.change_month_named', '{month}, change month', { month: title });
export function monthButtonAccessibilityLabel(date: Date, system: CalendarSystem, locale: Locale, t: Translate): string {
return t('calendar.change_month_named', '{month}, change month', { month: monthTitle(date, system, locale, true) });
}
/** "Remove Ana" for the cross on an invited participant's chip (webmail recipient_remove_named). */
+1 -1
View File
@@ -1037,7 +1037,7 @@ export default function CalendarScreen() {
style={styles.titleBtn}
hitSlop={6}
accessibilityRole="button"
accessibilityLabel={monthButtonAccessibilityLabel(headerTitle(titleDate, locale, system), t)}
accessibilityLabel={monthButtonAccessibilityLabel(titleDate, system, locale, t)}
accessibilityState={{ expanded: monthPanelOpen }}
>
<Text style={styles.headerTitle} numberOfLines={1}>