diff --git a/src/gresource.xml b/src/gresource.xml index a110bc4e..bfd3dbe6 100644 --- a/src/gresource.xml +++ b/src/gresource.xml @@ -62,6 +62,7 @@ foliate-js/vendor/pdfjs/pdf.worker.js opds/opds.html opds/opds.js + opds/widgets.js reader/reader.html reader/reader.js reader/markup.js diff --git a/src/library.js b/src/library.js index 71f6a66c..8152d1d1 100644 --- a/src/library.js +++ b/src/library.js @@ -561,25 +561,32 @@ export const Library = GObject.registerClass({ } showCatalog(url) { this._main_stack.visible_child = this._catalog_toolbar_view - this._catalog_toolbar_view.content ??= utils.connect(new WebView({ - settings: new WebKit.Settings({ - enable_write_console_messages_to_stdout: true, - enable_developer_extras: true, - enable_back_forward_navigation_gestures: false, - enable_hyperlink_auditing: false, - enable_html5_database: false, - enable_html5_local_storage: false, - disable_web_security: true, - }), - }), { - 'context-menu': () => false, - 'load-changed': (webView, event) => { - if (event === WebKit.LoadEvent.FINISHED) { - webView.run(`globalThis.uiText = ${JSON.stringify(uiText)}`) - .catch(e => console.error(e)) - } - }, - }) + if (!this._catalog_toolbar_view.content) { + const webView = new WebView({ + settings: new WebKit.Settings({ + enable_write_console_messages_to_stdout: true, + enable_developer_extras: true, + enable_back_forward_navigation_gestures: false, + enable_hyperlink_auditing: false, + enable_html5_database: false, + enable_html5_local_storage: false, + disable_web_security: true, + }), + }) + const initFormatMediaType = webView.provide('formatMediaType', type => + Gio.content_type_get_description(type)) + utils.connect(webView, { + 'context-menu': () => false, + 'load-changed': (webView, event) => { + if (event === WebKit.LoadEvent.FINISHED) { + webView.run(`globalThis.uiText = ${JSON.stringify(uiText)}`) + .catch(e => console.error(e)) + initFormatMediaType() + } + }, + }) + this._catalog_toolbar_view.content = webView + } const webView = this._catalog_toolbar_view.content webView.loadURI(`foliate-opds:///opds/opds.html?url=${encodeURIComponent(url)}`) .catch(e => console.error(e)) diff --git a/src/opds/opds.html b/src/opds/opds.html index 0a4b9441..f7b45587 100644 --- a/src/opds/opds.html +++ b/src/opds/opds.html @@ -5,6 +5,16 @@ :root { font-size: 11pt; font-family: system-ui; + --shade: rgba(0, 0, 0, .1); + --raised: rgba(0, 0, 0, .05); + --pressed: rgba(0, 0, 0, .15); +} +@media (prefers-color-scheme: dark) { + :root { + --shade: rgba(255, 255, 255, .1); + --raised: rgba(255, 255, 255, .05); + --pressed: rgba(255, 255, 255, .15); + } } hgroup { margin-bottom: 24px; @@ -55,17 +65,76 @@ display: block; max-width: 42em; } -button { +button, foliate-menubutton::part(button) { padding: 9px 18px; font-weight: 700; - min-width: min(100%, 8em); + border-radius: 6px; + border: 0; + background: var(--shade); } -opds-pub-full [slot="actions"] { +button:hover, foliate-menubutton::part(button):hover { + background: var(--raised); +} +button:active, foliate-menubutton::part(button):active { + background: var(--pressed); +} +opds-pub-full > [slot="actions"] { display: flex; flex-wrap: wrap; gap: 9px; width: 100%; } +opds-pub-full > [slot="actions"] > * { + min-width: min(100%, 8em); +} +.split-button { + display: flex; +} +.split-button button { + border-start-end-radius: 0; + border-end-end-radius: 0; +} +.split-button foliate-menubutton::part(button) { + padding: 9px; + border-start-start-radius: 0; + border-end-start-radius: 0; + border-inline-start: 1px solid color-mix(in hsl, currentColor, transparent 85%);; +} +foliate-menubutton { + display: flex; +} +foliate-menu { + position: absolute; + inset-block-start: 100%; + inset-inline-end: 0; + display: flex; + flex-direction: column; + width: max-content; + background: canvas; + border-radius: 9px; + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.03), + 0 1px 3px 1px rgba(0, 0, 0, 0.07), + 0 2px 6px 2px rgba(0, 0, 0, 0.03); + visibility: hidden; + padding: 6px; +} +foliate-menu:not([hidden]) { + visibility: visible; +} +button[role="menuitem"] { + border: 0; + text-align: start; + font: menu; + background: none; + border-radius: 6px; + padding: 9px; +} +button[role="menuitem"]:hover { + background: var(--raised); +} +button[role="menuitem"]:active { + background: var(--pressed); +}