Skip to content

Conversation

@divyanshu-patil
Copy link

@divyanshu-patil divyanshu-patil commented Nov 20, 2025

will update description upon completion

Proposed changes

Issue(s)

#6780

How to test or reproduce

Screenshots

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • Improvement (non-breaking change which improves a current function)
  • New feature (non-breaking change which adds functionality)
  • Documentation update (if none of the other choices apply)

Checklist

  • I have read the CONTRIBUTING doc
  • I have signed the CLA
  • Lint and unit tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works (if applicable)
  • I have added necessary documentation (if applicable)
  • Any dependent changes have been merged and published in downstream modules

Further comments

Summary by CodeRabbit

  • New Features

    • Auto-bullet insertion now automatically adds bullet points when pressing enter, supporting numbered and hyphenated formats for better message composition
  • Bug Fixes

    • Improved input handling to remove excess leading and trailing whitespace from messages before processing and sending
  • Documentation

    • Added parameter documentation for enhanced code clarity

✏️ Tip: You can customize this high-level summary in your review settings.

@divyanshu-patil divyanshu-patil marked this pull request as draft November 20, 2025 19:00
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 20, 2025

Walkthrough

The changes introduce text trimming in MessageComposer to strip leading/trailing whitespace from input, add auto-bullet formatting functionality in ComposerInput with state management via inputValue, and document the TSetInput interface. Three files modified across the message composition flow.

Changes

Cohort / File(s) Summary
Text trimming
app/containers/MessageComposer/MessageComposer.tsx
Added .trim() to getTextAndClear() result to remove leading/trailing whitespace from composed text before downstream processing (edit, quote, slash-command, message send).
Auto-bullet & state management
app/containers/MessageComposer/components/ComposerInput.tsx
Introduced inputValue state to track TextInput value; added handleAutoBullet function for auto-inserting bullet/numbered lines on newline; updated onChangeText to compute text via handleAutoBullet, update state, and sync with native TextInput.
Documentation
app/containers/MessageComposer/interfaces.ts
Added JSDoc comment block documenting TSetInput type parameters (text, selection, forceUpdateDraftMessage) and their behavior.

Sequence Diagram

sequenceDiagram
    participant User
    participant ComposerInput
    participant handleAutoBullet
    participant MessageComposer
    participant Backend

    User->>ComposerInput: Type text + press Enter
    ComposerInput->>ComposerInput: onChangeText triggered
    ComposerInput->>handleAutoBullet: newText passed
    handleAutoBullet->>handleAutoBullet: Detect previous line type<br/>(numbered/hyphen/none)
    handleAutoBullet->>handleAutoBullet: Auto-insert bullet if applicable
    handleAutoBullet-->>ComposerInput: Return formatted text
    ComposerInput->>ComposerInput: setInput(newText)<br/>setInputValue(newText)
    ComposerInput->>ComposerInput: Update TextInput value
    ComposerInput->>MessageComposer: Pass final text
    MessageComposer->>MessageComposer: Apply .trim()
    MessageComposer->>Backend: Send trimmed message
    Backend-->>User: Message delivered
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–25 minutes

Areas requiring extra attention:

  • Auto-bullet logic in handleAutoBullet(): Verify detection of previous line type (numbered vs. hyphen) and bullet insertion correctness across edge cases (empty lines, mixed formats)
  • State synchronization: Ensure inputValue state stays in sync with internal text refs and native TextInput across all input paths
  • Trim placement: Confirm .trim() in MessageComposer doesn't inadvertently strip intentional whitespace needed for special formats (slash commands, quotes)
  • Debounce interaction: Review interaction between debounced updates and state changes to prevent race conditions or stale state

Poem

A rabbit types with joy and care,
Auto-bullets sprouting there!
Trimmed of whitespace, clean and bright,
Each message formatted just right.
🐰✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'improved bullets functionality in message composer' accurately reflects the main change: adding auto-bullet functionality to the MessageComposer component as evidenced by the handleAutoBullet function addition and related text handling logic.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3532447 and 92b599a.

