A whole category accepted in one click, and one undo
Five article fixes were five clicks, five confetti bursts and five undo steps. "Accept all Tidy-up (5)" makes them one of each. The single undo decided the implementation: every replacement goes into one Tiptap chain, which applies as one transaction and so undoes as one history event. That only works if the spans can't move under each other, so the plan resolves every span against the document as it stands and applies them last-first. Three outcomes rather than one, because a batch that quietly dropped a card would be reporting edits it never made: a span she already fixed herself is settled without an edit (what a single Accept does too), and a card quoting the same words as one already taken is left on screen, since findRange would resolve both to the same place. The control sits on the first card of its kind — the rail can't carry a category header, its cards are anchored to their own sentences — and only when the category has company. It is outlined rather than filled: it acts on cards she can't see from where she's standing.
This commit is contained in:
@@ -1,13 +1,17 @@
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import type { Suggestion } from '../../api/client'
|
||||
import type { Suggestion, SuggestionType } from '../../api/client'
|
||||
import { usePack } from '../../i18n'
|
||||
import { AskPetal } from './AskPetal'
|
||||
import { TYPE_META, typeLabel } from './suggestionMeta'
|
||||
import { TYPE_META, batchLabel, typeLabel } from './suggestionMeta'
|
||||
|
||||
interface Props {
|
||||
suggestion: Suggestion
|
||||
style: React.CSSProperties
|
||||
// How many pending suggestions share this card's type (including this one).
|
||||
// Two or more offers to take the whole category in one step.
|
||||
batchCount: number
|
||||
onAccept: (s: Suggestion) => void
|
||||
onAcceptAll: (type: SuggestionType) => void
|
||||
onDismiss: (s: Suggestion) => void
|
||||
onPointerEnter: () => void
|
||||
onPointerLeave: () => void
|
||||
@@ -30,7 +34,9 @@ interface Props {
|
||||
export function SuggestionCard({
|
||||
suggestion,
|
||||
style,
|
||||
batchCount,
|
||||
onAccept,
|
||||
onAcceptAll,
|
||||
onDismiss,
|
||||
onPointerEnter,
|
||||
onPointerLeave,
|
||||
@@ -144,6 +150,17 @@ export function SuggestionCard({
|
||||
Dismiss
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{hasReplacement && batchCount > 1 && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onAcceptAll(suggestion.type)}
|
||||
className="petal-accept-all mt-2 w-full rounded-full py-1.5 text-xs font-bold"
|
||||
style={{ color: 'var(--color-plum)', borderColor: meta.color }}
|
||||
>
|
||||
{batchLabel(suggestion.type, batchCount)}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user