mirror of
https://github.com/schlagmichdoch/PairDrop.git
synced 2026-04-06 09:53:49 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fea15d3ee1 | ||
|
|
028752a809 | ||
|
|
1093f4d246 | ||
|
|
7ddd600b0c | ||
|
|
715356aafb | ||
|
|
490e4db380 |
@@ -6,7 +6,7 @@
|
||||
<h1>PairDrop</h1>
|
||||
|
||||
<p>
|
||||
Local file sharing in your browser. Inspired by Apple's Airdrop.
|
||||
Local file sharing in your browser. Inspired by Apple's AirDrop.
|
||||
<br />
|
||||
<a href="https://pairdrop.net"><strong>Explore »</strong></a>
|
||||
<br />
|
||||
|
||||
@@ -58,8 +58,11 @@ If your devices are paired and behind a NAT, the public TURN Server from [Open R
|
||||
Yes. Your files are sent using WebRTC, which encrypts them on transit. To ensure the connection is secure and there is no MITM, compare the security number shown under the device name on both devices. The security number is different for every connection.
|
||||
|
||||
### Transferring many files with paired devices takes too long
|
||||
Naturally, if traffic needs to be routed through the turn server transfer speed decreases.
|
||||
As a workaround you can open a hotspot on one of your devices to bridge the connection which makes transfers much faster.
|
||||
Naturally, if traffic needs to be routed through the turn server because your devices are behind different NATs, transfer speed decreases.
|
||||
|
||||
As the public TURN server used is not super fast, you can easily [specify to use your own TURN server](https://github.com/schlagmichdoch/PairDrop/blob/master/docs/host-your-own.md#specify-stunturn-servers) if you host your own instance.
|
||||
|
||||
Alternatively, you can open a hotspot on one of your devices to bridge the connection which makes transfers much faster as no TURN server is needed.
|
||||
|
||||
- [How to open a hotspot on Windows](https://support.microsoft.com/en-us/windows/use-your-windows-pc-as-a-mobile-hotspot-c89b0fad-72d5-41e8-f7ea-406ad9036b85#WindowsVersion=Windows_11)
|
||||
- [How to open a hotspot on Mac](https://support.apple.com/guide/mac-help/share-internet-connection-mac-network-users-mchlp1540/mac)
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "pairdrop",
|
||||
"version": "1.4.4",
|
||||
"version": "1.4.5",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "pairdrop",
|
||||
"version": "1.4.4",
|
||||
"version": "1.4.5",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "pairdrop",
|
||||
"version": "1.4.4",
|
||||
"version": "1.4.5",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -524,6 +524,7 @@ class RTCPeer extends Peer {
|
||||
this._peerId = peerId;
|
||||
this._conn = new RTCPeerConnection(window.rtcConfig);
|
||||
this._conn.onicecandidate = e => this._onIceCandidate(e);
|
||||
this._conn.onicecandidateerror = e => this._onError(e);
|
||||
this._conn.onconnectionstatechange = _ => this._onConnectionStateChange();
|
||||
this._conn.oniceconnectionstatechange = e => this._onIceConnectionStateChange(e);
|
||||
}
|
||||
|
||||
@@ -632,26 +632,34 @@ class ReceiveFileDialog extends ReceiveDialog {
|
||||
|
||||
createPreviewElement(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let mime = file.type.split('/')[0]
|
||||
let previewElement = {
|
||||
image: 'img',
|
||||
audio: 'audio',
|
||||
video: 'video'
|
||||
}
|
||||
try {
|
||||
let mime = file.type.split('/')[0]
|
||||
let previewElement = {
|
||||
image: 'img',
|
||||
audio: 'audio',
|
||||
video: 'video'
|
||||
}
|
||||
|
||||
if (Object.keys(previewElement).indexOf(mime) === -1) {
|
||||
resolve(false);
|
||||
} else {
|
||||
console.log('the file is able to preview');
|
||||
let element = document.createElement(previewElement[mime]);
|
||||
element.src = URL.createObjectURL(file);
|
||||
element.controls = true;
|
||||
element.onload = _ => {
|
||||
this.$previewBox.appendChild(element);
|
||||
resolve(true)
|
||||
};
|
||||
element.addEventListener('loadeddata', _ => resolve(true));
|
||||
element.onerror = _ => reject(`${mime} preview could not be loaded from type ${file.type}`);
|
||||
if (Object.keys(previewElement).indexOf(mime) === -1) {
|
||||
resolve(false);
|
||||
} else {
|
||||
let element = document.createElement(previewElement[mime]);
|
||||
element.controls = true;
|
||||
element.onload = _ => {
|
||||
this.$previewBox.appendChild(element);
|
||||
resolve(true);
|
||||
};
|
||||
element.onloadeddata = _ => {
|
||||
this.$previewBox.appendChild(element);
|
||||
resolve(true);
|
||||
};
|
||||
element.onerror = _ => {
|
||||
reject(`${mime} preview could not be loaded from type ${file.type}`);
|
||||
};
|
||||
element.src = URL.createObjectURL(file);
|
||||
}
|
||||
} catch (e) {
|
||||
reject(`preview could not be loaded from type ${file.type}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -734,20 +742,30 @@ class ReceiveFileDialog extends ReceiveDialog {
|
||||
setTimeout(_ => this.$downloadBtn.style.pointerEvents = "unset", 2000);
|
||||
};
|
||||
|
||||
this.createPreviewElement(files[0]).finally(_ => {
|
||||
document.title = files.length === 1
|
||||
? 'File received - PairDrop'
|
||||
: `${files.length} Files received - PairDrop`;
|
||||
document.changeFavicon("images/favicon-96x96-notification.png");
|
||||
Events.fire('set-progress', {peerId: peerId, progress: 1, status: 'process'})
|
||||
this.show();
|
||||
document.title = files.length === 1
|
||||
? 'File received - PairDrop'
|
||||
: `${files.length} Files received - PairDrop`;
|
||||
document.changeFavicon("images/favicon-96x96-notification.png");
|
||||
Events.fire('set-progress', {peerId: peerId, progress: 1, status: 'process'})
|
||||
this.show();
|
||||
|
||||
setTimeout(_ => {
|
||||
if (canShare) {
|
||||
this.$shareBtn.click();
|
||||
} else {
|
||||
this.$downloadBtn.click();
|
||||
}
|
||||
}).catch(r => console.error(r));
|
||||
}, 500);
|
||||
|
||||
this.createPreviewElement(files[0])
|
||||
.then(canPreview => {
|
||||
if (canPreview) {
|
||||
console.log('the file is able to preview');
|
||||
} else {
|
||||
console.log('the file is not able to preview');
|
||||
}
|
||||
})
|
||||
.catch(r => console.error(r));
|
||||
}
|
||||
|
||||
_downloadFilesIndividually(files) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const cacheVersion = 'v1.4.4';
|
||||
const cacheVersion = 'v1.4.5';
|
||||
const cacheTitle = `pairdrop-cache-${cacheVersion}`;
|
||||
const urlsToCache = [
|
||||
'index.html',
|
||||
|
||||
@@ -22,13 +22,18 @@ body {
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
height: 100%;
|
||||
/* mobile viewport bug fix */
|
||||
min-height: -webkit-fill-available;
|
||||
min-height: -moz-available; /* WebKit-based browsers will ignore this. */
|
||||
min-height: -webkit-fill-available; /* Mozilla-based browsers will ignore this. */
|
||||
min-height: fill-available;
|
||||
}
|
||||
|
||||
html {
|
||||
height: -webkit-fill-available;
|
||||
height: 100%;
|
||||
min-height: -moz-available; /* WebKit-based browsers will ignore this. */
|
||||
min-height: -webkit-fill-available; /* Mozilla-based browsers will ignore this. */
|
||||
min-height: fill-available;
|
||||
}
|
||||
|
||||
.row-reverse {
|
||||
|
||||
@@ -535,6 +535,7 @@ class RTCPeer extends Peer {
|
||||
this._peerId = peerId;
|
||||
this._conn = new RTCPeerConnection(window.rtcConfig);
|
||||
this._conn.onicecandidate = e => this._onIceCandidate(e);
|
||||
this._conn.onicecandidateerror = e => this._onError(e);
|
||||
this._conn.onconnectionstatechange = _ => this._onConnectionStateChange();
|
||||
this._conn.oniceconnectionstatechange = e => this._onIceConnectionStateChange(e);
|
||||
}
|
||||
|
||||
@@ -633,26 +633,34 @@ class ReceiveFileDialog extends ReceiveDialog {
|
||||
|
||||
createPreviewElement(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let mime = file.type.split('/')[0]
|
||||
let previewElement = {
|
||||
image: 'img',
|
||||
audio: 'audio',
|
||||
video: 'video'
|
||||
}
|
||||
try {
|
||||
let mime = file.type.split('/')[0]
|
||||
let previewElement = {
|
||||
image: 'img',
|
||||
audio: 'audio',
|
||||
video: 'video'
|
||||
}
|
||||
|
||||
if (Object.keys(previewElement).indexOf(mime) === -1) {
|
||||
resolve(false);
|
||||
} else {
|
||||
console.log('the file is able to preview');
|
||||
let element = document.createElement(previewElement[mime]);
|
||||
element.src = URL.createObjectURL(file);
|
||||
element.controls = true;
|
||||
element.onload = _ => {
|
||||
this.$previewBox.appendChild(element);
|
||||
resolve(true)
|
||||
};
|
||||
element.addEventListener('loadeddata', _ => resolve(true));
|
||||
element.onerror = _ => reject(`${mime} preview could not be loaded from type ${file.type}`);
|
||||
if (Object.keys(previewElement).indexOf(mime) === -1) {
|
||||
resolve(false);
|
||||
} else {
|
||||
let element = document.createElement(previewElement[mime]);
|
||||
element.controls = true;
|
||||
element.onload = _ => {
|
||||
this.$previewBox.appendChild(element);
|
||||
resolve(true);
|
||||
};
|
||||
element.onloadeddata = _ => {
|
||||
this.$previewBox.appendChild(element);
|
||||
resolve(true);
|
||||
};
|
||||
element.onerror = _ => {
|
||||
reject(`${mime} preview could not be loaded from type ${file.type}`);
|
||||
};
|
||||
element.src = URL.createObjectURL(file);
|
||||
}
|
||||
} catch (e) {
|
||||
reject(`preview could not be loaded from type ${file.type}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -735,20 +743,30 @@ class ReceiveFileDialog extends ReceiveDialog {
|
||||
setTimeout(_ => this.$downloadBtn.style.pointerEvents = "unset", 2000);
|
||||
};
|
||||
|
||||
this.createPreviewElement(files[0]).finally(_ => {
|
||||
document.title = files.length === 1
|
||||
? 'File received - PairDrop'
|
||||
: `${files.length} Files received - PairDrop`;
|
||||
document.changeFavicon("images/favicon-96x96-notification.png");
|
||||
Events.fire('set-progress', {peerId: peerId, progress: 1, status: 'process'})
|
||||
this.show();
|
||||
document.title = files.length === 1
|
||||
? 'File received - PairDrop'
|
||||
: `${files.length} Files received - PairDrop`;
|
||||
document.changeFavicon("images/favicon-96x96-notification.png");
|
||||
Events.fire('set-progress', {peerId: peerId, progress: 1, status: 'process'})
|
||||
this.show();
|
||||
|
||||
setTimeout(_ => {
|
||||
if (canShare) {
|
||||
this.$shareBtn.click();
|
||||
} else {
|
||||
this.$downloadBtn.click();
|
||||
}
|
||||
}).catch(r => console.error(r));
|
||||
}, 500);
|
||||
|
||||
this.createPreviewElement(files[0])
|
||||
.then(canPreview => {
|
||||
if (canPreview) {
|
||||
console.log('the file is able to preview');
|
||||
} else {
|
||||
console.log('the file is not able to preview');
|
||||
}
|
||||
})
|
||||
.catch(r => console.error(r));
|
||||
}
|
||||
|
||||
_downloadFilesIndividually(files) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const cacheVersion = 'v1.4.4';
|
||||
const cacheVersion = 'v1.4.5';
|
||||
const cacheTitle = `pairdrop-included-ws-fallback-cache-${cacheVersion}`;
|
||||
const urlsToCache = [
|
||||
'index.html',
|
||||
|
||||
@@ -23,13 +23,18 @@ body {
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
height: 100%;
|
||||
/* mobile viewport bug fix */
|
||||
min-height: -webkit-fill-available;
|
||||
min-height: -moz-available; /* WebKit-based browsers will ignore this. */
|
||||
min-height: -webkit-fill-available; /* Mozilla-based browsers will ignore this. */
|
||||
min-height: fill-available;
|
||||
}
|
||||
|
||||
html {
|
||||
height: -webkit-fill-available;
|
||||
height: 100%;
|
||||
min-height: -moz-available; /* WebKit-based browsers will ignore this. */
|
||||
min-height: -webkit-fill-available; /* Mozilla-based browsers will ignore this. */
|
||||
min-height: fill-available;
|
||||
}
|
||||
|
||||
.row-reverse {
|
||||
|
||||
Reference in New Issue
Block a user