mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-06-18 20:15:20 +02:00
refine draft
This commit is contained in:
parent
75e0f50855
commit
22e5452003
2 changed files with 86 additions and 12 deletions
|
|
@ -793,13 +793,45 @@
|
||||||
border-top: 1px solid var(--gm-border);
|
border-top: 1px solid var(--gm-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gmail-compose-actions-primary {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gmail-refine-button {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 30px;
|
||||||
|
padding: 0 14px;
|
||||||
|
border: 1px solid var(--gm-border-strong);
|
||||||
|
border-radius: 6px;
|
||||||
|
background: var(--gm-bg-pill);
|
||||||
|
color: var(--gm-text);
|
||||||
|
font: inherit;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gmail-refine-button:hover {
|
||||||
|
background: var(--gm-bg-pill-hover);
|
||||||
|
border-color: var(--gm-accent);
|
||||||
|
color: var(--gm-accent);
|
||||||
|
}
|
||||||
|
|
||||||
.gmail-send-button {
|
.gmail-send-button {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
padding: 0 14px;
|
padding: 0 14px;
|
||||||
border: none;
|
border: 1px solid transparent;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
background: var(--gm-accent);
|
background: var(--gm-accent);
|
||||||
color: var(--gm-accent-fg);
|
color: var(--gm-accent-fg);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import { Bold, Forward, Italic, Link as LinkIcon, List, ListOrdered, LoaderIcon, Quote, RefreshCw, Reply, Search, Send, Strikethrough } from 'lucide-react'
|
import { Bold, Forward, Italic, Link as LinkIcon, List, ListOrdered, LoaderIcon, Quote, RefreshCw, Reply, Search, Send, Sparkles, Strikethrough } from 'lucide-react'
|
||||||
import { useEditor, EditorContent, type Editor } from '@tiptap/react'
|
import { useEditor, EditorContent, type Editor } from '@tiptap/react'
|
||||||
import StarterKit from '@tiptap/starter-kit'
|
import StarterKit from '@tiptap/starter-kit'
|
||||||
import Link from '@tiptap/extension-link'
|
import Link from '@tiptap/extension-link'
|
||||||
|
|
@ -463,6 +463,37 @@ function ComposeBox({
|
||||||
if (editor && sel) editor.chain().focus().setTextSelection(sel).run()
|
if (editor && sel) editor.chain().focus().setTextSelection(sel).run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const refineWithCopilot = () => {
|
||||||
|
if (!editor) return
|
||||||
|
const currentDraft = editor.getText().trim()
|
||||||
|
const subject = thread.subject || '(No subject)'
|
||||||
|
|
||||||
|
const lines: string[] = []
|
||||||
|
lines.push(`Help me refine this draft email response. **Please ask me how I want to refine it before making any changes** — wait for my answer, then apply the edits.`)
|
||||||
|
lines.push('')
|
||||||
|
lines.push(`**Mode:** ${mode === 'reply' ? 'Reply' : 'Forward'}`)
|
||||||
|
lines.push(`**Subject:** ${subject}`)
|
||||||
|
lines.push('')
|
||||||
|
lines.push(`## Thread (${thread.messages.length} message${thread.messages.length === 1 ? '' : 's'})`)
|
||||||
|
lines.push('')
|
||||||
|
thread.messages.forEach((message, index) => {
|
||||||
|
lines.push(`### Message ${index + 1}`)
|
||||||
|
if (message.from) lines.push(`**From:** ${message.from}`)
|
||||||
|
if (message.to) lines.push(`**To:** ${message.to}`)
|
||||||
|
if (message.date) lines.push(`**Date:** ${message.date}`)
|
||||||
|
lines.push('')
|
||||||
|
lines.push((message.body || '(empty)').trim())
|
||||||
|
lines.push('')
|
||||||
|
})
|
||||||
|
|
||||||
|
lines.push(`## Current draft`)
|
||||||
|
lines.push('')
|
||||||
|
lines.push(currentDraft || '(empty — no draft yet)')
|
||||||
|
|
||||||
|
window.__pendingEmailDraft = { prompt: lines.join('\n') }
|
||||||
|
window.dispatchEvent(new Event('email-block:draft-with-assistant'))
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="gmail-compose-card">
|
<div className="gmail-compose-card">
|
||||||
<div className="gmail-compose-header">
|
<div className="gmail-compose-header">
|
||||||
|
|
@ -502,16 +533,27 @@ function ComposeBox({
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="gmail-compose-actions">
|
<div className="gmail-compose-actions">
|
||||||
<button
|
<div className="gmail-compose-actions-primary">
|
||||||
type="button"
|
<button
|
||||||
className="gmail-send-button"
|
type="button"
|
||||||
onClick={() => {
|
className="gmail-send-button"
|
||||||
toast('Sending from this view needs Gmail send scope. Draft UI is ready.', 'info')
|
onClick={() => {
|
||||||
}}
|
toast('Sending from this view needs Gmail send scope. Draft UI is ready.', 'info')
|
||||||
>
|
}}
|
||||||
<Send size={15} />
|
>
|
||||||
Send
|
<Send size={15} />
|
||||||
</button>
|
Send
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="gmail-refine-button"
|
||||||
|
onClick={refineWithCopilot}
|
||||||
|
title="Refine this draft with Copilot"
|
||||||
|
>
|
||||||
|
<Sparkles size={15} />
|
||||||
|
Refine
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
{editor && <ComposeToolbar editor={editor} onOpenLink={openLink} />}
|
{editor && <ComposeToolbar editor={editor} onOpenLink={openLink} />}
|
||||||
<button type="button" className="gmail-compose-link" onClick={onClose}>Discard</button>
|
<button type="button" className="gmail-compose-link" onClick={onClose}>Discard</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue