|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import { app } from '../../scripts/app.js' |
|
|
|
const log = (...args) => { |
|
if (window.MTB?.TRACE) { |
|
console.debug(...args) |
|
} |
|
} |
|
|
|
let transition_time = 300 |
|
|
|
const containerStyle = ` |
|
position: fixed; |
|
top: 20px; |
|
left: 20px; |
|
font-family: monospace; |
|
z-index: 99999; |
|
height: 0; |
|
overflow: hidden; |
|
transition: height ${transition_time}ms ease-in-out; |
|
|
|
` |
|
|
|
const toastStyle = ` |
|
background-color: #333; |
|
color: #fff; |
|
padding: 10px; |
|
border-radius: 5px; |
|
opacity: 0; |
|
overflow:hidden; |
|
height:20px; |
|
transition-property: opacity, height, padding; |
|
transition-duration: ${transition_time}ms; |
|
` |
|
|
|
function notify(message, timeout = 3000) { |
|
log('Creating toast') |
|
const container = document.getElementById('mtb-notify-container') |
|
const toast = document.createElement('div') |
|
toast.style.cssText = toastStyle |
|
toast.innerText = message |
|
container.appendChild(toast) |
|
|
|
toast.addEventListener('transitionend', (e) => { |
|
|
|
if ( |
|
e.target === toast && |
|
e.propertyName === 'height' && |
|
e.elapsedTime > transition_time / 1000 - Number.EPSILON |
|
) { |
|
log('Transition out') |
|
const totalHeight = Array.from(container.children).reduce( |
|
(acc, child) => acc + child.offsetHeight + 10, |
|
0 |
|
) |
|
container.style.height = `${totalHeight}px` |
|
|
|
|
|
if (container.children.length === 0) { |
|
container.style.height = '0' |
|
} |
|
|
|
setTimeout(() => { |
|
container.removeChild(toast) |
|
log('Removed toast from DOM') |
|
}, transition_time) |
|
} else { |
|
log('Transition') |
|
} |
|
}) |
|
|
|
|
|
toast.style.opacity = '1' |
|
|
|
|
|
const totalHeight = Array.from(container.children).reduce( |
|
(acc, child) => acc + child.offsetHeight + 10, |
|
0 |
|
) |
|
container.style.height = `${totalHeight}px` |
|
|
|
|
|
setTimeout(() => { |
|
|
|
toast.style.opacity = '0' |
|
toast.style.height = '0' |
|
toast.style.paddingTop = '0' |
|
toast.style.paddingBottom = '0' |
|
}, timeout - transition_time) |
|
} |
|
|
|
app.registerExtension({ |
|
name: 'mtb.Notify', |
|
setup() { |
|
if (!window.MTB) { |
|
window.MTB = {} |
|
} |
|
|
|
const container = document.createElement('div') |
|
container.id = 'mtb-notify-container' |
|
container.style.cssText = containerStyle |
|
|
|
document.body.appendChild(container) |
|
window.MTB.notify = notify |
|
|
|
}, |
|
}) |
|
|