Skip to content

chore: replace react-native-file-viewer with @magrinj/expo-quick-look#7486

Open
diegolmello wants to merge 1 commit into
chore/rn-0.83-expo-55from
chore/deinterop-file-viewer
Open

chore: replace react-native-file-viewer with @magrinj/expo-quick-look#7486
diegolmello wants to merge 1 commit into
chore/rn-0.83-expo-55from
chore/deinterop-file-viewer

Conversation

@diegolmello

@diegolmello diegolmello commented Jul 10, 2026

Copy link
Copy Markdown
Member

Proposed changes

react-native-file-viewer is a dead (last published 2022) legacy native module with no codegenConfig. On React Native's New Architecture it runs only via the default-on interop layer, so it is first in line to break on a future RN bump and has no upstream TurboModule/Fabric path.

This replaces it with @magrinj/expo-quick-look (Expo modules API, new + old arch): iOS QLPreviewController, Android ACTION_VIEW intent chooser — a 1:1 match for the previous behavior with a single cross-platform API.

The module has exactly one call site: fileDownloadAndPreview in app/lib/methods/helpers/fileDownload.ts (reached from a message Reply's generic type === 'file' attachments). FileViewer.open(file, { showOpenWithDialog, showAppsSuggestions }) becomes ExpoQuickLook.previewFile({ uri: file }). The jest mock is updated accordingly.

Issue(s)

Part of the RN 0.83 / Expo 55 upgrade — getting risky modules off the New-Arch interop layer. NATIVE-1234

How to test or reproduce

  1. Open a channel that has a non-media file attachment (PDF, docx, zip, etc.).
  2. Tap the attachment in the message.
  3. The file downloads (and decrypts if E2E) and opens in the system previewer — QuickLook on iOS, the app chooser on Android.

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

Bumping react-native-file-viewer was not an option — its latest release (2.1.5) is also legacy-only, with no new-arch path. @magrinj/expo-quick-look is niche; pinned to an exact version. Fallback if it proves unfit: expo-intent-launcher (Android) + a thin iOS QuickLook shim (per-platform split).

Summary by CodeRabbit

  • Enhancements
    • Updated file previews to use the device’s native Quick Look experience.
    • Improved compatibility when opening downloaded or locally stored files.

react-native-file-viewer is a dead (2022) legacy native module with no
codegenConfig, running only via the New-Arch interop layer. Replace it
with @magrinj/expo-quick-look (Expo modules API, new + old arch): iOS
QLPreviewController + Android ACTION_VIEW chooser, one API both platforms.

Single call site (fileDownloadAndPreview) swapped to previewFile({ uri }).
@diegolmello diegolmello temporarily deployed to approve_e2e_testing July 10, 2026 19:13 — with GitHub Actions Inactive
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8d913645-7a4f-46cc-8257-904cb1cae94d

📥 Commits

Reviewing files that changed from the base of the PR and between a32e82a and cf89654.

⛔ Files ignored due to path filters (2)
  • ios/Podfile.lock is excluded by !**/*.lock
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • app/lib/methods/helpers/fileDownload.ts
  • jest.setup.js
  • package.json
📜 Recent review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: CodeRabbit / Review
  • GitHub Check: ESLint and Test / run-eslint-and-test
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{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/lib/methods/helpers/fileDownload.ts
  • jest.setup.js
**/*.{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 numbers

**/*.{ts,tsx}: Use TypeScript in strict mode, with imports resolved from the app/ baseUrl
Follow the repository's TypeScript/React Native code style enforced by Prettier: tabs, single quotes, 130-character width, no trailing commas, omit arrow-function parens when possible, and keep brackets on the same line

Files:

  • app/lib/methods/helpers/fileDownload.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use the project's ESLint setup (@rocket.chat/eslint-config with React, React Native, TypeScript, and Jest plugins) for code quality and style compliance

Files:

  • app/lib/methods/helpers/fileDownload.ts
  • jest.setup.js
🧠 Learnings (4)
📚 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/lib/methods/helpers/fileDownload.ts
📚 Learning: 2026-03-30T15:49:26.708Z
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6875
File: app/containers/RoomItem/Actions.tsx:12-12
Timestamp: 2026-03-30T15:49:26.708Z
Learning: In Rocket.Chat.ReactNative, do not rely on `react-native-worklets` v0.6.1 exporting a built-in Jest mock (e.g., `react-native-worklets/lib/module/mock` does not exist for this version). Instead, add the Jest manual mock in your repo’s `jest.setup.js`/`jest.setup.ts`, mocking `react-native-worklets` to provide `scheduleOnRN: jest.fn((fn, ...args) => fn(...args))`. This ensures Jest can import the module and that `scheduleOnRN` executes the passed function during tests.

Applied to files:

  • jest.setup.js
📚 Learning: 2026-02-05T13:55:00.974Z
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6930
File: package.json:101-101
Timestamp: 2026-02-05T13:55:00.974Z
Learning: In this repository, the dependency on react-native-image-crop-picker should reference the RocketChat fork (RocketChat/react-native-image-crop-picker) with explicit commit pins, not the upstream ivpusic/react-native-image-crop-picker. Update package.json dependencies (and any lockfile) to point to the fork URL and a specific commit, ensuring edge-to-edge Android fixes are included. This pattern should apply to all package.json files in the repo that declare this dependency.

Applied to files:

  • package.json
📚 Learning: 2026-05-07T17:47:14.516Z
Learnt from: diegolmello
Repo: RocketChat/Rocket.Chat.ReactNative PR: 7303
File: package.json:5-5
Timestamp: 2026-05-07T17:47:14.516Z
Learning: When reviewing pnpm `packageManager` version pins in any `package.json` (e.g., `"packageManager": "pnpm@<version>"`), don’t rely solely on web-search results to determine whether a version exists. For very recently published versions, cross-check the target version against the official pnpm release page (https://github.com/pnpm/pnpm/releases) and the npm registry page for pnpm (https://www.npmjs.com/package/pnpm) before flagging the pinned version as non-existent.

Applied to files:

  • package.json
🔇 Additional comments (3)
package.json (1)

31-31: No remaining references to react-native-file-viewer found.

app/lib/methods/helpers/fileDownload.ts (1)

2-2: previewFile is available on the default export
@magrinj/expo-quick-look exports ExpoQuickLookModule as its default export, and it includes previewFile(options: PreviewFileOptions): Promise<void> with uri: string in the options shape.

jest.setup.js (1)

53-54: No change needed for the Expo Quick Look mock. The CommonJS-style factory still works with import ExpoQuickLook from '@magrinj/expo-quick-look', matching the existing react-native-file-viewer mock.

			> Likely an incorrect or invalid review comment.

Walkthrough

The file download helper now uses @magrinj/expo-quick-look to preview files. Jest mocks and package dependencies were updated to replace react-native-file-viewer.

Changes

File preview provider

Layer / File(s) Summary
Preview provider wiring
package.json, app/lib/methods/helpers/fileDownload.ts, jest.setup.js
The helper calls ExpoQuickLook.previewFile({ uri: file }); the Jest mock exposes a resolved previewFile stub; dependencies add @magrinj/expo-quick-look and remove react-native-file-viewer.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested labels: type: chore

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main change: swapping react-native-file-viewer for @magrinj/expo-quick-look.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

package.json

Parsing error: Missing semicolon. (2:7)

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • NATIVE-1234: Request failed with status code 401

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.

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.

1 participant