custom feedback highlights

This commit is contained in:
2026-03-02 09:18:12 +10:00
parent 338eaf5c5f
commit c735eed1f3
5 changed files with 46 additions and 9 deletions

View File

@@ -7,8 +7,6 @@ import { parseAnnotationsFromAIResponse } from '../../utils/annotationParser'
import type { Attachment, TextAnnotation } from '../../types/editor'
import './Chat.css'
type TabId = 'chat' | 'feedback'
function formatSessionTime(createdAt: number): string {
const date = new Date(createdAt)
const now = new Date()
@@ -41,10 +39,13 @@ export function ChatPanel(): JSX.Element {
setAnnotations,
linkAnnotationsToMessage,
newChat,
setActiveSession
setActiveSession,
rightPanelTab,
setRightPanelTab,
} = useEditorStore()
const [tab, setTab] = useState<TabId>('chat')
const tab = rightPanelTab
const setTab = setRightPanelTab
const [showHistory, setShowHistory] = useState(false)
const [pendingAttachmentCount, setPendingAttachmentCount] = useState(0)
const scrollRef = useRef<HTMLDivElement>(null)

View File

@@ -116,7 +116,9 @@ export function analyseAnnotation(
documentContent: activeFileContent,
documentPath: activeFilePath ?? '',
conversationHistory: [],
userMessage: `This passage was flagged for ${typeName}: "${ann.matchedText}"\n\nIn 12 sentences explain the specific issue, then provide a direct rewrite in a markdown blockquote like this:\n\n> Rewritten passage here.\n\nBe specific to this exact text—no generic advice.`
userMessage: ann.autoAnalyse
? `Please provide editorial feedback on this selected passage: "${ann.matchedText}"\n\nIn 12 sentences, identify the most important issue or opportunity for improvement, then provide a suggested rewrite in a markdown blockquote:\n\n> Rewritten version here.\n\nBe specific to this exact text.`
: `This passage was flagged for ${typeName}: "${ann.matchedText}"\n\nIn 12 sentences explain the specific issue, then provide a direct rewrite in a markdown blockquote like this:\n\n> Rewritten passage here.\n\nBe specific to this exact text—no generic advice.`
},
(chunk: string) => {
if (cancelled) return
@@ -607,7 +609,32 @@ export function MarkdownEditor(): JSX.Element {
selectAll(view)
view.focus()
}
}
},
...(hasSelection ? [
'separator' as const,
{
label: 'Generate feedback',
action: () => {
const view = viewRef.current
if (!view) return
const { from, to } = view.state.selection.main
const text = view.state.sliceDoc(from, to)
if (!text.trim()) return
const annotation: TextAnnotation = {
id: `custom-${Date.now()}`,
type: 'custom',
from,
to,
matchedText: text,
message: 'Generating feedback...',
autoAnalyse: true,
}
const store = useEditorStore.getState()
store.setAnnotations([...store.annotations, annotation])
store.setRightPanelTab('feedback')
}
}
] : [])
]
return (

View File

@@ -44,7 +44,8 @@ function FeedbackCard({ ann, autoAnalyse, onDismiss }: FeedbackCardProps): JSX.E
if (cached) return { status: 'done', text: cached.text, suggestion: cached.suggestion }
// Custom (attachment-driven) annotations already carry their analysis — show
// the problem description and suggestion immediately without an extra AI call.
if (ann.type === 'custom') {
// Context-menu annotations (autoAnalyse: true) need AI analysis, so start idle.
if (ann.type === 'custom' && !ann.autoAnalyse) {
return { status: 'done', text: ann.message, suggestion: ann.suggestion ?? null }
}
return { status: 'idle' }
@@ -93,7 +94,7 @@ function FeedbackCard({ ann, autoAnalyse, onDismiss }: FeedbackCardProps): JSX.E
<div className="fb-card-header-top">
<div className="fb-card-header-badges">
<span className="fb-card-badge">{typeName}</span>
{ann.type === 'custom' && (
{ann.type === 'custom' && !ann.autoAnalyse && (
<span className="fb-card-source-tag">from attachment</span>
)}
</div>
@@ -251,7 +252,7 @@ export function FeedbackPanel(): JSX.Element {
<FeedbackCard
key={ann.id}
ann={ann}
autoAnalyse={analyseAll}
autoAnalyse={analyseAll || ann.autoAnalyse === true}
onDismiss={() => { cancelPendingDismiss(ann.id); removeAnnotation(ann.id); tooltipAnalysisCache.delete(ann.id) }}
/>
))}