fix toaster behavior upon setFile

pull/3094/head
yann300 6 years ago
parent 6ae9340494
commit f25469f9ee
  1. 6
      src/app/files/fileManager.js
  2. 32
      src/app/ui/styles/tooltip-styles.js
  3. 67
      src/app/ui/tooltip.js

@ -136,8 +136,9 @@ class FileManager extends ApiFactory {
if (this.currentRequest) { if (this.currentRequest) {
let reject = false let reject = false
let savedAsAnotherFile = false let savedAsAnotherFile = false
let warnToaster
const actions = yo`<div class="container ml-1"> const actions = yo`<div class="container ml-1">
<button class="btn btn-primary btn-sm m-1" onclick=${(e) => { reject = true; e.target.innerHTML = 'Canceled' }}>Cancel</button> <button class="btn btn-primary btn-sm m-1" onclick=${(e) => { reject = true; e.target.innerHTML = 'Canceled'; warnToaster.hide() }}>Cancel</button>
<button class="btn btn-primary btn-sm m-1" onclick=${(e) => { <button class="btn btn-primary btn-sm m-1" onclick=${(e) => {
if (savedAsAnotherFile) return if (savedAsAnotherFile) return
savedAsAnotherFile = true savedAsAnotherFile = true
@ -145,9 +146,10 @@ class FileManager extends ApiFactory {
this._setFileInternal(newPath, content) this._setFileInternal(newPath, content)
this.switchFile(newPath) this.switchFile(newPath)
e.target.innerHTML = 'Saved' e.target.innerHTML = 'Saved'
warnToaster.hide()
}}>Save As Another</button> }}>Save As Another</button>
</div>` </div>`
await toaster(yo`<div><span class="text-primary">${this.currentRequest.from}</span> is modyfing to <span class="text-primary">${path}</span></div>`, actions, { time: 4000 }) warnToaster = await toaster(yo`<div><span class="text-primary">${this.currentRequest.from}</span> is modyfing to <span class="text-primary">${path}</span></div>`, actions, { time: 4000 })
if (reject) throw new Error(`set file operation on ${path} aborted by user.`) if (reject) throw new Error(`set file operation on ${path} aborted by user.`)
if (savedAsAnotherFile) return if (savedAsAnotherFile) return
} }

@ -9,30 +9,42 @@ var css = csjs`
position: fixed; position: fixed;
color: var(--primary) color: var(--primary)
min-height: 50px; min-height: 50px;
min-width: 290px;
padding: 16px 24px 12px; padding: 16px 24px 12px;
border-radius: 3px; border-radius: 3px;
bottom: -300; bottom: -300;
left: 40%; left: 40%;
font-size: 12px; font-size: 12px;
text-align: center; text-align: center;
-webkit-animation-name: animatebottom; bottom: 0;
-webkit-animation-duration: 6s;
animation-name: animatebottom;
animation-duration: 6s
} }
@-webkit-keyframes animatebottom { @-webkit-keyframes animatebottom {
0% {bottom: -300px} 0% {bottom: -300px}
20% {bottom: 0} 100% {bottom: 0}
50% {bottom: 0}
100% {bottom: -300px}
} }
@keyframes animatebottom { @keyframes animatebottom {
0% {bottom: -300px} 0% {bottom: -300px}
20% {bottom: 0} 100% {bottom: 0}
50% {bottom: 0} }
@-webkit-keyframes animatetop {
0% {bottom: 0}
100% {bottom: -300px}
}
@keyframes animatetop {
0% {bottom: 0}
100% {bottom: -300px} 100% {bottom: -300px}
} }
.animateTop {
-webkit-animation-name: animatetop;
-webkit-animation-duration: 2s;
animation-name: animatetop;
animation-duration: 2s;
}
.animateBottom {
-webkit-animation-name: animatebottom;
-webkit-animation-duration: 2s;
animation-name: animatebottom;
animation-duration: 2s;
}
` `
module.exports = css module.exports = css

@ -7,24 +7,63 @@ var css = require('./styles/tooltip-styles')
* @param {HTMLElement} [action] An HTMLElement to display for action * @param {HTMLElement} [action] An HTMLElement to display for action
*/ */
module.exports = function addTooltip (tooltipText, action, opts) { module.exports = function addTooltip (tooltipText, action, opts) {
opts = defaultOptions(opts) let t = new Toaster()
var tooltip = yo` t.render(tooltipText, action, opts)
<div class="${css.tooltip} bg-secondary"> return t
<span>${tooltipText}</span> }
${action}
</div>` class Toaster {
return new Promise((resolve, reject) => { hide () {
document.body.appendChild(tooltip) if (this.id) clearTimeout(this.id)
setTimeout(function () { setTimeout(() => {
document.body.removeChild(tooltip) // remove from body after the animation is finished
resolve() if (this.tooltip.parentElement) this.tooltip.parentElement.removeChild(this.tooltip)
}, opts.time) }, 2000)
}) animation(this.tooltip, css.animateTop.className)
}
render (tooltipText, action, opts) {
opts = defaultOptions(opts)
return new Promise((resolve, reject) => {
this.tooltip = yo`
<div class="${css.tooltip} bg-secondary" onmouseenter=${() => { over() }} onmouseleave=${() => { out() }}>
<span>${tooltipText}</span>
${action}
</div>`
let timeOut = () => {
return setTimeout(() => {
if (this.id) {
this.hide()
resolve()
}
}, opts.time)
}
let over = () => {
if (this.id) {
clearTimeout(this.id)
this.id = null
}
}
let out = () => {
if (!this.id) this.id = timeOut()
}
this.id = timeOut()
document.body.appendChild(this.tooltip)
animation(this.tooltip, css.animateBottom.className)
})
}
} }
let defaultOptions = (opts) => { let defaultOptions = (opts) => {
opts = opts || {} opts = opts || {}
return { return {
time: opts.time || 70000 time: opts.time || 7000
} }
} }
let animation = (tooltip, anim) => {
tooltip.classList.remove(css.animateTop.className)
tooltip.classList.remove(css.animateBottom.className)
void tooltip.offsetWidth // trick for restarting the animation
tooltip.classList.add(anim)
}

Loading…
Cancel
Save