From 07e46e472ec0932d3bebc7c5e7409cf05004a016 Mon Sep 17 00:00:00 2001 From: schlagmichdoch Date: Thu, 22 Feb 2024 15:30:09 +0100 Subject: [PATCH 1/4] Prevent flickering of text on load by adding defer="true" to deferred style sheets --- public/scripts/main.js | 1 + 1 file changed, 1 insertion(+) diff --git a/public/scripts/main.js b/public/scripts/main.js index 9403567..9def333 100644 --- a/public/scripts/main.js +++ b/public/scripts/main.js @@ -137,6 +137,7 @@ class PairDrop { let stylesheet = document.createElement('link'); stylesheet.rel = 'preload'; stylesheet.as = 'style'; + stylesheet.defer = true; stylesheet.href = url; stylesheet.onload = _ => { stylesheet.onload = null; From 8a56a271bcc81d1b969791dad9ce496360a35ef8 Mon Sep 17 00:00:00 2001 From: schlagmichdoch Date: Fri, 23 Feb 2024 13:02:40 +0100 Subject: [PATCH 2/4] Make PWA run standalone (fixes #264) --- public/manifest.json | 2 +- public/scripts/main.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/manifest.json b/public/manifest.json index 63a9bb9..4a3239b 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -28,7 +28,7 @@ "background_color": "#efefef", "start_url": "/", "scope": "/", - "display": "minimal-ui", + "display": "standalone", "theme_color": "#3367d6", "screenshots" : [ { diff --git a/public/scripts/main.js b/public/scripts/main.js index 9def333..750d7f9 100644 --- a/public/scripts/main.js +++ b/public/scripts/main.js @@ -101,7 +101,7 @@ class PairDrop { } onPwaInstallable(e) { - if (!window.matchMedia('(display-mode: minimal-ui)').matches) { + if (!window.matchMedia('(display-mode: standalone)').matches) { // only display install btn when not installed this.$headerInstallBtn.removeAttribute('hidden'); this.$headerInstallBtn.addEventListener('click', () => { From 9b3571feacc76d4981adbe162f94b64510248752 Mon Sep 17 00:00:00 2001 From: schlagmichdoch Date: Thu, 16 May 2024 19:37:32 +0200 Subject: [PATCH 3/4] Refactor BrowserTabsConnector and PeersManager --- public/scripts/browser-tabs-connector.js | 21 +++++-- public/scripts/network.js | 72 ++++++++++++++++++------ public/scripts/ui-main.js | 12 ++-- 3 files changed, 75 insertions(+), 30 deletions(-) diff --git a/public/scripts/browser-tabs-connector.js b/public/scripts/browser-tabs-connector.js index acc0005..0329319 100644 --- a/public/scripts/browser-tabs-connector.js +++ b/public/scripts/browser-tabs-connector.js @@ -2,18 +2,27 @@ class BrowserTabsConnector { constructor() { this.bc = new BroadcastChannel('pairdrop'); this.bc.addEventListener('message', e => this._onMessage(e)); - Events.on('broadcast-send', e => this._broadcastSend(e.detail)); + Events.on('broadcast-send', e => this._broadcastSend(e.detail.type, e.detail.data)); + Events.on('broadcast-self-display-name-changed', e => this._onBroadcastSelfDisplayNameChanged(e.detail.displayName)); } - _broadcastSend(message) { - this.bc.postMessage(message); + _broadcastSend(type, data) { + this.bc.postMessage({ type, data }); + } + + _onBroadcastSelfDisplayNameChanged(displayName) { + this._broadcastSend('self-display-name-changed', { displayName: displayName }); } _onMessage(e) { - Logger.debug('Broadcast:', e.data) - switch (e.data.type) { + const type = e.data.type; + const data = e.data.data; + + Logger.debug('Broadcast:', type, data); + + switch (type) { case 'self-display-name-changed': - Events.fire('self-display-name-changed', e.data.detail); + Events.fire('self-display-name-changed', data.displayName); break; } } diff --git a/public/scripts/network.js b/public/scripts/network.js index af4900c..be2ae21 100644 --- a/public/scripts/network.js +++ b/public/scripts/network.js @@ -550,7 +550,7 @@ class Peer { } Events.fire('peer-display-name-changed', {peerId: this._peerId, displayName: message.displayName}); - Events.fire('notify-peer-display-name-changed', this._peerId); + Events.fire('notify-display-name-changed', { recipient: this._peerId }); } _sendState() { @@ -1487,13 +1487,16 @@ class WSPeer extends Peer { class PeersManager { constructor(serverConnection) { - this.peers = {}; this._server = serverConnection; + this.peers = {}; + this._device = { + originalDisplayName: '', + displayName: '', + publicRoomId: null + }; + Events.on('signal', e => this._onSignal(e.detail)); Events.on('peers', e => this._onPeers(e.detail)); - Events.on('files-selected', e => this._onFilesSelected(e.detail)); - Events.on('respond-to-files-transfer-request', e => this._onRespondToFileTransferRequest(e.detail)) - Events.on('send-text', e => this._onSendText(e.detail)); Events.on('peer-left', e => this._onPeerLeft(e.detail)); Events.on('peer-joined', e => this._onPeerJoined(e.detail)); Events.on('peer-connected', e => this._onPeerConnected(e.detail.peerId)); @@ -1505,16 +1508,25 @@ class PeersManager { // peer closes connection Events.on('secret-room-deleted', e => this._onSecretRoomDeleted(e.detail)); - Events.on('room-secret-regenerated', e => this._onRoomSecretRegenerated(e.detail)); + + // peer Events.on('display-name', e => this._onDisplayName(e.detail.displayName)); - Events.on('self-display-name-changed', e => this._notifyPeersDisplayNameChanged(e.detail)); - Events.on('notify-peer-display-name-changed', e => this._notifyPeerDisplayNameChanged(e.detail)); + Events.on('self-display-name-changed', e => this._notifyPeersDisplayNameChanged(e.detail.displayName)); + Events.on('notify-display-name-changed', e => this._notifyPeerDisplayNameChanged(e.detail.recipient)); Events.on('auto-accept-updated', e => this._onAutoAcceptUpdated(e.detail.roomSecret, e.detail.autoAccept)); + + // transfer + Events.on('send-text', e => this._onSendText(e.detail)); + Events.on('files-selected', e => this._onFilesSelected(e.detail)); + Events.on('respond-to-files-transfer-request', e => this._onRespondToFileTransferRequest(e.detail)) + + // websocket connection Events.on('ws-disconnected', _ => this._onWsDisconnected()); Events.on('ws-relay', e => this._onWsRelay(e.detail.peerId, e.detail.message)); Events.on('ws-config', e => this._onWsConfig(e.detail)); + // no-sleep Events.on('evaluate-no-sleep', _ => this._onEvaluateNoSleep()); } @@ -1664,25 +1676,34 @@ class PeersManager { } _onRoomSecretsDeleted(roomSecrets) { - for (let i=0; i 1) { peer._removeRoomType(roomType); @@ -1710,7 +1731,10 @@ class PeersManager { } _notifyPeersDisplayNameChanged(newDisplayName) { - this._displayName = newDisplayName ? newDisplayName : this._originalDisplayName; + this._device.displayName = newDisplayName + ? newDisplayName + : this._device.originalDisplayName; + for (const peerId in this.peers) { this._notifyPeerDisplayNameChanged(peerId); } @@ -1719,23 +1743,35 @@ class PeersManager { _notifyPeerDisplayNameChanged(peerId) { const peer = this.peers[peerId]; if (!peer) return; - this.peers[peerId]._sendDisplayName(this._displayName); + this.peers[peerId]._sendDisplayName(this._device.displayName); } _onDisplayName(displayName) { - this._originalDisplayName = displayName; + this._device.originalDisplayName = displayName; // if the displayName has not been changed (yet) set the displayName to the original displayName - if (!this._displayName) this._displayName = displayName; + if (!this._device.displayName) this._device.displayName = displayName; } _onAutoAcceptUpdated(roomSecret, autoAccept) { - const peerId = this._getPeerIdsFromRoomId(roomSecret)[0]; + let peerIds = this._getPeerIdsFromRoomId(roomSecret); + const peerId = this._removePeerIdsSameBrowser(peerIds)[0]; if (!peerId) return; this.peers[peerId]._setAutoAccept(autoAccept); } + _removePeerIdsSameBrowser(peerIds) { + let peerIdsNotSameBrowser = []; + for (let i = 0; i < peerIds.length; i++) { + const peer = this.peers[peerIds[i]]; + if (!peer._isSameBrowser()) { + peerIdsNotSameBrowser.push(peerIds[i]); + } + } + return peerIdsNotSameBrowser; + } + _getPeerIdsFromRoomId(roomId) { if (!roomId) return []; diff --git a/public/scripts/ui-main.js b/public/scripts/ui-main.js index 93cafb1..a43e727 100644 --- a/public/scripts/ui-main.js +++ b/public/scripts/ui-main.js @@ -205,7 +205,7 @@ class FooterUI { this.$displayName.addEventListener('blur', e => this._saveDisplayName(e.target.innerText)); Events.on('display-name', e => this._onDisplayName(e.detail.displayName)); - Events.on('self-display-name-changed', e => this._insertDisplayName(e.detail)); + Events.on('self-display-name-changed', e => this._insertDisplayName(e.detail.displayName)); // Load saved display name on page load Events.on('ws-connected', _ => this._loadSavedDisplayName()); @@ -239,7 +239,7 @@ class FooterUI { if (!displayName) return; Logger.debug("Retrieved edited display name:", displayName) - Events.fire('self-display-name-changed', displayName); + Events.fire('self-display-name-changed', { displayName: displayName }); } _onDisplayName(displayName){ @@ -280,8 +280,8 @@ class FooterUI { Events.fire('notify-user', Localization.getTranslation("notifications.display-name-changed-temporarily")); }) .finally(() => { - Events.fire('self-display-name-changed', newDisplayName); - Events.fire('broadcast-send', {type: 'self-display-name-changed', detail: newDisplayName}); + Events.fire('self-display-name-changed', { displayName: newDisplayName }); + Events.fire('broadcast-self-display-name-changed', { displayName: newDisplayName }); }); } else { @@ -292,8 +292,8 @@ class FooterUI { }) .finally(() => { Events.fire('notify-user', Localization.getTranslation("notifications.display-name-random-again")); - Events.fire('self-display-name-changed', ''); - Events.fire('broadcast-send', {type: 'self-display-name-changed', detail: ''}); + Events.fire('self-display-name-changed', { displayName: '' }); + Events.fire('broadcast-self-display-name-changed', { displayName: '' }); }); } } From be381ea43822f84e2dca6b8d7126ffa781a03e6a Mon Sep 17 00:00:00 2001 From: schlagmichdoch Date: Thu, 16 May 2024 19:44:43 +0200 Subject: [PATCH 4/4] When switching public rooms disconnect from devices in old room (fixes #298) --- public/scripts/network.js | 8 +++++++- public/scripts/ui.js | 31 ++++++++++++++++--------------- server/ws-server.js | 3 +-- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/public/scripts/network.js b/public/scripts/network.js index be2ae21..2e5d036 100644 --- a/public/scripts/network.js +++ b/public/scripts/network.js @@ -1502,9 +1502,12 @@ class PeersManager { Events.on('peer-connected', e => this._onPeerConnected(e.detail.peerId)); Events.on('peer-disconnected', e => this._onPeerDisconnected(e.detail)); + // ROOMS + Events.on('join-public-room', e => this._onJoinPublicRoom(e.detail.roomId)); + // this device closes connection Events.on('room-secrets-deleted', e => this._onRoomSecretsDeleted(e.detail)); - Events.on('leave-public-room', e => this._onLeavePublicRoom(e.detail)); + Events.on('leave-public-room', _ => this._onLeavePublicRoom()); // peer closes connection Events.on('secret-room-deleted', e => this._onSecretRoomDeleted(e.detail)); @@ -1682,6 +1685,9 @@ class PeersManager { } _onJoinPublicRoom(roomId) { + if (roomId !== this._device.publicRoomId) { + this._disconnectFromPublicRoom(); + } this._device.publicRoomId = roomId; } diff --git a/public/scripts/ui.js b/public/scripts/ui.js index 10b8f46..b70cb1d 100644 --- a/public/scripts/ui.js +++ b/public/scripts/ui.js @@ -2046,8 +2046,8 @@ class PublicRoomDialog extends Dialog { Events.on('keydown', e => this._onKeyDown(e)); Events.on('public-room-created', e => this._onPublicRoomCreated(e.detail)); - Events.on('peers', e => this._onPeers(e.detail)); - Events.on('peer-joined', e => this._onPeerJoined(e.detail.peer, e.detail.roomId)); + Events.on('peers', e => this._onPeers(e.detail.peers, e.detail.roomId)); + Events.on('peer-joined', e => this._onPeerJoined(e.detail.roomId)); Events.on('public-room-id-invalid', e => this._onPublicRoomIdInvalid(e.detail)); Events.on('public-room-left', _ => this._onPublicRoomLeft()); this.$el.addEventListener('paste', e => this._onPaste(e)); @@ -2177,29 +2177,30 @@ class PublicRoomDialog extends Dialog { } } - _onPeers(message) { - message.peers.forEach(messagePeer => { - this._evaluateJoinedPeer(messagePeer.id, message.roomId); - }); + _onPeers(peers, roomId) { + // Do not evaluate if creating new room + if (this.roomId && !peers.length) return; + + this._evaluateJoinedPeer(roomId); } - _onPeerJoined(peer, roomId) { - this._evaluateJoinedPeer(peer.id, roomId); + _onPeerJoined(roomId) { + this._evaluateJoinedPeer(roomId); } - _evaluateJoinedPeer(peerId, roomId) { - const isInitiatedRoomId = roomId === this.roomId; - const isJoinedRoomId = roomId === this.roomIdJoin; + _evaluateJoinedPeer(roomId) { + const peerJoinedThisRoom = roomId === this.roomId; + const switchedToOtherRoom = roomId === this.roomIdJoin; - if (!peerId || !roomId || (!isInitiatedRoomId && !isJoinedRoomId)) return; + if (!roomId || (!peerJoinedThisRoom && !switchedToOtherRoom)) return; this.hide(); sessionStorage.setItem('public_room_id', roomId); - if (isJoinedRoomId) { + if (switchedToOtherRoom) { + this.roomIdJoin = null; this.roomId = roomId; - this.roomIdJoin = false; this._setKeyAndQrCode(); } } @@ -2212,7 +2213,7 @@ class PublicRoomDialog extends Dialog { } _leavePublicRoom() { - Events.fire('leave-public-room', this.roomId); + Events.fire('leave-public-room'); } _onPublicRoomLeft() { diff --git a/server/ws-server.js b/server/ws-server.js index 589c424..a55b55d 100644 --- a/server/ws-server.js +++ b/server/ws-server.js @@ -251,7 +251,6 @@ export default class PairDropWsServer { return; } - this._leavePublicRoom(sender); this._joinPublicRoom(sender, message.publicRoomId); } @@ -312,7 +311,7 @@ export default class PairDropWsServer { _joinPublicRoom(peer, publicRoomId) { // prevent joining of 2 public rooms simultaneously - this._leavePublicRoom(peer); + this._leavePublicRoom(peer, true); this._joinRoom(peer, 'public-id', publicRoomId);