Skip to content

feat(write): editable quotes with lists inside, uploaded cover images, Write-only welcome content (T-19) - #32

Merged
vlidholt merged 1 commit into
serverpod:mainfrom
vlidholt:t-19-various-improvements
Oct 21, 2026
Merged

vlidholt merged 1 commit into
serverpod:mainfrom
vlidholt:t-19-various-improvements

Conversation

@vlidholt

Copy link
Copy Markdown
Contributor

Wonky-Task: T-19
Wonky-Claim: H3WG-TSXR

Addresses #24 (no default Sheets document), #25 (editing quotes in Write) and #27 (uploading the blog cover image).

Acceptance criteria

  • Sign-up creates only the Write starter document. AccountService.ensureWelcomeContent no longer creates the welcome spreadsheet; there never was a welcome presentation. The sheets.welcome template stays so spreadsheets that older accounts already got from it still resolve. Server test: a new account has exactly New here? Read me first and no spreadsheet row (user_endpoint_test.dart).
  • Quote text can be clicked, selected, edited and formatted (single- and multi-line). Root cause: the quote bar is a CustomPaint whose painter didn't override hitTest, so RenderCustomPaint.hitTestSelf returned true and every quote line absorbed taps and clicks before the document interactor below it saw them. The painter now returns false. The bars of a multi-paragraph quote also had a 4 px break (line spacing outside the bar); that spacing is now inside the bar, so the quote shows one unbroken bar.
  • Lists inside quotes can be selected and edited. Lists in quotes are now real: a list line may carry blockquote: true (bullet, numbered, task, any indent). This was confirmed with you before implementing, and overrides the task's "don't change the schema" note. Changes:
    • Validator, normalizer, IR and generators. A quoted list next to an unquoted one counts as two lists, so indent and numbering restart.
    • Markdown (> - item round-trips) and HTML (<blockquote><ul>) import and export, with quote bar and indent in TXT, DOCX, ODT, RTF and PDF export.
    • Editor: rendering under the quote bar, the - / 1. / [ ] / > shortcuts, Enter/Backspace/Tab and the block-type commands.
    • MCP write.set_block_type, which gains an optional quoted; block listings report quoted.
  • Undo/redo inside quotes and quoted lists. Widget tests (wonky_write/test/features/editor/components/blockquote_test.dart, 32 cases, touch and mouse interactors) cover tapping, double-click selection, typing, Mod+B, Enter, Backspace, Tab, Markdown shortcuts and the commands, plus undo (and redo for typing). All of them failed before the fix.
  • Submit dialog has a cover image upload, styled in light and dark. A new reusable ImageFieldSpec in the shared form dialog has a 16:9 thumbnail, Upload image (Replace), Remove and a hint, and MCP can operate it. The Submit dialog uses it instead of a picker of the document's images. The image is uploaded as an image file of the story's document; it is not inserted into the text, so blogs don't show it twice. Widget tests cover the empty state in both themes, uploading, removing, a cancelled picker, a failed upload and MCP setField.
  • Uploaded covers reach the publication. SubmissionService.submit accepts a cover that is either in the text or a ready image file of the story's document. Anything else is dropped, and a required cover that isn't valid is refused. The cover is listed in the webhook's assets and recorded as a submission_asset, so GET assets/{id} serves it. The webhook's shape is unchanged: fields.coverImage is still an asset id. Server tests are in submission_cover_test.dart. docs/blog-integration.md notes that the cover usually isn't in the Markdown.

Also fixed: HTML import dropped a heading containing only whitespace. The property tests found it once they started generating quoted lists.

Specs updated: 04 §1.1, 18 §4.2/§7.1/§9.2/§13, 19, Write 02 §1.2/§2.2, 04 §14 (AC-14.2, AC-14.3), 07 (fidelity tables), 09.

Known limits: DOCX, ODT and RTF import still read a list inside a quote as a plain list item. Tabs still running an older build may strip the quote from such lines until they reload.

Screenshots

These are rendered from the real widgets in a test. The editor's fonts don't load in tests, so its text shows as boxes.

Light Dark
Submit dialog, no cover
Submit dialog, uploaded cover
Quote with paragraphs, a nested list, a numbered item and a task

