mirror of
https://github.com/schlagmichdoch/PairDrop.git
synced 2025-04-21 15:26:17 -04:00
implement persistent storage request and add notification for users on Google Chrome
This commit is contained in:
parent
fafdbcc829
commit
47e040d666
4 changed files with 98 additions and 22 deletions
|
@ -87,12 +87,16 @@ class PeersUI {
|
||||||
if (newDisplayName === savedDisplayName) return;
|
if (newDisplayName === savedDisplayName) return;
|
||||||
|
|
||||||
if (newDisplayName) {
|
if (newDisplayName) {
|
||||||
PersistentStorage.set('editedDisplayName', newDisplayName).then(_ => {
|
PersistentStorage.set('editedDisplayName', newDisplayName).then(async _ => {
|
||||||
|
const persistent = await PersistentStorage.isStoragePersistent();
|
||||||
|
if (!persistent) {
|
||||||
|
throw ErrorEvent("Storage not persistent.")
|
||||||
|
}
|
||||||
Events.fire('notify-user', 'Device name is changed permanently.');
|
Events.fire('notify-user', 'Device name is changed permanently.');
|
||||||
}).catch(_ => {
|
}).catch(_ => {
|
||||||
console.log("This browser does not support IndexedDB. Use localStorage instead.");
|
console.log("This browser does not support IndexedDB. Use localStorage instead.");
|
||||||
localStorage.setItem('editedDisplayName', newDisplayName);
|
localStorage.setItem('editedDisplayName', newDisplayName);
|
||||||
Events.fire('notify-user', 'Device name is changed only for this session.');
|
Events.fire('notify-user', 'Device name is changed for this session only.\n\nGoogle Chrome:\nSave page as bookmark or enable notifications to enable persistence.');
|
||||||
}).finally(_ => {
|
}).finally(_ => {
|
||||||
Events.fire('self-display-name-changed', newDisplayName);
|
Events.fire('self-display-name-changed', newDisplayName);
|
||||||
Events.fire('broadcast-send', {type: 'self-display-name-changed', detail: newDisplayName});
|
Events.fire('broadcast-send', {type: 'self-display-name-changed', detail: newDisplayName});
|
||||||
|
@ -101,7 +105,6 @@ class PeersUI {
|
||||||
PersistentStorage.delete('editedDisplayName').catch(_ => {
|
PersistentStorage.delete('editedDisplayName').catch(_ => {
|
||||||
console.log("This browser does not support IndexedDB. Use localStorage instead.")
|
console.log("This browser does not support IndexedDB. Use localStorage instead.")
|
||||||
localStorage.removeItem('editedDisplayName');
|
localStorage.removeItem('editedDisplayName');
|
||||||
Events.fire('notify-user', 'Random Display name is used again.');
|
|
||||||
}).finally(_ => {
|
}).finally(_ => {
|
||||||
Events.fire('notify-user', 'Device name is randomly generated again.');
|
Events.fire('notify-user', 'Device name is randomly generated again.');
|
||||||
Events.fire('self-display-name-changed', '');
|
Events.fire('self-display-name-changed', '');
|
||||||
|
@ -1027,17 +1030,21 @@ class PairDeviceDialog extends Dialog {
|
||||||
|
|
||||||
_pairDeviceJoined(peerId, roomSecret) {
|
_pairDeviceJoined(peerId, roomSecret) {
|
||||||
this.hide();
|
this.hide();
|
||||||
PersistentStorage.addRoomSecret(roomSecret).then(_ => {
|
PersistentStorage.addRoomSecret(roomSecret).then(async addedRoomSecret => {
|
||||||
|
const persistent = await PersistentStorage.isStoragePersistent();
|
||||||
|
if (!persistent) {
|
||||||
|
throw ErrorEvent("Storage not persistent.")
|
||||||
|
}
|
||||||
Events.fire('notify-user', 'Devices paired successfully.');
|
Events.fire('notify-user', 'Devices paired successfully.');
|
||||||
const oldRoomSecret = $(peerId).ui.roomSecret;
|
const oldRoomSecret = $(peerId).ui.roomSecret;
|
||||||
if (oldRoomSecret) PersistentStorage.deleteRoomSecret(oldRoomSecret);
|
if (oldRoomSecret) await PersistentStorage.deleteRoomSecret(oldRoomSecret);
|
||||||
$(peerId).ui.roomSecret = roomSecret;
|
$(peerId).ui.roomSecret = addedRoomSecret;
|
||||||
this._evaluateNumberRoomSecrets();
|
|
||||||
}).finally(_ => {
|
}).finally(_ => {
|
||||||
|
this._evaluateNumberRoomSecrets();
|
||||||
this._cleanUp();
|
this._cleanUp();
|
||||||
})
|
})
|
||||||
.catch(_ => {
|
.catch(_ => {
|
||||||
Events.fire('notify-user', 'Paired devices are not persistent.');
|
Events.fire('notify-user', 'Paired device is saved for this session only.\n\nGoogle Chrome:\nSave page as bookmark or enable notifications to enable persistence.');
|
||||||
PersistentStorage.logBrowserNotCapable();
|
PersistentStorage.logBrowserNotCapable();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1460,6 +1467,15 @@ class Notifications {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Events.fire('notify-user', 'Notifications enabled.');
|
Events.fire('notify-user', 'Notifications enabled.');
|
||||||
|
PersistentStorage.isStoragePersistent().then(persistent => {
|
||||||
|
if (!persistent) {
|
||||||
|
PersistentStorage.requestPersistentStorage().then(updatedPersistence => {
|
||||||
|
if (updatedPersistence) {
|
||||||
|
Events.fire('notify-user', 'Successfully enabled persistent storage.')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
this.$button.setAttribute('hidden', 1);
|
this.$button.setAttribute('hidden', 1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1722,8 +1738,27 @@ class PersistentStorage {
|
||||||
console.log("This browser does not support IndexedDB. Paired devices will be gone after the browser is closed.");
|
console.log("This browser does not support IndexedDB. Paired devices will be gone after the browser is closed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async isStoragePersistent() {
|
||||||
|
return await navigator.storage.persisted();
|
||||||
|
}
|
||||||
|
|
||||||
|
static async requestPersistentStorage() {
|
||||||
|
if (!navigator.storage || !navigator.storage.persist) return false;
|
||||||
|
if (await this.isStoragePersistent()) return true;
|
||||||
|
|
||||||
|
const persistent = await navigator.storage.persist()
|
||||||
|
if (persistent) {
|
||||||
|
console.log("Storage will not be cleared except by explicit user action");
|
||||||
|
} else {
|
||||||
|
console.warn("Storage may be cleared by the UA under storage pressure.");
|
||||||
|
}
|
||||||
|
return persistent;
|
||||||
|
}
|
||||||
|
|
||||||
static set(key, value) {
|
static set(key, value) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
|
await this.requestPersistentStorage();
|
||||||
|
|
||||||
const DBOpenRequest = window.indexedDB.open('pairdrop_store');
|
const DBOpenRequest = window.indexedDB.open('pairdrop_store');
|
||||||
DBOpenRequest.onsuccess = (e) => {
|
DBOpenRequest.onsuccess = (e) => {
|
||||||
const db = e.target.result;
|
const db = e.target.result;
|
||||||
|
@ -1780,7 +1815,9 @@ class PersistentStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
static addRoomSecret(roomSecret) {
|
static addRoomSecret(roomSecret) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
|
await this.requestPersistentStorage();
|
||||||
|
|
||||||
const DBOpenRequest = window.indexedDB.open('pairdrop_store');
|
const DBOpenRequest = window.indexedDB.open('pairdrop_store');
|
||||||
DBOpenRequest.onsuccess = (e) => {
|
DBOpenRequest.onsuccess = (e) => {
|
||||||
const db = e.target.result;
|
const db = e.target.result;
|
||||||
|
@ -1789,7 +1826,7 @@ class PersistentStorage {
|
||||||
const objectStoreRequest = objectStore.add({'secret': roomSecret});
|
const objectStoreRequest = objectStore.add({'secret': roomSecret});
|
||||||
objectStoreRequest.onsuccess = _ => {
|
objectStoreRequest.onsuccess = _ => {
|
||||||
console.log(`Request successful. RoomSecret added: ${roomSecret}`);
|
console.log(`Request successful. RoomSecret added: ${roomSecret}`);
|
||||||
resolve();
|
resolve(roomSecret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBOpenRequest.onerror = (e) => {
|
DBOpenRequest.onerror = (e) => {
|
||||||
|
|
|
@ -1128,6 +1128,7 @@ x-toast {
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
x-toast:not([show]):not(:hover) {
|
x-toast:not([show]):not(:hover) {
|
||||||
|
|
|
@ -87,12 +87,16 @@ class PeersUI {
|
||||||
if (newDisplayName === savedDisplayName) return;
|
if (newDisplayName === savedDisplayName) return;
|
||||||
|
|
||||||
if (newDisplayName) {
|
if (newDisplayName) {
|
||||||
PersistentStorage.set('editedDisplayName', newDisplayName).then(_ => {
|
PersistentStorage.set('editedDisplayName', newDisplayName).then(async _ => {
|
||||||
|
const persistent = await PersistentStorage.isStoragePersistent();
|
||||||
|
if (!persistent) {
|
||||||
|
throw ErrorEvent("Storage not persistent.")
|
||||||
|
}
|
||||||
Events.fire('notify-user', 'Device name is changed permanently.');
|
Events.fire('notify-user', 'Device name is changed permanently.');
|
||||||
}).catch(_ => {
|
}).catch(_ => {
|
||||||
console.log("This browser does not support IndexedDB. Use localStorage instead.");
|
console.log("This browser does not support IndexedDB. Use localStorage instead.");
|
||||||
localStorage.setItem('editedDisplayName', newDisplayName);
|
localStorage.setItem('editedDisplayName', newDisplayName);
|
||||||
Events.fire('notify-user', 'Device name is changed only for this session.');
|
Events.fire('notify-user', 'Device name is changed for this session only.\n\nGoogle Chrome:\nSave page as bookmark or enable notifications to enable persistence.');
|
||||||
}).finally(_ => {
|
}).finally(_ => {
|
||||||
Events.fire('self-display-name-changed', newDisplayName);
|
Events.fire('self-display-name-changed', newDisplayName);
|
||||||
Events.fire('broadcast-send', {type: 'self-display-name-changed', detail: newDisplayName});
|
Events.fire('broadcast-send', {type: 'self-display-name-changed', detail: newDisplayName});
|
||||||
|
@ -101,7 +105,6 @@ class PeersUI {
|
||||||
PersistentStorage.delete('editedDisplayName').catch(_ => {
|
PersistentStorage.delete('editedDisplayName').catch(_ => {
|
||||||
console.log("This browser does not support IndexedDB. Use localStorage instead.")
|
console.log("This browser does not support IndexedDB. Use localStorage instead.")
|
||||||
localStorage.removeItem('editedDisplayName');
|
localStorage.removeItem('editedDisplayName');
|
||||||
Events.fire('notify-user', 'Random Display name is used again.');
|
|
||||||
}).finally(_ => {
|
}).finally(_ => {
|
||||||
Events.fire('notify-user', 'Device name is randomly generated again.');
|
Events.fire('notify-user', 'Device name is randomly generated again.');
|
||||||
Events.fire('self-display-name-changed', '');
|
Events.fire('self-display-name-changed', '');
|
||||||
|
@ -1027,17 +1030,21 @@ class PairDeviceDialog extends Dialog {
|
||||||
|
|
||||||
_pairDeviceJoined(peerId, roomSecret) {
|
_pairDeviceJoined(peerId, roomSecret) {
|
||||||
this.hide();
|
this.hide();
|
||||||
PersistentStorage.addRoomSecret(roomSecret).then(_ => {
|
PersistentStorage.addRoomSecret(roomSecret).then(async addedRoomSecret => {
|
||||||
|
const persistent = await PersistentStorage.isStoragePersistent();
|
||||||
|
if (!persistent) {
|
||||||
|
throw ErrorEvent("Storage not persistent.")
|
||||||
|
}
|
||||||
Events.fire('notify-user', 'Devices paired successfully.');
|
Events.fire('notify-user', 'Devices paired successfully.');
|
||||||
const oldRoomSecret = $(peerId).ui.roomSecret;
|
const oldRoomSecret = $(peerId).ui.roomSecret;
|
||||||
if (oldRoomSecret) PersistentStorage.deleteRoomSecret(oldRoomSecret);
|
if (oldRoomSecret) await PersistentStorage.deleteRoomSecret(oldRoomSecret);
|
||||||
$(peerId).ui.roomSecret = roomSecret;
|
$(peerId).ui.roomSecret = addedRoomSecret;
|
||||||
this._evaluateNumberRoomSecrets();
|
|
||||||
}).finally(_ => {
|
}).finally(_ => {
|
||||||
|
this._evaluateNumberRoomSecrets();
|
||||||
this._cleanUp();
|
this._cleanUp();
|
||||||
})
|
})
|
||||||
.catch(_ => {
|
.catch(_ => {
|
||||||
Events.fire('notify-user', 'Paired devices are not persistent.');
|
Events.fire('notify-user', 'Paired device is saved for this session only.\n\nGoogle Chrome:\nSave page as bookmark or enable notifications to enable persistence.');
|
||||||
PersistentStorage.logBrowserNotCapable();
|
PersistentStorage.logBrowserNotCapable();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1460,6 +1467,15 @@ class Notifications {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Events.fire('notify-user', 'Notifications enabled.');
|
Events.fire('notify-user', 'Notifications enabled.');
|
||||||
|
PersistentStorage.isStoragePersistent().then(persistent => {
|
||||||
|
if (!persistent) {
|
||||||
|
PersistentStorage.requestPersistentStorage().then(updatedPersistence => {
|
||||||
|
if (updatedPersistence) {
|
||||||
|
Events.fire('notify-user', 'Successfully enabled persistent storage.')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
this.$button.setAttribute('hidden', 1);
|
this.$button.setAttribute('hidden', 1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1722,8 +1738,27 @@ class PersistentStorage {
|
||||||
console.log("This browser does not support IndexedDB. Paired devices will be gone after the browser is closed.");
|
console.log("This browser does not support IndexedDB. Paired devices will be gone after the browser is closed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async isStoragePersistent() {
|
||||||
|
return await navigator.storage.persisted();
|
||||||
|
}
|
||||||
|
|
||||||
|
static async requestPersistentStorage() {
|
||||||
|
if (!navigator.storage || !navigator.storage.persist) return false;
|
||||||
|
if (await this.isStoragePersistent()) return true;
|
||||||
|
|
||||||
|
const persistent = await navigator.storage.persist()
|
||||||
|
if (persistent) {
|
||||||
|
console.log("Storage will not be cleared except by explicit user action");
|
||||||
|
} else {
|
||||||
|
console.warn("Storage may be cleared by the UA under storage pressure.");
|
||||||
|
}
|
||||||
|
return persistent;
|
||||||
|
}
|
||||||
|
|
||||||
static set(key, value) {
|
static set(key, value) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
|
await this.requestPersistentStorage();
|
||||||
|
|
||||||
const DBOpenRequest = window.indexedDB.open('pairdrop_store');
|
const DBOpenRequest = window.indexedDB.open('pairdrop_store');
|
||||||
DBOpenRequest.onsuccess = (e) => {
|
DBOpenRequest.onsuccess = (e) => {
|
||||||
const db = e.target.result;
|
const db = e.target.result;
|
||||||
|
@ -1780,7 +1815,9 @@ class PersistentStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
static addRoomSecret(roomSecret) {
|
static addRoomSecret(roomSecret) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
|
await this.requestPersistentStorage();
|
||||||
|
|
||||||
const DBOpenRequest = window.indexedDB.open('pairdrop_store');
|
const DBOpenRequest = window.indexedDB.open('pairdrop_store');
|
||||||
DBOpenRequest.onsuccess = (e) => {
|
DBOpenRequest.onsuccess = (e) => {
|
||||||
const db = e.target.result;
|
const db = e.target.result;
|
||||||
|
@ -1789,7 +1826,7 @@ class PersistentStorage {
|
||||||
const objectStoreRequest = objectStore.add({'secret': roomSecret});
|
const objectStoreRequest = objectStore.add({'secret': roomSecret});
|
||||||
objectStoreRequest.onsuccess = _ => {
|
objectStoreRequest.onsuccess = _ => {
|
||||||
console.log(`Request successful. RoomSecret added: ${roomSecret}`);
|
console.log(`Request successful. RoomSecret added: ${roomSecret}`);
|
||||||
resolve();
|
resolve(roomSecret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBOpenRequest.onerror = (e) => {
|
DBOpenRequest.onerror = (e) => {
|
||||||
|
|
|
@ -1154,6 +1154,7 @@ x-toast {
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
x-toast:not([show]):not(:hover) {
|
x-toast:not([show]):not(:hover) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue