mirror of
https://github.com/schlagmichdoch/PairDrop.git
synced 2026-04-06 09:53:49 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f195c686e7 | ||
|
|
3505f161c6 | ||
|
|
3e2368c0c9 | ||
|
|
d36cd3524c | ||
|
|
a3a8228327 | ||
|
|
520b772bc8 | ||
|
|
27bf0fa74f | ||
|
|
e9f3c39f38 | ||
|
|
58b7f6bb7c |
16
index.js
16
index.js
@@ -219,10 +219,15 @@ class PairDropServer {
|
||||
}
|
||||
|
||||
_onDisconnect(sender) {
|
||||
this._disconnect(sender);
|
||||
}
|
||||
|
||||
_disconnect(sender) {
|
||||
this._leaveRoom(sender, 'ip', '', true);
|
||||
this._leaveAllSecretRooms(sender, true);
|
||||
this._removeRoomKey(sender.roomKey);
|
||||
sender.roomKey = null;
|
||||
sender.socket.terminate();
|
||||
}
|
||||
|
||||
_onRoomSecrets(sender, message) {
|
||||
@@ -357,10 +362,6 @@ class PairDropServer {
|
||||
_joinRoom(peer, roomType = 'ip', roomSecret = '') {
|
||||
const room = roomType === 'ip' ? peer.ip : roomSecret;
|
||||
|
||||
if (this._rooms[room] && this._rooms[room][peer.id]) {
|
||||
this._leaveRoom(peer, roomType, roomSecret);
|
||||
}
|
||||
|
||||
// if room doesn't exist, create it
|
||||
if (!this._rooms[room]) {
|
||||
this._rooms[room] = {};
|
||||
@@ -385,10 +386,6 @@ class PairDropServer {
|
||||
// delete the peer
|
||||
delete this._rooms[room][peer.id];
|
||||
|
||||
if (roomType === 'ip') {
|
||||
peer.socket.terminate();
|
||||
}
|
||||
|
||||
//if room is empty, delete the room
|
||||
if (!Object.keys(this._rooms[room]).length) {
|
||||
delete this._rooms[room];
|
||||
@@ -468,8 +465,7 @@ class PairDropServer {
|
||||
peer.lastBeat = Date.now();
|
||||
}
|
||||
if (Date.now() - peer.lastBeat > 2 * timeout) {
|
||||
this._leaveRoom(peer);
|
||||
this._leaveAllSecretRooms(peer);
|
||||
this._disconnect(peer);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "pairdrop",
|
||||
"version": "1.7.3",
|
||||
"version": "1.7.5",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "pairdrop",
|
||||
"version": "1.7.3",
|
||||
"version": "1.7.5",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "pairdrop",
|
||||
"version": "1.7.3",
|
||||
"version": "1.7.5",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -278,7 +278,7 @@
|
||||
</svg>
|
||||
<div class="title-wrapper">
|
||||
<h1>PairDrop</h1>
|
||||
<div class="font-subheading">v1.7.3</div>
|
||||
<div class="font-subheading">v1.7.5</div>
|
||||
</div>
|
||||
<div class="font-subheading">The easiest way to transfer files across devices</div>
|
||||
<div class="row">
|
||||
|
||||
@@ -529,7 +529,7 @@ class Peer {
|
||||
this._abortTransfer();
|
||||
}
|
||||
|
||||
// include for compatibility with Snapdrop for Android app
|
||||
// include for compatibility with 'Snapdrop & PairDrop for Android' app
|
||||
Events.fire('file-received', fileBlob);
|
||||
|
||||
this._filesReceived.push(fileBlob);
|
||||
@@ -547,6 +547,7 @@ class Peer {
|
||||
if (!this._filesQueue.length) {
|
||||
this._busy = false;
|
||||
Events.fire('notify-user', 'File transfer completed.');
|
||||
Events.fire('files-sent'); // used by 'Snapdrop & PairDrop for Android' app
|
||||
} else {
|
||||
this._dequeueFile();
|
||||
}
|
||||
|
||||
@@ -1024,7 +1024,8 @@ class PairDeviceDialog extends Dialog {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.has('room_key')) {
|
||||
this._pairDeviceJoin(urlParams.get('room_key'));
|
||||
window.history.replaceState({}, "title**", '/'); //remove room_key from url
|
||||
const url = getUrlWithoutArguments();
|
||||
window.history.replaceState({}, "Rewrite URL", url); //remove room_key from url
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1295,13 +1296,13 @@ class SendTextDialog extends Dialog {
|
||||
}
|
||||
|
||||
async _onKeyDown(e) {
|
||||
if (this.isShown()) {
|
||||
if (e.code === "Escape") {
|
||||
this.hide();
|
||||
} else if (e.code === "Enter" && (e.ctrlKey || e.metaKey)) {
|
||||
if (this._textInputEmpty()) return;
|
||||
this._send();
|
||||
}
|
||||
if (!this.isShown()) return;
|
||||
|
||||
if (e.code === "Escape") {
|
||||
this.hide();
|
||||
} else if (e.code === "Enter" && (e.ctrlKey || e.metaKey)) {
|
||||
if (this._textInputEmpty()) return;
|
||||
this._send();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1419,7 +1420,8 @@ class ReceiveTextDialog extends Dialog {
|
||||
}
|
||||
|
||||
async _onCopy() {
|
||||
await navigator.clipboard.writeText(this.$text.textContent);
|
||||
const sanitizedText = this.$text.innerText.replace(/\u00A0/gm, ' ');
|
||||
await navigator.clipboard.writeText(sanitizedText);
|
||||
Events.fire('notify-user', 'Copied to clipboard');
|
||||
this.hide();
|
||||
}
|
||||
@@ -1575,7 +1577,8 @@ class Base64ZipDialog extends Dialog {
|
||||
}
|
||||
|
||||
clearBrowserHistory() {
|
||||
window.history.replaceState({}, "Rewrite URL", '/');
|
||||
const url = getUrlWithoutArguments();
|
||||
window.history.replaceState({}, "Rewrite URL", url);
|
||||
}
|
||||
|
||||
hide() {
|
||||
@@ -1594,7 +1597,7 @@ class Toast extends Dialog {
|
||||
|
||||
_onNotify(message) {
|
||||
if (this.hideTimeout) clearTimeout(this.hideTimeout);
|
||||
this.$el.textContent = message;
|
||||
this.$el.innerText = message;
|
||||
this.show();
|
||||
this.hideTimeout = setTimeout(_ => this.hide(), 5000);
|
||||
}
|
||||
@@ -1791,7 +1794,8 @@ class WebShareTargetUI {
|
||||
}
|
||||
}
|
||||
}
|
||||
window.history.replaceState({}, "Rewrite URL", '/');
|
||||
const url = getUrlWithoutArguments();
|
||||
window.history.replaceState({}, "Rewrite URL", url);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1815,7 +1819,8 @@ class WebFileHandlersUI {
|
||||
Events.fire('activate-paste-mode', {files: files, text: ""})
|
||||
launchParams = null;
|
||||
});
|
||||
window.history.replaceState({}, "Rewrite URL", '/');
|
||||
const url = getUrlWithoutArguments();
|
||||
window.history.replaceState({}, "Rewrite URL", url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ if (!navigator.clipboard) {
|
||||
|
||||
// A <span> contains the text to copy
|
||||
const span = document.createElement('span');
|
||||
span.textContent = text;
|
||||
span.innerText = text;
|
||||
span.style.whiteSpace = 'pre'; // Preserve consecutive spaces and newlines
|
||||
|
||||
// Paint the span outside the viewport
|
||||
@@ -402,3 +402,7 @@ const cyrb53 = function(str, seed = 0) {
|
||||
function onlyUnique (value, index, array) {
|
||||
return array.indexOf(value) === index;
|
||||
}
|
||||
|
||||
function getUrlWithoutArguments() {
|
||||
return `${window.location.protocol}//${window.location.host}${window.location.pathname}`;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const cacheVersion = 'v1.7.3';
|
||||
const cacheVersion = 'v1.7.5';
|
||||
const cacheTitle = `pairdrop-cache-${cacheVersion}`;
|
||||
const urlsToCache = [
|
||||
'index.html',
|
||||
@@ -72,8 +72,7 @@ self.addEventListener('fetch', function(event) {
|
||||
if (event.request.method === "POST") {
|
||||
// Requests related to Web Share Target.
|
||||
event.respondWith((async () => {
|
||||
let share_url = await evaluateRequestData(event.request);
|
||||
share_url = event.request.url + share_url;
|
||||
const share_url = await evaluateRequestData(event.request);
|
||||
return Response.redirect(encodeURI(share_url), 302);
|
||||
})());
|
||||
} else {
|
||||
@@ -101,15 +100,16 @@ self.addEventListener('activate', evt =>
|
||||
)
|
||||
);
|
||||
|
||||
const evaluateRequestData = async function (request) {
|
||||
const formData = await request.formData();
|
||||
const title = formData.get("title");
|
||||
const text = formData.get("text");
|
||||
const url = formData.get("url");
|
||||
const files = formData.getAll("allfiles");
|
||||
|
||||
|
||||
const evaluateRequestData = function (request) {
|
||||
return new Promise(async (resolve) => {
|
||||
const formData = await request.formData();
|
||||
const title = formData.get("title");
|
||||
const text = formData.get("text");
|
||||
const url = formData.get("url");
|
||||
const files = formData.getAll("allfiles");
|
||||
|
||||
const pairDropUrl = request.url;
|
||||
|
||||
if (files && files.length > 0) {
|
||||
let fileObjects = [];
|
||||
for (let i=0; i<files.length; i++) {
|
||||
@@ -128,21 +128,21 @@ const evaluateRequestData = async function (request) {
|
||||
|
||||
const objectStoreRequest = objectStore.add(fileObjects[i]);
|
||||
objectStoreRequest.onsuccess = _ => {
|
||||
if (i === fileObjects.length - 1) resolve('?share-target=files');
|
||||
if (i === fileObjects.length - 1) resolve(pairDropUrl + '?share-target=files');
|
||||
}
|
||||
}
|
||||
}
|
||||
DBOpenRequest.onerror = _ => {
|
||||
resolve('');
|
||||
resolve(pairDropUrl);
|
||||
}
|
||||
} else {
|
||||
let share_url = '?share-target=text';
|
||||
let urlArgument = '?share-target=text';
|
||||
|
||||
if (title) share_url += `&title=${title}`;
|
||||
if (text) share_url += `&text=${text}`;
|
||||
if (url) share_url += `&url=${url}`;
|
||||
if (title) urlArgument += `&title=${title}`;
|
||||
if (text) urlArgument += `&text=${text}`;
|
||||
if (url) urlArgument += `&url=${url}`;
|
||||
|
||||
resolve(share_url);
|
||||
resolve(pairDropUrl + urlArgument);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1124,11 +1124,14 @@ button::-moz-focus-inner {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#about header {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#about .fade-in {
|
||||
transition: opacity 300ms;
|
||||
will-change: opacity;
|
||||
transition-delay: 300ms;
|
||||
z-index: 11;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
|
||||
@@ -281,7 +281,7 @@
|
||||
</svg>
|
||||
<div class="title-wrapper">
|
||||
<h1>PairDrop</h1>
|
||||
<div class="font-subheading">v1.7.3</div>
|
||||
<div class="font-subheading">v1.7.5</div>
|
||||
</div>
|
||||
<div class="font-subheading">The easiest way to transfer files across devices</div>
|
||||
<div class="row">
|
||||
|
||||
@@ -1025,7 +1025,8 @@ class PairDeviceDialog extends Dialog {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.has('room_key')) {
|
||||
this._pairDeviceJoin(urlParams.get('room_key'));
|
||||
window.history.replaceState({}, "title**", '/'); //remove room_key from url
|
||||
const url = getUrlWithoutArguments();
|
||||
window.history.replaceState({}, "Rewrite URL", url); //remove room_key from url
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1296,13 +1297,13 @@ class SendTextDialog extends Dialog {
|
||||
}
|
||||
|
||||
async _onKeyDown(e) {
|
||||
if (this.isShown()) {
|
||||
if (e.code === "Escape") {
|
||||
this.hide();
|
||||
} else if (e.code === "Enter" && (e.ctrlKey || e.metaKey)) {
|
||||
if (this._textInputEmpty()) return;
|
||||
this._send();
|
||||
}
|
||||
if (!this.isShown()) return;
|
||||
|
||||
if (e.code === "Escape") {
|
||||
this.hide();
|
||||
} else if (e.code === "Enter" && (e.ctrlKey || e.metaKey)) {
|
||||
if (this._textInputEmpty()) return;
|
||||
this._send();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1420,7 +1421,8 @@ class ReceiveTextDialog extends Dialog {
|
||||
}
|
||||
|
||||
async _onCopy() {
|
||||
await navigator.clipboard.writeText(this.$text.textContent);
|
||||
const sanitizedText = this.$text.innerText.replace(/\u00A0/gm, ' ');
|
||||
await navigator.clipboard.writeText(sanitizedText);
|
||||
Events.fire('notify-user', 'Copied to clipboard');
|
||||
this.hide();
|
||||
}
|
||||
@@ -1576,7 +1578,8 @@ class Base64ZipDialog extends Dialog {
|
||||
}
|
||||
|
||||
clearBrowserHistory() {
|
||||
window.history.replaceState({}, "Rewrite URL", '/');
|
||||
const url = getUrlWithoutArguments();
|
||||
window.history.replaceState({}, "Rewrite URL", url);
|
||||
}
|
||||
|
||||
hide() {
|
||||
@@ -1595,7 +1598,7 @@ class Toast extends Dialog {
|
||||
|
||||
_onNotify(message) {
|
||||
if (this.hideTimeout) clearTimeout(this.hideTimeout);
|
||||
this.$el.textContent = message;
|
||||
this.$el.innerText = message;
|
||||
this.show();
|
||||
this.hideTimeout = setTimeout(_ => this.hide(), 5000);
|
||||
}
|
||||
@@ -1792,7 +1795,8 @@ class WebShareTargetUI {
|
||||
}
|
||||
}
|
||||
}
|
||||
window.history.replaceState({}, "Rewrite URL", '/');
|
||||
const url = getUrlWithoutArguments();
|
||||
window.history.replaceState({}, "Rewrite URL", url);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1816,7 +1820,8 @@ class WebFileHandlersUI {
|
||||
Events.fire('activate-paste-mode', {files: files, text: ""})
|
||||
launchParams = null;
|
||||
});
|
||||
window.history.replaceState({}, "Rewrite URL", '/');
|
||||
const url = getUrlWithoutArguments();
|
||||
window.history.replaceState({}, "Rewrite URL", url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ if (!navigator.clipboard) {
|
||||
|
||||
// A <span> contains the text to copy
|
||||
const span = document.createElement('span');
|
||||
span.textContent = text;
|
||||
span.innerText = text;
|
||||
span.style.whiteSpace = 'pre'; // Preserve consecutive spaces and newlines
|
||||
|
||||
// Paint the span outside the viewport
|
||||
@@ -403,6 +403,10 @@ function onlyUnique (value, index, array) {
|
||||
return array.indexOf(value) === index;
|
||||
}
|
||||
|
||||
function getUrlWithoutArguments() {
|
||||
return `${window.location.protocol}//${window.location.host}${window.location.pathname}`;
|
||||
}
|
||||
|
||||
function arrayBufferToBase64(buffer) {
|
||||
var binary = '';
|
||||
var bytes = new Uint8Array(buffer);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const cacheVersion = 'v1.7.3';
|
||||
const cacheVersion = 'v1.7.5';
|
||||
const cacheTitle = `pairdrop-included-ws-fallback-cache-${cacheVersion}`;
|
||||
const urlsToCache = [
|
||||
'index.html',
|
||||
@@ -72,8 +72,7 @@ self.addEventListener('fetch', function(event) {
|
||||
if (event.request.method === "POST") {
|
||||
// Requests related to Web Share Target.
|
||||
event.respondWith((async () => {
|
||||
let share_url = await evaluateRequestData(event.request);
|
||||
share_url = event.request.url + share_url;
|
||||
const share_url = await evaluateRequestData(event.request);
|
||||
return Response.redirect(encodeURI(share_url), 302);
|
||||
})());
|
||||
} else {
|
||||
@@ -101,15 +100,16 @@ self.addEventListener('activate', evt =>
|
||||
)
|
||||
);
|
||||
|
||||
const evaluateRequestData = async function (request) {
|
||||
const formData = await request.formData();
|
||||
const title = formData.get("title");
|
||||
const text = formData.get("text");
|
||||
const url = formData.get("url");
|
||||
const files = formData.getAll("allfiles");
|
||||
|
||||
|
||||
const evaluateRequestData = function (request) {
|
||||
return new Promise(async (resolve) => {
|
||||
const formData = await request.formData();
|
||||
const title = formData.get("title");
|
||||
const text = formData.get("text");
|
||||
const url = formData.get("url");
|
||||
const files = formData.getAll("allfiles");
|
||||
|
||||
const pairDropUrl = request.url;
|
||||
|
||||
if (files && files.length > 0) {
|
||||
let fileObjects = [];
|
||||
for (let i=0; i<files.length; i++) {
|
||||
@@ -128,21 +128,21 @@ const evaluateRequestData = async function (request) {
|
||||
|
||||
const objectStoreRequest = objectStore.add(fileObjects[i]);
|
||||
objectStoreRequest.onsuccess = _ => {
|
||||
if (i === fileObjects.length - 1) resolve('?share-target=files');
|
||||
if (i === fileObjects.length - 1) resolve(pairDropUrl + '?share-target=files');
|
||||
}
|
||||
}
|
||||
}
|
||||
DBOpenRequest.onerror = _ => {
|
||||
resolve('');
|
||||
resolve(pairDropUrl);
|
||||
}
|
||||
} else {
|
||||
let share_url = '?share-target=text';
|
||||
let urlArgument = '?share-target=text';
|
||||
|
||||
if (title) share_url += `&title=${title}`;
|
||||
if (text) share_url += `&text=${text}`;
|
||||
if (url) share_url += `&url=${url}`;
|
||||
if (title) urlArgument += `&title=${title}`;
|
||||
if (text) urlArgument += `&text=${text}`;
|
||||
if (url) urlArgument += `&url=${url}`;
|
||||
|
||||
resolve(share_url);
|
||||
resolve(pairDropUrl + urlArgument);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1150,11 +1150,14 @@ button::-moz-focus-inner {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#about header {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#about .fade-in {
|
||||
transition: opacity 300ms;
|
||||
will-change: opacity;
|
||||
transition-delay: 300ms;
|
||||
z-index: 11;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user