Skip to content

Commit cf57a2b

Browse files
committed
#204 fix for zip plain files
1 parent 770789e commit cf57a2b

File tree

9 files changed

+575
-263
lines changed

9 files changed

+575
-263
lines changed

.eslintrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"extends": [
3-
"@react-native-community"
3+
"@react-native-community",
4+
"prettier"
45
]
56
}

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import { MainBundlePath, DocumentDirectoryPath } from 'react-native-fs'
4747

4848
## API
4949

50-
**`zip(source: string, target: string): Promise<string>`**
50+
**`zip(source: string | string[], target: string): Promise<string>`**
5151

5252
> zip source to target
5353
@@ -68,7 +68,7 @@ zip(sourcePath, targetPath)
6868
})
6969
```
7070

71-
**`zipWithPassword(source: string, target: string, password: string, encryptionType: string): Promise<string>`**
71+
**`zipWithPassword(source: string | string[], target: string, password: string, encryptionType: string): Promise<string>`**
7272

7373
> zip source to target
7474

android/src/main/java/com/rnziparchive/RNZipArchiveModule.java

Lines changed: 69 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.facebook.react.bridge.ReactContextBaseJavaModule;
1111
import com.facebook.react.bridge.ReactMethod;
1212
import com.facebook.react.bridge.WritableMap;
13+
import com.facebook.react.bridge.ReadableArray;
1314
import com.facebook.react.modules.core.DeviceEventManagerModule;
1415

1516
import java.io.BufferedInputStream;
@@ -324,23 +325,33 @@ public void onCopyProgress(long bytesRead) {
324325
}
325326

326327
@ReactMethod
327-
public void zip(String fileOrDirectory, String destDirectory, Promise promise) {
328-
try{
329-
330-
ZipParameters parameters = new ZipParameters();
331-
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
332-
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
328+
public void zipFiles(final ReadableArray files, final String destDirectory, final Promise promise) {
329+
zip(files.toArrayList(), destDirectory, promise);
330+
}
333331

334-
processZip(fileOrDirectory, destDirectory, parameters, promise);
332+
@ReactMethod
333+
public void zipFolder(final String folder, final String destFile, final Promise promise) {
334+
ArrayList<Object> folderAsArrayList = new ArrayList<>();
335+
folderAsArrayList.add(folder);
336+
zip(folderAsArrayList, destFile, promise);
337+
}
335338

336-
} catch (Exception ex) {
337-
promise.reject(null, ex.getMessage());
338-
return;
339-
}
339+
@ReactMethod
340+
public void zipFilesWithPassword(final ReadableArray files, final String destFile, final String password,
341+
String encryptionMethod, Promise promise) {
342+
zipWithPassword(files.toArrayList(), destFile, password, encryptionMethod, promise);
340343
}
341344

345+
342346
@ReactMethod
343-
public void zipWithPassword(String fileOrDirectory, String destDirectory, String password,
347+
public void zipFolderWithPassword(final String folder, final String destFile, final String password,
348+
String encryptionMethod, Promise promise) {
349+
ArrayList<Object> folderAsArrayList = new ArrayList<>();
350+
folderAsArrayList.add(folder);
351+
zipWithPassword(folderAsArrayList, destFile, password, encryptionMethod, promise);
352+
}
353+
354+
private void zipWithPassword(final ArrayList<Object> filesOrDirectory, final String destFile, final String password,
344355
String encryptionMethod, Promise promise) {
345356
try{
346357

@@ -373,7 +384,7 @@ public void zipWithPassword(String fileOrDirectory, String destDirectory, String
373384
promise.reject(null, "Password is empty");
374385
}
375386

376-
processZip(fileOrDirectory, destDirectory, parameters, promise);
387+
processZip(filesOrDirectory, destFile, parameters, promise);
377388

378389
} catch (Exception ex) {
379390
promise.reject(null, ex.getMessage());
@@ -382,51 +393,67 @@ public void zipWithPassword(String fileOrDirectory, String destDirectory, String
382393

383394
}
384395

385-
private void processZip(final String fileOrDirectory, final String destDirectory, final ZipParameters parameters, final Promise promise) {
396+
private void zip(final ArrayList<Object> filesOrDirectory, final String destFile, final Promise promise) {
397+
try{
398+
399+
ZipParameters parameters = new ZipParameters();
400+
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
401+
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
402+
403+
processZip(filesOrDirectory, destFile, parameters, promise);
404+
405+
} catch (Exception ex) {
406+
promise.reject(null, ex.getMessage());
407+
return;
408+
}
409+
}
410+
411+
private void processZip(final ArrayList<Object> entries, final String destFile, final ZipParameters parameters, final Promise promise) {
386412
new Thread(new Runnable() {
387413
@Override
388414
public void run() {
389415
try {
390-
net.lingala.zip4j.core.ZipFile zipFile = new net.lingala.zip4j.core.ZipFile(destDirectory);
391-
392-
updateProgress(0, 100, destDirectory);
416+
net.lingala.zip4j.core.ZipFile zipFile = new net.lingala.zip4j.core.ZipFile(destFile);
393417

394-
File f = new File(fileOrDirectory);
418+
updateProgress(0, 100, destFile);
395419

396420
int totalFiles = 0;
397421
int fileCounter = 0;
398422

399-
if (f.exists()) {
400-
if (f.isDirectory()) {
423+
for (int i = 0; i < entries.size(); i++) {
424+
File f = new File(entries.get(i).toString());
401425

402-
List<File> files = Arrays.asList(f.listFiles());
426+
if (f.exists()) {
427+
if (f.isDirectory()) {
403428

404-
totalFiles = files.size();
405-
for (int i = 0; i < files.size(); i++) {
406-
if (files.get(i).isDirectory()) {
407-
zipFile.addFolder(files.get(i).getAbsolutePath(), parameters);
408-
}
409-
else {
410-
zipFile.addFile(files.get(i), parameters);
429+
List<File> files = Arrays.asList(f.listFiles());
430+
431+
totalFiles += files.size();
432+
for (int j = 0; j < files.size(); j++) {
433+
if (files.get(j).isDirectory()) {
434+
zipFile.addFolder(files.get(j).getAbsolutePath(), parameters);
435+
}
436+
else {
437+
zipFile.addFile(files.get(j), parameters);
438+
}
439+
fileCounter += 1;
440+
updateProgress(fileCounter, totalFiles, destFile);
411441
}
442+
443+
} else {
444+
totalFiles += 1;
445+
zipFile.addFile(f, parameters);
412446
fileCounter += 1;
413-
updateProgress(fileCounter, totalFiles, destDirectory);
447+
updateProgress(fileCounter, totalFiles, destFile);
414448
}
415-
416-
} else {
417-
totalFiles = 1;
418-
zipFile.addFile(f, parameters);
419-
fileCounter += 1;
420-
updateProgress(fileCounter, totalFiles, destDirectory);
421449
}
422-
}
423-
else {
424-
promise.reject(null, "File or folder does not exist");
425-
}
426-
427-
updateProgress(1, 1, destDirectory); // force 100%
428-
promise.resolve(destDirectory);
450+
else {
451+
promise.reject(null, "File or folder does not exist");
452+
}
429453

454+
updateProgress(1, 1, destFile); // force 100%
455+
promise.resolve(destFile);
456+
}
430457
} catch (Exception ex) {
431458
promise.reject(null, ex.getMessage());
432459
return;

index.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ declare module 'react-native-zip-archive' {
66
}
77
import { NativeEventSubscription } from 'react-native';
88
export function isPasswordProtected(source: string): Promise<boolean>;
9-
export function zip(source: string, target: string): Promise<string>;
10-
export function zipWithPassword(source: string, target: string, password: string, encryptionMethod?: encryptionMethods): Promise<string>;
9+
export function zip(source: string | [string], target: string): Promise<string>;
10+
export function zipWithPassword(source: string | [string], target: string, password: string, encryptionMethod?: encryptionMethods): Promise<string>;
1111
export function unzip(source: string, target: string, charset?: string): Promise<string>;
1212
export function unzipWithPassword(assetPath: string, target: string, password: string): Promise<string>;
1313
export function unzipAssets(assetPath: string, target: string): Promise<string>;

index.js

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ const RNZipArchive = NativeModules.RNZipArchive;
66

77
const rnzaEmitter = new NativeEventEmitter(RNZipArchive);
88

9-
const normalizeFilePath = path =>
9+
const normalizeFilePath = (path) =>
1010
path.startsWith("file://") ? path.slice(7) : path;
1111

1212
export const unzip = (source, target, charset = "UTF-8") => {
1313
return RNZipArchive.unzip(normalizeFilePath(source), target, charset);
1414
};
15-
export const isPasswordProtected = source => {
15+
export const isPasswordProtected = (source) => {
1616
return RNZipArchive.isPasswordProtected(normalizeFilePath(source)).then(
17-
isEncrypted => !!isEncrypted
17+
(isEncrypted) => !!isEncrypted
1818
);
1919
};
2020

@@ -32,16 +32,25 @@ export const zipWithPassword = (
3232
password,
3333
encryptionMethod = ""
3434
) => {
35-
return RNZipArchive.zipWithPassword(
36-
normalizeFilePath(source),
37-
target,
38-
password,
39-
encryptionMethod
40-
);
35+
return Array.isArray(source)
36+
? RNZipArchive.zipFilesWithPassword(
37+
source.map(normalizeFilePath),
38+
target,
39+
password,
40+
encryptionMethod
41+
)
42+
: RNZipArchive.zipFolderWithPassword(
43+
normalizeFilePath(source),
44+
target,
45+
password,
46+
encryptionMethod
47+
);
4148
};
4249

4350
export const zip = (source, target) => {
44-
return RNZipArchive.zip(normalizeFilePath(source), target);
51+
return Array.isArray(source)
52+
? RNZipArchive.zipFiles(source.map(normalizeFilePath), target)
53+
: RNZipArchive.zipFolder(normalizeFilePath(source), target);
4554
};
4655

4756
export const unzipAssets = (source, target) => {
@@ -52,6 +61,6 @@ export const unzipAssets = (source, target) => {
5261
return RNZipArchive.unzipAssets(normalizeFilePath(source), target);
5362
};
5463

55-
export const subscribe = callback => {
64+
export const subscribe = (callback) => {
5665
return rnzaEmitter.addListener("zipArchiveProgressEvent", callback);
5766
};

ios/RNZipArchive.m

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ @implementation RNZipArchive
8080
}
8181
}
8282

83-
RCT_EXPORT_METHOD(zip:(NSString *)from
83+
RCT_EXPORT_METHOD(zipFolder:(NSString *)from
8484
destinationPath:(NSString *)destinationPath
8585
resolver:(RCTPromiseResolveBlock)resolve
8686
rejecter:(RCTPromiseRejectBlock)reject) {
@@ -90,6 +90,7 @@ @implementation RNZipArchive
9090

9191
BOOL success;
9292
[self setProgressHandler];
93+
9394
success = [SSZipArchive createZipFileAtPath:destinationPath withContentsOfDirectory:from keepParentDirectory:NO withPassword:nil andProgressHandler:self.progressHandler];
9495

9596
self.progress = 1.0;
@@ -103,8 +104,32 @@ @implementation RNZipArchive
103104
}
104105
}
105106

107+
RCT_EXPORT_METHOD(zipFiles:(NSArray<NSString *> *)from
108+
destinationPath:(NSString *)destinationPath
109+
resolver:(RCTPromiseResolveBlock)resolve
110+
rejecter:(RCTPromiseRejectBlock)reject) {
111+
self.progress = 0.0;
112+
self.processedFilePath = @"";
113+
[self zipArchiveProgressEvent:0 total:1]; // force 0%
114+
115+
BOOL success;
116+
[self setProgressHandler];
117+
118+
success = [SSZipArchive createZipFileAtPath:destinationPath withFilesAtPaths:from];
119+
120+
self.progress = 1.0;
121+
[self zipArchiveProgressEvent:1 total:1]; // force 100%
122+
123+
if (success) {
124+
resolve(destinationPath);
125+
} else {
126+
NSError *error = nil;
127+
reject(@"zip_error", @"unable to zip", error);
128+
}
129+
}
130+
106131

107-
RCT_EXPORT_METHOD(zipWithPassword:(NSString *)from
132+
RCT_EXPORT_METHOD(zipFolderWithPassword:(NSString *)from
108133
destinationPath:(NSString *)destinationPath
109134
password:(NSString *)password
110135
encryptionType:(NSString *)encryptionType
@@ -129,6 +154,31 @@ @implementation RNZipArchive
129154
}
130155
}
131156

157+
RCT_EXPORT_METHOD(zipFilesWithPassword:(NSArray<NSString *> *)from
158+
destinationPath:(NSString *)destinationPath
159+
password:(NSString *)password
160+
encryptionType:(NSString *)encryptionType
161+
resolver:(RCTPromiseResolveBlock)resolve
162+
rejecter:(RCTPromiseRejectBlock)reject) {
163+
self.progress = 0.0;
164+
self.processedFilePath = @"";
165+
[self zipArchiveProgressEvent:0 total:1]; // force 0%
166+
167+
BOOL success;
168+
[self setProgressHandler];
169+
success = [SSZipArchive createZipFileAtPath:destinationPath withFilesAtPaths:from withPassword:password];
170+
171+
self.progress = 1.0;
172+
[self zipArchiveProgressEvent:1 total:1]; // force 100%
173+
174+
if (success) {
175+
resolve(destinationPath);
176+
} else {
177+
NSError *error = nil;
178+
reject(@"zip_error", @"unable to zip", error);
179+
}
180+
}
181+
132182
- (dispatch_queue_t)methodQueue {
133183
return dispatch_queue_create("com.mockingbot.ReactNative.ZipArchiveQueue", DISPATCH_QUEUE_SERIAL);
134184
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>IDEDidComputeMac32BitWarning</key>
6+
<true/>
7+
</dict>
8+
</plist>

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"main": "index.js",
66
"scripts": {
77
"test": "echo \"Error: no test specified\" && exit 1",
8-
"lint:js": "eslint index.js"
8+
"lint": "eslint index.js"
99
},
1010
"repository": {
1111
"type": "git",
@@ -25,7 +25,7 @@
2525
"license": "MIT",
2626
"devDependencies": {
2727
"@babel/core": "*",
28-
"@react-native-community/eslint-config": "^0.0.5",
28+
"@react-native-community/eslint-config": "^2.0.0",
2929
"eslint": "^6.7.2",
3030
"react": "^16.8.6",
3131
"react-native": "^0.60.0"

0 commit comments

Comments
 (0)