Skip to content

Commit ee2da23

Browse files
committed
Refactor drive item handling to support empty file downloads and improve folder/file classification
1 parent e94bbba commit ee2da23

File tree

15 files changed

+576
-60
lines changed

15 files changed

+576
-60
lines changed

ios/Podfile.lock

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,17 +89,17 @@ PODS:
8989
- React-Core
9090
- jail-monkey (2.8.3):
9191
- React-Core
92-
- libwebp (1.3.2):
93-
- libwebp/demux (= 1.3.2)
94-
- libwebp/mux (= 1.3.2)
95-
- libwebp/sharpyuv (= 1.3.2)
96-
- libwebp/webp (= 1.3.2)
97-
- libwebp/demux (1.3.2):
92+
- libwebp (1.5.0):
93+
- libwebp/demux (= 1.5.0)
94+
- libwebp/mux (= 1.5.0)
95+
- libwebp/sharpyuv (= 1.5.0)
96+
- libwebp/webp (= 1.5.0)
97+
- libwebp/demux (1.5.0):
9898
- libwebp/webp
99-
- libwebp/mux (1.3.2):
99+
- libwebp/mux (1.5.0):
100100
- libwebp/demux
101-
- libwebp/sharpyuv (1.3.2)
102-
- libwebp/webp (1.3.2):
101+
- libwebp/sharpyuv (1.5.0)
102+
- libwebp/webp (1.5.0):
103103
- libwebp/sharpyuv
104104
- RCT-Folly (2022.05.16.00):
105105
- boost
@@ -1543,7 +1543,7 @@ SPEC CHECKSUMS:
15431543
IDZSwiftCommonCrypto: aefd3487b88dc3d7a1de2553188c720ac3194940
15441544
internxt-mobile-sdk: 821a26ae1521019b968b5c2bc716ca5498e8a7d1
15451545
jail-monkey: 066e0af74e67cbf432fbb4d214b046ef6dccf910
1546-
libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009
1546+
libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
15471547
RCT-Folly: 7169b2b1c44399c76a47b5deaaba715eeeb476c0
15481548
RCTRequired: ca1d7414aba0b27efcfa2ccd37637edb1ab77d96
15491549
RCTTypeSafety: 678e344fb976ff98343ca61dc62e151f3a042292

