Now deals with tablets and foldables better. The previous version didn’t hide the tab list when hiding the header.
JS
export async function invoke(app) {
const duration = 250;
document.body.style.setProperty('--headertransduration', `${duration}ms`);
const capacitorapp = window.Capacitor?.Plugins?.App;
let viewHeaderHeight = parseInt(window.getComputedStyle(document.body).getPropertyValue('--view-header-height'));
let tabHeaderHeight = parseInt(window.getComputedStyle(document.body).getPropertyValue('--header-height'));
let keyboardopen = false;
let headerhidden = false;
function adjustScroll(delta) {
const editor = app.workspace?.activeLeaf?.view?.editor;
if (!editor || app.workspace?.activeLeaf?.view?.file?.extension != 'md') return;
const scrollInfo = editor.getScrollInfo();
const start = scrollInfo.top;
const end = start + delta;
const startTime = performance.now();
function animate(time) {
const elapsed = time - startTime;
const progress = Math.min(elapsed / duration, 1);
const ease = progress < 0.5
? 2 * progress * progress
: -1 + (4 - 2 * progress) * progress;
editor.scrollTo(scrollInfo.left, start + (end - start) * ease);
if (progress < 1) {
requestAnimationFrame(animate);
}
}
requestAnimationFrame(animate);
}
function hideHeader() {
if (headerhidden || !document.activeElement.classList.contains('cm-content') || document.activeElement.closest('.metadata-property-value') || document.activeElement.closest('.metadata-property-key')) return;
document.body.classList.add('hide-view-header');
document.body.classList.contains('is-tablet') ? adjustScroll(-(viewHeaderHeight + tabHeaderHeight)) : adjustScroll(-viewHeaderHeight);
headerhidden = true;
}
function showHeader() {
if (!headerhidden) return;
document.body.classList.remove('hide-view-header');
document.body.classList.contains('is-tablet') ? adjustScroll(viewHeaderHeight + tabHeaderHeight) : adjustScroll(viewHeaderHeight);
headerhidden = false;
}
function elementDefocused() {
setTimeout(() => {
if(!document.activeElement.onblur) document.activeElement.onblur = elementDefocused;
if (keyboardopen) {
if (document.activeElement.classList.contains('cm-content')) {
hideHeader();
} else if (!document.activeElement.closest('.metadata-property-value') && !document.activeElement.closest('.metadata-property-key')) {
showHeader();
}
}
}, 100);
}
if (capacitorapp?.addListener) {
window.Capacitor?.Plugins?.Keyboard?.addListener('keyboardWillShow', () => {
keyboardopen = true;
hideHeader();
if(!document.activeElement.onblur) document.activeElement.onblur = elementDefocused;
});
window.Capacitor?.Plugins?.Keyboard?.addListener('keyboardWillHide', () => {
keyboardopen = false;
showHeader();
});
}
}
CSS
body {
--headertransduration: 0ms;
}
.workspace-leaf-content[data-type="markdown"] .view-header, .workspace-tab-header-container {
transition: height var(--headertransduration), opacity var(--headertransduration);
}
body.hide-view-header .workspace-leaf-content[data-type="markdown"] .view-header, body.hide-view-header .workspace-tab-header-container {
border-bottom: 0;
height: 0;
opacity: 0;
overflow: hidden;
}