Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
180 commits
Select commit Hold shift + click to select a range
2fe2027
feat: implement store/caching attachment for native
NJ-2020 Jun 6, 2025
5907988
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Jun 6, 2025
5381d33
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Jun 7, 2025
fc2382a
implement store/caching for web and fix some issues
NJ-2020 Jun 7, 2025
79f2ad2
remove unnecessary code
NJ-2020 Jun 7, 2025
11b7669
fix eslint errors
NJ-2020 Jun 7, 2025
78aaa7b
fix: eslint errors & store file path for native
NJ-2020 Jun 8, 2025
6ba6580
fix: remove attachment when deleting comment, improvements, eslint er…
NJ-2020 Jun 8, 2025
b690613
remove unnecessary changes
NJ-2020 Jun 8, 2025
ad8e005
fix: eslint errors
NJ-2020 Jun 8, 2025
041bcbc
fix: eslint errors
NJ-2020 Jun 8, 2025
393ad06
fix: attachmentID is returning undefined
NJ-2020 Jun 8, 2025
6b23b6f
fix: remove unnecessary code
NJ-2020 Jun 8, 2025
21f59ee
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Jun 10, 2025
60ed019
add missing comments
NJ-2020 Jun 10, 2025
1e56909
revert showImagePicker changes
NJ-2020 Jun 10, 2025
efeee2b
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Jun 11, 2025
1efadb4
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Jun 12, 2025
e395df4
feat: add unit test file
NJ-2020 Jun 12, 2025
63ad3f7
fix some comments and improve the code
NJ-2020 Jun 12, 2025
70ff800
Merge remote-tracking branch 'origin' into new-feat/9402-1
NJ-2020 Jun 15, 2025
648c196
fix some comments & issues
NJ-2020 Jun 16, 2025
bf021da
remove unnecessary checks
NJ-2020 Jun 16, 2025
9dc2822
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Jun 17, 2025
7f79697
refactor buildOptimisticAddCommentReportAction to use parameter object
NJ-2020 Jun 17, 2025
8b118a1
fix: getHtmlWithAttachmentID, some issues & errors
NJ-2020 Jun 18, 2025
6324aa1
fix: eslint error
NJ-2020 Jun 18, 2025
ce31649
Merge branch 'main' into new-feat/9402-1
NJ-2020 Jun 19, 2025
22ddea1
Merge branch 'main' into new-feat/9402-1
NJ-2020 Jun 27, 2025
0b9bde7
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Jun 28, 2025
fe4a186
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Jul 2, 2025
6010787
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Jul 15, 2025
a0ec7de
fix: conflicts
NJ-2020 Jul 18, 2025
b57ce6f
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Jul 20, 2025
aa88d66
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Jul 21, 2025
667606f
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Jul 23, 2025
dc1487b
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Jul 24, 2025
7aad16a
fix get attachment return typo
NJ-2020 Jul 24, 2025
4655701
fix: remove unnecessary consoles
NJ-2020 Jul 24, 2025
1f9b280
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Jul 26, 2025
6c74c33
fix: attachment test & add missing test case
NJ-2020 Jul 26, 2025
89ee558
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Jul 28, 2025
57180af
fix getCachedAttachment for uncached attachment
NJ-2020 Jul 29, 2025
a588705
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Jul 29, 2025
89ed3ba
fix getCachedAttachment native
NJ-2020 Jul 29, 2025
ca73324
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Jul 30, 2025
5403b29
fix: migrate from Onyx.connect to useOnyx
NJ-2020 Jul 30, 2025
c9df3cd
fix attachment typo and issues
NJ-2020 Jul 30, 2025
e75db34
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Jul 31, 2025
922776f
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Aug 5, 2025
f502c26
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Aug 6, 2025
282e4d4
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Aug 7, 2025
062445b
fix: attachment test
NJ-2020 Aug 7, 2025
a2b1679
fix report action test
NJ-2020 Aug 7, 2025
0a6a928
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Aug 7, 2025
6431283
Merge branch 'main' into new-feat/9402-1
NJ-2020 Aug 14, 2025
4fa8736
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Aug 20, 2025
c8d0c38
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Aug 21, 2025
7d93ed5
fix attachment picker & some improvements
NJ-2020 Aug 21, 2025
e66a8ef
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Aug 23, 2025
54d1f51
fix cacheAttachment issue file path, some issue & improvements
NJ-2020 Aug 23, 2025
23ae3d2
fix RNFS cacheAttachment on native platform
NJ-2020 Aug 23, 2025
e08598d
fix attachment unit test & spell name error
NJ-2020 Aug 25, 2025
98a02e4
fix sepll name, eslint and jest unit test error
NJ-2020 Aug 25, 2025
fb95150
fix attachment test eslint errror
NJ-2020 Aug 25, 2025
19cc2f7
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Aug 25, 2025
9b0fa1d
fix eslint error
NJ-2020 Aug 25, 2025
af6f48f
fix report action test
NJ-2020 Aug 25, 2025
4cd3348
fix: clean up the code
NJ-2020 Aug 25, 2025
f5a59b0
Merge remote-tracking branch 'origin' into new-feat/9402-1
NJ-2020 Aug 28, 2025
1983eca
remove unnecessary import
NJ-2020 Aug 28, 2025
42d72a2
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Aug 29, 2025
09b69af
fix: getCachedAttachment error
NJ-2020 Aug 29, 2025
2cdf779
fix native: attachment file upload
NJ-2020 Aug 29, 2025
52f6e94
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Aug 30, 2025
637f9b9
remove unnecessary code
NJ-2020 Aug 30, 2025
fe24a5c
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Sep 1, 2025
bdc1a67
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Sep 5, 2025
5fc46c2
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Sep 6, 2025
33ffbd7
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Sep 9, 2025
8ed26df
draft: use web worker when clearing CacheAPI on logout
NJ-2020 Sep 10, 2025
e21c68b
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Sep 10, 2025
b3026be
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Sep 11, 2025
9aa921a
revert: draft web worker
NJ-2020 Sep 11, 2025
948553f
fix: improve error handling
NJ-2020 Sep 11, 2025
4025551
remove unnecessary, fix some issues, improvements
NJ-2020 Sep 12, 2025
e407e58
fix eslint, ts check
NJ-2020 Sep 12, 2025
a439a87
fix attachment test workflow check
NJ-2020 Sep 12, 2025
fc9ef18
fix jest test, eslint errors
NJ-2020 Sep 12, 2025
18236aa
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Sep 12, 2025
ef91e0c
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Sep 13, 2025
0d220bd
fix: store/caching attachment issues
NJ-2020 Sep 13, 2025
26200d1
fix: eslint errors
NJ-2020 Sep 13, 2025
99a3fee
fix: jest unit test
NJ-2020 Sep 13, 2025
a9e3994
fix typo
NJ-2020 Sep 13, 2025
167ab16
fix: eslint error
NJ-2020 Sep 14, 2025
9e4196b
fix all issues store caching attachment both native + web
NJ-2020 Sep 15, 2025
d675c4b
fix: eslint error
NJ-2020 Sep 15, 2025
85e6a60
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Sep 15, 2025
3344e95
fix: unbound eslint error
NJ-2020 Sep 15, 2025
776520f
fix: jest test
NJ-2020 Sep 16, 2025
1f89a0e
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Sep 16, 2025
d1aed4a
fix: remove attachment unit test error
NJ-2020 Sep 16, 2025
565b52f
fix: eslint error
NJ-2020 Sep 16, 2025
226cc7a
add catch handler for RNFetchBlob
NJ-2020 Sep 16, 2025
a94aaac
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Oct 2, 2025
f706bde
fix sourceID
NJ-2020 Oct 2, 2025
940cc42
fix all workflow failures
NJ-2020 Oct 2, 2025
81e448b
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Oct 2, 2025
413ccc9
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Oct 2, 2025
13049ef
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Oct 6, 2025
953173d
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Oct 8, 2025
e6a4d22
add more unit tests
NJ-2020 Oct 8, 2025
2ffa15a
Merge branch 'main' into new-feat/9402-1
NJ-2020 Oct 11, 2025
a64bbe0
fix failing tests
NJ-2020 Oct 11, 2025
d921958
Merge remote-tracking branch 'origin' into new-feat/9402-1
NJ-2020 Feb 15, 2026
1e104aa
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Feb 17, 2026
6129f12
fix some errors, refactor buildOptimisticAddCommentReportAction
NJ-2020 Feb 17, 2026
cd6ef5b
only allow jpg/jpeg images
NJ-2020 Feb 17, 2026
9c29149
fix eslint error
NJ-2020 Feb 17, 2026
68bcbab
fix eslint errors, improvemance
NJ-2020 Feb 17, 2026
0a47103
fix: eslint error & remove attachment test
NJ-2020 Feb 17, 2026
91cce69
fix: missing global expression
NJ-2020 Feb 17, 2026
0879254
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Feb 18, 2026
fc8d202
fix: getImageCacheFileExtension, jest error & improvemance
NJ-2020 Feb 18, 2026
ecb35d7
fix: revert ReportTest
NJ-2020 Feb 18, 2026
0468734
fix: jest error
NJ-2020 Feb 18, 2026
f835fae
fix: error, issues & improvemance
NJ-2020 Feb 18, 2026
d78e136
fix: regex matching & improvemance
NJ-2020 Feb 19, 2026
ce92bcc
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Feb 19, 2026
94f6fd9
Merge branch 'main' into new-feat/9402-1
NJ-2020 Feb 20, 2026
422abba
fix: error
NJ-2020 Feb 20, 2026
5eea5cf
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Feb 21, 2026
3c6a540
fix: only re-cache for outdated attachment
NJ-2020 Feb 21, 2026
0adbfe8
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Feb 21, 2026
cd344ec
fix: regex issues
NJ-2020 Feb 21, 2026
dfe2134
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Feb 23, 2026
066e0a4
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Feb 23, 2026
a1c473e
fix: prettier error
NJ-2020 Feb 23, 2026
93372c4
fix: eslint error
NJ-2020 Feb 23, 2026
8b0b584
feat: create attachment test
NJ-2020 Feb 24, 2026
c9cd99d
fix: update IMAGE_CACHE_FILE_TYPES
NJ-2020 Feb 24, 2026
388a061
Merge remote-tracking branch 'origin' into new-feat/9402-1
NJ-2020 Feb 24, 2026
a37771e
fix: CacheAPI initialization
NJ-2020 Feb 24, 2026
a08f268
fix: IMAGE_CACHE_FILE_TYPES & improvemance
NJ-2020 Feb 24, 2026
81220cd
Merge remote-tracking branch 'origin' into new-feat/9402-1
NJ-2020 Feb 25, 2026
69bc7be
fix: error & unnecessary code
NJ-2020 Feb 25, 2026
1bcf986
fix: clear cached attachments on signout
NJ-2020 Feb 25, 2026
088a6fb
remove unnecessary comment
NJ-2020 Feb 25, 2026
7737911
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Feb 25, 2026
73d137e
fix: prettier
NJ-2020 Feb 25, 2026
22d3d80
fix: missing return statement
NJ-2020 Feb 25, 2026
152854b
Merge remote-tracking branch 'origin' into new-feat/9402-1
NJ-2020 Feb 26, 2026
ec20fa7
fix: add HEIC file caching support & improvemance
NJ-2020 Feb 26, 2026
28077cb
fix
NJ-2020 Feb 26, 2026
6cdeaa9
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Mar 2, 2026
7f41b0b
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Mar 3, 2026
4d4dcea
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Mar 4, 2026
527fda6
fix: attachmentID loading/flickering bug
NJ-2020 Mar 5, 2026
a461ac7
Merge remote-tracking branch 'origin' into new-feat/9402-1
NJ-2020 Mar 5, 2026
e3825c4
fix: typecheck
NJ-2020 Mar 5, 2026
d75bc1e
fix prettier
NJ-2020 Mar 5, 2026
14632eb
fix: add missing dependency variable
NJ-2020 Mar 6, 2026
e49303a
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Mar 6, 2026
249d692
fix: invalid reportActionID & missing trailing space
NJ-2020 Mar 7, 2026
6f8d25d
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Mar 7, 2026
9f629d7
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Mar 9, 2026
a8393a6
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Mar 9, 2026
22bb13a
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Mar 10, 2026
947f13b
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Mar 11, 2026
d958da0
Merge remote-tracking branch 'origin' into new-feat/9402-1
NJ-2020 Mar 11, 2026
7f6e8a6
fix: add comment explanation
NJ-2020 Mar 11, 2026
6d45e3c
fix: spelling
NJ-2020 Mar 11, 2026
89c4410
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Mar 11, 2026
9daa004
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Mar 11, 2026
a83f371
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Mar 12, 2026
e724bce
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Mar 13, 2026
349a02a
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Mar 14, 2026
7d7092f
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Mar 15, 2026
f7a8da4
Merge branch 'Expensify:main' into new-feat/9402-1
NJ-2020 Mar 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 32 additions & 5 deletions src/CONST/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2200,7 +2200,6 @@ const CONST = {
YOUR_LOCATION_TEXT: 'Your Location',

ATTACHMENT_MESSAGE_TEXT: '[Attachment]',
ATTACHMENT_REGEX: /<video |<img /,
ATTACHMENT_SOURCE_ATTRIBUTE: 'data-expensify-source',
ATTACHMENT_ID_ATTRIBUTE: 'data-attachment-id',
ATTACHMENT_OPTIMISTIC_SOURCE_ATTRIBUTE: 'data-optimistic-src',
Expand Down Expand Up @@ -2254,6 +2253,20 @@ const CONST = {
HEIC: 'image/heic',
},

IMAGE_CACHE_FILE_TYPES: {
'image/webp': 'webp',
'image/png': 'png',
'image/apng': 'png',
'image/avif': 'avif',
'image/jpeg': 'jpg',
'image/jpg': 'jpg',
'image/gif': 'gif',
'image/svg+xml': 'svg',
'image/x-icon': 'ico',
'image/vnd.microsoft.icon': 'ico',
'image/heic': 'heic',
},

SHARE_FILE_MIMETYPE: {
JPG: 'image/jpg',
JPEG: 'image/jpeg',
Expand Down Expand Up @@ -4200,15 +4213,25 @@ const CONST = {
NON_NUMERIC: /\D/g,
ANY_SPACE: /\s/g,

// Extract attachment's source from the data's html string
ATTACHMENT_DATA: /(data-expensify-source|data-name)="([^"]+)"/g,

EMOJI_NAME: /(?<=^|[\s\S]):[\p{L}0-9_+-]+:/gu,
EMOJI_SUGGESTIONS: /(?<=^|[\s\S]):[\p{L}0-9_+-]{1,40}$/u,
AFTER_FIRST_LINE_BREAK: /\n.*/g,
LINE_BREAK: /\r\n|\r|\n|\u2028/g,
CODE_2FA: /^\d{6}$/,
ATTACHMENT_ID: /chat-attachments\/(\d+)/,

ATTACHMENT: {
// Match any attachment tag inside the markdown text i.e only: <img or <video
ATTACHMENT_REGEX: /<video |<img /g,
// Extract all attachments including all atributes and values from markdown text
ATTACHMENT: /<(img|video)[^>]*>/gi,
// Retrieve the attachment id value from data-attachment-id attribute
ATTACHMENT_ID: /data-attachment-id=(["'])(.*?)\1/,
// Retrive attachment source id from attachment source url link
ATTACHMENT_SOURCE_ID: /chat-attachments\/(\d+)/,
// Retrieve attachment source either local or remote
ATTACHMENT_SOURCE: /(src|data-expensify-source|data-optimistic-src)="([^"]+)"/i,
},

HAS_COLON_ONLY_AT_THE_BEGINNING: /^:[^:]+$/,
HAS_AT_MOST_TWO_AT_SIGNS: /^@[^@]*@?[^@]*$/,
EMPTY_COMMENT: /^(\s)*$/,
Expand Down Expand Up @@ -7120,6 +7143,10 @@ const CONST = {
BOOK_MEETING_LINK: 'https://calendly.com/d/cqsm-2gm-fxr/expensify-product-team',
},

CACHE_API_KEYS: {
ATTACHMENTS: 'attachments',
},

SESSION_STORAGE_KEYS: {
INITIAL_URL: 'INITIAL_URL',
ACTIVE_WORKSPACE_ID: 'ACTIVE_WORKSPACE_ID',
Expand Down
2 changes: 2 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@ const ONYXKEYS = {

/** Collection Keys */
COLLECTION: {
ATTACHMENT: 'attachment_',
DOMAIN: 'domain_',
DOWNLOAD: 'download_',
POLICY: 'policy_',
Expand Down Expand Up @@ -1165,6 +1166,7 @@ type OnyxFormDraftValuesMapping = {
};

type OnyxCollectionValuesMapping = {
[ONYXKEYS.COLLECTION.ATTACHMENT]: OnyxTypes.Attachment;
[ONYXKEYS.COLLECTION.DOMAIN]: OnyxTypes.Domain;
[ONYXKEYS.COLLECTION.DOWNLOAD]: OnyxTypes.Download;
[ONYXKEYS.COLLECTION.POLICY]: OnyxTypes.Policy;
Expand Down
5 changes: 3 additions & 2 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4069,18 +4069,19 @@ function getAttachmentModalScreenRoute(url: AttachmentRoutes, params?: ReportAtt
return url;
}

const {source, attachmentID, type, reportID, accountID, isAuthTokenRequired, originalFileName, attachmentLink} = params;
const {source, attachmentID, type, reportID, reportActionID, accountID, isAuthTokenRequired, originalFileName, attachmentLink} = params;

const sourceParam = `?source=${encodeURIComponent(source as string)}`;
const attachmentIDParam = attachmentID ? `&attachmentID=${attachmentID}` : '';
const typeParam = type ? `&type=${type as string}` : '';
const reportIDParam = reportID ? `&reportID=${reportID}` : '';
const reportActionIDParam = reportActionID ? `&reportActionID=${reportActionID}` : '';
const accountIDParam = accountID ? `&accountID=${accountID}` : '';
const authTokenParam = isAuthTokenRequired ? '&isAuthTokenRequired=true' : '';
const fileNameParam = originalFileName ? `&originalFileName=${originalFileName}` : '';
const attachmentLinkParam = attachmentLink ? `&attachmentLink=${attachmentLink}` : '';

return `${url}${sourceParam}${typeParam}${reportIDParam}${attachmentIDParam}${accountIDParam}${authTokenParam}${fileNameParam}${attachmentLinkParam} ` as const;
return `${url}${sourceParam}${typeParam}${reportIDParam}${reportActionIDParam}${attachmentIDParam}${accountIDParam}${authTokenParam}${fileNameParam}${attachmentLinkParam} ` as const;
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type BaseAnchorForAttachmentsOnlyProps = AnchorForAttachmentsOnlyProps & {
};

function BaseAnchorForAttachmentsOnly({style, source = '', displayName = '', onPressIn, onPressOut, isDeleted}: BaseAnchorForAttachmentsOnlyProps) {
const sourceID = (source.match(CONST.REGEX.ATTACHMENT_ID) ?? [])[1];
const sourceID = (source.match(CONST.REGEX.ATTACHMENT.ATTACHMENT_SOURCE_ID) ?? [])[1];

const [download] = useOnyx(`${ONYXKEYS.COLLECTION.DOWNLOAD}${sourceID}`);
const session = useSession();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ function ImageRenderer({tnode}: CustomRendererProps<TBlock>) {
const route = ROUTES.REPORT_ATTACHMENTS?.getRoute({
attachmentID,
reportID,
reportActionID: action?.reportActionID,
type,
source,
accountID,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function VideoRenderer({tnode, key}: VideoRendererProps) {
const isDeleted = isDeletedNode(tnode);
const attachmentID = htmlAttribs[CONST.ATTACHMENT_ID_ATTRIBUTE];

const {report} = useShowContextMenuState();
const {report, action} = useShowContextMenuState();

return (
<AttachmentContext.Consumer>
Expand All @@ -49,6 +49,7 @@ function VideoRenderer({tnode, key}: VideoRendererProps) {
const route = ROUTES.REPORT_ATTACHMENTS.getRoute({
attachmentID,
reportID: report?.reportID,
reportActionID: action?.reportActionID,
type,
source: sourceURL,
accountID,
Expand Down
1 change: 1 addition & 0 deletions src/libs/API/parameters/AddCommentOrAttachmentParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ type AddCommentOrAttachmentParams = {
reportActionID?: string;
commentReportActionID?: string | null;
reportComment?: string;
attachmentID?: string;
file?: FileObject;
timezone?: string;
clientCreatedTime?: string;
Expand Down
10 changes: 9 additions & 1 deletion src/libs/AttachmentUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,13 @@ function isDirectoryCheck(data: FileObject) {
return true;
}

export default validateAttachmentFile;
/**
* Returns image cache file extension based from mime type
*/
function getImageCacheFileExtension(contentType: string) {
const imageCacheFileTypes: Record<string, string> = CONST.IMAGE_CACHE_FILE_TYPES;
return imageCacheFileTypes[contentType] ?? '';
}

export {validateAttachmentFile, getImageCacheFileExtension};
export type {AttachmentValidationResult};
14 changes: 14 additions & 0 deletions src/libs/CacheAPI/index.native.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Cache API only works for web, so we will return empty function here
function init() {}
Copy link
Member

Choose a reason for hiding this comment

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

Please add comment on why we are not implementing here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

function put() {}
function get() {}
function remove() {}
function clear() {}

export default {
init,
put,
get,
remove,
clear,
};
54 changes: 54 additions & 0 deletions src/libs/CacheAPI/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import type {ValueOf} from 'type-fest';
import Log from '@libs/Log';
import CONST from '@src/CONST';

type CacheNameType = ValueOf<typeof CONST.CACHE_API_KEYS>;

function init() {
// Exit early if the Cache API is not supported in the current browser.
if (!('caches' in window)) {
Log.warn('Cache API is not supported');
return;
}
const keys = Object.values(CONST.CACHE_API_KEYS);
for (const key of keys) {
caches.has(key).then((isExist) => {
if (isExist) {
return;
}
caches.open(key);
});
}
}

function put(cacheName: CacheNameType, key: string, value: Response) {
return caches.open(cacheName).then((cache) => cache.put(key, value));
}

function get(cacheName: CacheNameType, key: string) {
return caches.open(cacheName).then((cache) => cache.match(key));
}

function remove(cacheName: CacheNameType, key: string) {
return caches.open(cacheName).then((cache) => cache.delete(key));
}

function clear(cacheName?: CacheNameType) {
// If a cache name is provided, delete only that key.
if (cacheName) {
return caches.delete(cacheName);
}

const keys = Object.values(CONST.CACHE_API_KEYS);
const deletePromises = keys.map((key) => caches.delete(key));

return Promise.all(deletePromises);
}

export default {
init,
put,
get,
remove,
clear,
};
2 changes: 2 additions & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2872,6 +2872,7 @@ type AttachmentModalScreensParamList = {
[SCREENS.REPORT_ATTACHMENTS]: AttachmentModalContainerModalProps & {
source?: AvatarSource;
reportID?: string;
reportActionID?: string;
accountID?: number;
attachmentID?: string;
type?: ValueOf<typeof CONST.ATTACHMENT_TYPE>;
Expand All @@ -2887,6 +2888,7 @@ type AttachmentModalScreensParamList = {
};
[SCREENS.REPORT_ADD_ATTACHMENT]: AttachmentModalContainerModalProps & {
reportID?: string;
reportActionID?: string;
accountID?: number;
attachmentID?: string;
source?: AvatarSource;
Expand Down
14 changes: 10 additions & 4 deletions src/libs/ReportActionsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
}

let allReportActions: OnyxCollection<ReportActions>;
Onyx.connect({

Check warning on line 92 in src/libs/ReportActionsUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
waitForCollectionCallback: true,
callback: (actions) => {
Expand All @@ -101,7 +101,7 @@
});

let allReports: OnyxCollection<Report>;
Onyx.connect({

Check warning on line 104 in src/libs/ReportActionsUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.REPORT,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -110,13 +110,13 @@
});

let isNetworkOffline = false;
Onyx.connect({

Check warning on line 113 in src/libs/ReportActionsUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.NETWORK,
callback: (val) => (isNetworkOffline = val?.isOffline ?? false),
});

let deprecatedCurrentUserAccountID: number | undefined;
Onyx.connect({

Check warning on line 119 in src/libs/ReportActionsUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.SESSION,
callback: (value) => {
// When signed out, value is undefined
Expand Down Expand Up @@ -223,16 +223,22 @@

/**
* This function will add attachment ID attribute on img and video HTML tags inside the passed html content
* of a report action. This attachment id is the reportActionID concatenated with the order index that the attachment
* appears inside the report action message so as to identify attachments with identical source inside a report action.
* of a report action. For newer attachments, it will use the existing attachmentID unique id value. otherwise, it falls back to the reportActionID concatenated
* with the order index that the attachment appears inside the report action message, so as to identify
* attachments with identical source inside a report action.
*/
function getHtmlWithAttachmentID(html: string, reportActionID: string | undefined) {
if (!reportActionID) {
return html;
}

let attachmentID = 0;
return html.replaceAll(/<img |<video /g, (m) => m.concat(`${CONST.ATTACHMENT_ID_ATTRIBUTE}="${reportActionID}_${++attachmentID}" `));
let index = 0;
return html.replaceAll(CONST.REGEX.ATTACHMENT.ATTACHMENT, (match) => {
const attachmentID = match.match(CONST.REGEX.ATTACHMENT.ATTACHMENT_ID)?.[2];

// If the attachment ID is already present, skip it
return attachmentID ? match : match.replaceAll(CONST.REGEX.ATTACHMENT.ATTACHMENT_REGEX, (m) => m.concat(`${CONST.ATTACHMENT_ID_ATTRIBUTE}="${reportActionID}_${++index}" `));
});
}

function getReportActionMessage(reportAction: PartialReportAction) {
Expand Down
46 changes: 32 additions & 14 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,16 @@
| 'delegateAccountID'
> & {isOptimisticAction: boolean};

type BuildOptimisticAddCommentReportActionParams = {
text?: string;
file?: FileObject;
actorAccountID?: number;
createdOffset?: number;
reportID?: string;
reportActionID?: string;
attachmentID?: string;
};

type OptimisticReportAction = {
commentText: string;
reportAction: OptimisticAddCommentReportAction;
Expand Down Expand Up @@ -1036,7 +1046,7 @@
};

let conciergeReportIDOnyxConnect: OnyxEntry<string>;
Onyx.connect({

Check warning on line 1049 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.CONCIERGE_REPORT_ID,
callback: (value) => {
conciergeReportIDOnyxConnect = value;
Expand All @@ -1044,7 +1054,7 @@
});

const defaultAvatarBuildingIconTestID = 'SvgDefaultAvatarBuilding Icon';
Onyx.connect({

Check warning on line 1057 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.SESSION,
callback: (value) => {
// When signed out, val is undefined
Expand All @@ -1062,7 +1072,7 @@
let allPersonalDetails: OnyxEntry<PersonalDetailsList>;
let allPersonalDetailLogins: string[];
let currentUserPersonalDetails: OnyxEntry<PersonalDetails>;
Onyx.connect({

Check warning on line 1075 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.PERSONAL_DETAILS_LIST,
callback: (value) => {
if (currentUserAccountID) {
Expand All @@ -1074,7 +1084,7 @@
});

let allReportsDraft: OnyxCollection<Report>;
Onyx.connect({

Check warning on line 1087 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.REPORT_DRAFT,
waitForCollectionCallback: true,
callback: (value) => (allReportsDraft = value),
Expand All @@ -1082,7 +1092,7 @@

let allPolicies: OnyxCollection<Policy>;
let policiesArray: Policy[] = [];
Onyx.connect({

Check warning on line 1095 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.POLICY,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -1092,7 +1102,7 @@
});

let allPolicyDrafts: OnyxCollection<Policy>;
Onyx.connect({

Check warning on line 1105 in src/libs/ReportUtils.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.POLICY_DRAFTS,
waitForCollectionCallback: true,
callback: (value) => (allPolicyDrafts = value),
Expand Down Expand Up @@ -6316,7 +6326,7 @@
});
}

function getUploadingAttachmentHtml(file?: FileObject): string {
function getUploadingAttachmentHtml(file?: FileObject, attachmentID?: string): string {
if (!file || typeof file.uri !== 'string') {
return '';
}
Expand All @@ -6325,6 +6335,7 @@
`${CONST.ATTACHMENT_OPTIMISTIC_SOURCE_ATTRIBUTE}="${file.uri}"`,
`${CONST.ATTACHMENT_SOURCE_ATTRIBUTE}="${file.uri}"`,
`${CONST.ATTACHMENT_ORIGINAL_FILENAME_ATTRIBUTE}="${file.name}"`,
attachmentID && `${CONST.ATTACHMENT_ID_ATTRIBUTE}="${attachmentID}"`,
'width' in file && `${CONST.ATTACHMENT_THUMBNAIL_WIDTH_ATTRIBUTE}="${file.width}"`,
'height' in file && `${CONST.ATTACHMENT_THUMBNAIL_HEIGHT_ATTRIBUTE}="${file.height}"`,
]
Expand Down Expand Up @@ -6364,16 +6375,17 @@
return Parser.htmlToText(policy.description);
}

function buildOptimisticAddCommentReportAction(
text?: string,
file?: FileObject,
actorAccountID?: number,
function buildOptimisticAddCommentReportAction({
text,
file,
actorAccountID,
createdOffset = 0,
reportID?: string,
reportActionID: string = rand64(),
): OptimisticReportAction {
reportID,
reportActionID = rand64(),
attachmentID,
}: BuildOptimisticAddCommentReportActionParams): OptimisticReportAction {
const commentText = getParsedComment(text ?? '', {reportID});
const attachmentHtml = getUploadingAttachmentHtml(file);
const attachmentHtml = getUploadingAttachmentHtml(file, attachmentID);

const htmlForNewComment = `${commentText}${commentText && attachmentHtml ? '<br /><br />' : ''}${attachmentHtml}`;
const textForNewComment = Parser.htmlToText(htmlForNewComment);
Expand Down Expand Up @@ -6499,7 +6511,7 @@
actorAccountID?: number,
createdOffset = 0,
): OptimisticReportAction {
const reportAction = buildOptimisticAddCommentReportAction(text, undefined, undefined, createdOffset, taskReportID);
const reportAction = buildOptimisticAddCommentReportAction({text, reportID: taskReportID, createdOffset});
if (Array.isArray(reportAction.reportAction.message)) {
const message = reportAction.reportAction.message.at(0);
if (message) {
Expand Down Expand Up @@ -11634,7 +11646,7 @@

// Text message
const message = typeof onboardingMessage.message === 'function' ? onboardingMessage.message(onboardingTaskParams) : onboardingMessage.message;
const textComment = buildOptimisticAddCommentReportAction(message, undefined, actorAccountID, 1);
const textComment = buildOptimisticAddCommentReportAction({text: message, actorAccountID, createdOffset: 1});
const textCommentAction: OptimisticAddCommentReportAction = textComment.reportAction;
const textMessage: AddCommentOrAttachmentParams = {
reportID: targetChatReportID,
Expand All @@ -11651,7 +11663,13 @@
if (shouldUseFollowupsInsteadOfTasks && companySize === CONST.ONBOARDING_COMPANY_SIZE.MICRO) {
bespokeWelcomeMessage = getBespokeWelcomeMessage(userReportedIntegration);
optimisticConciergeReportActionID = rand64();
bespokeAction = buildOptimisticAddCommentReportAction(bespokeWelcomeMessage, undefined, CONST.ACCOUNT_ID.CONCIERGE, 2, targetChatReportID, optimisticConciergeReportActionID);
bespokeAction = buildOptimisticAddCommentReportAction({
text: bespokeWelcomeMessage,
actorAccountID: CONST.ACCOUNT_ID.CONCIERGE,
createdOffset: 2,
reportID: targetChatReportID,
reportActionID: optimisticConciergeReportActionID,
});
}

let createWorkspaceTaskReportID;
Expand Down Expand Up @@ -11762,7 +11780,7 @@
const welcomeSignOffText =
// eslint-disable-next-line @typescript-eslint/no-deprecated
engagementChoice === CONST.ONBOARDING_CHOICES.MANAGE_TEAM ? translateLocal('onboarding.welcomeSignOffTitleManageTeam') : translateLocal('onboarding.welcomeSignOffTitle');
const welcomeSignOffComment = buildOptimisticAddCommentReportAction(welcomeSignOffText, undefined, actorAccountID, tasksData.length + 3);
const welcomeSignOffComment = buildOptimisticAddCommentReportAction({text: welcomeSignOffText, actorAccountID, createdOffset: tasksData.length + 3});
const welcomeSignOffCommentAction: OptimisticAddCommentReportAction = welcomeSignOffComment.reportAction;
const welcomeSignOffMessage = {
reportID: targetChatReportID,
Expand Down Expand Up @@ -12391,7 +12409,7 @@
const message = Array.isArray(reportAction?.message) ? (reportAction?.message?.at(-1) ?? null) : (reportAction?.message ?? null);
const html = message?.html ?? '';
const {sourceURL} = getAttachmentDetails(html);
const sourceID = (sourceURL?.match(CONST.REGEX.ATTACHMENT_ID) ?? [])[1];
const sourceID = (sourceURL?.match(CONST.REGEX.ATTACHMENT.ATTACHMENT_SOURCE_ID) ?? [])[1];
return sourceID;
}

Expand Down
Loading
Loading