From 8fb9e043469497b216cd530c800799defb617917 Mon Sep 17 00:00:00 2001 From: mARTin Date: Mon, 13 Apr 2026 09:45:33 +0200 Subject: [PATCH] fix: plain style for user tasks, colored boxes only for calendar events Per webapp behavior: regular user tasks render as white background with a thin colored left border (clean/minimal); external calendar events (externalProvider != null) get a light tinted background box. Completed tasks use a subtle gray style. The all-day strip keeps solid bars for all entries (matching the webapp's ALL DAY section). v1.95.5 --- package.json | 2 +- src/app/api/user/export-week-view/route.ts | 82 +++++++++++++++------- 2 files changed, 58 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index f6fbee7..b357e25 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "my-weekly-todo-list", - "version": "1.95.4", + "version": "1.95.5", "description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view", "main": "index.js", "scripts": { diff --git a/src/app/api/user/export-week-view/route.ts b/src/app/api/user/export-week-view/route.ts index 05ebf6f..1e9f5d2 100644 --- a/src/app/api/user/export-week-view/route.ts +++ b/src/app/api/user/export-week-view/route.ts @@ -167,6 +167,7 @@ type TaskItem = { startTime: string | null; endTime: string | null; completed: boolean; + isExternal: boolean; // true = imported from Google/MS/Apple Calendar project: { name: string; color: string | null } | null; }; @@ -544,7 +545,9 @@ function WeekCalendarPDF({ }) ), - // Task blocks — solid fill matching webapp style + // Task blocks: + // User tasks → white bg + thin colored left border (clean/minimal) + // Calendar events → light tinted bg + colored left border (boxed) ...timedTasks.map(t => { const startMins = parseTimeMinutes(t.startTime)!; const endMins = t.endTime @@ -561,39 +564,67 @@ function WeekCalendarPDF({ const rawH = minutesToY(ceMin - csMin); const taskH = Math.max(rawH, 14); - const bgColor = t.completed ? DONE_BG : (t.project?.color || userStyle.taskColor); - const textColor = t.completed ? DONE_TEXT : contrastColor(bgColor); - const isShort = (ceMin - csMin) <= 30; - const showTime = t.startTime && (!t.startTime.endsWith(':00') || isShort); + const accentColor = t.project?.color || userStyle.weekdayColor; + const isShort = (ceMin - csMin) <= 30; + const showTime = t.startTime && (!t.startTime.endsWith(':00') || isShort); + if (t.completed) { + // Completed: subtle strikethrough-style, always plain + return React.createElement(View, { + key: t.id, + style: { + position: 'absolute', top: topPx + 1, left: 2, right: 2, + height: taskH - 2, backgroundColor: WHITE, + borderLeftWidth: 2, borderLeftColor: DONE_BG, + paddingLeft: 5, paddingRight: 3, paddingVertical: 2, + overflow: 'hidden', + }, + }, + React.createElement(Text, { + style: { fontSize: 7, color: DONE_TEXT, lineHeight: 1.25 }, + }, (t.title || '').slice(0, 44)), + ); + } + + if (t.isExternal) { + // External calendar event: light tinted background box + const bg = lighten(accentColor, 0.8); + return React.createElement(View, { + key: t.id, + style: { + position: 'absolute', top: topPx + 1, left: 2, right: 2, + height: taskH - 2, backgroundColor: bg, + borderRadius: 3, borderLeftWidth: 3, borderLeftColor: accentColor, + paddingLeft: 5, paddingRight: 3, paddingVertical: 2, + overflow: 'hidden', + }, + }, + React.createElement(Text, { + style: { fontFamily: 'Helvetica-Bold', fontSize: 7, color: '#1e293b', lineHeight: 1.25 }, + }, (t.title || '').slice(0, 44)), + showTime ? React.createElement(Text, { + style: { fontSize: 6, color: accentColor, marginTop: 0.5 }, + }, fmtTime(t.startTime!)) : null, + ); + } + + // Regular user task: white background, thin colored left border return React.createElement(View, { key: t.id, style: { - position: 'absolute', - top: topPx + 1, - left: 2, - right: 2, - height: taskH - 2, - backgroundColor: bgColor, - borderRadius: 3, - paddingHorizontal: 4, - paddingVertical: 2, + position: 'absolute', top: topPx + 1, left: 2, right: 2, + height: taskH - 2, backgroundColor: WHITE, + borderLeftWidth: 3, borderLeftColor: accentColor, + paddingLeft: 5, paddingRight: 3, paddingVertical: 2, overflow: 'hidden', }, }, React.createElement(Text, { - style: { - fontFamily: 'Helvetica-Bold', - fontSize: 7, - color: textColor, - lineHeight: 1.25, - }, + style: { fontFamily: 'Helvetica-Bold', fontSize: 7, color: '#1e293b', lineHeight: 1.25 }, }, (t.title || '').slice(0, 44)), - showTime - ? React.createElement(Text, { - style: { fontSize: 6, color: textColor, opacity: 0.8, marginTop: 0.5 }, - }, fmtTime(t.startTime!)) - : null, + showTime ? React.createElement(Text, { + style: { fontSize: 6, color: accentColor, marginTop: 0.5 }, + }, fmtTime(t.startTime!)) : null, ); }).filter(Boolean), ), // end time grid @@ -848,6 +879,7 @@ export async function GET(request: Request) { const item: TaskItem = { id: task.id, title: task.title, startTime: task.startTime, endTime: task.endTime ?? null, completed: task.completed, + isExternal: !!((task as any).externalProvider), project: task.project, };