Implement support for browser history API.

This commit is contained in:
projectmoon 2023-01-06 16:51:35 +01:00
parent 41d2586d97
commit b2fa05060d
2 changed files with 63 additions and 12 deletions

View File

@ -25,7 +25,7 @@
<div id="real-body" class="d-none"> <div id="real-body" class="d-none">
<nav id="main-navbar" class="navbar px-0 sticky-top navbar-expand-lg bg-light"> <nav id="main-navbar" class="navbar px-0 sticky-top navbar-expand-lg bg-light">
<div class="container-fluid"> <div class="container-fluid">
<a class="navbar-brand" href="#"> <a class="navbar-brand" href="javascript:void(0);">
🔥 MSN Viewer 🔥 MSN Viewer
</a> </a>
<button class="navbar-toggler" type="button" <button class="navbar-toggler" type="button"
@ -64,7 +64,7 @@
</button> </button>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li> <li>
<a id="loaded-load-previous-button" class="dropdown-item disabled" href="#"> <a id="loaded-load-previous-button" class="dropdown-item disabled" href="javascript:void(0);">
<i class="text-start bi bi-files"></i> Load Previous <i class="text-start bi bi-files"></i> Load Previous
</a> </a>
</li> </li>

View File

@ -28,6 +28,12 @@ function showLoadedControls() {
ui.fileLoadedControls.classList.remove('d-none'); ui.fileLoadedControls.classList.remove('d-none');
} }
function showNotLoadedControls() {
ui.noFileLoadedControls.classList.remove('d-none');
ui.noFileLoadedControls.classList.add('d-lg-block');
ui.fileLoadedControls.classList.add('d-none');
}
function displayError(errorDiv: HTMLElement, category: string, ex: Error) { function displayError(errorDiv: HTMLElement, category: string, ex: Error) {
console.error(ex); console.error(ex);
const errorHeading = errorDiv.querySelector('.alert-heading') as HTMLElement | null; const errorHeading = errorDiv.querySelector('.alert-heading') as HTMLElement | null;
@ -121,6 +127,11 @@ function displayBackup(xsltProcessor: XSLTProcessor, filename: string, xmlText:
ui.chatDisplay.appendChild(fragment); ui.chatDisplay.appendChild(fragment);
ui.currentlyViewing.value = filename; ui.currentlyViewing.value = filename;
processFragment(); processFragment();
if (history.state?.filename != filename) {
history.pushState({ filename }, '', `#!/${filename}`);
}
document.title = `MSN Viewer - ${filename}`;
return true; return true;
} }
catch (e) { catch (e) {
@ -183,7 +194,27 @@ async function initEvents() {
} }
}); });
// ui.previousBackupsList.addEventListener('click', , true); window.onpopstate = async (event) => {
const filename = event?.state?.filename as string | null;
if (filename) {
await doLoadBackup(event.state.filename);
} else {
reset();
}
}
}
function reset() {
//real body shown
//minibar hidden
//initial stuff shown
showApplication(true);
showNotLoadedControls();
hideErrors();
removeChildren(ui.chatDisplay);
history.replaceState(null, 'MSN Viewer', '');
document.title = 'MSN Viewer';
} }
async function deleteBackup(e: MouseEvent) { async function deleteBackup(e: MouseEvent) {
@ -208,25 +239,33 @@ async function deleteBackup(e: MouseEvent) {
} }
} }
async function doLoadBackup(filename: string) {
const entry = await db.entries.get(filename);
if (entry) {
displayBackup(xsltProcessor, entry.filename, entry.backupData);
} else {
displayNonFatalError(
'Internal Error',
new Error(`Could not find data for backup: ${filename}`)
);
}
bootstrap.Modal.getInstance(ui.previousBackupsModal)?.hide();
}
async function loadBackup(e: MouseEvent) { async function loadBackup(e: MouseEvent) {
const listItem = e.target as HTMLElement | null; const listItem = e.target as HTMLElement | null;
const filename = listItem?.dataset['filename']; const filename = listItem?.dataset['filename'];
if (filename) { if (filename) {
const entry = await db.entries.get(filename); await doLoadBackup(filename);
if (entry) {
displayBackup(xsltProcessor, entry.filename, entry.backupData);
} else {
displayNonFatalError('Internal Error', new Error('Backup data disappeared?!'));
}
bootstrap.Modal.getInstance(ui.previousBackupsModal)?.hide();
} }
} }
function BackupListItem(props: { filename: string }) { function BackupListItem(props: { filename: string }) {
return ( return (
<a href="#" class="backup-entry list-group-item list-group-item-action" <a href="javascript:void(0);"
class="backup-entry list-group-item list-group-item-action"
onClick={loadBackup} dataset={{ filename: props.filename }}> onClick={loadBackup} dataset={{ filename: props.filename }}>
<div class="backup-name pe-none"> <div class="backup-name pe-none">
{props.filename} {props.filename}
@ -250,8 +289,20 @@ async function populateSavedBackups() {
modal.show(); modal.show();
} }
async function parseURL() {
if (window.location.hash && window.location.hash.startsWith('#!/')) {
const split = window.location.hash.split('#!/');
if (split.length > 1) {
const filename = split[1];
console.log(filename);
await doLoadBackup(filename);
}
}
}
window.addEventListener('DOMContentLoaded', async () => { window.addEventListener('DOMContentLoaded', async () => {
await initEvents(); await initEvents();
showLoadingIndicator(false); showLoadingIndicator(false);
await parseURL();
showApplication(true); showApplication(true);
}); });