Skip to content

Fix/attachment width word wrapping#3256

Open
Ram-sah19 wants to merge 175 commits intoRocketChat:masterfrom
Ram-sah19:fix/attachment-width-word-wrapping
Open

Fix/attachment width word wrapping#3256
Ram-sah19 wants to merge 175 commits intoRocketChat:masterfrom
Ram-sah19:fix/attachment-width-word-wrapping

Conversation

@Ram-sah19
Copy link
Copy Markdown

@Ram-sah19 Ram-sah19 commented Mar 11, 2026

Description

Fixes #3113

Text format attachments were hardcoded to a fixed 360px width, causing poor word wrapping and formatting issues for webhook messages (e.g. Grafana alerts). This prevented long URLs and formatted text from using the full available horizontal space.

Changes Made

  • Removed the hardcoded 360px width constraint on text format attachments
  • Updated the attachment container to use 100% of available horizontal space

Type of Change

  • Bug fix

How to Test

  1. Send a text format attachment via webhook (e.g. a Grafana alert)
  2. Open the message in the Desktop app
  3. Confirm the attachment text uses the full available width before wrapping
  4. Confirm long URLs and formatted text display correctly

Screenshots

Related Issue

Closes #3113

Summary by CodeRabbit

  • New Features

    • Added crash recovery system with automatic cache clearing after consecutive crashes.
    • Added external link opening support via system protocols.
  • Bug Fixes

    • Text notifications now trigger window attention indicator (previously voice-only).
    • Enhanced notification dismissal handling.
  • Localization

    • Updated Hungarian translations; removed obsolete menu and settings strings.
  • Chores

    • Updated Electron and build tool dependencies.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 11, 2026

Walkthrough

This PR downgrades Electron from 40.0.0 to ~34.0.2 and electron-builder from 26.0.3 to 25.1.8, removes build configuration hooks and snapcraft parameters, cleans up internationalization files, injects custom CSS to override attachment width constraints, adds external URL handling via IPC, enhances notification attention flashing, and implements renderer process crash recovery with cache clearing.

Changes

Cohort / File(s) Summary
Build Configuration
.github/workflows/build-release.yml, electron-builder.json
Removed snapcraft_token parameter and afterPack hook reference from build configurations.
Dependency Versions
package.json
Downgraded Electron to ~34.0.2 and electron-builder to 25.1.8.
Internationalization
src/i18n/de-DE.i18n.json, src/i18n/fr.i18n.json, src/i18n/hu.i18n.json, src/i18n/ru.i18n.json
Fixed end-of-file newlines across German, French, Russian locales. Removed translation keys from Hungarian (menu items and sidebar entries) and shortened description for videoCallWindowPersistence.
Attachment Display
src/injected.ts
Added custom CSS to override attachment width constraints. Replaced setInterval polling with self-rescheduling function for feature readiness detection based on setupFlags and version conditions. Removed themeAppearance from setup flags.
External Link Handling
src/main.ts
Added IPC handler for open-external channel that validates URLs, checks protocol allowance, and opens http/https links via openExternal or other schemes via shell.openExternal.
Notification Attention
src/notifications/main.ts
Extended attention flashing to trigger for both text and voice notifications. Simplified dismiss handler to stop attention unconditionally for all notification types.
Crash Recovery
src/ui/main/rootWindow.ts
Introduced renderer process crash handling with crash counter and recovery logic; clears cache and specific storage after 3+ consecutive crashes before reloading window.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Suggested labels

type: bug

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Multiple unrelated changes are present: downgraded Electron (40.0.0→34.0.2) and electron-builder (26.0.3→25.1.8), removed snapcraft_token, modified notification flashing behavior, added crash recovery logic, and added external link handling via IPC. These appear outside the scope of fixing attachment width. Isolate the attachment width fix into a focused PR. Move version downgrades, snapcraft changes, notification behavior, crash handling, and IPC changes to separate PRs with documented justification for each change.
Linked Issues check ❓ Inconclusive The PR includes CSS injection to override attachment width in src/injected.ts (custom CSS for width constraints), IPC handler for external links, crash recovery, and notification improvements. However, the core requirement from issue #3113 to remove the fixed 360px width constraint and use 100% available space is not directly visible in the provided file summaries as a standalone CSS or styling change. Verify that the CSS override in src/injected.ts directly addresses the 360px width constraint removal and confirms the attachment container is set to 100% width as required by issue #3113.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Fix/attachment width word wrapping' directly addresses the main objective of fixing attachment width and word wrapping issues for text-format attachments, matching the core bug fix purpose.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ 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.

