mirror of
https://github.com/schlagmichdoch/PairDrop.git
synced 2025-04-20 15:06:15 -04:00
Streamline client initiation by using await/async instead of .then and events
This commit is contained in:
parent
25d6595a8f
commit
cb86ce0e39
4 changed files with 169 additions and 148 deletions
|
@ -1,42 +1,64 @@
|
||||||
class PairDrop {
|
class PairDrop {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.$header = $$('header.opacity-0');
|
|
||||||
this.$center = $$('#center');
|
|
||||||
this.$footer = $$('footer');
|
|
||||||
this.$xNoPeers = $$('x-no-peers');
|
|
||||||
this.$headerNotificationButton = $('notification');
|
this.$headerNotificationButton = $('notification');
|
||||||
this.$editPairedDevicesHeaderBtn = $('edit-paired-devices');
|
this.$headerEditPairedDevicesBtn = $('edit-paired-devices');
|
||||||
this.$footerInstructionsPairedDevices = $$('.discovery-wrapper .badge-room-secret');
|
this.$footerPairedDevicesBadge = $$('.discovery-wrapper .badge-room-secret');
|
||||||
this.$head = $$('head');
|
this.$headerInstallBtn = $('install');
|
||||||
this.$installBtn = $('install');
|
|
||||||
|
this.deferredStyles = [
|
||||||
|
"styles/deferred-styles.css"
|
||||||
|
];
|
||||||
|
this.deferredScripts = [
|
||||||
|
"scripts/browser-tabs-connector.js",
|
||||||
|
"scripts/util.js",
|
||||||
|
"scripts/network.js",
|
||||||
|
"scripts/ui.js",
|
||||||
|
"scripts/qr-code.min.js",
|
||||||
|
"scripts/zip.min.js",
|
||||||
|
"scripts/no-sleep.min.js"
|
||||||
|
];
|
||||||
|
|
||||||
this.registerServiceWorker();
|
this.registerServiceWorker();
|
||||||
|
|
||||||
Events.on('beforeinstallprompt', e => this.onPwaInstallable(e));
|
Events.on('beforeinstallprompt', e => this.onPwaInstallable(e));
|
||||||
|
|
||||||
const persistentStorage = new PersistentStorage();
|
this.persistentStorage = new PersistentStorage();
|
||||||
const themeUI = new ThemeUI();
|
this.localization = new Localization();
|
||||||
const backgroundCanvas = new BackgroundCanvas();
|
this.themeUI = new ThemeUI();
|
||||||
|
this.backgroundCanvas = new BackgroundCanvas();
|
||||||
|
this.headerUI = new HeaderUI();
|
||||||
|
this.centerUI = new CenterUI();
|
||||||
|
this.footerUI = new FooterUI();
|
||||||
|
|
||||||
|
this.initialize()
|
||||||
|
.then(_ => {
|
||||||
|
console.log("Initialization completed.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async initialize() {
|
||||||
// Translate page before fading in
|
// Translate page before fading in
|
||||||
const localization = new Localization();
|
await this.localization.setInitialTranslation()
|
||||||
localization
|
console.log("Initial translation successful.");
|
||||||
.setInitialTranslation()
|
|
||||||
.then(() => {
|
|
||||||
console.log("Initial translation successful.");
|
|
||||||
|
|
||||||
// FooterUI needs translations
|
// Show "Loading..." until connected to WsServer
|
||||||
const footerUI = new FooterUI();
|
await this.footerUI.showLoading();
|
||||||
|
|
||||||
Events.on('fade-in-ui', _ => this.fadeInUI())
|
// Evaluate css shifting UI elements and fade in UI elements
|
||||||
Events.on('fade-in-header', _ => this.fadeInHeader())
|
await this.evaluateUI();
|
||||||
|
await this.headerUI.fadeIn();
|
||||||
|
await this.footerUI._evaluateFooterBadges();
|
||||||
|
await this.footerUI.fadeIn();
|
||||||
|
await this.centerUI.fadeIn();
|
||||||
|
await this.backgroundCanvas.fadeIn();
|
||||||
|
|
||||||
// Evaluate UI elements and fade in UI
|
// Load deferred assets
|
||||||
this.evaluateUI();
|
await this.loadDeferredAssets();
|
||||||
|
console.log("Loading of deferred assets completed.");
|
||||||
|
|
||||||
// Load deferred assets
|
await this.hydrate();
|
||||||
this.loadDeferredAssets();
|
console.log("UI hydrated.");
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
registerServiceWorker() {
|
registerServiceWorker() {
|
||||||
|
@ -53,131 +75,101 @@ class PairDrop {
|
||||||
onPwaInstallable(e) {
|
onPwaInstallable(e) {
|
||||||
if (!window.matchMedia('(display-mode: minimal-ui)').matches) {
|
if (!window.matchMedia('(display-mode: minimal-ui)').matches) {
|
||||||
// only display install btn when not installed
|
// only display install btn when not installed
|
||||||
this.$installBtn.removeAttribute('hidden');
|
this.$headerInstallBtn.removeAttribute('hidden');
|
||||||
this.$installBtn.addEventListener('click', () => {
|
this.$headerInstallBtn.addEventListener('click', () => {
|
||||||
this.$installBtn.setAttribute('hidden', true);
|
this.$headerInstallBtn.setAttribute('hidden', true);
|
||||||
e.prompt();
|
e.prompt();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return e.preventDefault();
|
return e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
evaluateUI() {
|
async evaluateUI() {
|
||||||
// Check whether notification permissions have already been granted
|
// Check whether notification permissions have already been granted
|
||||||
if ('Notification' in window && Notification.permission !== 'granted') {
|
if ('Notification' in window && Notification.permission !== 'granted') {
|
||||||
this.$headerNotificationButton.removeAttribute('hidden');
|
this.$headerNotificationButton.removeAttribute('hidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
PersistentStorage
|
let roomSecrets = await PersistentStorage.getAllRoomSecrets();
|
||||||
.getAllRoomSecrets()
|
if (roomSecrets.length > 0) {
|
||||||
.then(roomSecrets => {
|
this.$headerEditPairedDevicesBtn.removeAttribute('hidden');
|
||||||
if (roomSecrets.length > 0) {
|
this.$footerPairedDevicesBadge.removeAttribute('hidden');
|
||||||
this.$editPairedDevicesHeaderBtn.removeAttribute('hidden');
|
}
|
||||||
this.$footerInstructionsPairedDevices.removeAttribute('hidden');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
Events.fire('evaluate-footer-badges');
|
|
||||||
Events.fire('fade-in-header');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fadeInUI() {
|
async loadDeferredAssets() {
|
||||||
this.$center.classList.remove('opacity-0');
|
|
||||||
this.$footer.classList.remove('opacity-0');
|
|
||||||
|
|
||||||
// Prevent flickering on load
|
|
||||||
setTimeout(() => {
|
|
||||||
this.$xNoPeers.classList.remove('no-animation-on-load');
|
|
||||||
}, 600);
|
|
||||||
}
|
|
||||||
|
|
||||||
fadeInHeader() {
|
|
||||||
this.$header.classList.remove('opacity-0');
|
|
||||||
}
|
|
||||||
|
|
||||||
loadDeferredAssets() {
|
|
||||||
console.log("Load deferred assets");
|
console.log("Load deferred assets");
|
||||||
this.deferredStyles = [
|
for (const url of this.deferredStyles) {
|
||||||
"styles/deferred-styles.css"
|
await this.loadAndApplyStylesheet(url);
|
||||||
];
|
|
||||||
this.deferredScripts = [
|
|
||||||
"scripts/browser-tabs-connector.js",
|
|
||||||
"scripts/util.js",
|
|
||||||
"scripts/network.js",
|
|
||||||
"scripts/ui.js",
|
|
||||||
"scripts/qr-code.min.js",
|
|
||||||
"scripts/zip.min.js",
|
|
||||||
"scripts/no-sleep.min.js"
|
|
||||||
];
|
|
||||||
this.deferredStyles.forEach(url => this.loadStyleSheet(url, _ => this.onStyleLoaded(url)))
|
|
||||||
this.deferredScripts.forEach(url => this.loadScript(url, _ => this.onScriptLoaded(url)))
|
|
||||||
}
|
|
||||||
|
|
||||||
loadStyleSheet(url, callback) {
|
|
||||||
let stylesheet = document.createElement('link');
|
|
||||||
stylesheet.rel = 'stylesheet';
|
|
||||||
stylesheet.href = url;
|
|
||||||
stylesheet.type = 'text/css';
|
|
||||||
stylesheet.onload = callback;
|
|
||||||
this.$head.appendChild(stylesheet);
|
|
||||||
}
|
|
||||||
|
|
||||||
loadScript(url, callback) {
|
|
||||||
let script = document.createElement("script");
|
|
||||||
script.src = url;
|
|
||||||
script.onload = callback;
|
|
||||||
document.body.appendChild(script);
|
|
||||||
}
|
|
||||||
|
|
||||||
onStyleLoaded(url) {
|
|
||||||
// remove entry from array
|
|
||||||
const index = this.deferredStyles.indexOf(url);
|
|
||||||
if (index !== -1) {
|
|
||||||
this.deferredStyles.splice(index, 1);
|
|
||||||
}
|
}
|
||||||
this.onAssetLoaded();
|
for (const url of this.deferredScripts) {
|
||||||
}
|
await this.loadAndApplyScript(url);
|
||||||
|
|
||||||
onScriptLoaded(url) {
|
|
||||||
// remove entry from array
|
|
||||||
const index = this.deferredScripts.indexOf(url);
|
|
||||||
if (index !== -1) {
|
|
||||||
this.deferredScripts.splice(index, 1);
|
|
||||||
}
|
}
|
||||||
this.onAssetLoaded();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onAssetLoaded() {
|
loadStyleSheet(url) {
|
||||||
if (this.deferredScripts.length || this.deferredStyles.length) return;
|
return new Promise((resolve, reject) => {
|
||||||
|
let stylesheet = document.createElement('link');
|
||||||
|
stylesheet.rel = 'stylesheet';
|
||||||
|
stylesheet.href = url;
|
||||||
|
stylesheet.type = 'text/css';
|
||||||
|
stylesheet.onload = resolve;
|
||||||
|
stylesheet.onerror = reject;
|
||||||
|
|
||||||
console.log("Loading of deferred assets completed. Start UI hydration.");
|
document.head.appendChild(stylesheet);
|
||||||
|
});
|
||||||
this.hydrate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hydrate() {
|
async loadAndApplyStylesheet(url) {
|
||||||
const peersUI = new PeersUI();
|
try {
|
||||||
const languageSelectDialog = new LanguageSelectDialog();
|
await this.loadStyleSheet(url);
|
||||||
const receiveFileDialog = new ReceiveFileDialog();
|
console.log(`Stylesheet loaded successfully: ${url}`);
|
||||||
const receiveRequestDialog = new ReceiveRequestDialog();
|
} catch (error) {
|
||||||
const sendTextDialog = new SendTextDialog();
|
console.error('Error loading stylesheet:', error);
|
||||||
const receiveTextDialog = new ReceiveTextDialog();
|
}
|
||||||
const pairDeviceDialog = new PairDeviceDialog();
|
}
|
||||||
const clearDevicesDialog = new EditPairedDevicesDialog();
|
|
||||||
const publicRoomDialog = new PublicRoomDialog();
|
loadScript(url) {
|
||||||
const base64ZipDialog = new Base64ZipDialog();
|
return new Promise((resolve, reject) => {
|
||||||
const shareTextDialog = new ShareTextDialog();
|
let script = document.createElement("script");
|
||||||
const toast = new Toast();
|
script.src = url;
|
||||||
const notifications = new Notifications();
|
script.onload = resolve;
|
||||||
const networkStatusUI = new NetworkStatusUI();
|
script.onerror = reject;
|
||||||
const webShareTargetUI = new WebShareTargetUI();
|
|
||||||
const webFileHandlersUI = new WebFileHandlersUI();
|
document.body.appendChild(script);
|
||||||
const noSleepUI = new NoSleepUI();
|
});
|
||||||
const broadCast = new BrowserTabsConnector();
|
}
|
||||||
const server = new ServerConnection();
|
|
||||||
const peers = new PeersManager(server);
|
async loadAndApplyScript(url) {
|
||||||
console.log("UI hydrated.")
|
try {
|
||||||
|
await this.loadScript(url);
|
||||||
|
console.log(`Script loaded successfully: ${url}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error loading script:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async hydrate() {
|
||||||
|
this.peersUI = new PeersUI();
|
||||||
|
this.languageSelectDialog = new LanguageSelectDialog();
|
||||||
|
this.receiveFileDialog = new ReceiveFileDialog();
|
||||||
|
this.receiveRequestDialog = new ReceiveRequestDialog();
|
||||||
|
this.sendTextDialog = new SendTextDialog();
|
||||||
|
this.receiveTextDialog = new ReceiveTextDialog();
|
||||||
|
this.pairDeviceDialog = new PairDeviceDialog();
|
||||||
|
this.clearDevicesDialog = new EditPairedDevicesDialog();
|
||||||
|
this.publicRoomDialog = new PublicRoomDialog();
|
||||||
|
this.base64Dialog = new Base64Dialog();
|
||||||
|
this.shareTextDialog = new ShareTextDialog();
|
||||||
|
this.toast = new Toast();
|
||||||
|
this.notifications = new Notifications();
|
||||||
|
this.networkStatusUI = new NetworkStatusUI();
|
||||||
|
this.webShareTargetUI = new WebShareTargetUI();
|
||||||
|
this.webFileHandlersUI = new WebFileHandlersUI();
|
||||||
|
this.noSleepUI = new NoSleepUI();
|
||||||
|
this.broadCast = new BrowserTabsConnector();
|
||||||
|
this.server = new ServerConnection();
|
||||||
|
this.peers = new PeersManager(this.server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ class PersistentStorage {
|
||||||
return(secrets);
|
return(secrets);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.logBrowserNotCapable();
|
this.logBrowserNotCapable();
|
||||||
return 0;
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,15 +111,41 @@ class ThemeUI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class HeaderUI {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.$header = $$('header.opacity-0');
|
||||||
|
}
|
||||||
|
|
||||||
|
async fadeIn() {
|
||||||
|
this.$header.classList.remove('opacity-0');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CenterUI {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.$center = $$('#center');
|
||||||
|
this.$xNoPeers = $$('x-no-peers');
|
||||||
|
}
|
||||||
|
|
||||||
|
async fadeIn() {
|
||||||
|
this.$center.classList.remove('opacity-0');
|
||||||
|
|
||||||
|
// Prevent flickering on load
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$xNoPeers.classList.remove('no-animation-on-load');
|
||||||
|
}, 600);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class FooterUI {
|
class FooterUI {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
this.$footer = $$('footer');
|
||||||
this.$displayName = $('display-name');
|
this.$displayName = $('display-name');
|
||||||
this.$discoveryWrapper = $$('footer .discovery-wrapper');
|
this.$discoveryWrapper = $$('footer .discovery-wrapper');
|
||||||
|
|
||||||
// Show "Loading…"
|
|
||||||
this.$displayName.setAttribute('placeholder', this.$displayName.dataset.placeholder);
|
|
||||||
|
|
||||||
this.$displayName.addEventListener('keydown', e => this._onKeyDownDisplayName(e));
|
this.$displayName.addEventListener('keydown', e => this._onKeyDownDisplayName(e));
|
||||||
this.$displayName.addEventListener('keyup', e => this._onKeyUpDisplayName(e));
|
this.$displayName.addEventListener('keyup', e => this._onKeyUpDisplayName(e));
|
||||||
this.$displayName.addEventListener('blur', e => this._saveDisplayName(e.target.innerText));
|
this.$displayName.addEventListener('blur', e => this._saveDisplayName(e.target.innerText));
|
||||||
|
@ -133,7 +159,15 @@ class FooterUI {
|
||||||
Events.on('evaluate-footer-badges', _ => this._evaluateFooterBadges());
|
Events.on('evaluate-footer-badges', _ => this._evaluateFooterBadges());
|
||||||
}
|
}
|
||||||
|
|
||||||
_evaluateFooterBadges() {
|
async showLoading() {
|
||||||
|
this.$displayName.setAttribute('placeholder', this.$displayName.dataset.placeholder);
|
||||||
|
}
|
||||||
|
|
||||||
|
async fadeIn() {
|
||||||
|
this.$footer.classList.remove('opacity-0');
|
||||||
|
}
|
||||||
|
|
||||||
|
async _evaluateFooterBadges() {
|
||||||
if (this.$discoveryWrapper.querySelectorAll('div:last-of-type > span[hidden]').length < 2) {
|
if (this.$discoveryWrapper.querySelectorAll('div:last-of-type > span[hidden]').length < 2) {
|
||||||
this.$discoveryWrapper.classList.remove('row');
|
this.$discoveryWrapper.classList.remove('row');
|
||||||
this.$discoveryWrapper.classList.add('column');
|
this.$discoveryWrapper.classList.add('column');
|
||||||
|
@ -143,17 +177,15 @@ class FooterUI {
|
||||||
this.$discoveryWrapper.classList.add('row');
|
this.$discoveryWrapper.classList.add('row');
|
||||||
}
|
}
|
||||||
Events.fire('redraw-canvas');
|
Events.fire('redraw-canvas');
|
||||||
Events.fire('fade-in-ui');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_loadSavedDisplayName() {
|
async _loadSavedDisplayName() {
|
||||||
this._getSavedDisplayName()
|
const displayName = await this._getSavedDisplayName()
|
||||||
.then(displayName => {
|
|
||||||
console.log("Retrieved edited display name:", displayName)
|
if (!displayName) return;
|
||||||
if (displayName) {
|
|
||||||
Events.fire('self-display-name-changed', displayName);
|
console.log("Retrieved edited display name:", displayName)
|
||||||
}
|
Events.fire('self-display-name-changed', displayName);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onDisplayName(displayName){
|
_onDisplayName(displayName){
|
||||||
|
@ -234,9 +266,6 @@ class BackgroundCanvas {
|
||||||
this.cCtx = this.c.getContext('2d');
|
this.cCtx = this.c.getContext('2d');
|
||||||
this.$footer = $$('footer');
|
this.$footer = $$('footer');
|
||||||
|
|
||||||
// fade-in on load
|
|
||||||
Events.on('fade-in-ui', _ => this._fadeIn());
|
|
||||||
|
|
||||||
// redraw canvas
|
// redraw canvas
|
||||||
Events.on('resize', _ => this.init());
|
Events.on('resize', _ => this.init());
|
||||||
Events.on('redraw-canvas', _ => this.init());
|
Events.on('redraw-canvas', _ => this.init());
|
||||||
|
@ -246,7 +275,7 @@ class BackgroundCanvas {
|
||||||
Events.on('share-mode-changed', e => this.onShareModeChanged(e.detail.active));
|
Events.on('share-mode-changed', e => this.onShareModeChanged(e.detail.active));
|
||||||
}
|
}
|
||||||
|
|
||||||
_fadeIn() {
|
async fadeIn() {
|
||||||
this.c.classList.remove('opacity-0');
|
this.c.classList.remove('opacity-0');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2143,7 +2143,7 @@ class ShareTextDialog extends Dialog {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Base64ZipDialog extends Dialog {
|
class Base64Dialog extends Dialog {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super('base64-paste-dialog');
|
super('base64-paste-dialog');
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue