mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-04-26 00:46:23 +02:00
added only notes option
This commit is contained in:
parent
ea59208c38
commit
5a4009d181
2 changed files with 150 additions and 14 deletions
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue