Streamline client initiation by using await/async instead of .then and events

This commit is contained in:
schlagmichdoch 2023-12-05 18:53:21 +01:00
parent 25d6595a8f
commit cb86ce0e39
4 changed files with 169 additions and 148 deletions

View file

@ -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
.setInitialTranslation()
.then(() => {
console.log("Initial translation successful."); 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();
// Evaluate UI elements and fade in UI await this.footerUI._evaluateFooterBadges();
this.evaluateUI(); await this.footerUI.fadeIn();
await this.centerUI.fadeIn();
await this.backgroundCanvas.fadeIn();
// Load deferred assets // Load deferred assets
this.loadDeferredAssets(); await this.loadDeferredAssets();
}) console.log("Loading of deferred assets completed.");
await this.hydrate();
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()
.then(roomSecrets => {
if (roomSecrets.length > 0) { if (roomSecrets.length > 0) {
this.$editPairedDevicesHeaderBtn.removeAttribute('hidden'); this.$headerEditPairedDevicesBtn.removeAttribute('hidden');
this.$footerInstructionsPairedDevices.removeAttribute('hidden'); this.$footerPairedDevicesBadge.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 = [ for (const url of this.deferredScripts) {
"scripts/browser-tabs-connector.js", await this.loadAndApplyScript(url);
"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) { loadStyleSheet(url) {
return new Promise((resolve, reject) => {
let stylesheet = document.createElement('link'); let stylesheet = document.createElement('link');
stylesheet.rel = 'stylesheet'; stylesheet.rel = 'stylesheet';
stylesheet.href = url; stylesheet.href = url;
stylesheet.type = 'text/css'; stylesheet.type = 'text/css';
stylesheet.onload = callback; stylesheet.onload = resolve;
this.$head.appendChild(stylesheet); stylesheet.onerror = reject;
document.head.appendChild(stylesheet);
});
} }
loadScript(url, callback) { async loadAndApplyStylesheet(url) {
try {
await this.loadStyleSheet(url);
console.log(`Stylesheet loaded successfully: ${url}`);
} catch (error) {
console.error('Error loading stylesheet:', error);
}
}
loadScript(url) {
return new Promise((resolve, reject) => {
let script = document.createElement("script"); let script = document.createElement("script");
script.src = url; script.src = url;
script.onload = callback; script.onload = resolve;
script.onerror = reject;
document.body.appendChild(script); document.body.appendChild(script);
});
} }
onStyleLoaded(url) { async loadAndApplyScript(url) {
// remove entry from array try {
const index = this.deferredStyles.indexOf(url); await this.loadScript(url);
if (index !== -1) { console.log(`Script loaded successfully: ${url}`);
this.deferredStyles.splice(index, 1); } catch (error) {
console.error('Error loading script:', error);
} }
this.onAssetLoaded();
} }
onScriptLoaded(url) { async hydrate() {
// remove entry from array this.peersUI = new PeersUI();
const index = this.deferredScripts.indexOf(url); this.languageSelectDialog = new LanguageSelectDialog();
if (index !== -1) { this.receiveFileDialog = new ReceiveFileDialog();
this.deferredScripts.splice(index, 1); this.receiveRequestDialog = new ReceiveRequestDialog();
} this.sendTextDialog = new SendTextDialog();
this.onAssetLoaded(); this.receiveTextDialog = new ReceiveTextDialog();
} this.pairDeviceDialog = new PairDeviceDialog();
this.clearDevicesDialog = new EditPairedDevicesDialog();
onAssetLoaded() { this.publicRoomDialog = new PublicRoomDialog();
if (this.deferredScripts.length || this.deferredStyles.length) return; this.base64Dialog = new Base64Dialog();
this.shareTextDialog = new ShareTextDialog();
console.log("Loading of deferred assets completed. Start UI hydration."); this.toast = new Toast();
this.notifications = new Notifications();
this.hydrate(); this.networkStatusUI = new NetworkStatusUI();
} this.webShareTargetUI = new WebShareTargetUI();
this.webFileHandlersUI = new WebFileHandlersUI();
hydrate() { this.noSleepUI = new NoSleepUI();
const peersUI = new PeersUI(); this.broadCast = new BrowserTabsConnector();
const languageSelectDialog = new LanguageSelectDialog(); this.server = new ServerConnection();
const receiveFileDialog = new ReceiveFileDialog(); this.peers = new PeersManager(this.server);
const receiveRequestDialog = new ReceiveRequestDialog();
const sendTextDialog = new SendTextDialog();
const receiveTextDialog = new ReceiveTextDialog();
const pairDeviceDialog = new PairDeviceDialog();
const clearDevicesDialog = new EditPairedDevicesDialog();
const publicRoomDialog = new PublicRoomDialog();
const base64ZipDialog = new Base64ZipDialog();
const shareTextDialog = new ShareTextDialog();
const toast = new Toast();
const notifications = new Notifications();
const networkStatusUI = new NetworkStatusUI();
const webShareTargetUI = new WebShareTargetUI();
const webFileHandlersUI = new WebFileHandlersUI();
const noSleepUI = new NoSleepUI();
const broadCast = new BrowserTabsConnector();
const server = new ServerConnection();
const peers = new PeersManager(server);
console.log("UI hydrated.")
} }
} }

View file

@ -149,7 +149,7 @@ class PersistentStorage {
return(secrets); return(secrets);
} catch (e) { } catch (e) {
this.logBrowserNotCapable(); this.logBrowserNotCapable();
return 0; return [];
} }
} }

View file

@ -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,18 +177,16 @@ 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 => {
if (!displayName) return;
console.log("Retrieved edited display name:", displayName) console.log("Retrieved edited display name:", displayName)
if (displayName) {
Events.fire('self-display-name-changed', displayName); Events.fire('self-display-name-changed', displayName);
} }
});
}
_onDisplayName(displayName){ _onDisplayName(displayName){
// set display name // set display name
@ -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');
} }

View file

@ -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');