📒 Files selected for processing (3)
  • app/containers/MessageComposer/MessageComposer.tsx (1 hunks)
  • app/containers/MessageComposer/components/ComposerInput.tsx (5 hunks)
  • app/containers/MessageComposer/interfaces.ts (1 hunks)
🔇 Additional comments (5)
app/containers/MessageComposer/interfaces.ts (1)

20-25: LGTM! Clear documentation added.

The JSDoc comment effectively documents the TSetInput parameters and their behavior, improving code maintainability.

app/containers/MessageComposer/components/ComposerInput.tsx (3)

171-192: Verify the removal of trim logic.

The commented line 172 shows that previously text.trim() was applied conditionally. Now, setInput uses raw text without trimming. While trimming is now performed in MessageComposer.tsx (line 94) before sending, ensure that intermediate text states (drafts, autocomplete, etc.) work correctly with leading/trailing whitespace.


231-236: LGTM! Auto-bullet integration looks correct.

The onChangeText handler properly integrates the handleAutoBullet function and maintains consistency across textRef, debounced callback, and setInput.


403-403: Controlled TextInput now properly bound to state.

The TextInput is now correctly controlled via value={inputValue}, which synchronizes with the internal state management.

app/containers/MessageComposer/MessageComposer.tsx (1)

94-94: No issues found—trim is safe and verified.

The .trim() on line 94 is intentional and correct. Edit action tests explicitly expect trimmed text (expect(editRequest).toHaveBeenCalledWith({ id, msg: 'Message messageId', rid: 'rid' })), confirming this is the expected behavior. For quote actions, passing trimmed text to prepareQuoteMessage is appropriate and prevents sending unnecessary whitespace. The centralized trim at line 94 is cleaner than the previous scattered trim calls and aligns with how slash commands are handled (line 115).


