feature: Implement Download Caching for Chat Attachments
Maintainers usually reply within 1 day
@JASIM0021 is already working on this.
Since Nov 19, 2025.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 35/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Stale
- Tech stack
- react-native, typescript
- Domain
- mobile
Research direction
Locate the fileDownload entry point and read the existing getMediaCache and downloadMediaFile implementations, then trace how chat attachments invoke downloads. Done means a previously downloaded attachment is served from local cache on later access while uncached attachments still download normally; verify the behavior through the existing attachment flow.
Written by the indexing model from the issue text.
Description
Feature Description
- Implement a caching system for chat attachment downloads that stores files locally after first download, allowing subsequent access to use cached versions instead of re-downloading. This will significantly improve user experience by reducing download times, saving data usage, and eliminating redundant downloads for the same file.
poc:-
https://github.com/user-attachments/assets/4e5d2f2e-fc7c-404a-96ac-92db54558df4
Motivation and Use Case
Current Problem:
- Users must wait for full download every time they access an attachment (PDF, images, documents, etc.)
- Multiple downloads occur for the same file if accessed multiple times
- Unnecessary data usage and battery drain
- Poor user experience with slow file access in chat
Use Cases:
- Frequent Reference: Users accessing the same important documents multiple times during a work session
- Offline Access: Users wanting to quickly access previously viewed files without internet
- Data Conservation: Users on limited data plans wanting to avoid repeated downloads
- Quick Review: Users rapidly switching between different attachments in a conversation
Implementation Ideas
Based on the current implementation provided:
export const fileDownload = async ( url: string, attachment?: IAttachment, fileName?: string ): Promise<string> => { let path = ${FileSystem.documentDirectory}; if (fileName) { path = ${path}${sanitizeFileName(fileName)}; } if (attachment?.title) { path = ${path}${sanitizeFileName(attachment.title)}`;
}
// Check if file exists in cache first using existing cache system
const cache = await getMediaCache({
type: 'other' as const,
mimeType: attachment?.format,
urlToCache: url
});
if (cache?.exists) {
return cache.uri; // Return cached file URI if exists
}
// Create download options for media file
const option = {
messageId: url,
type: 'other' as const,
downloadUrl: url
};
// Download file if not cached
const uri = await downloadMediaFile(option);
return uri;
};`
profile
Qwen3-Coder
12:47 am
Feature Request: Implement Download Caching for Chat Attachments
Feature Description
Implement a caching system for chat attachment downloads that stores files locally after first download, allowing subsequent access to use cached versions instead of re-downloading. This will significantly improve user experience by reducing download times, saving data usage, and eliminating redundant downloads for the same file.
Motivation and Use Case
Current Problem:
Users must wait for full download every time they access an attachment (PDF, images, documents, etc.)
Multiple downloads occur for the same file if accessed multiple times
Unnecessary data usage and battery drain
Poor user experience with slow file access in chat
Use Cases:
Frequent Reference: Users accessing the same important documents multiple times during a work session
Offline Access: Users wanting to quickly access previously viewed files without internet
Data Conservation: Users on limited data plans wanting to avoid repeated downloads
Quick Review: Users rapidly switching between different attachments in a conversation
Implementation Ideas
Based on the current implementation provided:
export const fileDownload = async (
url: string,
attachment?: IAttachment,
fileName?: string
): Promise<string> => {
let path = `${FileSystem.documentDirectory}`;
if (fileName) {
path = `${path}${sanitizeFileName(fileName)}`;
}
if (attachment?.title) {
path = `${path}${sanitizeFileName(attachment.title)}`;
}
// Check if file exists in cache first using existing cache system
const cache = await getMediaCache({
type: 'other' as const,
mimeType: attachment?.format,
urlToCache: url
});
if (cache?.exists) {
return cache.uri; // Return cached file URI if exists
}
// Create download options for media file
const option = {
messageId: url,
type: 'other' as const,
downloadUrl: url
};
// Download file if not cached
const uri = await downloadMediaFile(option);
return uri;
};
Key Implementation Benefits:
- Leverages existing cache system: Uses the existing getMediaCache function for consistency
- Simple cache check: Checks if file exists before initiating download
- Integrates with existing download logic: Uses downloadMediaFile for actual download
- Maintains backward compatibility: Works with existing attachment handling
- Efficient: Only downloads when necessary, returns cached version otherwise
Is this feature available in the API or web version?
Available in API
Rocket.Chat Server Version
NA
Rocket.Chat App Version
4.66.0
Device Name
POCO M2 Pro
OS Version
Android
Additional Context
This feature will particularly benefit users who:
- Work with document-heavy conversations
- Have limited internet connectivity
- Need quick access to frequently referenced files
- Want to conserve mobile data usage
- Dominant language
- TypeScript
- Stars
- 2.4k
- Forks
- 1.5k
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 29
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from RocketChat/Rocket.Chat.ReactNative
-
[IMPROVEMENT] Remove redundant `await` on synchronous `userPreferences.getBool` in `getUsersPresence`Possibly taken A pull request linked to this issue is open or already merged. Opentype: feature
Difficulty 1/5 Under an hour Newbie friendliness 92/100
RocketChat/Rocket.Chat.ReactNative#7737 ·
Maintainers usually reply within 1 day
-
UIKit modal: a viewSubmit response with no `type` field fails to close the modal on mobile (regression from #7057)Possibly taken @erikurt9 claimed this 106 days ago. Opentype: bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
RocketChat/Rocket.Chat.ReactNative#7503 · 3 comments · 1 reaction ·
Maintainers usually reply within 1 day
-
type: bug
Difficulty 1/5 Under an hour Newbie friendliness 86/100
RocketChat/Rocket.Chat.ReactNative#7437 · 1 comment · 1 reaction ·
Maintainers usually reply within 1 day
-
✅ tests 👷 ci type: feature
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
RocketChat/Rocket.Chat.ReactNative#7247 · 1 comment ·
Maintainers usually reply within 1 day
-
bug: goRoom navigates to broken RoomView after failed DM creation from searchPossibly taken @deepak0x claimed this 215 days ago. Opentype: bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
RocketChat/Rocket.Chat.ReactNative#7098 ·
Maintainers usually reply within 1 day
All issues in RocketChat/Rocket.Chat.ReactNative
Similar issues
-
bug
Difficulty 2/5 Half a day Newbie friendliness 68/100
amosblomqvist/learnharness#758 ·
Maintainers usually reply within 2 days
-
Change WorkspacesOpen
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
bitfocus/companion-module-renewedvision-propresenter-api#134 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
rcpch/digital-growth-charts-react-component-library#304 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
dsh-market/dsh-market#1210 · 1 comment ·
Maintainers usually reply within 1 day
-
good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
trustjonathan/STUDY-HUB#13 ·