src/components/DriveNavigableItem/index.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import prettysize from 'prettysize';
33
import React from 'react';
44
import { TouchableHighlight, View } from 'react-native';
55
import { useTailwind } from 'tailwind-rn';
6-
import { FolderIcon, getFileTypeIcon } from '../../helpers';
6+
import { checkIsFolder, FolderIcon, getFileTypeIcon } from '../../helpers';
77
import { getDisplayName } from '../../helpers/itemNames';
88
import useGetColor from '../../hooks/useColor';
99
import globalStyle from '../../styles/global';
@@ -13,7 +13,9 @@ import AppText from '../AppText';
1313
const DriveNavigableItem: React.FC<DriveNavigableItemProps> = ({ isLoading, disabled, ...props }) => {
1414
const tailwind = useTailwind();
1515
const getColor = useGetColor();
16-
const isFolder = !props.data.fileId;
16+
17+
const isFolder = checkIsFolder(props.data);
18+
1719
const iconSize = 40;
1820
const IconFile = getFileTypeIcon(props.data.type || '');
1921

src/components/modals/DriveItemInfoModal/index.tsx

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import AppText from 'src/components/AppText';
2828
import { SLEEP_BECAUSE_MAYBE_BACKEND_IS_NOT_RETURNING_FRESHLY_MODIFIED_OR_CREATED_ITEMS_YET } from 'src/helpers/services';
2929
import { useTailwind } from 'tailwind-rn';
3030
import strings from '../../../../assets/lang/strings';
31-
import { FolderIcon, getFileTypeIcon } from '../../../helpers';
31+
import { checkIsFolder, FolderIcon, getFileSize, getFileTypeIcon, isEmptyFile } from '../../../helpers';
3232
import useGetColor from '../../../hooks/useColor';
3333
import { MAX_SIZE_TO_DOWNLOAD } from '../../../services/drive/constants';
3434
import { useAppDispatch, useAppSelector } from '../../../store/hooks';
@@ -56,7 +56,7 @@ function DriveItemInfoModal(): JSX.Element {
5656
return <></>;
5757
}
5858

59-
const isFolder = !item.fileId;
59+
const isFolder = checkIsFolder(item);
6060

6161
const handleRenameItem = () => {
6262
dispatch(uiActions.setShowItemModal(false));
@@ -165,7 +165,8 @@ function DriveItemInfoModal(): JSX.Element {
165165

166166
const handleExportFile = async () => {
167167
try {
168-
if (!item.fileId) {
168+
const fileSize = getFileSize(item);
169+
if (!item.fileId && fileSize !== 0) {
169170
throw new Error('Item fileID not found');
170171
}
171172
const canDownloadFile = isFileDownloadable();
@@ -187,12 +188,19 @@ function DriveItemInfoModal(): JSX.Element {
187188

188189
setDownloadProgress({ totalBytes: 0, progress: 0, bytesReceived: 0 });
189190
setExporting(true);
190-
const downloadPath = await downloadItem(
191-
item.fileId,
192-
item.bucket as string,
193-
decryptedFilePath,
194-
parseInt(item.size?.toString() ?? '0'),
195-
);
191+
192+
let downloadPath: string;
193+
194+
if (isEmptyFile(item)) {
195+
await drive.file.createEmptyDownloadedFile(decryptedFilePath);
196+
downloadPath = decryptedFilePath;
197+
} else {
198+
if (!item.fileId) {
199+
throw new Error('Item fileID not found for non-empty file');
200+
}
201+
downloadPath = await downloadItem(item.fileId, item.bucket as string, decryptedFilePath, fileSize);
202+
}
203+
196204
setExporting(false);
197205
await fs.shareFile({
198206
title: item.name,
@@ -204,18 +212,24 @@ function DriveItemInfoModal(): JSX.Element {
204212
errorService.reportError(error);
205213
} finally {
206214
setExporting(false);
215+
dispatch(uiActions.setShowItemModal(false));
207216
}
208217
};
218+
209219
const handleAbortDownload = () => {
210220
setExporting(false);
221+
dispatch(uiActions.setShowItemModal(false));
222+
211223
if (!downloadAbortableRef.current) return;
212224

213225
downloadAbortableRef.current('User requested abort');
214226
};
227+
215228
const handleAndroidDownloadFile = async () => {
216229
try {
217230
setDownloadProgress({ totalBytes: 0, progress: 0, bytesReceived: 0 });
218-
if (!item.fileId) {
231+
const fileSize = getFileSize(item);
232+
if (!item.fileId && fileSize !== 0) {
219233
throw new Error('Item fileID not found');
220234
}
221235
const canDownloadFile = isFileDownloadable();
@@ -234,12 +248,14 @@ function DriveItemInfoModal(): JSX.Element {
234248
// 2. If the file doesn't exists, download it
235249
if (!existsDecrypted) {
236250
setExporting(true);
237-
await downloadItem(
238-
item.fileId,
239-
item.bucket as string,
240-
decryptedFilePath,
241-
parseInt(item.size?.toString() ?? '0'),
242-
);
251+
if (isEmptyFile(item)) {
252+
await drive.file.createEmptyDownloadedFile(decryptedFilePath);
253+
} else {
254+
if (!item.fileId) {
255+
throw new Error('Item fileID not found for non-empty file');
256+
}
257+
await downloadItem(item.fileId, item.bucket as string, decryptedFilePath, fileSize);
258+
}
243259
setExporting(false);
244260
}
245261

@@ -259,7 +275,8 @@ function DriveItemInfoModal(): JSX.Element {
259275
const handleiOSSaveToFiles = async () => {
260276
try {
261277
setDownloadProgress({ totalBytes: 0, progress: 0, bytesReceived: 0 });
262-
if (!item.fileId) {
278+
const fileSize = getFileSize(item);
279+
if (!item.fileId && fileSize !== 0) {
263280
throw new Error('Item fileID not found');
264281
}
265282
const canDownloadFile = isFileDownloadable();
@@ -277,14 +294,16 @@ function DriveItemInfoModal(): JSX.Element {
277294

278295
// 2. If the file doesn't exists, download it
279296
if (!existsDecrypted) {
280-
setExporting(true);
281-
await downloadItem(
282-
item.fileId,
283-
item.bucket as string,
284-
decryptedFilePath,
285-
parseInt(item.size?.toString() ?? '0'),
286-
);
287-
setExporting(false);
297+
if (isEmptyFile(item)) {
298+
await drive.file.createEmptyDownloadedFile(decryptedFilePath);
299+
} else {
300+
setExporting(true);
301+
if (!item.fileId) {
302+
throw new Error('Item fileID not found for non-empty file');
303+
}
304+
await downloadItem(item.fileId, item.bucket as string, decryptedFilePath, fileSize);
305+
setExporting(false);
306+
}
288307
}
289308

290309
// 3. Share to iOS files app
@@ -364,7 +383,7 @@ function DriveItemInfoModal(): JSX.Element {
364383
}
365384

366385
if (
367-
item?.size &&
386+
(item?.size || item?.size === 0) &&
368387
downloadProgress?.bytesReceived &&
369388
downloadProgress?.bytesReceived >= parseInt(item?.size?.toString())
370389
) {

src/components/modals/MoveItemsModal/index.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import Portal from '@burstware/react-native-portal';
2525
import { useDrive } from '@internxt-mobile/hooks/drive';
2626
import { useNavigation } from '@react-navigation/native';
2727
import { useTailwind } from 'tailwind-rn';
28+
import { checkIsFile, checkIsFolder } from '../../../helpers';
2829
import useGetColor from '../../../hooks/useColor';
2930
import { logger } from '../../../services/common';
3031
import notificationsService from '../../../services/NotificationsService';
@@ -82,7 +83,7 @@ function MoveItemsModal(): JSX.Element {
8283
status: DriveItemStatus.Idle,
8384
data: {
8485
bucket: child.bucket,
85-
isFolder: 'fileId' in child ? false : true,
86+
isFolder: checkIsFolder(child as any),
8687
thumbnails: (child as DriveFileData).thumbnails,
8788
currentThumbnail: null,
8889
createdAt: child.createdAt,
@@ -106,7 +107,7 @@ function MoveItemsModal(): JSX.Element {
106107
[sortMode, destinationFolderContentResponse],
107108
);
108109

109-
const isFolder = !!(itemToMove && !itemToMove.fileId);
110+
const isFolder = checkIsFolder(itemToMove);
110111
const canGoBack = currentFolderIsRootFolder ? false : true;
111112
const onMoveButtonPressed = () => {
112113
setConfirmModalOpen(true);
@@ -380,7 +381,7 @@ function MoveItemsModal(): JSX.Element {
380381
return (
381382
<DriveNavigableItem
382383
key={item.data.id}
383-
disabled={!!item.data.fileId || item.data.id === itemToMove?.id}
384+
disabled={checkIsFile(item.data as any) || item.data.id === itemToMove?.id}
384385
type={DriveListType.Drive}
385386
status={DriveItemStatus.Idle}
386387
viewMode={DriveListViewMode.List}

src/components/modals/SharedLinkInfoModal/SharedLinkInfoModal.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useState } from 'react';
33
import { Text, View } from 'react-native';
44

55
import strings from '../../../../assets/lang/strings';
6-
import { FolderIcon, getFileTypeIcon } from '../../../helpers';
6+
import { checkIsFolder, FolderIcon, getFileTypeIcon } from '../../../helpers';
77
import { useAppDispatch, useAppSelector } from '../../../store/hooks';
88
import { uiActions } from '../../../store/slices/ui';
99
import globalStyle from '../../../styles/global';
@@ -44,7 +44,7 @@ export function SharedLinkInfoModal(): JSX.Element {
4444
return <></>;
4545
}
4646

47-
const isFolder = !item.fileId;
47+
const isFolder = checkIsFolder(item);
4848

4949
const handleCopyLink = async () => {
5050
const existingLink = await driveUseCases.generateShareLink({

src/components/modals/SharedLinkSettingsModal/SharedLinkSettingsModal.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import AppText from 'src/components/AppText';
1111
import { useAppDispatch, useAppSelector } from 'src/store/hooks';
1212
import { driveActions } from 'src/store/slices/drive';
1313
import { useTailwind } from 'tailwind-rn';
14+
import { checkIsFolder } from '../../../helpers';
1415
import BottomModal from '../BottomModal';
1516
import { GeneratingLinkModal } from '../common/GeneratingLinkModal';
1617
import { animations } from './animations';
@@ -120,7 +121,7 @@ export const SharedLinkSettingsModal: React.FC<SharedLinkSettingsModalProps> = (
120121
return;
121122
}
122123

123-
const isFolder = item?.fileId ? false : true;
124+
const isFolder = checkIsFolder(item);
124125

125126
// A share link already exists, obtain it
126127
if (item?.token && item?.code) {

src/contexts/Drive/Drive.context.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ export const DriveContextProvider: React.FC<DriveContextProviderProps> = ({ chil
173173
size: typeof file.size === 'bigint' ? Number(file.size) : file.size,
174174
folderId: file.folderId,
175175
thumbnails: file.thumbnails ?? [],
176+
isFolder: false,
176177
};
177178

178179
return driveFile;

0 commit comments

Comments
 (0)