An image with text: the text, then the image as a footnote (D-067) #330

Merged
littlefox merged 1 commit from issue-329-image-footnote into main 2026-10-24 21:57:51 +00:00
Owner

Closes #329 (D-067)

An image with a caption, or a presentation with a picture, was written as multipart/mixed. jskom showed it as [unknown content-type: …], and the Emacs client said "Flerdelade inlägg stöds inte". Both show image/* texts.

  • Draft::split_image: the text as usual, then the image as an image/* footnote to it, to the same recipients. An image without text stays one image text.
  • Composer: the image gets the whole text limit. A too-long refusal rescales and resends only the image, never the text.
  • Presentations the same. The avatar is the first image in the presentation or its footnotes (Kom::picture_of).
  • NeoKOM keeps reading multipart. Old posts are left; the user re-saves their presentation.

Tests:

  • Unit: split, no multipart.
  • Devserver: text plus footnote at the full budget; presentation avatar from its footnote.
  • post-image and profile specs.
  • Full suite: 410 passed, 1 flaky (unseen on iPhone, the draft-removal timing; unrelated, passed on retry).
  • Lint passes all three ways; devserver tests: 21 passed.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XJW2ocwLunyaLiUwCBHEP8

Closes #329 (D-067) An image with a caption, or a presentation with a picture, was written as `multipart/mixed`. jskom showed it as `[unknown content-type: …]`, and the Emacs client said "Flerdelade inlägg stöds inte". Both show `image/*` texts. - `Draft::split_image`: the text as usual, then the image as an `image/*` footnote to it, to the same recipients. An image without text stays one image text. - Composer: the image gets the whole text limit. A too-long refusal rescales and resends only the image, never the text. - Presentations the same. The avatar is the first image in the presentation or its footnotes (`Kom::picture_of`). - NeoKOM keeps reading multipart. Old posts are left; the user re-saves their presentation. Tests: - Unit: split, no multipart. - Devserver: text plus footnote at the full budget; presentation avatar from its footnote. - post-image and profile specs. - Full suite: 410 passed, 1 flaky (unseen on iPhone, the draft-removal timing; unrelated, passed on retry). - Lint passes all three ways; devserver tests: 21 passed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01XJW2ocwLunyaLiUwCBHEP8
An image with text: the text, then the image as a footnote (D-067)
Some checks failed
perf / perf (pull_request) Has been skipped
ci / check (push) Successful in 8m35s
ci / desktop (push) Successful in 17m55s
ci / e2e (push) Failing after 41m50s
128ea966c7
The user's profile picture showed in jskom as [unknown content-type:
"multipart/mixed;…"], and the Emacs client can't show it either: a
caption (or a presentation's text) made the text multipart/mixed, which
neither client renders. jskom shows text/* and image/* only, and posts
an image as the whole text; the Emacs client shows image/* but not
multipart. Design said "as jskom does"; it wasn't checked.

Now Draft::split_image makes two texts: the text as before, and the
image as an image/* footnote to it, to the same recipients. The Emacs
client reads it right after the text; jskom lists it; NeoKOM draws it
inside the post. The image gets the whole text limit; a too-long refusal
rescales and resends only the image. Presentations the same, and the
avatar is found in the presentation's footnotes (Kom::picture_of). Old
multipart posts are left; NeoKOM still reads multipart.

Tests: unit (split, no multipart), devserver (text + footnote at the
full budget, presentation avatar from its footnote), post-image and
profile specs.

Closes #329

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XJW2ocwLunyaLiUwCBHEP8
littlefox referenced this pull request from a commit 2026-10-25 09:02:12 +00:00
Sign in to join this conversation.
No description provided.