❤️ Share

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

Copy link
Copy Markdown
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.

🧹 Nitpick comments (1)
src/ui/main/rootWindow.ts (1)

521-561: Good crash recovery implementation with escalating strategy.

The crash handler appropriately:

  • Prevents duplicate listener registration
  • Uses escalating recovery (clear cache after 3+ failures)
  • Resets counter on successful load

One consideration: there's no upper bound on crash attempts. If a persistent issue causes repeated crashes, this could loop indefinitely. Consider adding a maximum attempt threshold (e.g., after 10 crashes, show an error dialog and stop retrying).

💡 Optional: Add maximum crash recovery attempts
 browserWindow.webContents.on(
   'render-process-gone',
   async (_event, details) => {
     console.error('Renderer process crashed:', details.reason);
     consecutiveCrashCount++;
+    
+    const MAX_RECOVERY_ATTEMPTS = 10;
+    if (consecutiveCrashCount > MAX_RECOVERY_ATTEMPTS) {
+      console.error('Maximum recovery attempts reached. Manual intervention required.');
+      return;
+    }
+    
     console.log(
       `Crash count: ${consecutiveCrashCount}. Attempting recovery...`
     );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/ui/main/rootWindow.ts` around lines 521 - 561, Add a maximum
crash-recovery threshold to prevent infinite retry loops: introduce a constant
like MAX_CRASH_ATTEMPTS (e.g., 10) and, inside the render-process-gone handler
where consecutiveCrashCount is incremented, check if consecutiveCrashCount >=
MAX_CRASH_ATTEMPTS and if so stop further recovery attempts (e.g., do not clear
cache/reload), remove or ignore the crash handler (using crashHandlerRegistered
or removeListener on browserWindow.webContents), and surface a user-visible
error (e.g., show an error dialog) explaining that automatic recovery has been
disabled; keep the existing reset logic in did-finish-load to resume normal
behavior if the page loads successfully.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/ui/main/rootWindow.ts`:
- Around line 521-561: Add a maximum crash-recovery threshold to prevent
infinite retry loops: introduce a constant like MAX_CRASH_ATTEMPTS (e.g., 10)
and, inside the render-process-gone handler where consecutiveCrashCount is
incremented, check if consecutiveCrashCount >= MAX_CRASH_ATTEMPTS and if so stop
further recovery attempts (e.g., do not clear cache/reload), remove or ignore
the crash handler (using crashHandlerRegistered or removeListener on
browserWindow.webContents), and surface a user-visible error (e.g., show an
error dialog) explaining that automatic recovery has been disabled; keep the
existing reset logic in did-finish-load to resume normal behavior if the page
loads successfully.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 284503ed-41a5-4f3b-9b7a-d427c0abe6a4

📥 Commits

Reviewing files that changed from the base of the PR and between 49261f5 and 422aba9.

⛔ Files ignored due to path filters (3)
  • package-lock.json is excluded by !**/package-lock.json
  • workspaces/desktop-release-action/dist/index.js is excluded by !**/dist/**
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (11)
  • .github/workflows/build-release.yml
  • electron-builder.json
  • package.json
  • src/i18n/de-DE.i18n.json
  • src/i18n/fr.i18n.json
  • src/i18n/hu.i18n.json
  • src/i18n/ru.i18n.json
  • src/injected.ts
  • src/main.ts
  • src/notifications/main.ts
  • src/ui/main/rootWindow.ts
💤 Files with no reviewable changes (2)
  • .github/workflows/build-release.yml
  • electron-builder.json
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript strict mode enabled in TypeScript configuration
Use React functional components with hooks instead of class components
Follow FSA (Flux Standard Action) pattern for Redux actions
Use camelCase for file names and PascalCase for component file names
All code must pass ESLint and TypeScript checks
Write self-documenting code with clear naming; avoid unnecessary comments except for complex business logic or non-obvious decisions
Use Fuselage components from @rocket.chat/fuselage for all UI work and only create custom components when Fuselage doesn't provide what's needed
Check Theme.d.ts for valid color tokens when using Fuselage components
Use defensive coding with optional chaining and fallbacks for Linux-only APIs (process.getuid(), process.getgid(), process.geteuid(), process.getegid()) to ensure cross-platform compatibility across Windows, macOS, and Linux

Files:

  • src/main.ts
  • src/injected.ts
  • src/ui/main/rootWindow.ts
  • src/notifications/main.ts
🧠 Learnings (3)
📓 Common learnings
Learnt from: Ram-sah19
Repo: RocketChat/Rocket.Chat.Electron PR: 3254
File: .github/workflows/build-release.yml:80-94
Timestamp: 2026-03-11T06:38:34.676Z
Learning: In the RocketChat/Rocket.Chat.Electron repository, the issues flagged in `.github/workflows/build-release.yml` (e.g., `node12` runtime in the release action and missing `snapcraft_token` input), i18n files, and `electron-builder.json` are pre-existing in the `develop` branch and are pulled in during merge conflict resolution. Do not flag these as new issues introduced by PRs that only modify `src/injected.ts` and `src/ui/main/rootWindow.ts`.
📚 Learning: 2026-02-04T19:29:54.650Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.Electron PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-04T19:29:54.650Z
Learning: Applies to **/*.{spec,main.spec}.ts : Use `*.spec.ts` file naming for renderer process tests and `*.main.spec.ts` for main process tests

Applied to files:

  • src/main.ts
📚 Learning: 2026-03-11T06:38:34.676Z
Learnt from: Ram-sah19
Repo: RocketChat/Rocket.Chat.Electron PR: 3254
File: .github/workflows/build-release.yml:80-94
Timestamp: 2026-03-11T06:38:34.676Z
Learning: In the RocketChat/Rocket.Chat.Electron repository, the issues flagged in `.github/workflows/build-release.yml` (e.g., `node12` runtime in the release action and missing `snapcraft_token` input), i18n files, and `electron-builder.json` are pre-existing in the `develop` branch and are pulled in during merge conflict resolution. Do not flag these as new issues introduced by PRs that only modify `src/injected.ts` and `src/ui/main/rootWindow.ts`.

Applied to files:

  • src/injected.ts
  • package.json
🪛 ESLint
src/injected.ts

[error] 206-206: Replace '[Rocket.Chat·Desktop]·Custom·CSS·injected·for·attachment·width·fix' with ⏎····'[Rocket.Chat·Desktop]·Custom·CSS·injected·for·attachment·width·fix'⏎··

(prettier/prettier)


[error] 604-606: Replace ⏎······Boolean⏎···· with Boolean

(prettier/prettier)

🔇 Additional comments (11)
src/i18n/ru.i18n.json (1)

437-437: LGTM!

End-of-file newline addition is a standard formatting improvement with no semantic changes.

src/i18n/de-DE.i18n.json (1)

435-435: LGTM!

End-of-file newline addition is a standard formatting improvement with no semantic changes.

src/i18n/fr.i18n.json (1)

434-434: LGTM!

End-of-file newline addition is a standard formatting improvement with no semantic changes.

src/main.ts (1)

148-171: Well-structured external URL handler with proper validation.

The handler correctly validates URLs, checks protocol allowlists, and routes to appropriate openers. One minor optimization opportunity:

The dynamic import of isProtocolAllowed (line 158) runs on every IPC call. Consider hoisting it to module scope or caching the import result if this handler is called frequently.

src/notifications/main.ts (2)

89-106: LGTM!

Good UX enhancement expanding attention drawing to both 'text' and 'voice' notification types. The idempotent stopAttention calls on close/dismiss are safe and ensure consistent cleanup regardless of notification type.


250-252: LGTM!

Consistent with the close handler - idempotent stopAttention ensures proper cleanup.

src/ui/main/rootWindow.ts (1)

47-48: LGTM!

Module-scoped state for crash handling is appropriately isolated.

src/injected.ts (2)

195-206: This CSS injection directly addresses the PR objective.

The approach of injecting CSS to override the hardcoded 360px width constraint on .rcx-attachment__content is appropriate for the Electron desktop client. Using !important ensures the override takes precedence over Fuselage's inline or compiled styles.

Minor: ESLint/Prettier flagged a formatting issue on line 206 - the log string could be wrapped.


592-618: Improved polling mechanism that self-terminates.

The change from setInterval to self-rescheduling setTimeout is an improvement - it stops polling once all features are initialized rather than running indefinitely. The version-based handling of backgroundSettings is a good approach for server version compatibility.

Minor: ESLint/Prettier flagged formatting on lines 604-606 where Boolean could be on the same line.

src/i18n/hu.i18n.json (2)

294-296: LGTM.

This is a safe copy-only change; the key path and translation contract stay unchanged.


395-402: LGTM.

No issue here; the sidebar.item.reloadClearingCache entry remains structurally consistent with the rest of the locale file.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Attachment width, word wrapping

5 participants