From 48c8d37e37dd9c19999df792237139cbff356eb1 Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Sat, 31 Oct 2026 17:52:28 +0100 Subject: [PATCH] fix: hide subscribe to calendar in lite, which can't fetch feeds --- .../calendar/__tests__/calendar-app.test.tsx | 20 ++++++++++++++++ components/calendar/calendar-app.tsx | 24 ++++++++++++------- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/components/calendar/__tests__/calendar-app.test.tsx b/components/calendar/__tests__/calendar-app.test.tsx index 8d7592afc..c9e67b2fb 100644 --- a/components/calendar/__tests__/calendar-app.test.tsx +++ b/components/calendar/__tests__/calendar-app.test.tsx @@ -28,6 +28,11 @@ vi.mock('@/hooks/use-account-principal-emails', () => ({ useAccountPrincipalEmai vi.mock('../participant-availability', () => ({ ParticipantAvailability: () => null })); const config = vi.hoisted(() => ({ demoMode: false })); vi.mock('@/hooks/use-config', () => ({ useConfig: () => config })); +const lite = vi.hoisted(() => ({ on: false })); +vi.mock('@/lib/lite', async (importOriginal) => ({ + ...(await importOriginal()), + get IS_LITE() { return lite.on; }, +})); import { CalendarApp } from '../calendar-app'; import { useRegisteredCommandGroups } from '@/lib/command-registry'; @@ -742,6 +747,21 @@ describe('CalendarApp in the demo', () => { }); }); +describe('CalendarApp in Lite', () => { + it('leaves Subscribe out, since the static build has no feed proxy', async () => { + lite.on = true; + try { + render(<>); + fireEvent.click(screen.getByRole('button', { name: 'toolbar.more' })); + expect(await screen.findByRole('menuitem', { name: 'toolbar.import' })).toBeInTheDocument(); + expect(screen.queryByRole('menuitem', { name: 'toolbar.subscribe' })).toBeNull(); + expect(screen.getByTestId('palette').textContent).not.toContain('toolbar.subscribe'); + } finally { + lite.on = false; + } + }); +}); + describe('CalendarApp view menu', () => { it('opens as a menu the keyboard can use and switches the view', async () => { renderApp(); diff --git a/components/calendar/calendar-app.tsx b/components/calendar/calendar-app.tsx index 2a9074233..8af63f0a7 100644 --- a/components/calendar/calendar-app.tsx +++ b/components/calendar/calendar-app.tsx @@ -100,6 +100,7 @@ import { type ScrollWindowState, type ScrollWindowViewProps, } from "@/lib/calendar-scroll-window"; import { useLiteLinkSegments } from "@/hooks/use-lite-link-segments"; +import { IS_LITE } from "@/lib/lite"; import { findMeetingLink } from "@/lib/event-links"; import { useDocumentTitle } from "@/hooks/use-document-title"; import { useFocusTrap } from "@/hooks/use-focus-trap"; @@ -144,6 +145,9 @@ export function CalendarApp({ linkSegments: routeSegments }: CalendarAppProps = useDocumentTitle(tSidebar("calendar")); const tWebcalAction = useTranslations("calendar.webcal_action"); const { demoMode } = useConfig(); + // Subscriptions fetch the feed through /api/fetch-ical, which the demo has no + // mail server for and the Lite static build does not have at all. + const canSubscribe = !demoMode && !IS_LITE; const tDeepLink = useTranslations("deep_link"); const isMobile = useIsMobile(); const isDesktop = useIsDesktop(); @@ -1643,7 +1647,7 @@ export function CalendarApp({ linkSegments: routeSegments }: CalendarAppProps = when: () => mode !== normalizedViewMode && (mode !== "tasks" || enableCalendarTasks), })), { id: "import", label: t("toolbar.import"), icon: Upload, run: () => setShowImportModal(true), when: () => !demoMode }, - { id: "subscribe", label: t("toolbar.subscribe"), icon: Globe, run: () => setShowSubscriptionModal(true), when: () => !demoMode }, + { id: "subscribe", label: t("toolbar.subscribe"), icon: Globe, run: () => setShowSubscriptionModal(true), when: () => canSubscribe }, { id: "refresh", label: tCommon("refresh"), icon: RefreshCw, shortcut: "F5", run: () => { void refreshCalendar(); } }, ], isEmbedded ? isFocusedProTab : !proInterfaceActive); @@ -1786,12 +1790,14 @@ export function CalendarApp({ linkSegments: routeSegments }: CalendarAppProps = {tWebcalAction("import_description")} - + {!IS_LITE && ( + + )} ) : null; @@ -2016,7 +2022,7 @@ export function CalendarApp({ linkSegments: routeSegments }: CalendarAppProps = onCreateEvent={openCreateForView} createLabel={createLabel} onImport={demoMode ? undefined : () => setShowImportModal(true)} - onSubscribe={demoMode ? undefined : () => setShowSubscriptionModal(true)} + onSubscribe={canSubscribe ? () => setShowSubscriptionModal(true) : undefined} onRefresh={() => { void refreshCalendar(); }} onPrint={() => { void requestPrint({ kind: "calendar-view" }); }} isMobile={isMobile} @@ -2197,7 +2203,7 @@ export function CalendarApp({ linkSegments: routeSegments }: CalendarAppProps = } } : undefined} onCreateCalendar={client ? () => setShowCreateCalendar(true) : undefined} - onSubscribe={demoMode ? undefined : () => setShowSubscriptionModal(true)} + onSubscribe={canSubscribe ? () => setShowSubscriptionModal(true) : undefined} onEditSubscription={(subId) => setEditingSubscription(subId)} client={client} multiAccountMode={multiAccountEnabled && accountClients.length > 1}