feat: add multicursor ColorPicker support#4153
Conversation
- Remove multicursor disallow restriction from textColor command - Add multicursor support to formatSelection action for foreColor/backColor - Apply color to all selected thoughts programmatically using a temporary hidden contenteditable element for execCommand - Extract background color cleanup into reusable stripBackgroundColor function - Add Puppeteer tests for multicursor text and background color application Agent-Logs-Url: https://github.com/cybersemics/em/sessions/1c53158e-9c08-4cae-9789-44b7bb36197e Co-authored-by: raineorshine <750276+raineorshine@users.noreply.github.com>
- Simplify shouldRemoveStyle by eliminating redundant isSameColor variable - Refactor Puppeteer tests to use keyboard navigation (ArrowUp) instead of [data-editable] selector, using only aria-label and data-testid selectors Agent-Logs-Url: https://github.com/cybersemics/em/sessions/1c53158e-9c08-4cae-9789-44b7bb36197e Co-authored-by: raineorshine <750276+raineorshine@users.noreply.github.com>
The cursor thought is not automatically added to state.multicursors on clickThought. By using multiselectThoughts with an array of both thoughts, both are explicitly added to the multicursor set via Ctrl+click, ensuring the color application covers the cursor thought as well. Agent-Logs-Url: https://github.com/cybersemics/em/sessions/1c53158e-9c08-4cae-9789-44b7bb36197e Co-authored-by: raineorshine <750276+raineorshine@users.noreply.github.com>
| const paths = Object.values(state.multicursors) | ||
| const colorValue = color ? colors[color] : '' | ||
|
|
||
| paths.forEach(path => { |
There was a problem hiding this comment.
Do not use .forEach to dispatch actions. Use .map and dispatch the array.
There was a problem hiding this comment.
Fixed in 687ff59 — replaced forEach with a single dispatch(paths.flatMap(...)) call.
| if (!pathThought) return | ||
| const oldValue = pathThought.value | ||
|
|
||
| let newValue: string |
There was a problem hiding this comment.
Prefer a ternary over let + if/else.
There was a problem hiding this comment.
Fixed in 687ff59 — replaced let newValue + if/else with a ternary.
Agent-Logs-Url: https://github.com/cybersemics/em/sessions/ede73d65-d8a2-47c6-90df-1ce5ebafb881 Co-authored-by: raineorshine <750276+raineorshine@users.noreply.github.com>
| const colorValue = color ? colors[color] : '' | ||
|
|
||
| dispatch( | ||
| paths.flatMap(path => { |
There was a problem hiding this comment.
Use .map, not .flatMap, and return null instead of [].
There was a problem hiding this comment.
Fixed in 65f40dd — switched to .map returning null instead of .flatMap returning [].
Agent-Logs-Url: https://github.com/cybersemics/em/sessions/894258b7-9122-46f2-a603-b51151333023 Co-authored-by: raineorshine <750276+raineorshine@users.noreply.github.com>
|
@copilot The puppeteer tests are failing. Use the test-diagnosis and ci-monitor skills to troubleshoot and fix. |
Agent-Logs-Url: https://github.com/cybersemics/em/sessions/57d19d4d-40cc-4d18-b5cb-e7e5f0635b09 Co-authored-by: raineorshine <750276+raineorshine@users.noreply.github.com>
Investigated the failure: |
Issue A: [Mobile] Text Color button is not showing the Color Picker when Command Center is on screen on mobileStep to Reproduce
Current behaviorColor Picker is not expanded. Issue.A.Mobile.Text.Color.button.is.not.showing.the.Color.Picker.when.Command.Center.is.on.screen.on.mobile.MP4Expected behaviorColor Picker should be expanded |
|
@copilot Use the Worker Bee agent to fix the three issues above. |
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
@copilot Fix Issue A, Issue B, and Issue C with Worker Bee agent. Reference: #4153 (review) |
…logic) Co-authored-by: raineorshine <750276+raineorshine@users.noreply.github.com>
Co-authored-by: raineorshine <750276+raineorshine@users.noreply.github.com>
Fixed in
Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
@copilot Issue A is still not fixed. It is not an issue on desktop. Troubleshoot and fix with the Worker Bee agent. Use emulation APIs with the Chrome DevTools MCP server to reproduce mobile conditions:
Either do this before the page is loaded, or do a refresh after emulation is enabled. em can't switch from desktop to mobile mode after it has loaded. |
…e A) Agent-Logs-Url: https://github.com/cybersemics/em/sessions/abb3af74-76bf-4e69-949a-c463e9a2426f Co-authored-by: raineorshine <750276+raineorshine@users.noreply.github.com>
Fixed in Root cause: Fix: Added checks for all toolbar dropdown states to the middleware's condition: } else if (
numMulticursors > 0 &&
!state.showCommandCenter &&
!state.showColorPicker &&
!state.showLetterCase &&
!state.showSortPicker &&
!state.showUndoSlider
) {
dispatch(toggleDropdown({ dropDownType: 'commandCenter', value: true }))
}When a toolbar dropdown is open, the Command Center stays closed. When the dropdown is dismissed (all dropdowns false), the middleware correctly re-opens the Command Center. |
|
@copilot The Command Center should not close when the dropdown opens. They should both be able to be open at the same time. |
Agent-Logs-Url: https://github.com/cybersemics/em/sessions/df7194fd-b944-4aea-b242-d46afebe7079 Co-authored-by: raineorshine <750276+raineorshine@users.noreply.github.com>
Fixed in
The workaround previously added to |



textColorcommand to allow multicursor (setmulticursor: false)formatSelectionaction (apply color to all selected thoughts)shouldRemoveStyle/collectTagsWithoutAttributes/removeTagshelpers into module-level functionsstripBackgroundColorutility for reuse between multicursor and single-cursor pathsapplyColorToHtmlhelper using a temporary hidden contenteditable for execCommand