fix: insert multiline code block as a fenced block on its own lines#7424
fix: insert multiline code block as a fenced block on its own lines#7424Shevilll wants to merge 2 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (4)
WalkthroughIntroduces a ChangeswrapCodeBlock helper and composer integration
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/containers/MessageComposer/helpers/wrapCodeBlock.ts`:
- Around line 7-9: Replace all three instances of the deprecated substr() method
in the wrapCodeBlock.ts file with slice(). Change text.substr(0, start) to
text.slice(0, start) for the before variable, text.substr(start, end - start) to
text.slice(start, end) for the selected variable, and text.substr(end) to
text.slice(end) for the after variable. Note that slice() takes an end index
rather than a length parameter, so adjust the second argument accordingly (in
the selected case, the length end - start becomes the end index end).
- Around line 6-21: The wrapCodeBlock function is missing an explicit return
type annotation and the returned object shape is not defined as an interface.
Create a new interface that defines the return type structure with updatedText
as a string property and selection as an object with start and end number
properties. Then add this interface as the explicit return type annotation to
the wrapCodeBlock function signature.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 7703a01b-9b74-4ede-bdd5-d021e519aa44
📒 Files selected for processing (5)
app/containers/MessageComposer/MessageComposer.test.tsxapp/containers/MessageComposer/components/ComposerInput.tsxapp/containers/MessageComposer/helpers/index.tsapp/containers/MessageComposer/helpers/wrapCodeBlock.test.tsapp/containers/MessageComposer/helpers/wrapCodeBlock.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,ts,jsx,tsx}: Use descriptive names for functions, variables, and classes that clearly convey their purpose
Write comments that explain the 'why' behind code decisions, not the 'what'
Keep functions small and focused on a single responsibility
Use const by default, let when reassignment is needed, and avoid var
Prefer async/await over .then() chains for handling asynchronous operations
Use explicit error handling with try/catch blocks for async operations
Avoid deeply nested code; refactor complex logic into helper functions
Files:
app/containers/MessageComposer/helpers/index.tsapp/containers/MessageComposer/MessageComposer.test.tsxapp/containers/MessageComposer/helpers/wrapCodeBlock.test.tsapp/containers/MessageComposer/helpers/wrapCodeBlock.tsapp/containers/MessageComposer/components/ComposerInput.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use TypeScript for type safety; add explicit type annotations to function parameters and return types
Prefer interfaces over type aliases for defining object shapes in TypeScript
Use enums for sets of related constants rather than magic strings or numbersUse TypeScript with strict mode enabled
Files:
app/containers/MessageComposer/helpers/index.tsapp/containers/MessageComposer/MessageComposer.test.tsxapp/containers/MessageComposer/helpers/wrapCodeBlock.test.tsapp/containers/MessageComposer/helpers/wrapCodeBlock.tsapp/containers/MessageComposer/components/ComposerInput.tsx
**/*.{js,jsx,ts,tsx,json}
📄 CodeRabbit inference engine (CLAUDE.md)
Use Prettier formatting with tabs, single quotes, 130 character line width, no trailing commas, and avoid arrow function parentheses
Files:
app/containers/MessageComposer/helpers/index.tsapp/containers/MessageComposer/MessageComposer.test.tsxapp/containers/MessageComposer/helpers/wrapCodeBlock.test.tsapp/containers/MessageComposer/helpers/wrapCodeBlock.tsapp/containers/MessageComposer/components/ComposerInput.tsx
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Enforce ESLint rules from
@rocket.chat/eslint-configwith React, React Native, TypeScript, and Jest plugins
Files:
app/containers/MessageComposer/helpers/index.tsapp/containers/MessageComposer/MessageComposer.test.tsxapp/containers/MessageComposer/helpers/wrapCodeBlock.test.tsapp/containers/MessageComposer/helpers/wrapCodeBlock.tsapp/containers/MessageComposer/components/ComposerInput.tsx
app/containers/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Place reusable UI components in 'app/containers/' directory
Files:
app/containers/MessageComposer/helpers/index.tsapp/containers/MessageComposer/MessageComposer.test.tsxapp/containers/MessageComposer/helpers/wrapCodeBlock.test.tsapp/containers/MessageComposer/helpers/wrapCodeBlock.tsapp/containers/MessageComposer/components/ComposerInput.tsx
🧠 Learnings (1)
📚 Learning: 2026-04-30T17:07:51.020Z
Learnt from: diegolmello
Repo: RocketChat/Rocket.Chat.ReactNative PR: 7274
File: app/lib/services/voip/MediaCallEvents.ts:0-0
Timestamp: 2026-04-30T17:07:51.020Z
Learning: In this Rocket.Chat React Native codebase, the ESLint rule `no-void: error` is enforced. When you see a promise returned from an async call that is not awaited (a “floating promise”), do not silence it with the `void somePromise()` pattern. Instead, handle the promise explicitly by attaching `.catch(...)` (or otherwise awaiting/handling the error) so unhandled-rejection risks are addressed in a way that satisfies the existing ESLint configuration.
Applied to files:
app/containers/MessageComposer/helpers/index.tsapp/containers/MessageComposer/MessageComposer.test.tsxapp/containers/MessageComposer/helpers/wrapCodeBlock.test.tsapp/containers/MessageComposer/helpers/wrapCodeBlock.tsapp/containers/MessageComposer/components/ComposerInput.tsx
🔇 Additional comments (4)
app/containers/MessageComposer/helpers/index.ts (1)
6-6: LGTM!app/containers/MessageComposer/helpers/wrapCodeBlock.test.ts (1)
1-38: LGTM!app/containers/MessageComposer/components/ComposerInput.tsx (1)
17-17: LGTM!Also applies to: 134-138
app/containers/MessageComposer/MessageComposer.test.tsx (1)
406-406: LGTM!Also applies to: 425-425
The code-block formatting button wrapped the selection inline, but fenced code blocks are only parsed when the ``` markers are alone on a line. Tapping the button therefore produced six backticks around the cursor on a single line, which does not render as a code block. Insert the opening and closing fences on their own lines instead, adding a leading newline when the cursor is not already at the start of a line, and leave the cursor on the (possibly empty) content line between the fences. Any selected text is wrapped inside the block. The logic is extracted into a pure wrapCodeBlock helper with unit tests. Closes RocketChat#7099
763fedd to
8e1d43e
Compare
Define ISelectionRange and IWrapCodeBlockResult for the helper's return shape per the repo's TypeScript interface conventions.
|
Hi team! I've updated the |
Proposed changes
Tapping the multiline code-block formatting button produced a broken result: it wrapped the selection inline, e.g. typing nothing and tapping the button inserted six backticks with the cursor stuck in the middle of them on a single line (
```|```). Fenced code blocks are only parsed by the renderer when the```markers sit alone on their own line, so this never actually rendered as a code block and forced users to manually add line breaks.This makes the code-block button insert a proper fenced block:
```fences are placed on their own lines;So tapping the button now yields:
(with the cursor
|on the middle line), matching the behaviour requested in the issue. The other formatting buttons (bold, italic, strike, inline code) are unchanged.The insertion logic is extracted into a pure
wrapCodeBlockhelper (mirroring the existinginsertEmojiAtCursorhelper) so it can be unit-tested directly.Issue(s)
Closes #7099
How to test or reproduce
```fenced block on its own lines, with the cursor on the content line — instead of six backticks on a single line.Automated:
TZ=UTC pnpm test --testPathPattern='wrapCodeBlock|MessageComposer/MessageComposer.test'(newwrapCodeBlockunit tests + updated MessageComposer toolbar tests, 39 tests pass).pnpm lint(ESLint +tsc) passes.Types of changes
Checklist
Summary by CodeRabbit