diff --git a/static/js/nav.js b/static/js/nav.js index 12b55ff..a972b0f 100644 --- a/static/js/nav.js +++ b/static/js/nav.js @@ -12,6 +12,8 @@ 'use strict'; const html = document.documentElement; const authed = typeof IS_AUTHENTICATED === 'undefined' || !!IS_AUTHENTICATED; + // A project's own window (desktop, docs/projects.md): it remembers nothing for the others. + const soloWindow = /[?&]project=\d+/.test(location.search); const SECTIONS = [ {id: 'home', group: 'home', label: 'Home', icon: '⌂', panel: 'home', account: true}, @@ -146,8 +148,10 @@ function setCurrent(id) { current = id; const s = byId[id]; - if (!s.transient) save('diora_nav_section', id); // the app opens where one was, not in the search - if (!s.footer) save('diora_nav_last_' + s.group, id); + if (!soloWindow) { + if (!s.transient) save('diora_nav_section', id); // the app opens where one was, not in the search + if (!s.footer) save('diora_nav_last_' + s.group, id); + } syncHash(); render(); listeners.slice().forEach(fn => { try { fn(id); } catch (e) {} }); diff --git a/static/js/projects.js b/static/js/projects.js index 4eba74b..5ff9405 100644 --- a/static/js/projects.js +++ b/static/js/projects.js @@ -843,18 +843,29 @@ } function openSource(i) { - if (i.kind === 'book') { - if (typeof openBook === 'function') openBook(i.ref); - } else if (i.kind === 'episode') { - const row = {id: i.ref, feed__id: i.data.feed, title: cslTitle(i.data.csl), feed__title: i.data.podcast}; + const c = (i.data && i.data.csl) || {}; + const what = {kind: i.kind, ref: i.ref, feed: i.data ? i.data.feed : 0, title: cslTitle(c), + podcast: i.data ? i.data.podcast : '', url: c.DOI ? 'https://doi.org/' + c.DOI : (c.URL || '')}; + // A project's own window (desktop): the main window opens it, with its reader and player. + if (solo && what.kind !== 'paper' && window.dioraDesktop && window.dioraDesktop.openInMain) { + window.dioraDesktop.openInMain(what); + return; + } + openThing(what); + } + + // {kind, ref, feed, url}: a book, an episode, an article where it lives; a paper by its link. + function openThing(w) { + if (w.kind === 'book') { + if (typeof openBook === 'function') openBook(w.ref); + } else if (w.kind === 'episode') { + const row = {id: w.ref, feed__id: w.feed, title: w.title || '', feed__title: w.podcast || ''}; if (window.__dioraPodcastOpenEpisode && window.__dioraPodcastOpenEpisode(row)) return; - if (i.data.feed && window.__dioraPodcastOpenFeed) window.__dioraPodcastOpenFeed(i.data.feed); - } else if (i.kind === 'article') { - if (window.__dioraFeedsOpenItem) window.__dioraFeedsOpenItem(i.ref); - } else { - const c = i.data.csl || {}; - const url = c.DOI ? 'https://doi.org/' + c.DOI : c.URL; - if (url) window.open(url, '_blank', 'noopener'); + if (w.feed && window.__dioraPodcastOpenFeed) window.__dioraPodcastOpenFeed(w.feed); + } else if (w.kind === 'article') { + if (window.__dioraFeedsOpenItem) window.__dioraFeedsOpenItem(w.ref); + } else if (w.url) { + window.open(w.url, '_blank', 'noopener'); } } @@ -1041,6 +1052,13 @@ }; } window.addEventListener('beforeunload', () => { if (saveState === 'nicht gespeichert') saveNote(); }); + // Back at this window (another one, another device may have changed the project): fresh, + // unless a note is being written here. + window.addEventListener('focus', () => { + if (tab.style.display === 'none' || st.note != null || st.creating) return; + if (st.open) openProject(st.open.id, true).catch(() => {}); + else loadList().then(render); + }); if (solo) { document.title = 'Projekt · diora'; if (typeof showTab === 'function') showTab('projekte'); @@ -1060,6 +1078,7 @@ openProject(Number(id)).catch(() => {}); }, onChange(fn) { if (typeof fn === 'function') linkListeners.push(fn); }, + openSource: openThing, load: loadList, }; // The links for the sheets ("in Projekt …"), once the page has settled. @@ -1152,7 +1171,8 @@ '#prj-toast { position: fixed; left: 50%; bottom: calc(var(--nui-dock-h, 0px) + 90px); transform: translateX(-50%); z-index: 3100; background: var(--raised, #222); color: var(--fg, #eee); padding: 10px 16px; border-radius: 8px; font-size: 14px; opacity: 0; pointer-events: none; transition: opacity .2s; max-width: calc(100vw - 32px); }', '#prj-toast.prj-show { opacity: 1; }', // A window of its own (desktop): only the project. - 'html.prj-solo #tabs, html.prj-solo #nav-segments, html.prj-solo header, html.prj-solo .site-header, html.prj-solo #nui-dock, html.prj-solo .nui-section-bar { display: none !important; }', + 'html.prj-solo #tabs, html.prj-solo #nav-segments, html.prj-solo header, html.prj-solo .site-header, html.prj-solo #nui-dock, html.prj-solo #tab-projekte .nui-section-bar { display: none !important; }', + 'html.prj-solo body { padding-left: 0 !important; padding-bottom: 0 !important; }', 'html.prj-solo #tab-projekte { padding-top: 12px; }', 'body.eink #tab-projekte .prj-primary, body.eink #tab-projekte .prj-chip.on { background: #000; color: #fff; }', ].join('\n');