Reader: add title and file chooser button

This commit is contained in:
John Factotum
2022-10-20 14:28:42 +00:00
committed by GitHub
parent 9a2bb558fd
commit 84691787fa
2 changed files with 73 additions and 43 deletions
+25 -1
View File
@@ -3,6 +3,7 @@
<meta name="color-scheme" content="light dark">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Security-Policy" content="default-src 'self' blob:; script-src 'self'; style-src 'self' blob: 'unsafe-inline'; img-src 'self' blob: data:; connect-src 'self' blob: data:; frame-src blob: data:; object-src 'none'; form-action 'none';">
<title>E-Book Reader</title>
<style>
body {
margin: 0;
@@ -13,6 +14,18 @@ body {
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
#drop-target h1 {
font-weight: 900;
}
#file-button {
font: inherit;
background: none;
border: 0;
padding: 0;
text-decoration: underline;
cursor: pointer;
}
.icon {
display: block;
@@ -20,6 +33,9 @@ body {
stroke: currentcolor;
stroke-width: 2px;
}
.empty-state-icon {
margin: auto;
}
.toolbar {
box-sizing: border-box;
position: absolute;
@@ -152,7 +168,15 @@ body {
}
</style>
<input type="file" id="file-input" hidden>
<div id="drop-target" class="filter">Drop a file here to open it.</div>
<div id="drop-target" class="filter">
<div>
<svg class="icon empty-state-icon" width="72" height="72" aria-hidden="true">
<path d="M36 18s-6-6-12-6-15 6-15 6v42s9-6 15-6 12 6 12 6c4-4 8-6 12-6s12 2 15 6V18c-6-4-12-6-15-6-4 0-8 2-12 6m0 0v42"/>
</svg>
<h1>Drop a book here!</h1>
<p>Or <button id="file-button">choose a file</button> to open it.</p>
</div>
</div>
<div id="dimming-overlay" aria-hidden="true"></div>
<div id="side-bar">
<div id="toc-view"></div>
+48 -42
View File
@@ -32,7 +32,7 @@ const isFBZ = ({ name, type }) =>
type === 'application/x-zip-compressed-fb2'
|| name.endsWith('.fb2.zip') || name.endsWith('.fbz')
globalThis.open = async (file, emit) => {
const getView = async (file, emit) => {
if (!file.size) throw new Error('File not found')
let book
if (await isZip(file)) {
@@ -121,53 +121,59 @@ const emit = obj => {
}
}
const open = async file => {
document.body.removeChild($('#drop-target'))
const view = await getView(file, emit)
const style = {
spacing: 1.4,
justify: true,
hyphenate: true,
}
view.setAppearance({ css: getCSS(style) })
view.renderer.next()
const title = view.book.metadata?.title
if (title) document.title = title
const closeSideBar = () => {
$('#dimming-overlay').classList.remove('show')
$('#side-bar').classList.remove('show')
}
const toc = view.book.toc
if (toc) {
const onclick = href => {
view.goTo(href).catch(e => console.error(e))
closeSideBar()
}
const tocView = createTOCView(toc, onclick)
setCurrentHref = tocView.setCurrentHref
$('#toc-view').append(tocView.element)
}
$('#header-bar').style.visibility = 'visible'
$('#side-bar-button').addEventListener('click', () => {
$('#dimming-overlay').classList.add('show')
$('#side-bar').classList.add('show')
})
$('#dimming-overlay').addEventListener('click', closeSideBar)
$('#nav-bar').style.visibility = 'visible'
$('#left-button').addEventListener('click', () => view.goLeft())
$('#right-button').addEventListener('click', () => view.goRight())
}
const dragOverHandler = e => e.preventDefault()
const dropHandler = e => {
e.preventDefault()
const file = Array.from(e.dataTransfer.items)
.find(item => item.kind === 'file')?.getAsFile()
if (file) {
document.body.removeChild($('#drop-target'))
open(file, emit)
.then(view => {
const style = {
spacing: 1.4,
justify: true,
hyphenate: true,
}
view.setAppearance({ css: getCSS(style) })
view.renderer.next()
const closeSideBar = () => {
$('#dimming-overlay').classList.remove('show')
$('#side-bar').classList.remove('show')
}
const toc = view.book.toc
if (toc) {
const onclick = href => {
view.goTo(href).catch(e => console.error(e))
closeSideBar()
}
const tocView = createTOCView(toc, onclick)
setCurrentHref = tocView.setCurrentHref
$('#toc-view').append(tocView.element)
}
$('#header-bar').style.visibility = 'visible'
$('#side-bar-button').addEventListener('click', () => {
$('#dimming-overlay').classList.add('show')
$('#side-bar').classList.add('show')
})
$('#dimming-overlay').addEventListener('click', closeSideBar)
$('#nav-bar').style.visibility = 'visible'
$('#left-button').addEventListener('click', () => view.goLeft())
$('#right-button').addEventListener('click', () => view.goRight())
})
.catch(e => emit(e))
}
if (file) open(file).catch(e => emit(e))
}
const dropTarget = $('#drop-target')
dropTarget.addEventListener('drop', dropHandler)
dropTarget.addEventListener('dragover', dragOverHandler)
$('#file-input').addEventListener('change', e =>
open(e.target.files[0]).catch(e => emit(e)))
$('#file-button').addEventListener('click', () => $('#file-input').click())