fix: show event titles instead of bare start times in a narrow month view

This commit is contained in:
Linus Rath
2026-10-15 04:05:55 +02:00
parent cf7275c9c3
commit 95c31631fb
3 changed files with 33 additions and 4 deletions
+8 -4
View File
@@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { View, Text, StyleSheet, Pressable } from 'react-native'; import { View, Text, StyleSheet, Pressable, useWindowDimensions } from 'react-native';
import { import {
addDays, addDays,
endOfMonth, endOfMonth,
@@ -24,7 +24,7 @@ import {
type EventDayIndex, type EventDayIndex,
type TimeFormat, type TimeFormat,
} from '../../lib/calendar-utils'; } from '../../lib/calendar-utils';
import { dayIndexIn, monthKeyOf, monthMask } from '../../lib/calendar-month-scroll'; import { dayIndexIn, monthChipShowsTime, monthKeyOf, monthMask } from '../../lib/calendar-month-scroll';
import { isInactiveEvent } from '../../lib/calendar-participants'; import { isInactiveEvent } from '../../lib/calendar-participants';
import { eventBlockColors } from '../../lib/event-colors'; import { eventBlockColors } from '../../lib/event-colors';
import { useCalendarLocale } from '../../lib/calendar-locale'; import { useCalendarLocale } from '../../lib/calendar-locale';
@@ -153,6 +153,8 @@ function MonthWeekRowInner({
onLongPressDate, onLongPressDate,
}: MonthWeekRowProps) { }: MonthWeekRowProps) {
const c = useColors(); const c = useColors();
const { width } = useWindowDimensions();
const chipTime = monthChipShowsTime(true, width / 7);
if (variant === 'full') { if (variant === 'full') {
return ( return (
<FullWeekRow <FullWeekRow
@@ -258,7 +260,7 @@ function MonthWeekRowInner({
]} ]}
> >
<Text style={[styles.chipText, { color: colors.text }]} numberOfLines={1}> <Text style={[styles.chipText, { color: colors.text }]} numberOfLines={1}>
{event.showWithoutTime {event.showWithoutTime || !chipTime
? null ? null
: `${format(getEventStartDate(event), timePattern(timeFormat), { locale })} `} : `${format(getEventStartDate(event), timePattern(timeFormat), { locale })} `}
<Text style={inactive && styles.chipTextInactive}>{event.title || ''}</Text> <Text style={inactive && styles.chipTextInactive}>{event.title || ''}</Text>
@@ -318,6 +320,8 @@ function FullWeekRow({
height: number; height: number;
colors: ThemePalette; colors: ThemePalette;
}) { }) {
const { width } = useWindowDimensions();
const showTime = monthChipShowsTime(showTimeInMonthView, width / 7);
return ( return (
<View style={[styles.fullWeekRow, { height }]}> <View style={[styles.fullWeekRow, { height }]}>
{showWeekNumbers && ( {showWeekNumbers && (
@@ -357,7 +361,7 @@ function FullWeekRow({
const inactive = isInactiveEvent(event, currentUserEmails); const inactive = isInactiveEvent(event, currentUserEmails);
const colors = eventBlockColors(getEventColor(event, calendars), inactive, c); const colors = eventBlockColors(getEventColor(event, calendars), inactive, c);
// No time on events that fill the whole day. // No time on events that fill the whole day.
const time = showTimeInMonthView && !event.showWithoutTime && !isTimedEventFullDayOnDate(event, d) const time = showTime && !event.showWithoutTime && !isTimedEventFullDayOnDate(event, d)
? `${format(getEventStartDate(event), timePattern(timeFormat), { locale })} ` ? `${format(getEventStartDate(event), timePattern(timeFormat), { locale })} `
: ''; : '';
return ( return (
+16
View File
@@ -0,0 +1,16 @@
import { describe, expect, it } from 'vitest';
import { monthChipShowsTime } from '../calendar-month-scroll';
describe('monthChipShowsTime', () => {
it('drops the time in a phone-portrait cell so the title shows', () => {
expect(monthChipShowsTime(true, 412 / 7)).toBe(false);
});
it('keeps the time where the cell has room', () => {
expect(monthChipShowsTime(true, 915 / 7)).toBe(true);
});
it('never shows the time when the setting is off', () => {
expect(monthChipShowsTime(false, 200)).toBe(false);
});
});
+9
View File
@@ -87,3 +87,12 @@ export function dayIndexIn(days: Date[], date: Date): number {
const diff = differenceInCalendarDays(date, days[0]); const diff = differenceInCalendarDays(date, days[0]);
return diff >= 0 && diff < days.length ? diff : -1; return diff >= 0 && diff < days.length ? diff : -1;
} }
// Below this cell width a start time fills the whole chip and the title never
// shows, as on a phone in portrait (about 58 dp, less at a larger font).
const MIN_CELL_WIDTH_FOR_TIME = 80;
/** Whether a full month cell of about `cellWidth` dp puts the start time before the title. */
export function monthChipShowsTime(showTimeSetting: boolean, cellWidth: number): boolean {
return showTimeSetting && cellWidth >= MIN_CELL_WIDTH_FOR_TIME;
}