Skip to content

fix: setFromObject() silently drops an image watermark (#95) - #96

Merged
otnc merged 2 commits into
mainfrom
fix/issue-95-watermark-object-roundtrip
Sep 3, 2026
Merged

fix: setFromObject() silently drops an image watermark (#95)#96
otnc merged 2 commits into
mainfrom
fix/issue-95-watermark-object-roundtrip

Conversation

@otnc

@otnc otnc commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #95.

  • Bug: QuoteData splits a watermark into watermark (text) and watermarkImage (image) halves, but applyInput() (used by setFromObject()) only ever read input.watermark. A QuoteData round-tripped through getData() -> setFromObject() always carries watermark: '' alongside a set watermarkImage for an image watermark, so the blank string silently overwrote the image and nothing was drawn.
    • QuoteInput now also accepts watermarkImage, symmetric with what getData() produces. applyInput() prefers it when truthy, and still falls through to the existing watermark handling (text, image, or null to clear) for every other input shape — including watermarkImage: null on its own, and a plain watermarkImage with no watermark field at all.
  • Enhancement: theme.watermark.size is tuned for a short text tag and reads small for a logo image drawn at the same height. Added theme.watermark.imageSize (null by default, falling back to size exactly as before — no visual change unless you opt in) so an image watermark can be sized independently of the text one.

Investigation

Looked for the same "split-field silently dropped on round-trip" pattern elsewhere in QuoteData/QuoteInput (avatar, username, displayName, markdown) and in the source adapters (fromMessage/fromNote/fromTweet) and the CLI's own watermark flag handling — watermark/watermarkImage is the only field pair with this split representation, and the CLI resolves its --watermark/--watermark-image flags into the single watermark field before calling setFromObject(), so it never hit this bug. No other instance found.

Test plan

  • npm run ci (biome)
  • npm run typecheck
  • npm run test (872 tests, all green; 5 new regression tests, each verified red against the pre-fix code then green after)
  • npm run build
  • npm run check:build (27 checks passed)

otnc added 2 commits September 3, 2026 19:50
QuoteData.watermark/.watermarkImage split a watermark into its text and
image halves, but QuoteInput (accepted by setFromObject()/applyInput())
only ever read input.watermark. A QuoteData object round-tripped through
getData() -> setFromObject() always carries watermark: '' alongside a set
watermarkImage for an image watermark, so applyInput() overwrote the image
with that blank string and drew nothing.

QuoteInput now also accepts watermarkImage, symmetric with what getData()
produces; applyInput() prefers it when truthy so the round trip works
without the caller having to reassemble the two fields by hand, and still
falls through to the existing watermark handling for every other input
shape.

Fixes #95.
theme.watermark.size is tuned for a short text tag and reads too small for
a logo image drawn at the same height. Adds an optional
theme.watermark.imageSize (null by default, falling back to size exactly
as before) so an image watermark can be sized on its own without moving
the text one.

Addresses the enhancement half of #95.
@otnc
otnc merged commit d8ac6e2 into main Sep 3, 2026
7 checks passed
@otnc
otnc deleted the fix/issue-95-watermark-object-roundtrip branch September 3, 2026 11:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

setFromObject() silently drops an image watermark, and the default watermark.size reads too small for a logo

1 participant