diff --git a/components/settings/__tests__/calendar-management-phone.test.tsx b/components/settings/__tests__/calendar-management-phone.test.tsx new file mode 100644 index 000000000..f9f67fbc6 --- /dev/null +++ b/components/settings/__tests__/calendar-management-phone.test.tsx @@ -0,0 +1,68 @@ +import { render, screen } from '@testing-library/react'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import type { Calendar } from '@/lib/jmap/types'; +import { useAuthStore } from '@/stores/auth-store'; +import { useCalendarStore } from '@/stores/calendar-store'; + +// Settings > Calendar on a phone: no right-click hint on a touch screen, a +// colour dot that can be hit, and no Import or Subscribe in the demo, which +// Calendar itself hides there too. + +const env = vi.hoisted(() => ({ touch: false, demoMode: false })); +vi.mock('@/hooks/use-media-query', () => ({ + useMediaQuery: (query: string) => (query === '(pointer: coarse)' ? env.touch : false), + useIsMobile: () => env.touch, + useIsDesktop: () => !env.touch, +})); +vi.mock('@/hooks/use-config', () => ({ useConfig: () => ({ demoMode: env.demoMode }) })); + +const { CalendarManagementSettings } = await import('../calendar-management-settings'); + +const work = { + id: 'c', name: 'Work', color: '#3b82f6', isDefault: true, isShared: false, shareWith: null, + myRights: { mayShare: true, mayDelete: true, mayWriteAll: true }, +} as unknown as Calendar; + +const initial = { auth: useAuthStore.getState(), calendar: useCalendarStore.getState() }; +beforeEach(() => { + env.touch = false; + env.demoMode = false; + useAuthStore.setState({ client: { getAccountId: () => 'acc' }, serverUrl: null, username: null } as never); + useCalendarStore.setState({ calendars: [work], icalSubscriptions: [] } as never); +}); +afterEach(() => { + useAuthStore.setState(initial.auth, true); + useCalendarStore.setState(initial.calendar, true); +}); + +describe('Settings > Calendar on a phone', () => { + it('mentions right-click only where there is a mouse', () => { + const { unmount } = render(); + expect(screen.getByText('description')).toBeInTheDocument(); + unmount(); + + env.touch = true; + render(); + expect(screen.queryByText('description')).toBeNull(); + expect(screen.getByText('description_touch')).toBeInTheDocument(); + }); + + it('gives the colour dot a 44px hit area on touch', () => { + render(); + const dot = screen.getByRole('button', { name: 'change_color' }); + expect(dot.className).toContain('pointer-coarse:after:min-h-11'); + expect(dot.className).toContain('pointer-coarse:after:min-w-11'); + }); + + it('offers Import and Subscribe only outside the demo', () => { + const { unmount } = render(); + // Both dialogs' titles are "title" here: one button each. + expect(screen.getAllByRole('button', { name: 'title' })).toHaveLength(2); + unmount(); + + env.demoMode = true; + render(); + expect(screen.queryByRole('button', { name: 'title' })).toBeNull(); + expect(screen.getByRole('button', { name: 'add_calendar' })).toBeInTheDocument(); + }); +}); diff --git a/components/settings/calendar-management-settings.tsx b/components/settings/calendar-management-settings.tsx index f8841ba76..00d901eef 100644 --- a/components/settings/calendar-management-settings.tsx +++ b/components/settings/calendar-management-settings.tsx @@ -29,6 +29,9 @@ import { IS_LITE } from '@/lib/lite'; import { shareRecipientNames, useShareRecipientLabels } from '@/hooks/use-share-recipient-labels'; import { calendarAccountKey, moveCalendar } from '@/lib/calendar-sort'; import { ConfirmDialog } from '@/components/ui/confirm-dialog'; +import { TOUCH_HIT_AREA } from '@/components/ui/button'; +import { useMediaQuery } from '@/hooks/use-media-query'; +import { useConfig } from '@/hooks/use-config'; function CalendarColorPicker({ value, @@ -291,6 +294,10 @@ export function CalendarManagementSettings() { const colorPickerRef = useRef(null); const [draggingId, setDraggingId] = useState(null); const { contextMenu, openContextMenu, openContextMenuFrom, closeContextMenu, menuRef } = useContextMenu(); + // No right-click on a touch screen, so the hint about it goes there. + const touch = useMediaQuery('(pointer: coarse)'); + // The demo has no server to import into or subscribe from, as in Calendar. + const { demoMode } = useConfig(); const listedCalendars = calendars .filter(cal => !isSubscriptionCalendar(cal.id)) @@ -620,7 +627,7 @@ export function CalendarManagementSettings() { }; return ( - + {renderRowMenu()} {listedCalendars.map((cal) => { @@ -686,7 +693,10 @@ export function CalendarManagementSettings() { setColorPickerId(colorPickerId === cal.id ? null : cal.id)} - className="w-5 h-5 rounded-full shrink-0 transition-transform hover:scale-110 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2" + className={cn( + "block w-5 h-5 rounded-full shrink-0 transition-transform hover:scale-110 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", + TOUCH_HIT_AREA, + )} style={{ backgroundColor: color }} title={t('change_color')} aria-label={t('change_color')} @@ -811,31 +821,34 @@ export function CalendarManagementSettings() { isLoading={isLoading} /> ) : ( - + // Stacked on a phone: side by side the three labels wrapped. + setIsCreating(true)} - className="flex items-center gap-2 flex-1 py-2.5 px-3 text-sm text-muted-foreground hover:text-foreground hover:bg-muted rounded-md border border-dashed border-border transition-colors" + className="flex items-center gap-2 flex-1 py-2.5 px-3 text-sm text-muted-foreground hover:text-foreground hover:bg-muted rounded-md border border-dashed border-border transition-colors whitespace-nowrap" > {t('add_calendar')} - setShowImportModal(true)} - className="flex items-center gap-2 py-2.5 px-3 text-sm text-muted-foreground hover:text-foreground hover:bg-muted rounded-md border border-dashed border-border transition-colors" - > - - {tImport('title')} - + {!demoMode && ( + setShowImportModal(true)} + className="flex items-center gap-2 py-2.5 px-3 text-sm text-muted-foreground hover:text-foreground hover:bg-muted rounded-md border border-dashed border-border transition-colors whitespace-nowrap" + > + + {tImport('title')} + + )} {/* ICS URL subscriptions refresh via /api/fetch-ical, absent in the static build. */} - {!IS_LITE && ( + {!IS_LITE && !demoMode && ( setShowSubscriptionModal(true)} - className="flex items-center gap-2 py-2.5 px-3 text-sm text-muted-foreground hover:text-foreground hover:bg-muted rounded-md border border-dashed border-border transition-colors" + className="flex items-center gap-2 py-2.5 px-3 text-sm text-muted-foreground hover:text-foreground hover:bg-muted rounded-md border border-dashed border-border transition-colors whitespace-nowrap" > {tSub('title')} diff --git a/locales/ar/common.json b/locales/ar/common.json index dec99a17c..f9d606775 100644 --- a/locales/ar/common.json +++ b/locales/ar/common.json @@ -4021,6 +4021,7 @@ "management": { "title": "إدارة التقويمات", "description": "أنشئ تقويماتك وأعد تسميتها وخصّصها. انقر بالزر الأيمن على تقويم في الشريط الجانبي لتغيير لونه بسرعة.", + "description_touch": "أنشئ تقويماتك وأعد تسميتها وخصّصها.", "name": "الاسم", "name_placeholder": "اسم التقويم", "color": "اللون", diff --git a/locales/ca/common.json b/locales/ca/common.json index 90f27c2d1..abe288e90 100644 --- a/locales/ca/common.json +++ b/locales/ca/common.json @@ -4021,6 +4021,7 @@ "management": { "title": "Gestió de calendaris", "description": "Creeu, canvieu el nom i personalitzeu els calendaris. Feu clic dret a un calendari a la barra lateral per canviar-ne ràpidament el color.", + "description_touch": "Creeu, canvieu el nom i personalitzeu els calendaris.", "name": "Nom", "name_placeholder": "Nom del calendari", "color": "Color", diff --git a/locales/cs/common.json b/locales/cs/common.json index b33f1e457..c1521e3ff 100644 --- a/locales/cs/common.json +++ b/locales/cs/common.json @@ -3992,6 +3992,7 @@ "management": { "title": "Správa kalendáře", "description": "Vytvářejte, přejmenovávejte a přizpůsobujte si své kalendáře. Klikněte pravým tlačítkem na kalendář v postranním panelu pro rychlou změnu jeho barvy.", + "description_touch": "Vytvářejte, přejmenovávejte a přizpůsobujte si své kalendáře.", "name": "Název", "name_placeholder": "Název kalendáře", "color": "Barva", diff --git a/locales/da/common.json b/locales/da/common.json index 4a40daf63..139c7893c 100644 --- a/locales/da/common.json +++ b/locales/da/common.json @@ -4018,6 +4018,7 @@ "management": { "title": "Kalenderadministration", "description": "Opret, omdøb og tilpas dine kalendere. Højreklik på en kalender i sidepanelet for hurtigt at ændre dens farve.", + "description_touch": "Opret, omdøb og tilpas dine kalendere.", "name": "Navn", "name_placeholder": "Kalendernavn", "color": "Farve", diff --git a/locales/de/common.json b/locales/de/common.json index b9434aaf6..1f12adf7d 100644 --- a/locales/de/common.json +++ b/locales/de/common.json @@ -3992,6 +3992,7 @@ "management": { "title": "Kalenderverwaltung", "description": "Erstellen, umbenennen und anpassen Ihrer Kalender. Rechtsklick auf einen Kalender in der Seitenleiste, um die Farbe schnell zu ändern.", + "description_touch": "Erstellen, benennen und gestalten Sie Ihre Kalender.", "name": "Name", "name_placeholder": "Kalendername", "color": "Farbe", diff --git a/locales/en/common.json b/locales/en/common.json index 6d0d3099f..a52308718 100644 --- a/locales/en/common.json +++ b/locales/en/common.json @@ -4021,6 +4021,7 @@ "management": { "title": "Calendar management", "description": "Create, rename, and customize your calendars. Right-click a calendar in the sidebar to quickly change its color.", + "description_touch": "Create, rename, and customize your calendars.", "name": "Name", "name_placeholder": "Calendar name", "color": "Color", diff --git a/locales/es/common.json b/locales/es/common.json index 6cb32bebe..c722761d6 100644 --- a/locales/es/common.json +++ b/locales/es/common.json @@ -3992,6 +3992,7 @@ "management": { "title": "Gestión de calendarios", "description": "Crea, renombra y personaliza tus calendarios. Haz clic derecho en un calendario en la barra lateral para cambiar su color rápidamente.", + "description_touch": "Crea, renombra y personaliza tus calendarios.", "name": "Nombre", "name_placeholder": "Nombre del calendario", "color": "Color", diff --git a/locales/et/common.json b/locales/et/common.json index ed985f591..e99d033b7 100644 --- a/locales/et/common.json +++ b/locales/et/common.json @@ -4021,6 +4021,7 @@ "management": { "title": "Kalendrite haldamine", "description": "Loo, nimeta ümber ja kohanda oma kalendreid. Kalendri värvi kiireks muutmiseks tee küljeribal kalendril paremklõps.", + "description_touch": "Loo, nimeta ümber ja kohanda oma kalendreid.", "name": "Nimi", "name_placeholder": "Kalendri nimi", "color": "Värv", diff --git a/locales/fa/common.json b/locales/fa/common.json index afc61b00a..433ef470c 100644 --- a/locales/fa/common.json +++ b/locales/fa/common.json @@ -4021,6 +4021,7 @@ "management": { "title": "مدیریت تقویم", "description": "ایجاد، تغییر نام و سفارشیسازی تقویمها.", + "description_touch": "ایجاد، تغییر نام و سفارشیسازی تقویمها.", "name": "نام", "name_placeholder": "نام تقویم", "color": "رنگ", diff --git a/locales/fr/common.json b/locales/fr/common.json index 78dceb226..2b16ab7fa 100644 --- a/locales/fr/common.json +++ b/locales/fr/common.json @@ -4018,6 +4018,7 @@ "management": { "title": "Gestion des calendriers", "description": "Créez, renommez et personnalisez vos calendriers. Clic droit sur un calendrier dans la barre latérale pour changer rapidement sa couleur.", + "description_touch": "Créez, renommez et personnalisez vos calendriers.", "name": "Nom", "name_placeholder": "Nom du calendrier", "color": "Couleur", diff --git a/locales/he/common.json b/locales/he/common.json index d96b5f35c..d8c5cd6d1 100644 --- a/locales/he/common.json +++ b/locales/he/common.json @@ -3901,6 +3901,7 @@ "management": { "title": "ניהול לוח שנה", "description": "צור, שנה שם והתאם אישית את היומנים שלך. לחץ לחיצה ימנית על לוח שנה בסרגל הצד כדי לשנות במהירות את צבעו.", + "description_touch": "צור, שנה שם והתאם אישית את היומנים שלך.", "name": "שֵׁם", "name_placeholder": "שם לוח שנה", "color": "צבע", diff --git a/locales/hu/common.json b/locales/hu/common.json index a7378ec83..56982eb18 100644 --- a/locales/hu/common.json +++ b/locales/hu/common.json @@ -4021,6 +4021,7 @@ "management": { "title": "Naptár kezelés", "description": "Naptárak létrehozása, átnevezése és testreszabása. Kattints jobb gombbal egy naptárra az oldalsávban a szín gyors módosításához.", + "description_touch": "Naptárak létrehozása, átnevezése és testreszabása.", "name": "Név", "name_placeholder": "Naptár neve", "color": "Szín", diff --git a/locales/it/common.json b/locales/it/common.json index 21f7c0091..a394dee03 100644 --- a/locales/it/common.json +++ b/locales/it/common.json @@ -3992,6 +3992,7 @@ "management": { "title": "Gestione calendari", "description": "Crea, rinomina e personalizza i tuoi calendari. Fai clic destro su un calendario nella barra laterale per cambiarne rapidamente il colore.", + "description_touch": "Crea, rinomina e personalizza i tuoi calendari.", "name": "Nome", "name_placeholder": "Nome del calendario", "color": "Colore", diff --git a/locales/ja/common.json b/locales/ja/common.json index 35e90d92c..0e2f81dbe 100644 --- a/locales/ja/common.json +++ b/locales/ja/common.json @@ -3992,6 +3992,7 @@ "management": { "title": "カレンダー管理", "description": "カレンダーの作成、名前変更、カスタマイズができます。サイドバーのカレンダーを右クリックして色を素早く変更できます。", + "description_touch": "カレンダーの作成、名前変更、カスタマイズができます。", "name": "名前", "name_placeholder": "カレンダー名", "color": "色", diff --git a/locales/ko/common.json b/locales/ko/common.json index ff8dce535..788d0108f 100644 --- a/locales/ko/common.json +++ b/locales/ko/common.json @@ -3992,6 +3992,7 @@ "management": { "title": "캘린더 관리", "description": "캘린더를 만들고 이름을 바꾸거나 색상을 꾸며보세요. 사이드바에서 캘린더를 우클릭하면 색상을 빠르게 바꿀 수 있어요.", + "description_touch": "캘린더를 만들고 이름을 바꾸거나 색상을 꾸며보세요.", "name": "이름", "name_placeholder": "캘린더 이름", "color": "색상", diff --git a/locales/lv/common.json b/locales/lv/common.json index 1ae3b700e..e780a45d3 100644 --- a/locales/lv/common.json +++ b/locales/lv/common.json @@ -3991,6 +3991,7 @@ "management": { "title": "Kalendāru pārvaldība", "description": "Izveidojiet, pārdēvējiet un konfigurējiet kalendārus. Ar labo klikšķi varat mainīt kalendāra krāsu.", + "description_touch": "Izveidojiet, pārdēvējiet un konfigurējiet kalendārus.", "name": "Nosaukums", "name_placeholder": "Kalendāra nosaukums", "color": "Krāsa", diff --git a/locales/mn/common.json b/locales/mn/common.json index b3ec75693..71e3dafe4 100644 --- a/locales/mn/common.json +++ b/locales/mn/common.json @@ -4021,6 +4021,7 @@ "management": { "title": "Календарийн менежмент", "description": "Хуанлигаа үүсгэх, нэрийг нь өөрчлөх, өөрчлөх. Хажуугийн самбар дээрх хуанли дээр хулганы баруун товчийг дарж өнгийг нь хурдан солино.", + "description_touch": "Хуанлигаа үүсгэх, нэрийг нь өөрчлөх, тохируулах.", "name": "Нэр", "name_placeholder": "Календарийн нэр", "color": "Өнгө", diff --git a/locales/nb/common.json b/locales/nb/common.json index 84a83db3c..943e14f3f 100644 --- a/locales/nb/common.json +++ b/locales/nb/common.json @@ -4021,6 +4021,7 @@ "management": { "title": "Administrer kalendere", "description": "Opprett, gi nytt navn og tilpass kalenderne dine. Høyreklikk på en kalender i sidefeltet for raskt å endre fargen.", + "description_touch": "Opprett, gi nytt navn og tilpass kalenderne dine.", "name": "Navn", "name_placeholder": "Kalendernavn", "color": "Farge", diff --git a/locales/nl/common.json b/locales/nl/common.json index 82cb0673a..a64db0111 100644 --- a/locales/nl/common.json +++ b/locales/nl/common.json @@ -3992,6 +3992,7 @@ "management": { "title": "Agendabeheer", "description": "Maak, hernoem en pas uw agenda's aan. Klik met de rechtermuisknop op een agenda in de zijbalk om snel de kleur te wijzigen.", + "description_touch": "Maak, hernoem en pas uw agenda's aan.", "name": "Naam", "name_placeholder": "Agendanaam", "color": "Kleur", diff --git a/locales/pl/common.json b/locales/pl/common.json index 4ada6ee70..c97bdd706 100644 --- a/locales/pl/common.json +++ b/locales/pl/common.json @@ -3992,6 +3992,7 @@ "management": { "title": "Zarządzanie kalendarzem", "description": "Twórz, zmieniaj nazwy i dostosowuj swoje kalendarze. Kliknij prawym przyciskiem kalendarz na pasku bocznym, aby szybko zmienić jego kolor.", + "description_touch": "Twórz, zmieniaj nazwy i dostosowuj swoje kalendarze.", "name": "Nazwa", "name_placeholder": "Nazwa kalendarza", "color": "Kolor", diff --git a/locales/pt/common.json b/locales/pt/common.json index 9291695ae..ffe459a15 100644 --- a/locales/pt/common.json +++ b/locales/pt/common.json @@ -4018,6 +4018,7 @@ "management": { "title": "Gerenciamento de calendários", "description": "Crie, renomeie e personalize seus calendários. Clique com o botão direito em um calendário na barra lateral para alterar rapidamente sua cor.", + "description_touch": "Crie, renomeie e personalize seus calendários.", "name": "Nome", "name_placeholder": "Nome do calendário", "color": "Cor", diff --git a/locales/ro/common.json b/locales/ro/common.json index 0db525ed5..4cc63873a 100644 --- a/locales/ro/common.json +++ b/locales/ro/common.json @@ -4021,6 +4021,7 @@ "management": { "title": "Gestionarea calendarului", "description": "Creați, redenumiți și personalizați-vă calendarele. Faceți clic dreapta pe un calendar din bara laterală pentru a-i schimba rapid culoarea.", + "description_touch": "Creați, redenumiți și personalizați-vă calendarele.", "name": "Nume", "name_placeholder": "Numele calendarului", "color": "Culoare", diff --git a/locales/ru/common.json b/locales/ru/common.json index 17749693f..185c9762f 100644 --- a/locales/ru/common.json +++ b/locales/ru/common.json @@ -3992,6 +3992,7 @@ "management": { "title": "Управление календарями", "description": "Создавайте, переименовывайте и настраивайте свои календари. Щёлкните правой кнопкой мыши на календаре в боковой панели для быстрой смены цвета.", + "description_touch": "Создавайте, переименовывайте и настраивайте свои календари.", "name": "Имя", "name_placeholder": "Название календаря", "color": "Цвет", diff --git a/locales/sk/common.json b/locales/sk/common.json index 56b612174..d6017ae92 100644 --- a/locales/sk/common.json +++ b/locales/sk/common.json @@ -4021,6 +4021,7 @@ "management": { "title": "Správa kalendára", "description": "Vytvárajte, premenúvajte a prispôsobujte si svoje kalendáre.", + "description_touch": "Vytvárajte, premenúvajte a prispôsobujte si svoje kalendáre.", "name": "Názov", "name_placeholder": "Názov kalendára", "color": "Farba", diff --git a/locales/th/common.json b/locales/th/common.json index 9b9191b43..9bd08d67c 100644 --- a/locales/th/common.json +++ b/locales/th/common.json @@ -3136,6 +3136,7 @@ "management": { "title": "การจัดการปฏิทิน", "description": "สร้าง เปลี่ยนชื่อ และปรับแต่งปฏิทินของคุณ คลิกขวาที่ปฏิทินในแถบด้านข้างเพื่อเปลี่ยนสีได้อย่างรวดเร็ว", + "description_touch": "สร้าง เปลี่ยนชื่อ และปรับแต่งปฏิทินของคุณ", "name": "ชื่อ", "name_placeholder": "ชื่อปฏิทิน", "color": "สี", diff --git a/locales/tr/common.json b/locales/tr/common.json index eb77f4dd1..ff701613f 100644 --- a/locales/tr/common.json +++ b/locales/tr/common.json @@ -4018,6 +4018,7 @@ "management": { "title": "Takvim Yönetimi", "description": "Takvimlerinizi oluşturun, yeniden adlandırın ve özelleştirin. Rengini hızlıca değiştirmek için kenar çubuğundaki bir takvime sağ tıklayın.", + "description_touch": "Takvimlerinizi oluşturun, yeniden adlandırın ve özelleştirin.", "name": "Ad", "name_placeholder": "Takvim adı", "color": "Renk", diff --git a/locales/uk/common.json b/locales/uk/common.json index e0d22b3a1..a3fe4e299 100644 --- a/locales/uk/common.json +++ b/locales/uk/common.json @@ -3992,6 +3992,7 @@ "management": { "title": "Управління календарем", "description": "Створюйте, перейменовуйте та налаштовуйте свої календарі. Клацніть правою кнопкою миші календар на бічній панелі, щоб швидко змінити його колір.", + "description_touch": "Створюйте, перейменовуйте та налаштовуйте свої календарі.", "name": "Ім'я", "name_placeholder": "Назва календаря", "color": "колір", diff --git a/locales/zh-TW/common.json b/locales/zh-TW/common.json index ef1aeccb2..8341a6a77 100644 --- a/locales/zh-TW/common.json +++ b/locales/zh-TW/common.json @@ -4021,6 +4021,7 @@ "management": { "title": "行事曆管理", "description": "建立、重新命名與自訂您的行事曆。在側邊欄的行事曆上按一下滑鼠右鍵,可快速變更顏色。", + "description_touch": "建立、重新命名與自訂您的行事曆。", "name": "名稱", "name_placeholder": "行事曆名稱", "color": "顏色", diff --git a/locales/zh/common.json b/locales/zh/common.json index 312c75537..9e9960596 100644 --- a/locales/zh/common.json +++ b/locales/zh/common.json @@ -3992,6 +3992,7 @@ "management": { "title": "日历管理", "description": "创建、重命名和自定义您的日历。右键单击侧栏中的日历可快速更改其颜色。", + "description_touch": "创建、重命名和自定义您的日历。", "name": "名称", "name_placeholder": "日历名称", "color": "颜色",