fix: stack the next-change line instead of letting it wrap
With the week down the right-hand side the main block is narrower, and putting the French and English on one row set the two languages competing for the width. In production that read as "Ouvre demain à" / "11:00" on one side and the separator stranded on a second line with "am" — visibly broken. They are stacked now, French above English, which is already the pattern in the banner, and each line is fitted to the width available rather than allowed to wrap. Found by rendering the real production payload rather than the sample one: the sample had a short enough sentence to hide it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012cSY9pVhZmJUKNN7wf1Myd
This commit is contained in:
@@ -76,18 +76,30 @@ describe('screenTree', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('drops the separator when only one language has something to say', () => {
|
||||
it('shows whichever language has something to say', () => {
|
||||
const frenchOnly = JSON.stringify(
|
||||
screenTree({ ...PAYLOAD, today: { ...PAYLOAD.today, next_change_en: '' } }),
|
||||
);
|
||||
expect(frenchOnly).toContain('Ferme à 13:00');
|
||||
expect(frenchOnly).not.toContain('"·"');
|
||||
expect(frenchOnly).not.toContain('Closes at');
|
||||
|
||||
const englishOnly = JSON.stringify(
|
||||
screenTree({ ...PAYLOAD, today: { ...PAYLOAD.today, next_change_fr: '' } }),
|
||||
);
|
||||
expect(englishOnly).toContain('Closes at 1:00 pm');
|
||||
expect(englishOnly).not.toContain('"·"');
|
||||
expect(englishOnly).not.toContain('Ferme à');
|
||||
});
|
||||
|
||||
it('shrinks a long next-change line instead of wrapping it', () => {
|
||||
// The main block is narrower now the week runs down the side; a long
|
||||
// sentence used to wrap and strand half of itself on a second line.
|
||||
const long = 'Ouvre lundi à 11:00 après la fermeture annuelle';
|
||||
const tree = JSON.stringify(
|
||||
screenTree({ ...PAYLOAD, today: { ...PAYLOAD.today, next_change_fr: long } }),
|
||||
);
|
||||
const sizes = [...tree.matchAll(/"fontSize":(\d+)/g)].map((match) => Number(match[1]));
|
||||
// Something on the screen had to come down from the preferred 24.
|
||||
expect(sizes.some((size) => size < 24 && size >= 18)).toBe(true);
|
||||
});
|
||||
|
||||
it('drops the whole next-change line when there is nothing ahead', () => {
|
||||
|
||||
+40
-6
@@ -220,21 +220,55 @@ function main(payload: ScreenPayload, width: number): ElementNode {
|
||||
today.hours_text,
|
||||
)
|
||||
: null,
|
||||
nextChangeLine(payload),
|
||||
nextChangeLine(payload, width),
|
||||
);
|
||||
}
|
||||
|
||||
function nextChangeLine(payload: ScreenPayload): ElementNode | null {
|
||||
/**
|
||||
* "Ferme à 18:30", then the English underneath.
|
||||
*
|
||||
* Stacked rather than side by side: the main block is narrower now that the
|
||||
* week runs down the right, and a row put the two languages in competition
|
||||
* for the width — the French wrapped and left the separator stranded on the
|
||||
* next line with half the English. Two lines also match the banner, where
|
||||
* French above English is already the pattern.
|
||||
*/
|
||||
function nextChangeLine(payload: ScreenPayload, width: number): ElementNode | null {
|
||||
const { next_change_fr: fr, next_change_en: en } = payload.today;
|
||||
if (!fr && !en) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const available = width - 2 * PADDING;
|
||||
|
||||
return h(
|
||||
'div',
|
||||
{ style: { display: 'flex', alignItems: 'baseline', marginTop: 12 } },
|
||||
fr ? h('div', { style: { display: 'flex', fontSize: 24 } }, fr) : null,
|
||||
fr && en ? h('div', { style: { display: 'flex', fontSize: 24, paddingLeft: 10, paddingRight: 10 } }, '·') : null,
|
||||
en ? h('div', { style: { display: 'flex', fontSize: 20 } }, en) : null,
|
||||
{ style: { display: 'flex', flexDirection: 'column', marginTop: 12 } },
|
||||
fr
|
||||
? h(
|
||||
'div',
|
||||
{
|
||||
style: {
|
||||
display: 'flex',
|
||||
fontSize: fitFontSize(fr, { available, preferred: 24, minimum: 18 }),
|
||||
},
|
||||
},
|
||||
fr,
|
||||
)
|
||||
: null,
|
||||
en
|
||||
? h(
|
||||
'div',
|
||||
{
|
||||
style: {
|
||||
display: 'flex',
|
||||
fontSize: fitFontSize(en, { available, preferred: 20, minimum: 15 }),
|
||||
marginTop: 2,
|
||||
},
|
||||
},
|
||||
en,
|
||||
)
|
||||
: null,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user