Conversation
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|
[Claude Opus 5 from Hatton's machine during preflight] Consulted Devin on 2026-08-23 22:56 UTC up to commit 379ee06. The review job reached |
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|
[Claude Opus 5 from Hatton's machine during preflight] Consulted Devin on this pull request, up to Devin raised these findings, plus two informational notes that need no action. Each is now a review thread above, with what came of it:
Devin has been re-triggered for |
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|
[Claude Opus 5 from Hatton's machine during preflight] Consulted Devin again, up to On One note in the last round is new and is a real question rather than a defect: a turn cannot be undone once the selection moves away. That thread is open, and the question is on the preflight report for Hatton. |
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|
[Claude Opus 5 from Hatton's machine during preflight] Consulted Devin on this PR up to Devin re-read the whole PR after the change that makes Rotate right keep a crop. It raised no new Its five Investigate flags are the same five as before, each with its own thread above: four are CI is green. Greptile posted only a notice that its trial has ended, so it reviewed nothing. |
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|
[Claude Opus 5 from Hatton's machine during preflight] Consulted Devin on this PR up to Devin re-read the whole PR at this commit and raised nothing new. It now marks all three of its |
|
The PR appears safe to merge because no blocking failure remains within the eligible follow-up review scope. SummaryThis PR adds rotation and mirroring for pictures and arbitrary-angle rotation for supported canvas elements, preserving these transformations through editing, undo, and publishing.
Reviews (2) · Last reviewed commit: "Rotate and flip pictures, and rotate can..." |
|
[Claude Opus 5 from Hatton's machine during preflight] Consulted Devin on this PR up to Devin re-read the whole PR at this commit and raised nothing new. It marks all three of its
Nothing Devin says touches the newest work in this commit: the rotation knob moving to the other |
|
[Claude Fable 5.1 following a prompt from Hatton] Preflight needed before this lands. Today's UI-test run pushed product-code changes to this branch, not only tests:
Tests for both are in 26fcd02 and fb2ac42 (Notion Test Case ID 827). Run |
hatton
left a comment
There was a problem hiding this comment.
@hatton reviewed 3 files and made 6 comments.
Reviewable status: 0 of 31 files reviewed, 15 unresolved discussions.
src/BloomBrowserUI/bookEdit/js/bloomEditing.ts line 155 at r3 (raw file):
// Marks the turned canvas element the pointer is inside, so it means nothing once the // page is saved. See kPointerInsideClass in canvasElementRotation.ts. $(this).removeClass(kPointerInsideClass);
Long ago, we had a convention where all classes that were for UI only should just start with "ui-" And thus we wouldn't have to list each one for cleanup? is that gone?
src/BloomBrowserUI/bookEdit/js/canvasElementManager/CanvasElementPointerInteractions.ts line 98 at r3 (raw file):
bloomCanvas.onmouseup = null; // While the pointer is inside the bloom-canvas, onMouseMove keeps the mark on the turned
this comment is hard for humans to read. improve it. Don't use "mark". Don't assume the reader is thinking in terms of rotating.
src/BloomBrowserUI/bookEdit/js/canvasElementManager/CanvasElementPointerInteractions.ts line 450 at r3 (raw file):
} if (event.buttons === 0) { // Not a drag, so keep the mark on the turned element the pointer is inside. This has
"the mark" is Not helpful.
src/BloomBrowserUI/bookEdit/js/canvasElementManager/CanvasElementPointerInteractions.ts line 481 at r3 (raw file):
// also keeps the work small: we walk the turned elements, not every element, and we do no // comicaljs hit test. private updateTurnedElementUnderPointer(event: MouseEvent) {
Don't use the term turned; use rotated.
src/BloomBrowserUI/bookEdit/js/canvasElementManager/CanvasElementPointerInteractions.ts line 498 at r3 (raw file):
} // Put the mark on one turned element and take it off the others. Pass undefined to clear it
Don't use mark or turned.
src/BloomBrowserUI/bookEdit/js/canvasElementManager/CanvasElementPointerInteractions.ts line 609 at r3 (raw file):
// another element covers is not clicked. And a button that is not displayed is not in the // list at all, so a hidden video cannot be started. private getVideoButtonInsideTurnedElement(
Rotated, not turned.
hatton
left a comment
There was a problem hiding this comment.
@hatton+JHAI made 6 comments and resolved 6 discussions.
Reviewable status: 0 of 31 files reviewed, 9 unresolved discussions.
src/BloomBrowserUI/bookEdit/js/bloomEditing.ts line 155 at r3 (raw file):
Previously, hatton (John Hatton) wrote…
Long ago, we had a convention where all classes that were for UI only should just start with "ui-" And thus we wouldn't have to list each one for cleanup? is that gone?
[Claude Opus 5.5 from Hatton's machine during reviewable-replies] That line is gone along with the video support, so this spot no longer adds a class to the list.
On the convention: it still exists, but it works on elements, not on class-name prefixes. Cleanup() removes any element that has the class bloom-ui ($(".bloom-ui").remove()), and HtmlDom.cs strips the same elements on the C# side. Nothing removes classes whose names start with ui-. The ui-draggable, ui-resizable and ui-...Highlight names in that list come from jQuery UI, and each one is removed individually. A class that Bloom adds to a real page element only while editing still has to be listed there by hand, or removed by the code that added it.
src/BloomBrowserUI/bookEdit/js/canvasElementManager/CanvasElementPointerInteractions.ts line 98 at r3 (raw file):
Previously, hatton (John Hatton) wrote…
this comment is hard for humans to read. improve it. Don't use "mark". Don't assume the reader is thinking in terms of rotating.
[Claude Opus 5.5 from Hatton's machine during reviewable-replies] Gone. The code this comment described existed only so that a rotated video could show its play, pause and replay buttons. Rotating a video is no longer supported, so the comment and the code under it are deleted. That removes the mouseleave listener and every use of the class it cleared.
src/BloomBrowserUI/bookEdit/js/canvasElementManager/CanvasElementPointerInteractions.ts line 450 at r3 (raw file):
Previously, hatton (John Hatton) wrote…
"the mark" is Not helpful.
[Claude Opus 5.5 from Hatton's machine during reviewable-replies] Gone. The code this comment described existed only so that a rotated video could show its play, pause and replay buttons. Rotating a video is no longer supported, so the comment and the code under it are deleted.
src/BloomBrowserUI/bookEdit/js/canvasElementManager/CanvasElementPointerInteractions.ts line 481 at r3 (raw file):
Previously, hatton (John Hatton) wrote…
Don't use the term turned; use rotated.
[Claude Opus 5.5 from Hatton's machine during reviewable-replies] Gone. The code this comment described existed only so that a rotated video could show its play, pause and replay buttons. Rotating a video is no longer supported, so the comment and the code under it are deleted. Separately, a pass over the whole branch is replacing "turn" and "turned" with "rotate" and "rotated" in the comments, test names and identifiers.
src/BloomBrowserUI/bookEdit/js/canvasElementManager/CanvasElementPointerInteractions.ts line 498 at r3 (raw file):
Previously, hatton (John Hatton) wrote…
Don't use mark or turned.
[Claude Opus 5.5 from Hatton's machine during reviewable-replies] Gone. The code this comment described existed only so that a rotated video could show its play, pause and replay buttons. Rotating a video is no longer supported, so the comment and the code under it are deleted.
src/BloomBrowserUI/bookEdit/js/canvasElementManager/CanvasElementPointerInteractions.ts line 609 at r3 (raw file):
Previously, hatton (John Hatton) wrote…
Rotated, not turned.
[Claude Opus 5.5 from Hatton's machine during reviewable-replies] Gone. The code this comment described existed only so that a rotated video could show its play, pause and replay buttons. Rotating a video is no longer supported, so the comment and the code under it are deleted. This method passed clicks through to the buttons of a rotated video.
|
[Claude Opus 5.5 from Hatton's machine during preflight] Consulted Devin on 2026-09-24 up to |
|
[Devin] Bug: Editing shortcuts multiply after adding elements ( The document-level key handlers are bound again each time a canvas element is added, so one key press runs several copies. [Claude Opus 5.5 from Hatton's machine during preflight] Not changed by this PR: bloomEditing.ts is now identical to master. The shortcuts there (clear formatting, the justify keys) give the same result however many copies run, so the extra copies do no harm. They only mattered while Ctrl+R rotated a picture, and that shortcut is gone. |
|
[Claude Opus 5.5 from Hatton's machine during preflight] Consulted Devin on this PR up to Devin re-read the whole PR from scratch at |
hatton
left a comment
There was a problem hiding this comment.
@hatton partially reviewed 27 files and made 2 comments.
Reviewable status: 0 of 41 files reviewed, 30 unresolved discussions.
src/BloomBrowserUI/bookEdit/js/canvasElementManager/CanvasElementManager.ts line 1361 at r8 (raw file):
// Rotate the active canvas element 90 degrees clockwise. Used by the Rotate Right // menu command, for everything except a background image; see rotateActiveImageRight. public rotateActiveElementRight(): void {
put the 90Degrees in the name (For all such functions). The idea is to differentiate this from the freeform rotation that we also support.
src/BloomBrowserUI/bookEdit/js/canvasElementManager/CanvasElementSelectionUi.ts line 30 at r8 (raw file):
// control frame is plain DOM that this file creates and removes by hand. The path is the one // in @mui/icons-material/Refresh. const kRefreshIconPath =
Okay, we reuse the refresh icon, but it's confusing to see that in the code. Just call it the rotate icon.
hatton
left a comment
There was a problem hiding this comment.
@hatton partially reviewed 12 files.
Reviewable status: 0 of 41 files reviewed, 30 unresolved discussions.
hatton
left a comment
There was a problem hiding this comment.
@hatton+JHAI made 2 comments and resolved 2 discussions.
Reviewable status: 0 of 41 files reviewed, 28 unresolved discussions.
src/BloomBrowserUI/bookEdit/js/canvasElementManager/CanvasElementManager.ts line 1361 at r8 (raw file):
Previously, hatton (John Hatton) wrote…
put the 90Degrees in the name (For all such functions). The idea is to differentiate this from the freeform rotation that we also support.
[Claude Opus 5.5 from Hatton's machine during reviewable-replies] Done in 9b599666d2. The four functions that rotate by a quarter turn are now rotateActiveElementRight90Degrees, rotateActiveImageRight90Degrees, rotateImageContentRight90Degrees, and the e2e helper rotateSelectedImageRight90Degrees.
src/BloomBrowserUI/bookEdit/js/canvasElementManager/CanvasElementSelectionUi.ts line 30 at r8 (raw file):
Previously, hatton (John Hatton) wrote…
Okay, we reuse the refresh icon, but it's confusing to see that in the code. Just call it the rotate icon.
[Claude Opus 5.5 from Hatton's machine during reviewable-replies] Done in 9b599666d2. The constant is now kRotateIconPath, and the comment calls it the rotate icon; it mentions Refresh only to say where the path was copied from.
|
[Claude Opus 5.5 from Hatton's machine during preflight] Consulted Devin on this PR up to Since the last log, Devin re-read the whole PR at each push. The real findings are fixed, each on its own resolved thread: typing, formatting, links and line breaks after a rotation are undone before the rotation, a duplicate keeps its angle and lands on its source, and navigation buttons and book link grids are never rotated. Three predicted edge cases in the Undo comparison did not happen when Hatton tried them, and their threads say so. At this commit it raised nothing new. |
hatton
left a comment
There was a problem hiding this comment.
@hatton partially reviewed 22 files.
Reviewable status: 0 of 45 files reviewed, 42 unresolved discussions.
…741) A picture that arrived on its side stayed on its side: Bloom could crop and move a picture but not rotate or mirror it, or set an item at an angle. - Rotate right on the picture menu rotates a picture 90 degrees clockwise. An ordinary picture rotates as a box; a background picture rotates inside its area, which is reshaped to match, keeping the crop. It does nothing on an empty placeholder. - Flip horizontal and Flip vertical mirror the picture about its own axes, whatever it is rotated by, so flipping then rotating gives the same result as rotating then flipping. - A rotation knob rotates a selected item to any angle, snapping to 45-degree steps unless Ctrl is held. Speech bubbles and similar shapes, videos, navigation buttons and book link grids get no knob; navigation buttons and book link grids are never rotated. - Dragging, resizing, cropping and typing work on a rotated item at any edit zoom, and a rotated background keeps its framing when the page changes shape. - Undo takes back each Rotate right, Flip and knob drag, only for the selected item, and after typing or formatting in a rotated text box it takes back the text edit first. Undo of a picture replacement is offered only while that picture is selected. - Reset Image clears the crop and the picture's rotation and mirror; it does not straighten a rotated box. A new picture, chosen or pasted, arrives upright and uncropped, and a duplicate keeps its original's angle and mirror. - Publishing writes a rotated or flipped picture into the published image upright and cropped to what the page shows, for BloomPUB, ePUB, upload and spreadsheet export; the AI Image Editor gets the same upright view. Every angle and mirror lives in the item's inline transform, saved in the book HTML. The rotate-and-flip e2e spec automates manual Test Case 827. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
46a2be0 to
b520cf1
Compare
Problem
A picture that arrives on its side stays on its side. Bloom could crop a picture and move it,
but it could not rotate it, mirror it, or set an item on a page at an angle. An author whose
camera saved a photograph sideways had to leave Bloom, rotate the file in another program, and
put it back.
Fix
picture rotates as a box. A background picture fills its page area and cannot rotate as a box,
so the picture inside it rotates and its area is reshaped to match. The result is upright, at
the same framing, with any crop kept, and a picture set to fill the page still fills it.
Neither path acts on an empty placeholder.
and its box are rotated by, so flipping and then rotating gives the same result as rotating
and then flipping.
edge, snapping to every 45 degrees within 14 degrees of one, with CTRL to turn snapping off.
Past 135 degrees the knob moves to the item's other edge so it stays clear of the control
panel. Items whose outline comicaljs draws (speech bubbles, captions, rectangles, ellipses) and
videos get no handle. Navigation buttons and book link grids are never rotated: no handle, and no Rotate right.
the item's own coordinates, a click picks the right item, and a rotated item stays put across
page loads and crop drags. The control frame rotates with the item: each handle shows the
cursor for the direction it really moves, tooltips stay level, and the crop marks show the
sides that are really hidden.
Image clears the crop and the picture's rotation and mirror; it does not straighten a rotated
box. A new picture, chosen or pasted, arrives upright and uncropped, and a duplicate keeps
its original's angle. The picture menu is regrouped, Escape now closes the
canvas element menu, and a click in the Flip submenu closes it.
cropped to what the page shows, for BloomPUB, ePUB, upload and spreadsheet export, so readers
see what the author saw. The AI Image Editor gets the same upright view. An item rotated with
the handle keeps its rotation in the published HTML.
rotated or not).
Every angle and mirror lives in the item's own inline
transform, saved in the book HTML.Ref: https://issues.bloomlibrary.org/youtrack/issue/BL-16741
Devin review
This change is