Skip to content

Commit 540af74

Browse files
authored
Merge pull request #246 from internxt/feature/download-in-chunks
[PB-3278] : feature/download in chunks
2 parents 4b2605d + cda9c2e commit 540af74

File tree

15 files changed

+260
-81
lines changed

15 files changed

+260
-81
lines changed

android/app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ android {
8888
applicationId 'com.internxt.cloud'
8989
minSdkVersion rootProject.ext.minSdkVersion
9090
targetSdkVersion rootProject.ext.targetSdkVersion
91-
versionCode 97
91+
versionCode 99
9292
versionName "1.6.0"
9393

9494
buildConfigField("boolean", "REACT_NATIVE_UNSTABLE_USE_RUNTIME_SCHEDULER_ALWAYS", (findProperty("reactNative.unstable_useRuntimeSchedulerAlways") ?: true).toString())

android/app/src/main/AndroidManifest.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
1+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2+
xmlns:tools="http://schemas.android.com/tools">
23
<uses-permission android:name="android.permission.DETECT_SCREEN_CAPTURE"/>
34
<uses-permission android:name="android.permission.INTERNET"/>
45
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

assets/lang/strings.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const strings = new LocalizedStrings({
1414
current: 'Current',
1515
new: 'New',
1616
calculating: 'Calculating',
17+
decrypting: 'Decrypting',
1718
atTime: 'at',
1819
loading: 'Loading',
1920
downloading: 'Downloading...',
@@ -647,7 +648,7 @@ const strings = new LocalizedStrings({
647648
confirmDeleteSharedLink: 'Users with the link will lose access to the shared content.',
648649
linkDeleted: 'Link deleted successfully',
649650
trashEmpty: 'Trash is empty',
650-
downloadLimit: 'The download limit in mobile app is 3GB.',
651+
downloadLimit: 'The download limit in mobile app is 5GB.',
651652
},
652653
errors: {
653654
runtimeLogsMissing: 'The logs file is missing or empty',
@@ -676,7 +677,6 @@ const strings = new LocalizedStrings({
676677
unknown: 'Unknown error',
677678
uploadFile: 'File upload error: {0}',
678679
storageLimitReached: 'You have reached your storage limit',
679-
680680
inviteAFriend: 'Error sending invitation: {0}',
681681
loadProducts: 'Cannot load products: {0}',
682682
passwordsDontMatch: "Passwords don't match",
@@ -698,6 +698,7 @@ const strings = new LocalizedStrings({
698698
changePassword: 'Error changing password',
699699
loadPrices: 'Error loading prices',
700700
cancelSubscription: 'Error cancelling subscription',
701+
notEnoughSpaceOnDevice: 'Not enough storage space available for download',
701702
},
702703
},
703704
es: {
@@ -709,6 +710,7 @@ const strings = new LocalizedStrings({
709710
current: 'Actual',
710711
new: 'Nuevo',
711712
calculating: 'Calculando',
713+
decrypting: 'Desencriptando',
712714
atTime: 'a las',
713715
loading: 'Cargando',
714716
security: 'Seguridad',
@@ -1346,7 +1348,7 @@ const strings = new LocalizedStrings({
13461348
confirmDeleteSharedLink: 'Los usuarios con el link compartido perderán el acceso a este contenido compartido.',
13471349
linkDeleted: 'Link eliminado correctamente',
13481350
trashEmpty: 'Papelera vaciada',
1349-
downloadLimit: 'El límite de descarga en la app movil son 3GB',
1351+
downloadLimit: 'El límite de descarga en la app movil son 5GB',
13501352
},
13511353
errors: {
13521354
runtimeLogsMissing: 'El archivo no se encuentra o está vacío',
@@ -1396,6 +1398,7 @@ const strings = new LocalizedStrings({
13961398
changePassword: 'Error cambiando contraseña',
13971399
loadPrices: 'Error cargando precios',
13981400
cancelSubscription: 'Error cancelando suscripción',
1401+
notEnoughSpaceOnDevice: 'No hay suficiente espacio de almacenamiento disponible para la descarga',
13991402
},
14001403
},
14011404
});

ios/Podfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,7 +1142,7 @@ PODS:
11421142
- React-Core
11431143
- RealmJS (11.10.2):
11441144
- React
1145-
- rn-crypto (0.1.12):
1145+
- rn-crypto (0.1.14):
11461146
- IDZSwiftCommonCrypto (~> 0.13)
11471147
- React-Core
11481148
- rn-fetch-blob (0.11.2):
@@ -1606,7 +1606,7 @@ SPEC CHECKSUMS:
16061606
ReactCommon: 447281ad2034ea3252bf81a60d1f77d5afb0b636
16071607
ReactNativeLocalization: fb171138cdc80d5d0d4f20243d2fc82c2b3cc48f
16081608
RealmJS: 73a36da3cbbe85e1bdcbf55683172b51f35070d3
1609-
rn-crypto: 160ce10c618571e5c051c8e12315df0b04ac7c3e
1609+
rn-crypto: 11206fba572b93aa936f225fa7e9dec24a330a58
16101610
rn-fetch-blob: f525a73a78df9ed5d35e67ea65e79d53c15255bc
16111611
RNCAsyncStorage: 618d03a5f52fbccb3d7010076bc54712844c18ef
16121612
RNDeviceInfo: aad3c663b25752a52bf8fce93f2354001dd185aa

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"@hookform/resolvers": "^2.9.1",
3737
"@internxt/lib": "^1.2.0",
3838
"@internxt/mobile-sdk": "^0.2.41",
39-
"@internxt/rn-crypto": "^0.1.12",
39+
"@internxt/rn-crypto": "0.1.14",
4040
"@internxt/sdk": "^1.4.96",
4141
"@react-native-async-storage/async-storage": "1.21.0",
4242
"@react-navigation/bottom-tabs": "^6.2.0",

src/components/AppTextInput/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ const AppTextInput = (props: AppTextInputProps): JSX.Element => {
6262
if (hasNothingSelected) {
6363
newPosition = selection.start + (newText.length - oldText.length);
6464
} else {
65-
newPosition = selectionStart;
65+
const insertedLength = newText.length - (oldText.length - (selection.end - selection.start));
66+
newPosition = selectionStart + insertedLength;
6667
}
6768
newPosition = Math.max(0, newPosition);
6869

src/components/modals/DriveItemInfoModal/index.tsx

Lines changed: 59 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import Portal from '@burstware/react-native-portal';
66
import { useDrive } from '@internxt-mobile/hooks/drive';
77
import AuthService from '@internxt-mobile/services/AuthService';
88
import errorService from '@internxt-mobile/services/ErrorService';
9-
import { fs } from '@internxt-mobile/services/FileSystemService';
9+
import fileSystemService, { fs } from '@internxt-mobile/services/FileSystemService';
1010
import notificationsService, { notifications } from '@internxt-mobile/services/NotificationsService';
1111
import { logger } from '@internxt-mobile/services/common';
1212
import { time } from '@internxt-mobile/services/common/time';
@@ -69,7 +69,7 @@ function DriveItemInfoModal(): JSX.Element {
6969
};
7070

7171
const isFileDownloadable = (): boolean => {
72-
if (parseInt(item.size?.toString() ?? '0') > MAX_SIZE_TO_DOWNLOAD['3GB']) {
72+
if (parseInt(item.size?.toString() ?? '0') > MAX_SIZE_TO_DOWNLOAD['5GB']) {
7373
notificationsService.info(strings.messages.downloadLimit);
7474
return false;
7575
}
@@ -125,21 +125,38 @@ function DriveItemInfoModal(): JSX.Element {
125125
return;
126126
};
127127

128-
const downloadItem = async (fileId: string, bucketId: string, decryptedFilePath: string) => {
128+
const downloadItem = async (fileId: string, bucketId: string, decryptedFilePath: string, fileSize: number) => {
129129
const { credentials } = await AuthService.getAuthCredentials();
130-
const { downloadPath } = await drive.file.downloadFile(credentials.user, bucketId, fileId, {
131-
downloadPath: decryptedFilePath,
132-
downloadProgressCallback(progress, bytesReceived, totalBytes) {
133-
setDownloadProgress({
134-
progress,
135-
bytesReceived,
136-
totalBytes,
137-
});
138-
},
139-
onAbortableReady(abortable) {
140-
downloadAbortableRef.current = abortable;
130+
try {
131+
const hasEnoughSpace = await fileSystemService.checkAvailableStorage(fileSize);
132+
if (!hasEnoughSpace) {
133+
notifications.error(strings.errors.notEnoughSpaceOnDevice);
134+
throw new Error(strings.errors.notEnoughSpaceOnDevice);
135+
}
136+
} catch (error) {
137+
logger.error('Error on downloadItem function:', JSON.stringify(error));
138+
errorService.reportError(error);
139+
}
140+
141+
const { downloadPath } = await drive.file.downloadFile(
142+
credentials.user,
143+
bucketId,
144+
fileId,
145+
{
146+
downloadPath: decryptedFilePath,
147+
downloadProgressCallback(progress, bytesReceived, totalBytes) {
148+
setDownloadProgress({
149+
progress,
150+
bytesReceived,
151+
totalBytes,
152+
});
153+
},
154+
onAbortableReady(abortable) {
155+
downloadAbortableRef.current = abortable;
156+
},
141157
},
142-
});
158+
fileSize,
159+
);
143160

144161
return downloadPath;
145162
};
@@ -168,7 +185,12 @@ function DriveItemInfoModal(): JSX.Element {
168185

169186
setDownloadProgress({ totalBytes: 0, progress: 0, bytesReceived: 0 });
170187
setExporting(true);
171-
const downloadPath = await downloadItem(item.fileId, item.bucket as string, decryptedFilePath);
188+
const downloadPath = await downloadItem(
189+
item.fileId,
190+
item.bucket as string,
191+
decryptedFilePath,
192+
parseInt(item.size?.toString() ?? '0'),
193+
);
172194
setExporting(false);
173195
await fs.shareFile({
174196
title: item.name,
@@ -210,7 +232,12 @@ function DriveItemInfoModal(): JSX.Element {
210232
// 2. If the file doesn't exists, download it
211233
if (!existsDecrypted) {
212234
setExporting(true);
213-
await downloadItem(item.fileId, item.bucket as string, decryptedFilePath);
235+
await downloadItem(
236+
item.fileId,
237+
item.bucket as string,
238+
decryptedFilePath,
239+
parseInt(item.size?.toString() ?? '0'),
240+
);
214241
setExporting(false);
215242
}
216243

@@ -249,7 +276,12 @@ function DriveItemInfoModal(): JSX.Element {
249276
// 2. If the file doesn't exists, download it
250277
if (!existsDecrypted) {
251278
setExporting(true);
252-
await downloadItem(item.fileId, item.bucket as string, decryptedFilePath);
279+
await downloadItem(
280+
item.fileId,
281+
item.bucket as string,
282+
decryptedFilePath,
283+
parseInt(item.size?.toString() ?? '0'),
284+
);
253285
setExporting(false);
254286
}
255287

@@ -327,6 +359,15 @@ function DriveItemInfoModal(): JSX.Element {
327359
if (!downloadProgress.totalBytes) {
328360
return strings.generic.calculating + '...';
329361
}
362+
363+
if (
364+
item?.size &&
365+
downloadProgress?.bytesReceived &&
366+
downloadProgress?.bytesReceived >= parseInt(item?.size?.toString())
367+
) {
368+
return strings.generic.decrypting + '...';
369+
}
370+
330371
const bytesReceivedStr = prettysize(downloadProgress.bytesReceived);
331372
const totalBytesStr = prettysize(downloadProgress.totalBytes);
332373
return `${bytesReceivedStr} ${strings.modals.downloadingFile.of} ${totalBytesStr}`;

0 commit comments

Comments
 (0)