IPFS Support + Loading Improvements (Better local file handling) + Streamlined Collection View (#25)
* support ipfs:// urls! misc: better error message for loading from http:// tabs: don't render pages/story/urls if hidden * ipfs work: remove ww only use sw * electron + ipfs: add ipfs support to electron app, using ipfs-core - route ipfs requests to files proxy with 'ipfs=' query param * file loading: - add support for new Chrome native file system api with file handles, which allows persistent access to files vial file handles - if window.showOpenFilePicker() is available use that, include file handle in load message - support asking permissions for file handles, using similar workflow as google drive auth - attempt to ask for file permission directly, show auth button if fails (user gestured required) - replace auth modal with iframe replacement insert to ask for auth for google drive and local file * ui overhaul for 1.3.0 / condense collection view: - don't show navbar in collection view - add logo to back to home page to location bar - condense location bar buttons - convert terms to general about dialog, available from collection context menu - add info tab to collection view in place of drop-down info - make <wr-coll-info> component, used in both collection list and info tab with additional details - update to wabac.js 2.2.0 * update CHANGES.md
This commit is contained in:
+82
-80
@@ -1,14 +1,11 @@
|
||||
import { LitElement, html, css } from 'lit-element';
|
||||
import { wrapCss, rwpLogo, IS_APP, clickOnSpacebarPress } from './misc';
|
||||
|
||||
import { registerSW, initDBWorker } from './pageutils';
|
||||
|
||||
import prettyBytes from 'pretty-bytes';
|
||||
import { registerSW } from './pageutils';
|
||||
|
||||
import fasHelp from '@fortawesome/fontawesome-free/svgs/solid/question-circle.svg';
|
||||
import fasArrowLeft from '@fortawesome/fontawesome-free/svgs/solid/arrow-left.svg';
|
||||
import fasArrowRight from '@fortawesome/fontawesome-free/svgs/solid/arrow-right.svg';
|
||||
import fasInfoIcon from '@fortawesome/fontawesome-free/svgs/solid/info-circle.svg';
|
||||
|
||||
|
||||
// ===========================================================================
|
||||
@@ -19,14 +16,13 @@ class App extends LitElement
|
||||
super();
|
||||
this.sourceUrl = null;
|
||||
this.collInfo = null;
|
||||
this.showTerms = false;
|
||||
this.showAbout = false;
|
||||
this.pageParams = {};
|
||||
|
||||
this.inited = false;
|
||||
this.navMenuShown = false;
|
||||
|
||||
registerSW(__SW_NAME__);
|
||||
initDBWorker();
|
||||
|
||||
this.safariKeyframes();
|
||||
}
|
||||
@@ -37,7 +33,7 @@ class App extends LitElement
|
||||
pageParams: { type: Object },
|
||||
sourceUrl: { type: String },
|
||||
navMenuShown: { type: Boolean },
|
||||
showTerms: { type: Boolean },
|
||||
showAbout: { type: Boolean },
|
||||
collInfo: { type: Object },
|
||||
loadInfo: { type: Object },
|
||||
embed: { type: String },
|
||||
@@ -112,12 +108,19 @@ class App extends LitElement
|
||||
`);
|
||||
}
|
||||
|
||||
renderNavBar() {
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.inited) {
|
||||
return html``;
|
||||
}
|
||||
|
||||
const showNavBar = !this.collInfo && (!this.embed || this.embed === "full");
|
||||
|
||||
return html`
|
||||
${!this.embed || this.embed === "full" ? html`
|
||||
${showNavBar ? html`
|
||||
<a href="#skip-main-target" @click=${this.skipMenu} class="skip-link">Skip main navigation</a>
|
||||
<nav class="navbar has-background-info" aria-label="main">
|
||||
<div class="navbar-brand">
|
||||
@@ -158,37 +161,6 @@ class App extends LitElement
|
||||
<fa-icon .svg="${fasArrowRight}" aria-hidden="true"></fa-icon><span class="menu-only"> Go Forward</span>
|
||||
</a>
|
||||
` : ``}
|
||||
${this.sourceUrl && this.collInfo ? html`
|
||||
<div class="navbar-item has-dropdown is-hoverable">
|
||||
<span tabindex="0" class="info-menu navbar-link is-arrowless" aria-labelledby="about-this-archive">
|
||||
<fa-icon size="1.2em" .svg="${fasInfoIcon}" aria-hidden="true"></fa-icon>
|
||||
<span id="about-this-archive" class="menu-only">About this Archive</span>
|
||||
</span>
|
||||
<div class="navbar-dropdown">
|
||||
<div class="navbar-item wide-only"><i>About this Archive</i></div>
|
||||
<hr class="navbar-divider">
|
||||
<div class="navbar-item">
|
||||
Source: <b>${this.sourceUrl}</b>
|
||||
</div>
|
||||
<div class="navbar-item">
|
||||
Filename: <b>${this.collInfo.filename}</b>
|
||||
</div>
|
||||
<div class="navbar-item">
|
||||
Total Size: <b>${prettyBytes(Number(this.collInfo.size || 0))}</b>
|
||||
</div>
|
||||
<div class="navbar-item">
|
||||
Loading Mode: <b>${this.collInfo.onDemand ? "Download On-Demand" : "Fully Local"}</b>
|
||||
</div>
|
||||
<div class="navbar-item">
|
||||
Collection Id: <b>${this.collInfo.coll}</b>
|
||||
</div>
|
||||
<hr class="navbar-divider">
|
||||
<div class="navbar-item">
|
||||
ReplayWeb.page Version: ${__VERSION__}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
` : ``}
|
||||
</div>
|
||||
${!this.embed ? html`
|
||||
<div class="navbar-end">
|
||||
@@ -196,10 +168,10 @@ class App extends LitElement
|
||||
<fa-icon .svg="${fasHelp}" aria-hidden="true"></fa-icon><span> User Docs</span>
|
||||
</a>
|
||||
<!--
|
||||
-- NB: the Terms modal is currently inaccessible to people using keyboards or screen readers.
|
||||
-- Should all the JS and infrastructure for accessible modals be added, or should Terms be a normal page?
|
||||
-- NB: the About modal is currently inaccessible to people using keyboards or screen readers.
|
||||
-- Should all the JS and infrastructure for accessible modals be added, or should About be a normal page?
|
||||
-->
|
||||
<a href="?terms" @click="${(e) => { e.preventDefault(); this.showTerms = true} }"class="navbar-item">Terms</a>
|
||||
<a href="?terms" @click="${(e) => { e.preventDefault(); this.showAbout = true} }"class="navbar-item">About</a>
|
||||
</div>` : html``}
|
||||
</div>
|
||||
</nav><p id="skip-main-target" tabindex="-1" class="is-sr-only">Skipped</p>
|
||||
@@ -211,7 +183,8 @@ class App extends LitElement
|
||||
sourceUrl="${this.sourceUrl}"
|
||||
embed="${this.embed}"
|
||||
@replay-favicons=${this.onFavIcons}
|
||||
@coll-loaded=${this.onCollLoaded}></wr-coll>
|
||||
@coll-loaded=${this.onCollLoaded}
|
||||
@about-show=${(e) => this.showAbout = true}></wr-coll>
|
||||
` : html`
|
||||
|
||||
<wr-coll-index>
|
||||
@@ -222,42 +195,8 @@ class App extends LitElement
|
||||
</wr-coll-index>
|
||||
`}
|
||||
|
||||
${this.showTerms ? html`
|
||||
<div class="modal is-active">
|
||||
<div class="modal-background" @click="${(e) => this.showTerms = false}"></div>
|
||||
<div class="modal-card">
|
||||
<header class="modal-card-head">
|
||||
<p class="modal-card-title">Terms and Privacy</p>
|
||||
<button class="delete" aria-label="close" @click="${(e) => this.showTerms = false}"></button>
|
||||
</header>
|
||||
<section class="modal-card-body">
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
<p>This site is a static browser-based application that loads web archive files provided by the user
|
||||
and renders them for replay in the browser.</p>
|
||||
<p>The site is operated by the <a href="https://webrecorder.net/">Webrecorder Project</a></p>
|
||||
<p>See the <a target="_blank" href="./docs">Docs</a> for more info on how it works.</p>
|
||||
|
||||
<h3>Privacy</h3>
|
||||
<p><b>No data is uploaded anywhere and no information is collected.</b></p>
|
||||
<p>All content rendered stays directly in your browser. When loading an archive from Google Drive,
|
||||
the site may ask for account authorization to download the specified file only.</p>
|
||||
|
||||
<h4>Disclaimer of Warranties</h4>
|
||||
<p>The application may not always be available. No guarantees!</p>
|
||||
<p>Some legalese:</p>
|
||||
<p style="font-size: 0.8rem">DISCLAIMER OF SOFTWARE WARRANTY. WEBRECORDER SOFTWARE PROVIDES THIS SOFTWARE TO YOU "AS AVAILABLE"
|
||||
AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
|
||||
INCLUDING WITHOUT LIMITATION ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
</p>
|
||||
<a class="button is-warning" href="#" @click="${(e) => this.showTerms = false}">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
` : ``} `
|
||||
${this.showAbout ? this.renderAbout() : ``}
|
||||
`;
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
@@ -344,7 +283,7 @@ class App extends LitElement
|
||||
this.embed = this.pageParams.get("embed") || "";
|
||||
|
||||
if (this.pageParams.has("terms")) {
|
||||
this.showTerms = true;
|
||||
this.showAbout = true;
|
||||
}
|
||||
|
||||
if (this.pageParams.get("config")) {
|
||||
@@ -438,6 +377,69 @@ class App extends LitElement
|
||||
document.head.appendChild(style);
|
||||
style.appendChild(document.createTextNode(css));
|
||||
}
|
||||
|
||||
renderAbout() {
|
||||
return html`
|
||||
<div class="modal is-active">
|
||||
<div class="modal-background" @click="${this.onAboutClose}"></div>
|
||||
<div class="modal-card">
|
||||
<header class="modal-card-head">
|
||||
<p class="modal-card-title">About ReplayWeb.page ${IS_APP ? 'App' : ''}</p>
|
||||
<button class="delete" aria-label="close" @click="${this.onAboutClose}"></button>
|
||||
</header>
|
||||
<section class="modal-card-body">
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
<div style="display: flex">
|
||||
<div class="has-text-centered" style="width: 220px">
|
||||
<wr-anim-logo class="logo" size="48px"></wr-anim-logo>
|
||||
<div style="font-size: smaller; margin-bottom: 1em">${IS_APP ? 'App' : ''} v${__VERSION__}</div>
|
||||
</div>
|
||||
|
||||
${IS_APP ? html`
|
||||
<p>ReplayWeb.page App is a standalone app for Mac, Windows and Linux that loads web archive files provided by the user
|
||||
and renders them for replay.</p>
|
||||
|
||||
` : html`
|
||||
<p><a href="https://replayweb.page" target="_blank">ReplayWeb.page</a> is a browser-based viewer that loads web archive files provided by the user
|
||||
and renders them for replay in the browser.</p>`}
|
||||
</div>
|
||||
|
||||
<p>Full source code is available at:
|
||||
<a href="https://github.com/webrecorder/replayweb.page" target="_blank">https://github.com/webrecorder/replayweb.page</a>
|
||||
</p>
|
||||
|
||||
<p>See the <a target="_blank" href="./docs">User Docs</a> or the GitHub README for more info on how it works.</p>
|
||||
|
||||
<p>ReplayWeb.page is part of the <a href="https://webrecorder.net/" target="_blank">Webrecorder Project</a>.</p>
|
||||
|
||||
<h3>Privacy</h3>
|
||||
<p><b>No data is uploaded anywhere and no information is collected.</b></p>
|
||||
<p>All content rendered stays directly in your browser.<br/>When loading an archive from Google Drive,
|
||||
the site may ask for account authorization to download the specified file only.</p>
|
||||
|
||||
<h4>Disclaimer of Warranties</h4>
|
||||
<p>The application is provided "as is" without any guarantees.</p>
|
||||
<details>
|
||||
<summary>Legalese:</summary>
|
||||
<p style="font-size: 0.8rem">DISCLAIMER OF SOFTWARE WARRANTY. WEBRECORDER SOFTWARE PROVIDES THIS SOFTWARE TO YOU "AS AVAILABLE"
|
||||
AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
|
||||
INCLUDING WITHOUT LIMITATION ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
</details>
|
||||
<div class="has-text-centered">
|
||||
<a class="button is-warning" href="#" @click="${this.onAboutClose}">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
onAboutClose() {
|
||||
this.showAbout = false;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("replay-app-main", App);
|
||||
|
||||
Reference in New Issue
Block a user