Add function to download all files as a zip
This commit is contained in:
@@ -50,6 +50,12 @@ Without docker:
|
|||||||
1. Run `npm install`
|
1. Run `npm install`
|
||||||
2. Run `npm run build && npm run start`
|
2. Run `npm run build && npm run start`
|
||||||
|
|
||||||
|
|
||||||
|
## Known issues / Limitations
|
||||||
|
Pingvin Share is currently in beta and there are issues and limitations that should be fixed in the future.
|
||||||
|
- `DownloadAll` generates the zip file on the client side. This takes alot of time. Because of that I temporarily limited this function to maximal 150 MB.
|
||||||
|
- If a user knows the share id, he can list and download the files directly from the Appwrite API even if the share is secured by a password or a visitor limit.
|
||||||
|
|
||||||
## Contribute
|
## Contribute
|
||||||
|
|
||||||
You're very welcome to contribute to Pingvin Share!
|
You're very welcome to contribute to Pingvin Share!
|
||||||
|
|||||||
152
package-lock.json
generated
152
package-lock.json
generated
@@ -19,7 +19,9 @@
|
|||||||
"axios": "^0.26.1",
|
"axios": "^0.26.1",
|
||||||
"cookie": "^0.5.0",
|
"cookie": "^0.5.0",
|
||||||
"cookies-next": "^2.0.4",
|
"cookies-next": "^2.0.4",
|
||||||
|
"file-saver": "^2.0.5",
|
||||||
"js-file-download": "^0.4.12",
|
"js-file-download": "^0.4.12",
|
||||||
|
"jszip": "^3.9.1",
|
||||||
"next": "12.1.5",
|
"next": "12.1.5",
|
||||||
"next-pwa": "^5.5.2",
|
"next-pwa": "^5.5.2",
|
||||||
"node-appwrite": "^5.1.0",
|
"node-appwrite": "^5.1.0",
|
||||||
@@ -30,6 +32,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/cookie": "^0.5.0",
|
"@types/cookie": "^0.5.0",
|
||||||
|
"@types/file-saver": "^2.0.5",
|
||||||
"@types/node": "17.0.23",
|
"@types/node": "17.0.23",
|
||||||
"@types/react": "18.0.4",
|
"@types/react": "18.0.4",
|
||||||
"@types/react-dom": "18.0.0",
|
"@types/react-dom": "18.0.0",
|
||||||
@@ -2527,6 +2530,12 @@
|
|||||||
"integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==",
|
"integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==",
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/file-saver": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-zv9kNf3keYegP5oThGLaPk8E081DFDuwfqjtiTzm6PoxChdJ1raSuADf2YGCVIyrSynLrgc8JWv296s7Q7pQSQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@types/glob": {
|
"node_modules/@types/glob": {
|
||||||
"version": "7.2.0",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
|
||||||
@@ -4455,6 +4464,11 @@
|
|||||||
"node": "^10.12.0 || >=12.0.0"
|
"node": "^10.12.0 || >=12.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/file-saver": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
|
||||||
|
},
|
||||||
"node_modules/file-selector": {
|
"node_modules/file-selector": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.4.0.tgz",
|
||||||
@@ -4895,6 +4909,11 @@
|
|||||||
"node": ">= 4"
|
"node": ">= 4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/immediate": {
|
||||||
|
"version": "3.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
|
||||||
|
"integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
|
||||||
|
},
|
||||||
"node_modules/import-fresh": {
|
"node_modules/import-fresh": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||||
@@ -5364,6 +5383,44 @@
|
|||||||
"node": ">=4.0"
|
"node": ">=4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/jszip": {
|
||||||
|
"version": "3.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.9.1.tgz",
|
||||||
|
"integrity": "sha512-H9A60xPqJ1CuC4Ka6qxzXZeU8aNmgOeP5IFqwJbQQwtu2EUYxota3LdsiZWplF7Wgd9tkAd0mdu36nceSaPuYw==",
|
||||||
|
"dependencies": {
|
||||||
|
"lie": "~3.3.0",
|
||||||
|
"pako": "~1.0.2",
|
||||||
|
"readable-stream": "~2.3.6",
|
||||||
|
"set-immediate-shim": "~1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/jszip/node_modules/isarray": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||||
|
},
|
||||||
|
"node_modules/jszip/node_modules/readable-stream": {
|
||||||
|
"version": "2.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||||
|
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
|
||||||
|
"dependencies": {
|
||||||
|
"core-util-is": "~1.0.0",
|
||||||
|
"inherits": "~2.0.3",
|
||||||
|
"isarray": "~1.0.0",
|
||||||
|
"process-nextick-args": "~2.0.0",
|
||||||
|
"safe-buffer": "~5.1.1",
|
||||||
|
"string_decoder": "~1.1.1",
|
||||||
|
"util-deprecate": "~1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/jszip/node_modules/string_decoder": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "~5.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/language-subtag-registry": {
|
"node_modules/language-subtag-registry": {
|
||||||
"version": "0.3.21",
|
"version": "0.3.21",
|
||||||
"resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz",
|
"resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz",
|
||||||
@@ -5400,6 +5457,14 @@
|
|||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lie": {
|
||||||
|
"version": "3.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
|
||||||
|
"integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"immediate": "~3.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/lines-and-columns": {
|
"node_modules/lines-and-columns": {
|
||||||
"version": "1.2.4",
|
"version": "1.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
||||||
@@ -5950,6 +6015,11 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pako": {
|
||||||
|
"version": "1.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
|
||||||
|
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
|
||||||
|
},
|
||||||
"node_modules/parent-module": {
|
"node_modules/parent-module": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||||
@@ -6597,6 +6667,14 @@
|
|||||||
"randombytes": "^2.1.0"
|
"randombytes": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/set-immediate-shim": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/shebang-command": {
|
"node_modules/shebang-command": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
@@ -9469,6 +9547,12 @@
|
|||||||
"integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==",
|
"integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==",
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
|
"@types/file-saver": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-zv9kNf3keYegP5oThGLaPk8E081DFDuwfqjtiTzm6PoxChdJ1raSuADf2YGCVIyrSynLrgc8JWv296s7Q7pQSQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/glob": {
|
"@types/glob": {
|
||||||
"version": "7.2.0",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
|
||||||
@@ -10991,6 +11075,11 @@
|
|||||||
"flat-cache": "^3.0.4"
|
"flat-cache": "^3.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"file-saver": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
|
||||||
|
},
|
||||||
"file-selector": {
|
"file-selector": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.4.0.tgz",
|
||||||
@@ -11314,6 +11403,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
|
||||||
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ=="
|
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ=="
|
||||||
},
|
},
|
||||||
|
"immediate": {
|
||||||
|
"version": "3.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
|
||||||
|
"integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
|
||||||
|
},
|
||||||
"import-fresh": {
|
"import-fresh": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||||
@@ -11648,6 +11742,46 @@
|
|||||||
"object.assign": "^4.1.2"
|
"object.assign": "^4.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"jszip": {
|
||||||
|
"version": "3.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.9.1.tgz",
|
||||||
|
"integrity": "sha512-H9A60xPqJ1CuC4Ka6qxzXZeU8aNmgOeP5IFqwJbQQwtu2EUYxota3LdsiZWplF7Wgd9tkAd0mdu36nceSaPuYw==",
|
||||||
|
"requires": {
|
||||||
|
"lie": "~3.3.0",
|
||||||
|
"pako": "~1.0.2",
|
||||||
|
"readable-stream": "~2.3.6",
|
||||||
|
"set-immediate-shim": "~1.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"isarray": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||||
|
},
|
||||||
|
"readable-stream": {
|
||||||
|
"version": "2.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||||
|
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
|
||||||
|
"requires": {
|
||||||
|
"core-util-is": "~1.0.0",
|
||||||
|
"inherits": "~2.0.3",
|
||||||
|
"isarray": "~1.0.0",
|
||||||
|
"process-nextick-args": "~2.0.0",
|
||||||
|
"safe-buffer": "~5.1.1",
|
||||||
|
"string_decoder": "~1.1.1",
|
||||||
|
"util-deprecate": "~1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"string_decoder": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||||
|
"requires": {
|
||||||
|
"safe-buffer": "~5.1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"language-subtag-registry": {
|
"language-subtag-registry": {
|
||||||
"version": "0.3.21",
|
"version": "0.3.21",
|
||||||
"resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz",
|
"resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz",
|
||||||
@@ -11678,6 +11812,14 @@
|
|||||||
"type-check": "~0.4.0"
|
"type-check": "~0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"lie": {
|
||||||
|
"version": "3.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
|
||||||
|
"integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
|
||||||
|
"requires": {
|
||||||
|
"immediate": "~3.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"lines-and-columns": {
|
"lines-and-columns": {
|
||||||
"version": "1.2.4",
|
"version": "1.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
||||||
@@ -12080,6 +12222,11 @@
|
|||||||
"integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
|
"integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"pako": {
|
||||||
|
"version": "1.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
|
||||||
|
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
|
||||||
|
},
|
||||||
"parent-module": {
|
"parent-module": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||||
@@ -12536,6 +12683,11 @@
|
|||||||
"randombytes": "^2.1.0"
|
"randombytes": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"set-immediate-shim": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E="
|
||||||
|
},
|
||||||
"shebang-command": {
|
"shebang-command": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
|
|||||||
@@ -22,7 +22,9 @@
|
|||||||
"axios": "^0.26.1",
|
"axios": "^0.26.1",
|
||||||
"cookie": "^0.5.0",
|
"cookie": "^0.5.0",
|
||||||
"cookies-next": "^2.0.4",
|
"cookies-next": "^2.0.4",
|
||||||
|
"file-saver": "^2.0.5",
|
||||||
"js-file-download": "^0.4.12",
|
"js-file-download": "^0.4.12",
|
||||||
|
"jszip": "^3.9.1",
|
||||||
"next": "12.1.5",
|
"next": "12.1.5",
|
||||||
"next-pwa": "^5.5.2",
|
"next-pwa": "^5.5.2",
|
||||||
"node-appwrite": "^5.1.0",
|
"node-appwrite": "^5.1.0",
|
||||||
@@ -33,6 +35,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/cookie": "^0.5.0",
|
"@types/cookie": "^0.5.0",
|
||||||
|
"@types/file-saver": "^2.0.5",
|
||||||
"@types/node": "17.0.23",
|
"@types/node": "17.0.23",
|
||||||
"@types/react": "18.0.4",
|
"@types/react": "18.0.4",
|
||||||
"@types/react-dom": "18.0.0",
|
"@types/react-dom": "18.0.0",
|
||||||
|
|||||||
67
src/components/share/DownloadAllButton.tsx
Normal file
67
src/components/share/DownloadAllButton.tsx
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
import { Tooltip, Button } from "@mantine/core";
|
||||||
|
import saveAs from "file-saver";
|
||||||
|
import JSZip from "jszip";
|
||||||
|
import { Dispatch, SetStateAction, useState } from "react";
|
||||||
|
import { AppwriteFileWithPreview } from "../../types/File.type";
|
||||||
|
import aw from "../../utils/appwrite.util";
|
||||||
|
|
||||||
|
const DownloadAllButton = ({
|
||||||
|
shareId,
|
||||||
|
files,
|
||||||
|
setFiles,
|
||||||
|
}: {
|
||||||
|
shareId: string;
|
||||||
|
files: AppwriteFileWithPreview[];
|
||||||
|
setFiles: Dispatch<SetStateAction<AppwriteFileWithPreview[]>>;
|
||||||
|
}) => {
|
||||||
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||||
|
const downloadAll = async () => {
|
||||||
|
setIsLoading(true);
|
||||||
|
var zip = new JSZip();
|
||||||
|
for (let i = 0; i < files.length; i++) {
|
||||||
|
files[i].uploadingState = "inProgress";
|
||||||
|
setFiles([...files]);
|
||||||
|
zip.file(
|
||||||
|
files[i].name,
|
||||||
|
await (
|
||||||
|
await fetch(
|
||||||
|
aw.storage.getFileDownload(shareId, files[i].$id).toString()
|
||||||
|
)
|
||||||
|
).blob()
|
||||||
|
);
|
||||||
|
files[i].uploadingState = "finished";
|
||||||
|
setFiles([...files]);
|
||||||
|
}
|
||||||
|
zip.generateAsync({ type: "blob" }).then(function (content) {
|
||||||
|
setIsLoading(false);
|
||||||
|
saveAs(content, `${shareId}-pingvin-share.zip`);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const isFileTooBig = () => {
|
||||||
|
let shareSize = 0;
|
||||||
|
files.forEach((file) => (shareSize = +file.sizeOriginal));
|
||||||
|
return 150000000 > shareSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!isFileTooBig())
|
||||||
|
return (
|
||||||
|
<Tooltip
|
||||||
|
wrapLines
|
||||||
|
position="bottom"
|
||||||
|
width={220}
|
||||||
|
withArrow
|
||||||
|
label="Only available if your share is smaller than 150 MB."
|
||||||
|
>
|
||||||
|
<Button variant="outline" onClick={downloadAll} disabled>
|
||||||
|
Download all
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<Button variant="outline" loading={isLoading} onClick={downloadAll}>
|
||||||
|
Download all
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DownloadAllButton;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ActionIcon, Skeleton, Table } from "@mantine/core";
|
import { ActionIcon, Loader, Skeleton, Table } from "@mantine/core";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { Download } from "tabler-icons-react";
|
import { CircleCheck, Download } from "tabler-icons-react";
|
||||||
import { AppwriteFileWithPreview } from "../../types/File.type";
|
import { AppwriteFileWithPreview } from "../../types/File.type";
|
||||||
import aw from "../../utils/appwrite.util";
|
import aw from "../../utils/appwrite.util";
|
||||||
import { bytesToSize } from "../../utils/math/byteToSize.util";
|
import { bytesToSize } from "../../utils/math/byteToSize.util";
|
||||||
@@ -50,6 +50,13 @@ const FileList = ({
|
|||||||
<td>{file.name}</td>
|
<td>{file.name}</td>
|
||||||
<td>{bytesToSize(file.sizeOriginal)}</td>
|
<td>{bytesToSize(file.sizeOriginal)}</td>
|
||||||
<td>
|
<td>
|
||||||
|
{file.uploadingState ? (
|
||||||
|
file.uploadingState != "finished" ? (
|
||||||
|
<Loader size={22} />
|
||||||
|
) : (
|
||||||
|
<CircleCheck color="green" size={22} />
|
||||||
|
)
|
||||||
|
) : (
|
||||||
<ActionIcon
|
<ActionIcon
|
||||||
size={25}
|
size={25}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
@@ -58,6 +65,7 @@ const FileList = ({
|
|||||||
>
|
>
|
||||||
<Download />
|
<Download />
|
||||||
</ActionIcon>
|
</ActionIcon>
|
||||||
|
)}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
|
import { Group } from "@mantine/core";
|
||||||
import { useModals } from "@mantine/modals";
|
import { useModals } from "@mantine/modals";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import Meta from "../../components/Meta";
|
import Meta from "../../components/Meta";
|
||||||
|
import DownloadAllButton from "../../components/share/DownloadAllButton";
|
||||||
import FileList from "../../components/share/FileList";
|
import FileList from "../../components/share/FileList";
|
||||||
import showEnterPasswordModal from "../../components/share/showEnterPasswordModal";
|
import showEnterPasswordModal from "../../components/share/showEnterPasswordModal";
|
||||||
import showShareNotFoundModal from "../../components/share/showShareNotFoundModal";
|
import showShareNotFoundModal from "../../components/share/showShareNotFoundModal";
|
||||||
@@ -13,7 +15,7 @@ const Share = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const modals = useModals();
|
const modals = useModals();
|
||||||
const shareId = router.query.shareId as string;
|
const shareId = router.query.shareId as string;
|
||||||
const [shareList, setShareList] = useState<AppwriteFileWithPreview[]>([]);
|
const [fileList, setFileList] = useState<AppwriteFileWithPreview[]>([]);
|
||||||
|
|
||||||
const submitPassword = async (password: string) => {
|
const submitPassword = async (password: string) => {
|
||||||
await shareService.authenticateWithPassword(shareId, password).then(() => {
|
await shareService.authenticateWithPassword(shareId, password).then(() => {
|
||||||
@@ -25,7 +27,9 @@ const Share = () => {
|
|||||||
const getFiles = (password?: string) =>
|
const getFiles = (password?: string) =>
|
||||||
shareService
|
shareService
|
||||||
.get(shareId, password)
|
.get(shareId, password)
|
||||||
.then((files) => setShareList(files))
|
.then((files) => {
|
||||||
|
setFileList(files);
|
||||||
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
const error = e.response.data.message;
|
const error = e.response.data.message;
|
||||||
if (e.response.status == 404) {
|
if (e.response.status == 404) {
|
||||||
@@ -44,10 +48,17 @@ const Share = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Meta title={`Share ${shareId}`} />
|
<Meta title={`Share ${shareId}`} />
|
||||||
<FileList
|
<Group position="right">
|
||||||
files={shareList}
|
<DownloadAllButton
|
||||||
shareId={shareId}
|
shareId={shareId}
|
||||||
isLoading={shareList.length == 0}
|
files={fileList}
|
||||||
|
setFiles={setFileList}
|
||||||
|
/>
|
||||||
|
</Group>
|
||||||
|
<FileList
|
||||||
|
files={fileList}
|
||||||
|
shareId={shareId}
|
||||||
|
isLoading={fileList.length == 0}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,5 +3,7 @@ import { Models } from "appwrite";
|
|||||||
export type FileUpload = File & { uploadingState?: UploadState };
|
export type FileUpload = File & { uploadingState?: UploadState };
|
||||||
export type UploadState = "finished" | "inProgress" | undefined;
|
export type UploadState = "finished" | "inProgress" | undefined;
|
||||||
|
|
||||||
export type AppwriteFileWithPreview = Models.File & { preview: Buffer };
|
export interface AppwriteFileWithPreview extends Models.File {
|
||||||
|
uploadingState?: UploadState;
|
||||||
|
preview: Buffer;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user