Checks

  • dart analyze and dart format are clean in every changed package, plus Slides, Sheets and Drive.
  • Test suites pass: wonky_write_core 785 (property tests under several seeds), wonky_write 740, wonky_app 938 (goldens excluded locally, per spec 15), wonky_rich_text 32, wonky_rich_editor 154, wonky_core 361, and the server's publication, user, analytics and Write tests.
  • No model changes, so no migration.
  • Verified by hand in the release build.

🤖 Generated with Claude Code

…, Write-only welcome content (T-19)

- Sign-up creates only the Write welcome document; no welcome spreadsheet.
- Quote text can be clicked, selected and edited again: the quote bar's
  painter no longer absorbs taps and clicks. The bars of a multi-paragraph
  quote join into one unbroken bar.
- Lists inside quotes: a list line may carry `blockquote: true` (bullet,
  numbered, task, any indent). Supported in the validator, normalizer, IR,
  Markdown and HTML import/export, TXT/DOCX/ODT/RTF/PDF export, the editor
  (rendering, Markdown shortcuts, Enter/Backspace/Tab, block-type commands)
  and MCP `write.set_block_type` (`quoted`).
- Submit dialog: the cover image is uploaded in the dialog as an image file
  of the story's document instead of picked from its text; the server
  accepts it, lists it in the webhook's `assets` and refuses an invalid
  required cover.
- HTML import keeps a whitespace-only heading (found by the property tests).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@wonky-work-bot

Copy link
Copy Markdown

Wonky task review: T-19: Various improvements

Screenshot: the description has an image of the changed UI.

This pull request successfully resolves the three requested improvements. It removes the extra spreadsheet creation upon signup, correctly fixes hit-testing and styling for blockquotes and quoted lists in Write, and smoothly integrates an inline cover image uploader into the submission dialog. The changes are accompanied by solid test coverage and spec updates.

Acceptance criterion Verdict Evidence Note
Creating a new account generates a starter document for Wonky Write only; no default spreadsheet or presentation is created. Met wonky_server/lib/src/platform/users/account_service.dart The default Sheets document creation was removed.
In Wonky Write, users can click, select, edit, and format text inside both single-line and multi-line blockquotes. Met wonky_write/lib/features/editor/components/wonky_components.dart, wonky_write/test/features/editor/components/blockquote_test.dart Hit testing logic was updated for the quote bar painter, allowing tap events to reach the editor.
In Wonky Write, lists and other block elements nested inside a blockquote can be selected and edited normally. Met packages/wonky_rich_text/lib/src/attributes.dart, wonky_write/lib/features/editor/components/wonky_components.dart, wonky_write/lib/features/editor/commands/write_editor_commands.dart Lists items can now carry quoted metadata and render correctly with quote bars.
Undo and redo function correctly when editing text or lists inside blockquotes. Met wonky_write/test/features/editor/components/blockquote_test.dart New widget tests extensively cover undo and redo behavior.
The Submit dialog in Wonky Write includes a file picker option to upload a cover image, with correct styling in both light and dark modes. Met packages/wonky_app/lib/src/shell/form_dialog.dart, wonky_write/lib/features/publish/submit_dialog.dart An ImageFieldSpec handles the upload UI natively inside the form dialog.
Uploaded cover images are correctly attached to the submission and sent to the publication webhook/API. Met wonky_server/lib/src/platform/publications/submission_service.dart The backend service fetches and validates the uploaded image before attaching it as an asset.
The pull request description includes a screenshot of the changed UI (light and dark where both change). Met PR description The author provided light and dark theme screenshots of the editor and submit dialog.

Scope:

  • packages/wonky_write_core/lib/src/import/html/html_importer.dart: Fixed a bug where HTML imports dropped headings containing only whitespace.

Tests: Added. Comprehensive server and widget tests were added for the new components and updated logic.

Specs: Updated. Several specifications were updated to reflect the new account flow, quoted lists, and upload capabilities.

Risks:

  • Security in wonky_server/lib/src/platform/publications/submission_service.dart: The submission endpoint verifies that the uploaded image belongs to the associated document to prevent unauthorized file access.
Facts
  • Changed files: 57 (+2399 −291)
  • Tests changed: yes
  • specs/ changed: yes
  • pubspec.yaml changed: no
  • Migrations added: none
  • Workflow or tooling changes: none
  • Security-sensitive paths: wonky_server/lib/src/platform/users/account_service.dart

Reviewed commit 993a9a962193. This review is advisory; CI and the maintainers decide.

@vlidholt
vlidholt merged commit d7aab04 into serverpod:main Oct 21, 2026
42 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 21, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant