Skip to content

Commit

Permalink
OPDS: add loading and error page
Browse files Browse the repository at this point in the history
  • Loading branch information
johnfactotum committed Dec 9, 2023
1 parent 067f2c8 commit 043c103
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 30 deletions.
3 changes: 3 additions & 0 deletions src/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import WebKit from 'gi://WebKit'
import { WebView } from './webview.js'

const uiText = {
loading: _('Loading'),
error: _('Failed to Load'),
reload: _('Reload'),
cancel: _('Cancel'),
viewCollection: _('See All'),
search: _('Search'),
Expand Down
61 changes: 36 additions & 25 deletions src/opds/opds.html
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,10 @@
inset: 0;
overflow: auto;
padding: 24px;
visibility: hidden;
}
body[data-state="feed"] #feed { visibility: visible }
body[data-state="entry"] #entry { visibility: visible }
body[data-state="search"] #search { visibility: visible }

#stack > [hidden] {
display: block;
}
#stack > *:before {
content: "";
display: block;
Expand All @@ -159,16 +157,15 @@
#stack > *[data-scrolled-to-top]:before {
opacity: 0;
}

#search > div {
text-align: center;
display: flex;
min-height: 100%;
#loading {
opacity: 0;
animation: .2s ease 1s 1 normal forwards fade-in;
}
#search > div > div {
margin: auto;
width: min(100%, 450px);
@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}

#search form p {
text-align: start;
}
Expand Down Expand Up @@ -520,7 +517,23 @@ <h1 id="heading"></h1>
<iframe sandbox="allow-same-origin"></iframe>
<slot name="details"></slot>
</template>
<div id="stack">
<foliate-stack id="stack">
<foliate-scrolled id="loading">
<foliate-center>
<svg width="48" height="48" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2">
<path d="M24 8A 16 16 0 0 0 24 40"><animateTransform attributeName="transform" type="rotate" from="0 24 24" to="360 24 24" dur="600ms" repeatCount="indefinite"/></path>
</svg>
<h1></h1>
</foliate-center>
</foliate-scrolled>
<foliate-scrolled id="error">
<foliate-center>
<h1></h1>
<p></p>
<hr style="visibility: hidden">
<button class="raised pill"></button>
</foliate-center>
</foliate-scrolled>
<foliate-scrolled id="feed">
<article>
<hgroup>
Expand All @@ -533,16 +546,14 @@ <h1></h1>
</foliate-scrolled>
<foliate-scrolled id="entry"></foliate-scrolled>
<foliate-scrolled id="search">
<div>
<div>
<h1></h1>
<p></p>
<form>
<div id="search-params"></div>
<button class="raised pill"></button>
</form>
</div>
</div>
<foliate-center>
<h1></h1>
<p></p>
<form>
<div id="search-params"></div>
<button class="raised pill"></button>
</form>
</foliate-center>
</foliate-scrolled>
</div>
</foliate-stack>
<script src="opds.js" type="module"></script>
17 changes: 12 additions & 5 deletions src/opds/opds.js
Original file line number Diff line number Diff line change
Expand Up @@ -624,17 +624,17 @@ const renderFeed = async (feed, baseURL) => {
addEventListener('hashchange', () => {
const hash = location.hash.slice(1)
if (!hash) {
document.body.dataset.state = 'feed'
document.querySelector('#stack').showChild(document.querySelector('#feed'))
document.querySelector('#entry').replaceChildren()
} else {
document.body.dataset.state = 'entry'
document.querySelector('#stack').showChild(document.querySelector('#entry'))
const pub = JSON.parse(decodeURIComponent(hash))
renderPublication(pub, baseURL)
.then(el => document.querySelector('#entry').append(el))
.catch(e => console.error(e))
}
})
document.body.dataset.state = 'feed'
document.querySelector('#stack').showChild(document.querySelector('#feed'))
}

const renderOpenSearch = (doc, baseURL) => {
Expand Down Expand Up @@ -682,7 +682,6 @@ const renderOpenSearch = (doc, baseURL) => {
children.find(filter('Description'))?.textContent ?? ''
document.querySelector('#search button').textContent = globalThis.uiText.search

document.body.dataset.state = 'search'
const container = document.querySelector('#search-params')
for (const [, prefix, param, optional] of template.matchAll(regex)) {
const namespace = prefix ? $url.lookupNamespaceURI(prefix) : null
Expand All @@ -706,17 +705,23 @@ const renderOpenSearch = (doc, baseURL) => {
p.append(label)
container.append(p)
}
document.querySelector('#stack').showChild(document.querySelector('#search'))
container.querySelector('input').focus()
}

globalThis.updateSearchURL = () =>
emit({ type: 'search', url: document.body.dataset.searchUrl })

document.querySelector('#loading h1').textContent = globalThis.uiText.loading
document.querySelector('#error h1').textContent = globalThis.uiText.error
document.querySelector('#error button').textContent = globalThis.uiText.reload
document.querySelector('#error button').onclick = () => location.reload()

try {
const params = new URLSearchParams(location.search)
const url = params.get('url')
const res = await fetch(url)
if (!res.ok) throw new Error()
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`)
const text = await res.text()
if (text.startsWith('<')) {
const doc = new DOMParser().parseFromString(text, MIME.XML)
Expand All @@ -741,4 +746,6 @@ try {
}
} catch (e) {
console.error(e)
document.querySelector('#error p').innerText = e.message + '\n' + e.stack
document.querySelector('#stack').showChild(document.querySelector('#error'))
}
47 changes: 47 additions & 0 deletions src/opds/widgets.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,53 @@ customElements.define('foliate-scrolled', class extends HTMLElement {
}
})

customElements.define('foliate-center', class extends HTMLElement {
#root = this.attachShadow({ mode: 'closed' })
constructor() {
super()
const sheet = new CSSStyleSheet()
this.#root.adoptedStyleSheets = [sheet]
sheet.replaceSync(`
:host {
--max-width: 450px;
text-align: center;
display: flex;
width: 100%;
min-height: 100%;
}
:host > div {
margin: auto;
width: min(100%, var(--max-width));
}`)
const div = document.createElement('div')
div.append(document.createElement('slot'))
this.#root.append(div)
}
})

customElements.define('foliate-stack', class extends HTMLElement {
#root = this.attachShadow({ mode: 'closed' })
#children = []
#visibleChild
constructor() {
super()
const sheet = new CSSStyleSheet()
this.#root.adoptedStyleSheets = [sheet]
sheet.replaceSync(`
::slotted([hidden]) {
display: none;
visibility: hidden !important;
}`)
const slot = document.createElement('slot')
slot.addEventListener('slotchange', () => this.showChild(
this.querySelector(':scope > :not([hidden])') ?? this.children[0]))
this.#root.append(slot)
}
showChild(child) {
for (const el of this.children) el.hidden = el !== child
}
})

customElements.define('foliate-menu', class extends HTMLElement {
#root = this.attachShadow({ mode: 'closed' })
#internals = this.attachInternals()
Expand Down

0 comments on commit 043c103

Please sign in to comment.