diff --git a/src/components/CalendarEventContent/index.tsx b/src/components/CalendarEventContent/index.tsx
index 91226966..050d9564 100644
--- a/src/components/CalendarEventContent/index.tsx
+++ b/src/components/CalendarEventContent/index.tsx
@@ -10,12 +10,13 @@ import { useFetchCalendarRsvps } from '@/hooks/useFetchCalendarRsvps'
import { useNostr } from '@/providers/NostrProvider'
import { toProfile } from '@/lib/link'
import { useSecondaryPage } from '@/PageManager'
+import MarkdownArticle from '@/components/Note/MarkdownArticle/MarkdownArticle'
import { Event } from 'nostr-tools'
import { useTranslation } from 'react-i18next'
import { useMemo } from 'react'
import Collapsible from '../Collapsible'
import { Button } from '../ui/button'
-import { Calendar, Clock, Video, CheckCircle, HelpCircle, XCircle } from 'lucide-react'
+import { Calendar, Clock, ExternalLink, MapPin, CheckCircle, HelpCircle, XCircle } from 'lucide-react'
import { cn } from '@/lib/utils'
import {
DropdownMenu,
@@ -32,22 +33,44 @@ type RsvpStatus = 'accepted' | 'tentative' | 'declined'
export default function CalendarEventContent({
event,
className,
- showRsvp = true
+ showRsvp = true,
+ showFull = false
}: {
event: Event
className?: string
showRsvp?: boolean
+ /** Note page / full detail: markdown body + complete tag list. */
+ showFull?: boolean
}) {
const { t } = useTranslation()
const { push } = useSecondaryPage()
const { pubkey: myPubkey, publish } = useNostr()
const { rsvps, isFetching, getRsvpStatus: getStatus } = useFetchCalendarRsvps(event)
- if (!isCalendarEventKind(event.kind)) return null
+ const meta = useMemo(() => {
+ if (!isCalendarEventKind(event.kind)) return null
+ return getCalendarEventMeta(event)
+ }, [event])
+
+ const markdownBody = useMemo(() => {
+ if (!meta) return ''
+ const s = meta.summary.trim()
+ const c = event.content?.trim() ?? ''
+ if (s && c) return `${s}\n\n${c}`
+ return s || c || ''
+ }, [meta, event.content])
+
+ const eventForMarkdown = useMemo((): Event => {
+ if (!markdownBody) return event
+ return { ...event, content: markdownBody }
+ }, [event, markdownBody])
+
+ const duplicateWebPreviewHints = useMemo(
+ () =>
+ !meta ? [] : [...meta.rUrls, ...(meta.image?.trim() ? [meta.image.trim()] : [])],
+ [meta]
+ )
- const { title, summary, image, start, end, startDate, endDate, isDateBased, joinUrl, topics } =
- getCalendarEventMeta(event)
- const description = summary || event.content?.trim() || ''
const myRsvp = myPubkey ? rsvps.find((r) => r.pubkey === myPubkey) : undefined
const myStatus = myRsvp ? getStatus(myRsvp) : undefined
@@ -71,6 +94,23 @@ export default function CalendarEventContent({
})
}, [event.pubkey, event.tags, rsvps])
+ if (!meta) return null
+
+ const {
+ title,
+ image,
+ start,
+ end,
+ startDate,
+ endDate,
+ isDateBased,
+ rUrls,
+ location,
+ startTzid,
+ endTzid,
+ topics
+ } = meta
+
const handleRsvp = async (status: RsvpStatus) => {
if (!myPubkey) {
toast.error(t('You need to log in to RSVP'))
@@ -105,17 +145,47 @@ export default function CalendarEventContent({
) : (
-
-
+
+
)}
-
+
{title || t('Scheduled video call')}
+ {!showFull && scheduleLine ? (
+
+
+ {scheduleLine}
+
+ ) : null}
+ {!showFull && location ? (
+
+
+ {location}
+
+ ) : null}
{topics.length > 0 && (
{topics.map((topic) => (
@@ -130,31 +200,66 @@ export default function CalendarEventContent({
)}
- {scheduleLine ? (
+ {showFull && scheduleLine ? (
-
{scheduleLine}
+
+
{scheduleLine}
+ {(startTzid || endTzid) && (
+
+ {startTzid ? (
+ <>
+ start_tzid: {startTzid}
+ >
+ ) : null}
+ {startTzid && endTzid && endTzid !== startTzid ? ' · ' : ''}
+ {endTzid && endTzid !== startTzid ? (
+ <>
+ end_tzid: {endTzid}
+ >
+ ) : null}
+
+ )}
+
) : null}
- {description ? (
- <>
- {/* NIP-52 31922/31923: collapse long summary+body only; card chrome stays outside MainNoteCard Collapsible. */}
-
-
- {description}
-
-
- >
+ {showFull && location ? (
+
+ ) : null}
+ {markdownBody ? (
+ showFull ? (
+
+
+
+ ) : (
+ <>
+ {/* NIP-52 31922/31923: collapse long summary+body only; card chrome stays outside MainNoteCard Collapsible. */}
+
+
+ {markdownBody}
+
+
+ >
+ )
) : null}
)}
+ {showFull && event.tags.length > 0 ? (
+
+
+ {t('All tags')}
+
+
+ {event.tags.map((tag, idx) => (
+
+
-
+ {tag[0] || '—'}
+
+ -
+ {tag.length > 1 ? tag.slice(1).join(' · ') : '—'}
+
+
+ ))}
+
+
+ ) : null}
)
}
diff --git a/src/components/Embedded/EmbeddedCalendarEvent.tsx b/src/components/Embedded/EmbeddedCalendarEvent.tsx
index 61ca077e..f94e12c1 100644
--- a/src/components/Embedded/EmbeddedCalendarEvent.tsx
+++ b/src/components/Embedded/EmbeddedCalendarEvent.tsx
@@ -9,7 +9,7 @@ import { Event } from 'nostr-tools'
import { useTranslation } from 'react-i18next'
import Collapsible from '../Collapsible'
import { Button } from '../ui/button'
-import { Calendar, Clock, Video } from 'lucide-react'
+import { Calendar, Clock, ExternalLink, MapPin } from 'lucide-react'
export function EmbeddedCalendarEvent({
event,
@@ -20,7 +20,7 @@ export function EmbeddedCalendarEvent({
}) {
const { t } = useTranslation()
if (!isCalendarEventKind(event.kind)) return null
- const { title, summary, image, start, end, startDate, endDate, isDateBased, joinUrl, topics } =
+ const { title, summary, image, start, end, startDate, endDate, isDateBased, rUrls, topics, location } =
getCalendarEventMeta(event)
const description = summary || event.content?.trim() || ''
@@ -44,17 +44,31 @@ export function EmbeddedCalendarEvent({
) : (
-
-
+
+
)}
-
+
{title || t('Scheduled video call')}
+ {scheduleLine ? (
+
+
+ {scheduleLine}
+
+ ) : null}
+ {location ? (
+
+
+ {location}
+
+ ) : null}
{topics.length > 0 && (
{topics.map((topic) => (
@@ -69,12 +83,6 @@ export function EmbeddedCalendarEvent({
)}
- {scheduleLine ? (
-
- ) : null}
{description ? (
<>
{/* NIP-52 31922/31923 embedded preview: long description only. */}
@@ -85,19 +93,14 @@ export function EmbeddedCalendarEvent({
>
) : null}
- {joinUrl && (
-
)
}
diff --git a/src/components/Note/MarkdownArticle/MarkdownArticle.tsx b/src/components/Note/MarkdownArticle/MarkdownArticle.tsx
index 210d4a9b..a1e43237 100644
--- a/src/components/Note/MarkdownArticle/MarkdownArticle.tsx
+++ b/src/components/Note/MarkdownArticle/MarkdownArticle.tsx
@@ -28,6 +28,7 @@ import { Event, kinds } from 'nostr-tools'
import Emoji, { EMOJI_IMG_INLINE_CLASS } from '@/components/Emoji'
import {
ExtendedKind,
+ isNip52CalendarCardKind,
SPOTIFY_OPEN_URL_REGEX,
WS_URL_REGEX,
YOUTUBE_URL_REGEX,
@@ -5898,7 +5899,10 @@ export default function MarkdownArticle({
{metadata.summary}
)}
- {hideMetadata && metadata.title && event.kind !== ExtendedKind.DISCUSSION && (
+ {hideMetadata &&
+ metadata.title &&
+ event.kind !== ExtendedKind.DISCUSSION &&
+ !isNip52CalendarCardKind(event.kind) && (
{metadata.title}
)}
diff --git a/src/components/Note/index.tsx b/src/components/Note/index.tsx
index e35c86cd..b022756c 100644
--- a/src/components/Note/index.tsx
+++ b/src/components/Note/index.tsx
@@ -396,7 +396,9 @@ export default function Note({
} else if (event.kind === ExtendedKind.RELAY_REVIEW) {
content =
} else if (isCalendarEventKind(event.kind)) {
- content =
+ content = (
+
+ )
} else if (event.kind === ExtendedKind.PUBLIC_MESSAGE) {
content = renderEventContent({ hideMetadata: true })
} else if (event.kind === ExtendedKind.ZAP_REQUEST || event.kind === ExtendedKind.ZAP_RECEIPT) {
diff --git a/src/components/Sidebar/SidebarCalendarWeekWidget.tsx b/src/components/Sidebar/SidebarCalendarWeekWidget.tsx
index 0629bafb..6c29e93b 100644
--- a/src/components/Sidebar/SidebarCalendarWeekWidget.tsx
+++ b/src/components/Sidebar/SidebarCalendarWeekWidget.tsx
@@ -2,6 +2,7 @@ import {
calendarOccurrenceOverlapsRange,
formatCalendarSidebarRow,
formatSidebarWeekLabel,
+ getCalendarEventMeta,
getCalendarOccurrenceWindowMs,
getLocalMondayWeekBounds
} from '@/lib/calendar-event'
@@ -262,7 +263,9 @@ export default function SidebarCalendarWeekWidget() {
) : (
{sortedForWeek.map((ev) => {
- const title = ev.tags.find((t) => t[0] === 'title')?.[1]?.trim() || t('Scheduled video call')
+ const meta = getCalendarEventMeta(ev)
+ const title = meta.title?.trim() || t('Scheduled video call')
+ const cover = meta.image?.trim()
const sub = formatCalendarSidebarRow(ev)
return (
-
@@ -270,16 +273,29 @@ export default function SidebarCalendarWeekWidget() {
type="button"
onClick={() => openEvent(ev)}
className={cn(
- 'w-full rounded-md border border-transparent px-1.5 py-1.5 text-left transition-colors',
+ 'flex w-full gap-2 rounded-md border border-transparent px-1.5 py-1.5 text-left transition-colors',
'hover:border-border/80 hover:bg-muted/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring'
)}
>
- {title}
- {sub ? (
-
- {sub}
-
- ) : null}
+ {cover ? (
+
+ ) : (
+
+ )}
+
+ {title}
+ {sub ? (
+
+ {sub}
+
+ ) : null}
+
)
diff --git a/src/i18n/locales/cs.ts b/src/i18n/locales/cs.ts
index 4b357a7b..4fca24e5 100644
--- a/src/i18n/locales/cs.ts
+++ b/src/i18n/locales/cs.ts
@@ -228,6 +228,8 @@ export default {
"Add at least one invitee (paste nostr:npub or nostr:nprofile links)": "Add at least one invitee (paste nostr:npub or nostr:nprofile links)",
"Scheduled call created and {{count}} invite(s) sent": "Scheduled call created and {{count}} invite(s) sent",
"Join video call": "Join video call",
+ "Open link": "Open link",
+ "All tags": "All tags",
"Scheduled video call": "Scheduled video call",
"Video call": "Video call",
"Schedule and send invite": "Schedule and send invite",
diff --git a/src/i18n/locales/de.ts b/src/i18n/locales/de.ts
index 64f2048e..db26fda7 100644
--- a/src/i18n/locales/de.ts
+++ b/src/i18n/locales/de.ts
@@ -228,6 +228,8 @@ export default {
"Add at least one invitee (paste nostr:npub or nostr:nprofile links)": "Mindestens eine Person hinzufügen (nostr:npub- oder nostr:nprofile-Links einfügen)",
"Scheduled call created and {{count}} invite(s) sent": "Geplanter Anruf erstellt und {{count}} Einladung(en) gesendet",
"Join video call": "Videoanruf beitreten",
+ "Open link": "Link öffnen",
+ "All tags": "Alle Tags",
"Scheduled video call": "Geplanter Videoanruf",
"Video call": "Videoanruf",
"Schedule and send invite": "Planen und Einladung senden",
diff --git a/src/i18n/locales/en.ts b/src/i18n/locales/en.ts
index f3de647a..99c5ab23 100644
--- a/src/i18n/locales/en.ts
+++ b/src/i18n/locales/en.ts
@@ -232,6 +232,8 @@ export default {
"Add at least one invitee (paste nostr:npub or nostr:nprofile links)": "Add at least one invitee (paste nostr:npub or nostr:nprofile links)",
"Scheduled call created and {{count}} invite(s) sent": "Scheduled call created and {{count}} invite(s) sent",
"Join video call": "Join video call",
+ "Open link": "Open link",
+ "All tags": "All tags",
"Scheduled video call": "Scheduled video call",
"Video call": "Video call",
"Schedule and send invite": "Schedule and send invite",
diff --git a/src/i18n/locales/es.ts b/src/i18n/locales/es.ts
index c16d4314..60d44bf5 100644
--- a/src/i18n/locales/es.ts
+++ b/src/i18n/locales/es.ts
@@ -228,6 +228,8 @@ export default {
"Add at least one invitee (paste nostr:npub or nostr:nprofile links)": "Add at least one invitee (paste nostr:npub or nostr:nprofile links)",
"Scheduled call created and {{count}} invite(s) sent": "Scheduled call created and {{count}} invite(s) sent",
"Join video call": "Join video call",
+ "Open link": "Open link",
+ "All tags": "All tags",
"Scheduled video call": "Scheduled video call",
"Video call": "Video call",
"Schedule and send invite": "Schedule and send invite",
diff --git a/src/i18n/locales/fr.ts b/src/i18n/locales/fr.ts
index 53109bb7..af9969f3 100644
--- a/src/i18n/locales/fr.ts
+++ b/src/i18n/locales/fr.ts
@@ -228,6 +228,8 @@ export default {
"Add at least one invitee (paste nostr:npub or nostr:nprofile links)": "Add at least one invitee (paste nostr:npub or nostr:nprofile links)",
"Scheduled call created and {{count}} invite(s) sent": "Scheduled call created and {{count}} invite(s) sent",
"Join video call": "Join video call",
+ "Open link": "Open link",
+ "All tags": "All tags",
"Scheduled video call": "Scheduled video call",
"Video call": "Video call",
"Schedule and send invite": "Schedule and send invite",
diff --git a/src/i18n/locales/nl.ts b/src/i18n/locales/nl.ts
index 4b357a7b..4fca24e5 100644
--- a/src/i18n/locales/nl.ts
+++ b/src/i18n/locales/nl.ts
@@ -228,6 +228,8 @@ export default {
"Add at least one invitee (paste nostr:npub or nostr:nprofile links)": "Add at least one invitee (paste nostr:npub or nostr:nprofile links)",
"Scheduled call created and {{count}} invite(s) sent": "Scheduled call created and {{count}} invite(s) sent",
"Join video call": "Join video call",
+ "Open link": "Open link",
+ "All tags": "All tags",
"Scheduled video call": "Scheduled video call",
"Video call": "Video call",
"Schedule and send invite": "Schedule and send invite",
diff --git a/src/i18n/locales/pl.ts b/src/i18n/locales/pl.ts
index a2feeb2f..48dd05e0 100644
--- a/src/i18n/locales/pl.ts
+++ b/src/i18n/locales/pl.ts
@@ -228,6 +228,8 @@ export default {
"Add at least one invitee (paste nostr:npub or nostr:nprofile links)": "Add at least one invitee (paste nostr:npub or nostr:nprofile links)",
"Scheduled call created and {{count}} invite(s) sent": "Scheduled call created and {{count}} invite(s) sent",
"Join video call": "Join video call",
+ "Open link": "Open link",
+ "All tags": "All tags",
"Scheduled video call": "Scheduled video call",
"Video call": "Video call",
"Schedule and send invite": "Schedule and send invite",
diff --git a/src/i18n/locales/ru.ts b/src/i18n/locales/ru.ts
index 2106369e..d14376e7 100644
--- a/src/i18n/locales/ru.ts
+++ b/src/i18n/locales/ru.ts
@@ -228,6 +228,8 @@ export default {
"Add at least one invitee (paste nostr:npub or nostr:nprofile links)": "Add at least one invitee (paste nostr:npub or nostr:nprofile links)",
"Scheduled call created and {{count}} invite(s) sent": "Scheduled call created and {{count}} invite(s) sent",
"Join video call": "Join video call",
+ "Open link": "Open link",
+ "All tags": "All tags",
"Scheduled video call": "Scheduled video call",
"Video call": "Video call",
"Schedule and send invite": "Schedule and send invite",
diff --git a/src/i18n/locales/tr.ts b/src/i18n/locales/tr.ts
index 4b357a7b..4fca24e5 100644
--- a/src/i18n/locales/tr.ts
+++ b/src/i18n/locales/tr.ts
@@ -228,6 +228,8 @@ export default {
"Add at least one invitee (paste nostr:npub or nostr:nprofile links)": "Add at least one invitee (paste nostr:npub or nostr:nprofile links)",
"Scheduled call created and {{count}} invite(s) sent": "Scheduled call created and {{count}} invite(s) sent",
"Join video call": "Join video call",
+ "Open link": "Open link",
+ "All tags": "All tags",
"Scheduled video call": "Scheduled video call",
"Video call": "Video call",
"Schedule and send invite": "Schedule and send invite",
diff --git a/src/i18n/locales/zh.ts b/src/i18n/locales/zh.ts
index cfc42a40..c03082b2 100644
--- a/src/i18n/locales/zh.ts
+++ b/src/i18n/locales/zh.ts
@@ -228,6 +228,8 @@ export default {
"Add at least one invitee (paste nostr:npub or nostr:nprofile links)": "Add at least one invitee (paste nostr:npub or nostr:nprofile links)",
"Scheduled call created and {{count}} invite(s) sent": "Scheduled call created and {{count}} invite(s) sent",
"Join video call": "Join video call",
+ "Open link": "Open link",
+ "All tags": "All tags",
"Scheduled video call": "Scheduled video call",
"Video call": "Video call",
"Schedule and send invite": "Schedule and send invite",
diff --git a/src/lib/calendar-event.ts b/src/lib/calendar-event.ts
index 3134822e..07f1b029 100644
--- a/src/lib/calendar-event.ts
+++ b/src/lib/calendar-event.ts
@@ -15,7 +15,21 @@ export interface CalendarEventMeta {
/** Date-based: YYYY-MM-DD (exclusive end). Time-based: undefined. */
endDate: string
isDateBased: boolean
+ /** First `r` tag with an http(s) URL (join / registration link). */
joinUrl: string
+ /** Same as {@link joinUrl}; every http(s) `r` value. */
+ rUrl: string
+ rUrls: string[]
+ /** `location` tag (venue / address text). */
+ location: string
+ /** `d` tag (replaceable identifier). */
+ d: string
+ /** `g` tag (geohash). */
+ geo: string
+ /** `start_tzid` (IANA zone). */
+ startTzid: string
+ /** `end_tzid` (IANA zone). */
+ endTzid: string
topics: string[]
}
@@ -25,9 +39,17 @@ export function getCalendarEventMeta(event: Event): CalendarEventMeta {
const image = event.tags.find(tagNameEquals('image'))?.[1] ?? ''
const startStr = event.tags.find(tagNameEquals('start'))?.[1]
const endStr = event.tags.find(tagNameEquals('end'))?.[1]
- const location = event.tags.find(tagNameEquals('location'))?.[1]
- const rTag = event.tags.find(tagNameEquals('r'))?.[1]
- const joinUrl = rTag || location || ''
+ const location = event.tags.find(tagNameEquals('location'))?.[1] ?? ''
+ const d = event.tags.find(tagNameEquals('d'))?.[1] ?? ''
+ const geo = event.tags.find(tagNameEquals('g'))?.[1] ?? ''
+ const startTzid = event.tags.find(tagNameEquals('start_tzid'))?.[1] ?? ''
+ const endTzid = event.tags.find(tagNameEquals('end_tzid'))?.[1] ?? ''
+ const rUrls = event.tags
+ .filter(tagNameEquals('r'))
+ .map((t) => t[1]?.trim())
+ .filter((u): u is string => !!u && (u.startsWith('http://') || u.startsWith('https://')))
+ const rUrl = rUrls[0] ?? ''
+ const joinUrl = rUrl
const topics = event.tags.filter(tagNameEquals('t')).map((t) => t[1]?.trim()).filter(Boolean)
const isDateBased = event.kind === ExtendedKind.CALENDAR_EVENT_DATE
if (isDateBased) {
@@ -41,6 +63,13 @@ export function getCalendarEventMeta(event: Event): CalendarEventMeta {
endDate: endStr ?? '',
isDateBased: true,
joinUrl,
+ rUrl,
+ rUrls,
+ location,
+ d,
+ geo,
+ startTzid,
+ endTzid,
topics
}
}
@@ -56,6 +85,13 @@ export function getCalendarEventMeta(event: Event): CalendarEventMeta {
endDate: '',
isDateBased: false,
joinUrl,
+ rUrl,
+ rUrls,
+ location,
+ d,
+ geo,
+ startTzid,
+ endTzid,
topics
}
}
diff --git a/src/pages/primary/CalendarPrimaryPage.tsx b/src/pages/primary/CalendarPrimaryPage.tsx
index 006d3361..ce6f06c7 100644
--- a/src/pages/primary/CalendarPrimaryPage.tsx
+++ b/src/pages/primary/CalendarPrimaryPage.tsx
@@ -19,11 +19,12 @@ import { useNostr } from '@/providers/NostrProvider'
import { useScreenSize } from '@/providers/ScreenSizeProvider'
import client from '@/services/client.service'
import indexedDb from '@/services/indexed-db.service'
+import storage from '@/services/local-storage.service'
import { CALENDAR_EVENT_KINDS, ExtendedKind } from '@/constants'
import { TPageRef } from '@/types'
import { RefreshButton } from '@/components/RefreshButton'
import { CalendarDays, ChevronLeft, ChevronRight } from 'lucide-react'
-import { type Event } from 'nostr-tools'
+import { type Event as NostrEvent } from 'nostr-tools'
import {
forwardRef,
useCallback,
@@ -50,8 +51,8 @@ export type CalendarPrimaryPageProps = {
weekOffset?: number
}
-function dedupeCalendarEvents(events: Event[]): Event[] {
- const map = new Map()
+function dedupeCalendarEvents(events: NostrEvent[]): NostrEvent[] {
+ const map = new Map()
for (const e of events) {
const k = replaceableEventDedupeKey(e)
const prev = map.get(k)
@@ -85,9 +86,22 @@ const CalendarPrimaryPage = forwardRef(funct
const { navigateToNote } = useSmartNoteNavigation()
const { push } = useSecondaryPage()
const { isSmallScreen } = useScreenSize()
+ const [panelMode, setPanelMode] = useState<'single' | 'double'>(() => storage.getPanelMode())
const layoutRef = useRef(null)
const [refreshKey, setRefreshKey] = useState(0)
+ useEffect(() => {
+ const onPanelMode = (ev: Event) => {
+ const d = (ev as CustomEvent<{ mode: 'single' | 'double' }>).detail?.mode
+ if (d === 'single' || d === 'double') setPanelMode(d)
+ }
+ window.addEventListener('panelModeChanged', onPanelMode)
+ return () => window.removeEventListener('panelModeChanged', onPanelMode)
+ }, [])
+
+ /** Month grid is unreadable in the narrow primary column of double-pane; use the same vertical layout as mobile. */
+ const useVerticalMonthCalendar = isSmallScreen || panelMode === 'double'
+
const [activeWeekOffset, setActiveWeekOffset] = useState(weekOffsetProp)
useEffect(() => {
setActiveWeekOffset(weekOffsetProp)
@@ -108,7 +122,7 @@ const CalendarPrimaryPage = forwardRef(funct
setViewMonth(d.getMonth())
}, [highlightBounds.weekStartMs])
- const [rawEvents, setRawEvents] = useState([])
+ const [rawEvents, setRawEvents] = useState([])
const [loading, setLoading] = useState(false)
const relayUrls = useMemo(() => {
@@ -193,7 +207,7 @@ const CalendarPrimaryPage = forwardRef(funct
)
if (cancelled) return
- const fromFollowing: Event[] = []
+ const fromFollowing: NostrEvent[] = []
if (followAuthorsKey) {
const authorList = followAuthorsKey.split('|').filter(Boolean).slice(0, FOLLOWING_CALENDAR_AUTHORS_CAP)
for (let i = 0; i < authorList.length; i += FOLLOWING_CALENDAR_AUTHORS_CHUNK) {
@@ -369,7 +383,7 @@ const CalendarPrimaryPage = forwardRef(funct
{t('sidebarCalendarLoading')}
) : null}
- {isSmallScreen ? (
+ {useVerticalMonthCalendar ? (
{Array.from({ length: daysInMonth(viewYear, viewMonth) }, (_, idx) => {
const day = idx + 1
@@ -401,17 +415,27 @@ const CalendarPrimaryPage = forwardRef
(funct
{list.slice(0, 4).map((ev) => {
const meta = getCalendarEventMeta(ev)
const title = meta.title?.trim() || t('calendarPageUntitledEvent')
+ const cover = meta.image?.trim()
return (
-
navigateToNote(toNote(ev), ev)}
className={cn(
- 'w-full truncate rounded-md px-2 py-1.5 text-left text-xs font-medium leading-snug text-primary',
+ 'flex w-full min-w-0 items-center gap-2 rounded-md px-2 py-1.5 text-left text-xs font-medium leading-snug text-primary',
'hover:bg-muted/80 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring'
)}
>
- {title}
+ {cover ? (
+
+ ) : null}
+ {title}
)
@@ -471,18 +495,28 @@ const CalendarPrimaryPage = forwardRef(funct
{list.slice(0, 4).map((ev) => {
const meta = getCalendarEventMeta(ev)
const title = meta.title?.trim() || t('calendarPageUntitledEvent')
+ const cover = meta.image?.trim()
return (
-
navigateToNote(toNote(ev), ev)}
className={cn(
- 'w-full truncate rounded px-0.5 py-px text-left text-[9px] font-medium leading-tight text-primary underline-offset-2',
+ 'flex w-full min-w-0 items-center gap-0.5 rounded px-0.5 py-px text-left text-[9px] font-medium leading-tight text-primary underline-offset-2',
'hover:bg-muted/80 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring md:text-[10px]'
)}
title={title}
>
- {title}
+ {cover ? (
+
+ ) : null}
+ {title}
)
diff --git a/src/pages/secondary/CalendarDayEventsPage/index.tsx b/src/pages/secondary/CalendarDayEventsPage/index.tsx
index 23b93070..11a6800b 100644
--- a/src/pages/secondary/CalendarDayEventsPage/index.tsx
+++ b/src/pages/secondary/CalendarDayEventsPage/index.tsx
@@ -75,17 +75,29 @@ const CalendarDayEventsPage = forwardRef {
const meta = getCalendarEventMeta(ev)
const label = meta.title?.trim() || t('calendarPageUntitledEvent')
+ const cover = meta.image?.trim()
return (
-
navigateToNote(toNote(ev), ev)}
>
- {label}
+ {cover ? (
+
+ ) : (
+
+ )}
+ {label}
)