fix: hide subscribe to calendar in lite, which can't fetch feeds

This commit is contained in:
Linus Rath
2026-10-31 17:52:28 +01:00
parent f11ddf82dd
commit 48c8d37e37
2 changed files with 35 additions and 9 deletions
@@ -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<typeof import('@/lib/lite')>()),
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(<><CalendarApp /><PaletteGroups /></>);
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();
+15 -9
View File
@@ -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 =
<span className="block text-xs text-muted-foreground mt-0.5">{tWebcalAction("import_description")}</span>
</span>
</Button>
<Button variant="outline" className="w-full justify-start h-auto py-3" onClick={handleSubscribeWebcal}>
<span className="text-start">
<span className="block font-medium">{tWebcalAction("subscribe_title")}</span>
<span className="block text-xs text-muted-foreground mt-0.5">{tWebcalAction("subscribe_description")}</span>
</span>
</Button>
{!IS_LITE && (
<Button variant="outline" className="w-full justify-start h-auto py-3" onClick={handleSubscribeWebcal}>
<span className="text-start">
<span className="block font-medium">{tWebcalAction("subscribe_title")}</span>
<span className="block text-xs text-muted-foreground mt-0.5">{tWebcalAction("subscribe_description")}</span>
</span>
</Button>
)}
</div>
</Dialog>
) : 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}