Implement support for browser history API.
This commit is contained in:
parent
41d2586d97
commit
b2fa05060d
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue