added only notes option

This commit is contained in:
Arjun 2026-03-21 15:07:18 +05:30
parent ea59208c38
commit 5a4009d181
2 changed files with 150 additions and 14 deletions

View file

@ -1,8 +1,8 @@
import { mergeAttributes, Node } from '@tiptap/react' import { mergeAttributes, Node } from '@tiptap/react'
import { ReactNodeViewRenderer, NodeViewWrapper } from '@tiptap/react' import { ReactNodeViewRenderer, NodeViewWrapper } from '@tiptap/react'
import { X, Calendar, Video } from 'lucide-react' import { X, Calendar, Video, ChevronDown, Mic } from 'lucide-react'
import { blocks } from '@x/shared' import { blocks } from '@x/shared'
import { useState, useEffect } from 'react' import { useState, useEffect, useRef } from 'react'
function formatTime(dateStr: string): string { function formatTime(dateStr: string): string {
const d = new Date(dateStr) const d = new Date(dateStr)
@ -64,6 +64,57 @@ interface ResolvedEvent {
const EVENT_BAR_COLOR = '#7ec8c8' const EVENT_BAR_COLOR = '#7ec8c8'
function JoinMeetingSplitButton({ onJoinAndNotes, onNotesOnly }: {
onJoinAndNotes: () => void
onNotesOnly: () => void
}) {
const [open, setOpen] = useState(false)
const ref = useRef<HTMLDivElement>(null)
useEffect(() => {
if (!open) return
const handler = (e: MouseEvent) => {
if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false)
}
document.addEventListener('mousedown', handler)
return () => document.removeEventListener('mousedown', handler)
}, [open])
return (
<div className="calendar-block-split-btn" ref={ref}>
<button
className="calendar-block-split-main"
onMouseDown={(e) => e.stopPropagation()}
onClick={(e) => { e.stopPropagation(); onJoinAndNotes() }}
>
<Video size={13} />
Join meeting & take notes
</button>
<div className="calendar-block-split-chevron-wrap">
<button
className={`calendar-block-split-chevron ${open ? 'calendar-block-split-chevron-open' : ''}`}
onMouseDown={(e) => e.stopPropagation()}
onClick={(e) => { e.stopPropagation(); setOpen(!open) }}
>
<ChevronDown size={12} />
</button>
{open && (
<div className="calendar-block-split-dropdown">
<button
className="calendar-block-split-option"
onMouseDown={(e) => e.stopPropagation()}
onClick={(e) => { e.stopPropagation(); setOpen(false); onNotesOnly() }}
>
<Mic size={13} />
Take notes only
</button>
</div>
)}
</div>
</div>
)
}
// Shared global to pass calendar event data to App.tsx when joining a meeting. // Shared global to pass calendar event data to App.tsx when joining a meeting.
// Set before dispatching the custom event, read by the handler in App.tsx. // Set before dispatching the custom event, read by the handler in App.tsx.
declare global { declare global {
@ -170,10 +221,12 @@ function CalendarBlockView({ node, deleteNode }: { node: { attrs: Record<string,
} }
} }
const handleJoinMeeting = (event: blocks.CalendarEvent & { conferenceLink?: string }, resolvedIdx: number) => { const handleJoinMeeting = (event: blocks.CalendarEvent & { conferenceLink?: string }, resolvedIdx: number, joinCall: boolean) => {
const meetingUrl = event.conferenceLink if (joinCall) {
if (meetingUrl) { const meetingUrl = event.conferenceLink
window.open(meetingUrl, '_blank') if (meetingUrl) {
window.open(meetingUrl, '_blank')
}
} }
// Find the original source path from config // Find the original source path from config
@ -249,14 +302,10 @@ function CalendarBlockView({ node, deleteNode }: { node: { attrs: Record<string,
{getTimeRange(event)} {getTimeRange(event)}
</div> </div>
{showJoinButton && event.conferenceLink && ( {showJoinButton && event.conferenceLink && (
<button <JoinMeetingSplitButton
className="calendar-block-join-btn" onJoinAndNotes={() => handleJoinMeeting(event, event._idx, true)}
onMouseDown={(e) => e.stopPropagation()} onNotesOnly={() => handleJoinMeeting(event, event._idx, false)}
onClick={(e) => { e.stopPropagation(); handleJoinMeeting(event, event._idx) }} />
>
<Video size={13} />
Join meeting & take notes
</button>
)} )}
</div> </div>
</div> </div>

View file

@ -989,6 +989,93 @@
color: color-mix(in srgb, var(--foreground) 45%, transparent); color: color-mix(in srgb, var(--foreground) 45%, transparent);
} }
.tiptap-editor .ProseMirror .calendar-block-split-btn {
position: relative;
display: inline-flex;
align-items: stretch;
margin-top: 4px;
border-radius: 5px;
overflow: visible;
}
.tiptap-editor .ProseMirror .calendar-block-split-main {
display: inline-flex;
align-items: center;
gap: 5px;
padding: 4px 8px 4px 10px;
font-size: 12px;
font-weight: 500;
color: #7ec8c8;
background: color-mix(in srgb, #7ec8c8 12%, transparent);
border: 1px solid color-mix(in srgb, #7ec8c8 25%, transparent);
border-right: none;
border-radius: 5px 0 0 5px;
cursor: pointer;
transition: background-color 0.12s ease;
}
.tiptap-editor .ProseMirror .calendar-block-split-main:hover {
background: color-mix(in srgb, #7ec8c8 22%, transparent);
}
.tiptap-editor .ProseMirror .calendar-block-split-chevron-wrap {
position: relative;
display: inline-flex;
}
.tiptap-editor .ProseMirror .calendar-block-split-chevron {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 4px 6px;
color: #7ec8c8;
background: color-mix(in srgb, #7ec8c8 12%, transparent);
border: 1px solid color-mix(in srgb, #7ec8c8 25%, transparent);
border-left: 1px solid color-mix(in srgb, #7ec8c8 20%, transparent);
border-radius: 0 5px 5px 0;
cursor: pointer;
transition: background-color 0.12s ease;
}
.tiptap-editor .ProseMirror .calendar-block-split-chevron:hover {
background: color-mix(in srgb, #7ec8c8 22%, transparent);
}
.tiptap-editor .ProseMirror .calendar-block-split-chevron-open {
border-radius: 0 5px 0 0;
border-bottom-color: transparent;
}
.tiptap-editor .ProseMirror .calendar-block-split-dropdown {
position: absolute;
top: calc(100% - 1px);
right: 0;
z-index: 50;
background: color-mix(in srgb, #7ec8c8 12%, transparent);
border: 1px solid color-mix(in srgb, #7ec8c8 25%, transparent);
border-top: none;
border-radius: 0 0 5px 5px;
}
.tiptap-editor .ProseMirror .calendar-block-split-option {
display: flex;
align-items: center;
gap: 5px;
white-space: nowrap;
padding: 5px 10px;
font-size: 12px;
font-weight: 500;
color: #7ec8c8;
background: none;
border: none;
cursor: pointer;
transition: background-color 0.12s ease;
}
.tiptap-editor .ProseMirror .calendar-block-split-option:hover {
background: color-mix(in srgb, #7ec8c8 22%, transparent);
}
.tiptap-editor .ProseMirror .calendar-block-join-btn { .tiptap-editor .ProseMirror .calendar-block-join-btn {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;