mirror of
https://github.com/schlagmichdoch/PairDrop.git
synced 2026-04-16 06:12:15 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
13d5c01935 | ||
|
|
787cd8dab5 | ||
|
|
2131307fc6 |
4
.github/ISSUE_TEMPLATE/bug-report.md
vendored
4
.github/ISSUE_TEMPLATE/bug-report.md
vendored
@@ -36,7 +36,7 @@ If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Bug occurs on official PairDrop instance https://pairdrop.net/**
|
||||
No | Yes
|
||||
Version: v1.9.0
|
||||
Version: v1.9.1
|
||||
|
||||
**Bug occurs on self-hosted PairDrop instance**
|
||||
No | Yes
|
||||
@@ -44,7 +44,7 @@ No | Yes
|
||||
**Self-Hosted Setup**
|
||||
Proxy: Nginx | Apache2
|
||||
Deployment: docker run | docker-compose | npm run start:prod
|
||||
Version: v1.9.0
|
||||
Version: v1.9.1
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "pairdrop",
|
||||
"version": "1.9.0",
|
||||
"version": "1.9.1",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "pairdrop",
|
||||
"version": "1.9.0",
|
||||
"version": "1.9.1",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "pairdrop",
|
||||
"version": "1.9.0",
|
||||
"version": "1.9.1",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -480,7 +480,7 @@
|
||||
</svg>
|
||||
<div class="title-wrapper" dir="ltr">
|
||||
<h1>PairDrop</h1>
|
||||
<div class="font-subheading">v1.9.0</div>
|
||||
<div class="font-subheading">v1.9.1</div>
|
||||
</div>
|
||||
<div class="font-subheading" data-i18n-key="about.claim" data-i18n-attrs="text"></div>
|
||||
<div class="row">
|
||||
|
||||
@@ -37,7 +37,7 @@ class ServerConnection {
|
||||
|
||||
_connect() {
|
||||
clearTimeout(this._reconnectTimer);
|
||||
if (this._isConnected() || this._isConnecting()) return;
|
||||
if (this._isConnected() || this._isConnecting() || this._isOffline()) return;
|
||||
if (this._isReconnect) {
|
||||
Events.fire('notify-user', {
|
||||
message: Localization.getTranslation("notifications.connecting"),
|
||||
@@ -246,6 +246,10 @@ class ServerConnection {
|
||||
return this._socket && this._socket.readyState === this._socket.CONNECTING;
|
||||
}
|
||||
|
||||
_isOffline() {
|
||||
return !navigator.onLine;
|
||||
}
|
||||
|
||||
_onError(e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
@@ -68,12 +68,25 @@ class PeersUI {
|
||||
this.fadedIn = false;
|
||||
|
||||
this.$header = document.querySelector('header.opacity-0');
|
||||
Events.on('header-evaluated', () => this._fadeInHeader());
|
||||
Events.on('header-evaluated', e => this._fadeInHeader(e.detail));
|
||||
|
||||
// wait for evaluation of notification, install and edit-paired-devices buttons
|
||||
this.evaluateHeaderCount = 3;
|
||||
if (!('Notification' in window)) this.evaluateHeaderCount -= 1;
|
||||
if (
|
||||
!('BeforeInstallPromptEvent' in window) ||
|
||||
('BeforeInstallPromptEvent' in window && window.matchMedia('(display-mode: minimal-ui)').matches)
|
||||
) {
|
||||
this.evaluateHeaderCount -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
_fadeInHeader() {
|
||||
//prevent flickering
|
||||
setTimeout(() => this.$header.classList.remove('opacity-0'), 50);
|
||||
_fadeInHeader(id) {
|
||||
this.evaluateHeaderCount -= 1;
|
||||
console.log(`Header btn ${id} evaluated. ${this.evaluateHeaderCount} to go.`);
|
||||
if (this.evaluateHeaderCount !== 0) return;
|
||||
|
||||
this.$header.classList.remove('opacity-0');
|
||||
}
|
||||
|
||||
_fadeInUI() {
|
||||
@@ -1413,6 +1426,7 @@ class PairDeviceDialog extends Dialog {
|
||||
this.$footerInstructionsPairedDevices.setAttribute('hidden', '');
|
||||
}
|
||||
Events.fire('evaluate-footer-badges');
|
||||
Events.fire('header-evaluated', 'edit-paired-devices');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -2092,10 +2106,7 @@ class Notifications {
|
||||
|
||||
constructor() {
|
||||
// Check if the browser supports notifications
|
||||
if (!('Notification' in window)) {
|
||||
Events.fire('header-evaluated');
|
||||
return;
|
||||
}
|
||||
if (!('Notification' in window)) return;
|
||||
|
||||
// Check whether notification permissions have already been granted
|
||||
if (Notification.permission !== 'granted') {
|
||||
@@ -2104,7 +2115,7 @@ class Notifications {
|
||||
this.$headerNotificationButton.addEventListener('click', _ => this._requestPermission());
|
||||
}
|
||||
|
||||
Events.fire('header-evaluated');
|
||||
Events.fire('header-evaluated', 'notification');
|
||||
|
||||
Events.on('text-received', e => this._messageNotification(e.detail.text, e.detail.peerId));
|
||||
Events.on('files-received', e => this._downloadNotification(e.detail.files));
|
||||
@@ -2258,7 +2269,10 @@ class NetworkStatusUI {
|
||||
}
|
||||
|
||||
_showOfflineMessage() {
|
||||
Events.fire('notify-user', Localization.getTranslation("notifications.offline"));
|
||||
Events.fire('notify-user', {
|
||||
message: Localization.getTranslation("notifications.offline"),
|
||||
persistent: true
|
||||
});
|
||||
}
|
||||
|
||||
_showOnlineMessage() {
|
||||
@@ -2815,12 +2829,16 @@ if ('serviceWorker' in navigator) {
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('beforeinstallprompt', e => {
|
||||
window.addEventListener('beforeinstallprompt', installEvent => {
|
||||
if (!window.matchMedia('(display-mode: minimal-ui)').matches) {
|
||||
// only display install btn when installed
|
||||
const btn = document.querySelector('#install')
|
||||
btn.hidden = false;
|
||||
btn.onclick = _ => e.prompt();
|
||||
// only display install btn when not installed
|
||||
const installBtn = document.querySelector('#install')
|
||||
installBtn.removeAttribute('hidden');
|
||||
installBtn.addEventListener('click', () => {
|
||||
installBtn.setAttribute('hidden', '');
|
||||
installEvent.prompt();
|
||||
});
|
||||
Events.fire('header-evaluated', 'install');
|
||||
}
|
||||
return e.preventDefault();
|
||||
});
|
||||
return installEvent.preventDefault();
|
||||
});
|
||||
@@ -1,16 +1,18 @@
|
||||
const cacheVersion = 'v1.9.0';
|
||||
const cacheVersion = 'v1.9.1';
|
||||
const cacheTitle = `pairdrop-cache-${cacheVersion}`;
|
||||
const urlsToCache = [
|
||||
'index.html',
|
||||
'./',
|
||||
'index.html',
|
||||
'manifest.json',
|
||||
'styles.css',
|
||||
'scripts/localization.js',
|
||||
'scripts/network.js',
|
||||
'scripts/NoSleep.min.js',
|
||||
'scripts/QRCode.min.js',
|
||||
'scripts/theme.js',
|
||||
'scripts/ui.js',
|
||||
'scripts/util.js',
|
||||
'scripts/qrcode.js',
|
||||
'scripts/zip.min.js',
|
||||
'scripts/NoSleep.min.js',
|
||||
'scripts/theme.js',
|
||||
'sounds/blop.mp3',
|
||||
'images/favicon-96x96.png',
|
||||
'images/favicon-96x96-notification.png',
|
||||
@@ -53,7 +55,7 @@ const fromNetwork = (request, timeout) =>
|
||||
fetch(request).then(response => {
|
||||
clearTimeout(timeoutId);
|
||||
fulfill(response);
|
||||
update(request);
|
||||
update(request).then(() => console.log("Cache successfully updated for", request.url));
|
||||
}, reject);
|
||||
});
|
||||
|
||||
@@ -62,9 +64,7 @@ const fromCache = request =>
|
||||
caches
|
||||
.open(cacheTitle)
|
||||
.then(cache =>
|
||||
cache
|
||||
.match(request)
|
||||
.then(matching => matching || cache.match('/offline/'))
|
||||
cache.match(request)
|
||||
);
|
||||
|
||||
// cache the current page to make it available for offline
|
||||
@@ -72,15 +72,16 @@ const update = request =>
|
||||
caches
|
||||
.open(cacheTitle)
|
||||
.then(cache =>
|
||||
fetch(request).then(response => {
|
||||
cache.put(request, response).then(_ => {
|
||||
console.log("Page successfully cached.")
|
||||
fetch(request)
|
||||
.then(async response => {
|
||||
await cache.put(request, response);
|
||||
})
|
||||
})
|
||||
.catch(() => console.log(`Cache could not be updated. ${request.url}`))
|
||||
);
|
||||
|
||||
// general strategy when making a request (eg if online try to fetch it
|
||||
// from the network with a timeout, if something fails serve from cache)
|
||||
// from cache, if something fails fetch from network. Update cache everytime files are fetched.
|
||||
// This way files should only be fetched if cacheVersion is changed
|
||||
self.addEventListener('fetch', function(event) {
|
||||
if (event.request.method === "POST") {
|
||||
// Requests related to Web Share Target.
|
||||
@@ -90,27 +91,33 @@ self.addEventListener('fetch', function(event) {
|
||||
})());
|
||||
} else {
|
||||
// Regular requests not related to Web Share Target.
|
||||
|
||||
// FOR DEVELOPMENT: Comment in next line to always update assets instead of using cached versions
|
||||
// event.respondWith(fromNetwork(event.request, 10000));return;
|
||||
event.respondWith(
|
||||
fromNetwork(event.request, 10000).catch(() => fromCache(event.request))
|
||||
fromCache(event.request).then(rsp => {
|
||||
// if fromCache resolves to undefined fetch from network instead
|
||||
return rsp || fromNetwork(event.request, 10000);
|
||||
})
|
||||
);
|
||||
event.waitUntil(update(event.request));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// on activation, we clean up the previously registered service workers
|
||||
self.addEventListener('activate', evt =>
|
||||
evt.waitUntil(
|
||||
caches.keys().then(cacheNames => {
|
||||
return Promise.all(
|
||||
cacheNames.map(cacheName => {
|
||||
if (cacheName !== cacheTitle) {
|
||||
return caches.delete(cacheName);
|
||||
}
|
||||
})
|
||||
);
|
||||
})
|
||||
)
|
||||
self.addEventListener('activate', evt => {
|
||||
return evt.waitUntil(
|
||||
caches.keys().then(cacheNames => {
|
||||
return Promise.all(
|
||||
cacheNames.map(cacheName => {
|
||||
if (cacheName !== cacheTitle) {
|
||||
return caches.delete(cacheName);
|
||||
}
|
||||
})
|
||||
);
|
||||
})
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
const evaluateRequestData = function (request) {
|
||||
|
||||
@@ -485,7 +485,7 @@
|
||||
</svg>
|
||||
<div class="title-wrapper" dir="ltr">
|
||||
<h1>PairDrop</h1>
|
||||
<div class="font-subheading">v1.9.0</div>
|
||||
<div class="font-subheading">v1.9.1</div>
|
||||
</div>
|
||||
<div class="font-subheading" data-i18n-key="about.claim" data-i18n-attrs="text"></div>
|
||||
<div class="row">
|
||||
|
||||
@@ -35,7 +35,7 @@ class ServerConnection {
|
||||
|
||||
_connect() {
|
||||
clearTimeout(this._reconnectTimer);
|
||||
if (this._isConnected() || this._isConnecting()) return;
|
||||
if (this._isConnected() || this._isConnecting() || this._isOffline()) return;
|
||||
if (this._isReconnect) {
|
||||
Events.fire('notify-user', {
|
||||
message: Localization.getTranslation("notifications.connecting"),
|
||||
@@ -257,6 +257,10 @@ class ServerConnection {
|
||||
return this._socket && this._socket.readyState === this._socket.CONNECTING;
|
||||
}
|
||||
|
||||
_isOffline() {
|
||||
return !navigator.onLine;
|
||||
}
|
||||
|
||||
_onError(e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
@@ -68,12 +68,25 @@ class PeersUI {
|
||||
this.fadedIn = false;
|
||||
|
||||
this.$header = document.querySelector('header.opacity-0');
|
||||
Events.on('header-evaluated', () => this._fadeInHeader());
|
||||
Events.on('header-evaluated', e => this._fadeInHeader(e.detail));
|
||||
|
||||
// wait for evaluation of notification, install and edit-paired-devices buttons
|
||||
this.evaluateHeaderCount = 3;
|
||||
if (!('Notification' in window)) this.evaluateHeaderCount -= 1;
|
||||
if (
|
||||
!('BeforeInstallPromptEvent' in window) ||
|
||||
('BeforeInstallPromptEvent' in window && window.matchMedia('(display-mode: minimal-ui)').matches)
|
||||
) {
|
||||
this.evaluateHeaderCount -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
_fadeInHeader() {
|
||||
//prevent flickering
|
||||
setTimeout(() => this.$header.classList.remove('opacity-0'), 50);
|
||||
_fadeInHeader(id) {
|
||||
this.evaluateHeaderCount -= 1;
|
||||
console.log(`Header btn ${id} evaluated. ${this.evaluateHeaderCount} to go.`);
|
||||
if (this.evaluateHeaderCount !== 0) return;
|
||||
|
||||
this.$header.classList.remove('opacity-0');
|
||||
}
|
||||
|
||||
_fadeInUI() {
|
||||
@@ -1415,6 +1428,7 @@ class PairDeviceDialog extends Dialog {
|
||||
this.$footerInstructionsPairedDevices.setAttribute('hidden', '');
|
||||
}
|
||||
Events.fire('evaluate-footer-badges');
|
||||
Events.fire('header-evaluated', 'edit-paired-devices');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -2094,10 +2108,7 @@ class Notifications {
|
||||
|
||||
constructor() {
|
||||
// Check if the browser supports notifications
|
||||
if (!('Notification' in window)) {
|
||||
Events.fire('header-evaluated');
|
||||
return;
|
||||
}
|
||||
if (!('Notification' in window)) return;
|
||||
|
||||
// Check whether notification permissions have already been granted
|
||||
if (Notification.permission !== 'granted') {
|
||||
@@ -2106,7 +2117,7 @@ class Notifications {
|
||||
this.$headerNotificationButton.addEventListener('click', _ => this._requestPermission());
|
||||
}
|
||||
|
||||
Events.fire('header-evaluated');
|
||||
Events.fire('header-evaluated', 'notification');
|
||||
|
||||
Events.on('text-received', e => this._messageNotification(e.detail.text, e.detail.peerId));
|
||||
Events.on('files-received', e => this._downloadNotification(e.detail.files));
|
||||
@@ -2260,7 +2271,10 @@ class NetworkStatusUI {
|
||||
}
|
||||
|
||||
_showOfflineMessage() {
|
||||
Events.fire('notify-user', Localization.getTranslation("notifications.offline"));
|
||||
Events.fire('notify-user', {
|
||||
message: Localization.getTranslation("notifications.offline"),
|
||||
persistent: true
|
||||
});
|
||||
}
|
||||
|
||||
_showOnlineMessage() {
|
||||
@@ -2817,12 +2831,16 @@ if ('serviceWorker' in navigator) {
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('beforeinstallprompt', e => {
|
||||
window.addEventListener('beforeinstallprompt', installEvent => {
|
||||
if (!window.matchMedia('(display-mode: minimal-ui)').matches) {
|
||||
// only display install btn when installed
|
||||
const btn = document.querySelector('#install')
|
||||
btn.hidden = false;
|
||||
btn.onclick = _ => e.prompt();
|
||||
// only display install btn when not installed
|
||||
const installBtn = document.querySelector('#install')
|
||||
installBtn.removeAttribute('hidden');
|
||||
installBtn.addEventListener('click', () => {
|
||||
installBtn.setAttribute('hidden', '');
|
||||
installEvent.prompt();
|
||||
});
|
||||
Events.fire('header-evaluated', 'install');
|
||||
}
|
||||
return e.preventDefault();
|
||||
});
|
||||
return installEvent.preventDefault();
|
||||
});
|
||||
@@ -1,16 +1,18 @@
|
||||
const cacheVersion = 'v1.9.0';
|
||||
const cacheVersion = 'v1.9.1';
|
||||
const cacheTitle = `pairdrop-included-ws-fallback-cache-${cacheVersion}`;
|
||||
const urlsToCache = [
|
||||
'index.html',
|
||||
'./',
|
||||
'index.html',
|
||||
'manifest.json',
|
||||
'styles.css',
|
||||
'scripts/localization.js',
|
||||
'scripts/network.js',
|
||||
'scripts/NoSleep.min.js',
|
||||
'scripts/QRCode.min.js',
|
||||
'scripts/theme.js',
|
||||
'scripts/ui.js',
|
||||
'scripts/util.js',
|
||||
'scripts/qrcode.js',
|
||||
'scripts/zip.min.js',
|
||||
'scripts/NoSleep.min.js',
|
||||
'scripts/theme.js',
|
||||
'sounds/blop.mp3',
|
||||
'images/favicon-96x96.png',
|
||||
'images/favicon-96x96-notification.png',
|
||||
@@ -53,7 +55,7 @@ const fromNetwork = (request, timeout) =>
|
||||
fetch(request).then(response => {
|
||||
clearTimeout(timeoutId);
|
||||
fulfill(response);
|
||||
update(request);
|
||||
update(request).then(() => console.log("Cache successfully updated for", request.url));
|
||||
}, reject);
|
||||
});
|
||||
|
||||
@@ -62,9 +64,7 @@ const fromCache = request =>
|
||||
caches
|
||||
.open(cacheTitle)
|
||||
.then(cache =>
|
||||
cache
|
||||
.match(request)
|
||||
.then(matching => matching || cache.match('/offline/'))
|
||||
cache.match(request)
|
||||
);
|
||||
|
||||
// cache the current page to make it available for offline
|
||||
@@ -72,15 +72,16 @@ const update = request =>
|
||||
caches
|
||||
.open(cacheTitle)
|
||||
.then(cache =>
|
||||
fetch(request).then(response => {
|
||||
cache.put(request, response).then(_ => {
|
||||
console.log("Page successfully cached.")
|
||||
fetch(request)
|
||||
.then(async response => {
|
||||
await cache.put(request, response);
|
||||
})
|
||||
})
|
||||
.catch(() => console.log(`Cache could not be updated. ${request.url}`))
|
||||
);
|
||||
|
||||
// general strategy when making a request (eg if online try to fetch it
|
||||
// from the network with a timeout, if something fails serve from cache)
|
||||
// from cache, if something fails fetch from network. Update cache everytime files are fetched.
|
||||
// This way files should only be fetched if cacheVersion is changed
|
||||
self.addEventListener('fetch', function(event) {
|
||||
if (event.request.method === "POST") {
|
||||
// Requests related to Web Share Target.
|
||||
@@ -90,27 +91,33 @@ self.addEventListener('fetch', function(event) {
|
||||
})());
|
||||
} else {
|
||||
// Regular requests not related to Web Share Target.
|
||||
|
||||
// FOR DEVELOPMENT: Comment in next line to always update assets instead of using cached versions
|
||||
// event.respondWith(fromNetwork(event.request, 10000));return;
|
||||
event.respondWith(
|
||||
fromNetwork(event.request, 10000).catch(() => fromCache(event.request))
|
||||
fromCache(event.request).then(rsp => {
|
||||
// if fromCache resolves to undefined fetch from network instead
|
||||
return rsp || fromNetwork(event.request, 10000);
|
||||
})
|
||||
);
|
||||
event.waitUntil(update(event.request));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// on activation, we clean up the previously registered service workers
|
||||
self.addEventListener('activate', evt =>
|
||||
evt.waitUntil(
|
||||
caches.keys().then(cacheNames => {
|
||||
return Promise.all(
|
||||
cacheNames.map(cacheName => {
|
||||
if (cacheName !== cacheTitle) {
|
||||
return caches.delete(cacheName);
|
||||
}
|
||||
})
|
||||
);
|
||||
})
|
||||
)
|
||||
self.addEventListener('activate', evt => {
|
||||
return evt.waitUntil(
|
||||
caches.keys().then(cacheNames => {
|
||||
return Promise.all(
|
||||
cacheNames.map(cacheName => {
|
||||
if (cacheName !== cacheTitle) {
|
||||
return caches.delete(cacheName);
|
||||
}
|
||||
})
|
||||
);
|
||||
})
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
const evaluateRequestData = function (request) {
|
||||
|
||||
Reference in New Issue
Block a user