Skip to content

feat: add editor multiline mode and many edge case fixes#476

Merged
7w1 merged 17 commits intodevfrom
feat/editor-multiline-mode
Mar 23, 2026
Merged

feat: add editor multiline mode and many edge case fixes#476
7w1 merged 17 commits intodevfrom
feat/editor-multiline-mode

Conversation

@hazre
Copy link
Member

@hazre hazre commented Mar 22, 2026

Description

Fixes #350

This adds a dynamic multiline layout to CustomEditor. When the message input grows past a single line (word wrap, explicit newlines, or multiple blocks), the editor shifts from a single-row layout into a two-row grid, before/textarea on top, with responsive content spanning the full width below. It drops back to single-row once the text fits on one line again.

The old replacementContent prop (which swapped out the textarea on mobile during voice recording) is gone. It's replaced by responsiveAfter, which renders inline next to the send button in single-line mode and moves down to the footer row in multiline mode. There's also a forceMultilineLayout prop for when you want to push into multiline immediately, which is what we use when the audio recorder opens. This means the recorder now takes the same code path on desktop and mobile instead of having a separate mobile-only branch.

A few other things got fixed along the way:

  • Holding the record button on mobile was selecting the "following the conversation" text underneath it. Fixed with userSelect: none. (related to voice message recording not possible on phone bc ui design #350)
  • The stop button's onClick was being skipped on mobile entirely, so if pointerup got lost mid-drag there was no way to stop recording. Now onClick works as a fallback when recording is already active. (a form of recovery in case more situations like voice message recording not possible on phone bc ui design #350 happen again)
  • The waveform bar count is now calculated from the actual container width via ResizeObserver instead of a hardcoded number.
  • cleanupMediaRecorder wasn't being called in all the stop/delete/restart/error/unmount paths, which could leave the mic track open. That's fixed.
  • Firefox couldn't seek voice messages because audio/webm doesn't include a seek index. Codec preference now puts audio/ogg;codecs=opus first so Firefox records seekable blobs. Also added a seekTo helper that waits for loadedmetadata if the audio element isn't ready yet, and audio.preload = 'auto' + audio.load() on mount so Firefox parses metadata right away.
  • Multiline wrap detection is now debounced through requestAnimationFrame and uses a ResizeObserver on the scroll container to cut down on flicker and extra re-renders.
  • Added cloudflared tunnels for easier testing on mobile

Also sorry for the cursed line height measurer, there was legit no other way to detect it that didn't cause other issues.

Good amount of this was created with help of AI (like figuring out options on how to fix the edge cases), especially the edge case unit tests, but It had to be fixed by hand in many places and frankly I can't tell you exactly where was what. I've been working on this for couple days now.. (losing my mind over it)

Screenshots:

Recording.2026-03-22.182018.mp4
Recording.2026-03-22.182144.mp4

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings

AI disclosure:

  • Partially AI assisted (clarify which code was AI assisted and briefly explain what it does).
  • Fully AI generated (explain what all the generated code does in moderate detail).

hazre added 16 commits March 22, 2026 14:33
Prevents mobile voice recording glitch where holding the record button
would select text from the 'following the conversation' row underneath.
When recording on mobile, if the pointerup listener was lost (e.g., dragging
off the button), there was no way to stop recording. Now the stop button's
onClick handler works on mobile when recording is active, providing a fallback.
…ecording

Prevents layout shift by rendering the recorder in the editor's main content
area instead of in the after buttons section. Uses replacementContent prop
to swap the editor with the recorder while maintaining proper padding.
@hazre hazre force-pushed the feat/editor-multiline-mode branch from 7078f73 to f22a764 Compare March 22, 2026 17:13
@hazre hazre marked this pull request as ready for review March 22, 2026 17:15
@hazre hazre requested a review from 7w1 as a code owner March 22, 2026 17:15
@hazre hazre added the ui change this pr introduces ui changes label Mar 22, 2026
@hazre hazre requested a review from dozro March 22, 2026 17:16
@dozro
Copy link
Contributor

dozro commented Mar 22, 2026

functional testing

functions well:

  • multiline editor
  • waveform

couldn't be tested rn:

  • mobile phone specific bugs regarding voice messages
  • firefox specific bugs

Copy link
Contributor

@dozro dozro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code lgtm.

could use a bit more of code documention :3

@dozro dozro assigned dozro and unassigned dozro Mar 22, 2026
@github-actions
Copy link
Contributor

Deploying with  Cloudflare Workers  Cloudflare Workers

Status Preview URL Commit Alias Updated (UTC)
✅ Deployment successful! https://pr-476-sable.raspy-dream-bb1d.workers.dev e5d5230 pr-476 Sun, 22 Mar 2026 18:21:53 GMT

@7w1 7w1 added this pull request to the merge queue Mar 23, 2026
Merged via the queue into dev with commit 4fbcfef Mar 23, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ui change this pr introduces ui changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

voice message recording not possible on phone bc ui design

3 participants