Skip to content

Commit

Permalink
Add zip compression, allow node 14, global ember-cli
Browse files Browse the repository at this point in the history
  • Loading branch information
valoricDe committed Sep 9, 2020
1 parent f3d0a9d commit 9ce8ae8
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 62 deletions.
6 changes: 2 additions & 4 deletions Dockerfile
Expand Up @@ -2,10 +2,8 @@ FROM node:14-buster
RUN mkdir -p /srv/app
WORKDIR /srv/app
COPY package.json yarn.lock ./
RUN yarn --production --frozen-lockfile --non-interactive
RUN yarn --frozen-lockfile --non-interactive

COPY . /srv/app
ENV NODE_ENV production
RUN yarn build
EXPOSE 8000
CMD [ "yarn", "start" ]
CMD [ "yarn", "develop" ]
19 changes: 1 addition & 18 deletions app/components/file-field.js
@@ -1,6 +1,5 @@
import TextField from '@ember/component/text-field';
import $ from 'jquery';
import JSZip from 'jszip';

export default TextField.extend({
type: 'file',
Expand All @@ -13,23 +12,7 @@ export default TextField.extend({
change(event) {
const input = event.target;
const { files } = input;

if (files.length > 1) {
const zip = new JSZip();
files.forEach((file) => {
zip.file(file.name, file);
});

zip.generateAsync({ type: 'blob' }).then(function (blob) {
this.onChange({
file: new File([blob], 'sharedrop.zip', {
type: 'application/zip',
}),
});
});
} else {
this.onchange({ file: files[0] });
}
this.onChange({ files });
this.reset();
},

Expand Down
48 changes: 21 additions & 27 deletions app/components/peer-avatar.js
Expand Up @@ -2,7 +2,6 @@ import Component from '@ember/component';
import { alias } from '@ember/object/computed';
import { later } from '@ember/runloop';
import $ from 'jquery';
import { Promise } from 'rsvp';

export default Component.extend({
tagName: 'img',
Expand Down Expand Up @@ -91,18 +90,15 @@ export default Component.extend({
const { peer } = this;
const dt = event.originalEvent.dataTransfer;
const { files } = dt;
const file = files[0];

if (this.canSendFile()) {
if (files.length > 1) {
if (!this.isTransferableBundle(files)) {
peer.setProperties({
state: 'error',
errorCode: 'multiple-files',
});
} else {
this.isFile(file).then(() => {
this.onFileDrop({ file });
});
this.onFileDrop({ files });
}
}
},
Expand All @@ -119,27 +115,25 @@ export default Component.extend({
return !(peer.get('transfer.file') || peer.get('transfer.info'));
},

isFile(file) {
return new Promise((resolve, reject) => {
if (file instanceof window.File) {
if (file.size > 1048576) {
// It's bigger than 1MB, so we assume it's a file
resolve();
} else {
// Try to read it using FileReader - if it's not a file,
// it should trigger onerror handler
const reader = new FileReader();
reader.onload = function () {
resolve();
};
reader.onerror = function () {
reject();
};
reader.readAsArrayBuffer(file);
}
} else {
reject();
isTransferableBundle(files) {
if (files.length === 1 && files[0] instanceof window.File) return true;

const fileSizeLimit = 50 * 1024 * 1024;
const bundleSizeLimit = 200 * 1024 * 1024;
let aggregatedSize = 0;
// eslint-disable-next-line no-restricted-syntax
for (const file of files) {
if (!(file instanceof window.File)) {
return false;
}
});
if (file.size > fileSizeLimit) {
return false;
}
aggregatedSize += file.size;
if (aggregatedSize > bundleSizeLimit) {
return false;
}
}
return true;
},
});
37 changes: 34 additions & 3 deletions app/components/peer-widget.js
@@ -1,6 +1,32 @@
import Component from '@ember/component';
import { computed } from '@ember/object';
import { alias, equal } from '@ember/object/computed';
import JSZip from 'jszip';

function reduceFiles(files) {
if (files.length === 1) {
return Promise.resolve(files[0]);
}

const zip = new JSZip();
Array.prototype.forEach.call(files, (file) => {
zip.file(file.name, file);
});

return zip.generateAsync({ type: 'blob' }).then(
(blob) =>
new File(
[blob],
`sharedrop-${new Date()
.toISOString()
.substring(0, 19)
.replace('T', '-')}.zip`,
{
type: 'application/zip',
},
),
);
}

export default Component.extend({
classNames: ['peer'],
Expand All @@ -13,6 +39,7 @@ export default Component.extend({
label: alias('peer.label'),

isIdle: equal('peer.state', 'idle'),
isPreparingFileTransfer: equal('peer.state', 'is_preparing_file_transfer'),
hasSelectedFile: equal('peer.state', 'has_selected_file'),
isSendingFileInfo: equal('peer.state', 'sending_file_info'),
isAwaitingFileInfo: equal('peer.state', 'awaiting_file_info'),
Expand All @@ -39,12 +66,16 @@ export default Component.extend({
// TODO: rename to something more meaningful (e.g. askIfWantToSendFile)
uploadFile(data) {
const { peer } = this;
const { file } = data;
const { files } = data;

peer.set('state', 'is_preparing_file_transfer');

// Cache the file, so that it's available
// when the response from the recipient comes in
peer.set('transfer.file', file);
peer.set('state', 'has_selected_file');
reduceFiles(files).then((file) => {
peer.set('transfer.file', file);
peer.set('state', 'has_selected_file');
});
},

sendFileTransferInquiry() {
Expand Down
11 changes: 9 additions & 2 deletions app/templates/components/peer-widget.hbs
@@ -1,4 +1,4 @@
{{! Sender related popups }}
{{! Sender related messages }}
{{#if hasSelectedFile}}
{{#popover-confirm
onConfirm=(action "sendFileTransferInquiry")
Expand Down Expand Up @@ -63,7 +63,14 @@
<div class="user-ip">
<div class="user-connection-status {{peer.peer.state}}"></div>
<span>{{peer.label}}</span>
{{#if isPreparingFileTransfer}}
<div>
Is packaging selected files
<br><br>
TIP: You can archive files on your device beforehand to speed up the operation
</div>
{{/if}}
</div>
</div>

{{file-field onChange=(action "uploadFile")}}
{{file-field multiple=true onChange=(action "uploadFile")}}
4 changes: 2 additions & 2 deletions app/templates/errors/popovers/multiple-files.hbs
@@ -1,3 +1,3 @@
You can only send one file at a time.
The files you have selected exceed the maximum allowed size of 200MB
<br><br>
TIP: You can archive mulitple files and send as one.
TIP: You can send single files without size restriction
5 changes: 0 additions & 5 deletions ember-cli-build.js
Expand Up @@ -3,11 +3,6 @@ const EmberApp = require('ember-cli/lib/broccoli/ember-app');

module.exports = function (defaults) {
const app = new EmberApp(defaults, {
autoImport: {
alias: {
jszip: require.resolve('jszip/lib/index.js'),
},
},
dotEnv: {
clientAllowedKeys: ['FIREBASE_URL'],
},
Expand Down
4 changes: 3 additions & 1 deletion package.json
Expand Up @@ -48,6 +48,7 @@
"ember-resolver": "^7.0.0",
"ember-source": "~3.17.0",
"ember-template-lint": "^2.4.0",
"emberx-file-input": "^1.2.1",
"eslint": "^7.5.0",
"eslint-config-airbnb-base": "^14.1.0",
"eslint-config-prettier": "^6.11.0",
Expand Down Expand Up @@ -75,6 +76,7 @@
"lodash": "^4.17.11",
"morgan": "^1.5.0",
"newrelic": "^6.11.0",
"stream": "^0.0.2",
"uuid": "^8.2.0"
},
"husky": {
Expand All @@ -90,7 +92,7 @@
]
},
"engines": {
"node": "12.*"
"node": ">=12.*"
},
"ember": {
"edition": "octane"
Expand Down
36 changes: 36 additions & 0 deletions yarn.lock
Expand Up @@ -3769,6 +3769,11 @@ caseless@~0.12.0:
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=

chai-jquery@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/chai-jquery/-/chai-jquery-2.1.0.tgz#ce40fb5d853e7886688787f16d14cd9595388563"
integrity sha512-DiKSXcmInlt4d+WC5PkisDL5MsgJPd1lCSfZ3NgeSZJ34CJntEIpPOCdpalH2IhOWHeLpESJaiuHFxX1dpZ6bw==

chalk@^1.0.0, chalk@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
Expand Down Expand Up @@ -4943,6 +4948,16 @@ ember-cli-htmlbars-inline-precompile@^2.1.0:
heimdalljs-logger "^0.1.9"
silent-error "^1.1.0"

ember-cli-htmlbars@^2.0.1:
version "2.0.5"
resolved "https://registry.yarnpkg.com/ember-cli-htmlbars/-/ember-cli-htmlbars-2.0.5.tgz#b5a105429a6bce4f7c9c97b667e3b8926e31397f"
integrity sha512-3f3PAxdnQ/fhQa8XP/3z4RLRgLHxV8j4Ln75aHbRdemOCjBa048KxL9l+acRLhCulbGQCMnLiIUIC89PAzLrcA==
dependencies:
broccoli-persistent-filter "^1.4.3"
hash-for-dep "^1.2.3"
json-stable-stringify "^1.0.0"
strip-bom "^3.0.0"

ember-cli-htmlbars@^4.2.3:
version "4.3.1"
resolved "https://registry.yarnpkg.com/ember-cli-htmlbars/-/ember-cli-htmlbars-4.3.1.tgz#4af8adc21ab3c4953f768956b7f7d207782cb175"
Expand Down Expand Up @@ -5378,6 +5393,20 @@ ember-test-waiters@^1.1.1:
ember-cli-babel "^7.11.0"
semver "^6.3.0"

emberx-file-input@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/emberx-file-input/-/emberx-file-input-1.2.1.tgz#a9214a9b3278c270a4d60e58836d2c1b98bce0ab"
integrity sha512-sDgoVTk/jnu5oghzGx4a2P0dbHpZXdomk8YWAbHone44sgdxXV/LpCC8EgOEvSmagv19E+CSfGJNzCNYcM59kg==
dependencies:
chai-jquery "^2.0.0"
ember-cli-babel "^6.6.0"
ember-cli-htmlbars "^2.0.1"

emitter-component@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/emitter-component/-/emitter-component-1.1.1.tgz#065e2dbed6959bf470679edabeaf7981d1003ab6"
integrity sha1-Bl4tvtaVm/RwZ57avq95gdEAOrY=

emoji-regex@^7.0.1:
version "7.0.3"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
Expand Down Expand Up @@ -11035,6 +11064,13 @@ stream-shift@^1.0.0:
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==

stream@^0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/stream/-/stream-0.0.2.tgz#7f5363f057f6592c5595f00bc80a27f5cec1f0ef"
integrity sha1-f1Nj8Ff2WSxVlfALyAon9c7B8O8=
dependencies:
emitter-component "^1.1.1"

strict-uri-encode@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
Expand Down

0 comments on commit 9ce8ae8

Please sign in to comment.