export const ComposerInput = memo(
forwardRef<IComposerInput, IComposerInputProps>(({ inputRef }, ref) => {
const [inputValue, setInputValue] = useState('');
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

Verify the controlled input behavior.

Converting the TextInput from uncontrolled to controlled by introducing the inputValue state is a significant change. Ensure that this doesn't introduce issues with cursor positioning, text selection, or input performance, especially for longer messages.

Run the following script to check if there are any related issues or tests that might be affected:


🏁 Script executed:

#!/bin/bash
# Description: Search for tests or usage patterns related to ComposerInput text handling

# Search for test files related to ComposerInput
fd -e test.tsx -e test.ts -e spec.tsx -e spec.ts | xargs rg -l "ComposerInput" -C 2

# Search for places where inputRef is used with setNativeProps
rg -n "inputRef.*setNativeProps" -A 3 -B 3

# Search for potential issues with controlled inputs
rg -n "value=\{.*\}" app/containers/MessageComposer -A 2 -B 2

Length of output: 4333


is NOT appropriate here as we need repository files


---

🏁 Script executed:

```shell
#!/bin/bash
# Get the full context of setInput function and surrounding code
sed -n '171,200p' app/containers/MessageComposer/components/ComposerInput.tsx

# Find all setInputValue calls in the file
rg -n "setInputValue" app/containers/MessageComposer/components/ComposerInput.tsx -B 2 -A 2

# Find all setNativeProps calls in the file
rg -n "setNativeProps" app/containers/MessageComposer/components/ComposerInput.tsx -B 3 -A 3

Length of output: 302


🏁 Script executed:

#!/bin/bash
# Find the actual file
fd "ComposerInput.tsx" -type f

# Get content using find + cat
fd "ComposerInput.tsx" -type f -exec cat {} \;

Length of output: 341


🏁 Script executed:

#!/bin/bash
# Find the file with correct fd syntax
fd "ComposerInput.tsx"

# List files to see structure
find . -name "ComposerInput.tsx" 2>/dev/null

# Try to get lines around setNativeProps and value binding
rg -n "setNativeProps|value=\{inputValue" --no-heading -C 10

Length of output: 8444


Remove setNativeProps call when using controlled input with state.

The conversion to controlled input (via inputValue state on line 403) conflicts with the direct native manipulation via setNativeProps on line 182. This mixed pattern creates inconsistency between React state and native layer, causing the exact issues mentioned: cursor positioning, text selection, and performance problems.

In a controlled input, React state is the single source of truth. Remove the setNativeProps call on line 182 and rely solely on the state-driven value binding.

🤖 Prompt for AI Agents
In app/containers/MessageComposer/components/ComposerInput.tsx around line 50
(inputValue state) and line 182 (setNativeProps call) — you have a controlled
input via inputValue but are also calling setNativeProps directly; remove the
setNativeProps call at line 182 so React state is the single source of truth.
Ensure the TextInput's value prop is bound to inputValue and onChangeText/update
handlers update setInputValue; remove any direct native ref manipulation related
to text content or cursor positioning, and if selection must be controlled
manage selection via state and props rather than setNativeProps.

Comment on lines +202 to +229
const handleAutoBullet = useCallback((text: string, prevText: string): string => {
if (text.endsWith('\n')) {
const lines = text.split('\n');

// check for deletion
if (text.length < prevText.length) {
return text;
}
const prevLine = lines[lines.length - 2];
console.log('prevline', prevLine);

const regex = /^((?:\d+\.|-\s)).*/;

if (prevLine && regex.test(prevLine)) {
if (prevLine.startsWith('- ')) {
const newText = `${text}- `;
console.log('new text', newText);
return newText;
}
const prevNumber = parseInt(prevLine.split('.')[0], 10);
const nextNumber = prevNumber + 1;
const newText = `${text}${nextNumber}. `;
console.log('new text', newText);
return newText;
}
}
return text;
}, []);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Remove debug console.log statements and fix regex pattern.

The function has several issues:

  1. Debug logs (lines 211, 218, 224): Remove console.log statements before merging to production.
  2. Regex inconsistency (line 213): The pattern /^((?:\d+\.|-\s)).*/ captures -\s (hyphen + space) but line 216 checks for '- ' (hyphen + space). The regex should be /^(\d+\.|-\s)/ or /^(\d+\.|- )/ for consistency.
  3. Missing exit logic: The feature doesn't handle exiting the bullet list when a user presses enter on an empty bullet line (e.g., "- \n" should not add another "- "). Consider adding logic to detect empty bullet lines and stop auto-insertion.

Apply this diff to fix the regex and remove debug logs:

 const handleAutoBullet = useCallback((text: string, prevText: string): string => {
   if (text.endsWith('\n')) {
     const lines = text.split('\n');
 
     // check for deletion
     if (text.length < prevText.length) {
       return text;
     }
     const prevLine = lines[lines.length - 2];
-    console.log('prevline', prevLine);
 
-    const regex = /^((?:\d+\.|-\s)).*/;
+    const regex = /^(\d+\.|-)(\s)/;
 
     if (prevLine && regex.test(prevLine)) {
       if (prevLine.startsWith('- ')) {
+        // Don't add bullet if previous line is empty bullet
+        if (prevLine.trim() === '-') {
+          return text.slice(0, -1); // Remove the newline, exit bullet mode
+        }
         const newText = `${text}- `;
-        console.log('new text', newText);
         return newText;
       }
       const prevNumber = parseInt(prevLine.split('.')[0], 10);
       const nextNumber = prevNumber + 1;
       const newText = `${text}${nextNumber}. `;
-      console.log('new text', newText);
       return newText;
     }
   }
   return text;
 }, []);

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In app/containers/MessageComposer/components/ComposerInput.tsx around lines 202
to 229, remove all debug console.log statements and fix the regex and exit
logic: replace the regex with a consistent pattern like /^(\d+\.|- )/ (or
/^(\d+\.|- )/), remove console.log calls at lines ~211, ~218, ~224, and add
handling to detect empty bullet lines (e.g., if prevLine matches /^- $/ or
/^\d+\. $/ or prevLine.trim() === '-' then do not auto-insert another bullet and
return text unchanged) so pressing Enter on an empty bullet line exits the list;
keep the existing numeric increment logic otherwise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant