diff --git a/CHANGES.md b/CHANGES.md index 2ea6bb4..810a00a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,17 @@ ## CHANGES +v1.3.0 +- UI: Condense navbar and location bar: add logo to location bar, condense button spacing, add about link to context menu +- UI: Add collection info dropdown to be a separate tab instead +- UI: Convert Terms into general About dialog +- Loading: IPFS support! Load from `ipfs://` URLs, eg. `ipfs://hash/filename.wacz. Possible to specify extension for root with: `ipfs://hash#filename=.wacz` +- App: Electron App uses IPFS in node, proxies through file proxy. +- Loading: Native File System (Chrome-only) support: Loading local files on Chrome uses FileHandle, which allows persistent reuse of files with permission +- Loading: Optimize local file loading on all browsers: No more separate webworker, serviceworker caches entire blob into memory. Should fix Firefox loading issues streaming from blob. +- Loading/UI: Revamp permissions UI to replace iframe instead of popup +- UI: Favicon smoother update, better check for valid icon +- UI: Purge Cache / Full Reload reloads current frame, not parent + v1.2.1 - Loading/UI: Fix Google Drive Loading/Reauthorization: Only trigger when reauth is needed. For rate-limit errors, attempt reloading more slowly (exponential backoff) - Loading: ReplayWeb.page App supports opening WACZ, WARC and HAR files via double-clicking from OS and via command-line. diff --git a/package.json b/package.json index 10b1081..79d3121 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "replaywebpage", "productName": "ReplayWeb.page", - "version": "1.2.3", + "version": "1.3.0", "description": "Serverless Web Archive Replay", "repository": "https://github.com/webrecorder/replayweb.page", "homepage": "https://replayweb.page/", @@ -9,10 +9,11 @@ "license": "AGPL-3.0-or-later", "dependencies": { "@fortawesome/fontawesome-free": "^5.13.0", - "@webrecorder/wabac": "^2.1.5", + "@webrecorder/wabac": "^2.2.0", "bulma": "^0.9.0", "fetch-ndjson": "^1.1.0", "flexsearch": "^0.6.32", + "ipfs-core": "^0.2.0", "keyword-mark-element": "^0.1.2", "lit-element": "^2.3.1", "marked": "^1.0.0", @@ -23,6 +24,7 @@ "split.js": "^1.6.2" }, "devDependencies": { + "copy-webpack-plugin": "^6.3.0", "css-loader": "^3.5.3", "electron": "^10.1.3", "electron-builder": "^22.7.0", @@ -35,7 +37,7 @@ "style-loader": "^1.2.1", "svg-inline-loader": "^0.8.2", "to-string-loader": "^1.1.6", - "webpack": "^4.43.0", + "webpack": "^4.44.2", "webpack-cli": "^3.3.11", "webpack-dev-server": "^3.10.3" }, @@ -56,6 +58,7 @@ "start-electron": "NODE_ENV=development electron ./dist/electron.js $1", "start-jekyll": "yarn run build-docs && bundle exec jekyll serve", "dist": "yarn run build && yarn run pack", + "dist-dev": "yarn run build-dev && yarn run pack", "release": "yarn run build && electron-builder" }, "build": { @@ -70,6 +73,8 @@ "files": [ "!**/node_modules/**/*", "dist/*.js", + "dist/prebuilds/${platform}-${arch}/*", + "dist/build/*", "*.js", "*.html", "webmanifest.json", diff --git a/src/appmain.js b/src/appmain.js index 9657bea..86f80e9 100644 --- a/src/appmain.js +++ b/src/appmain.js @@ -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`

Skipped

@@ -211,7 +183,8 @@ class App extends LitElement sourceUrl="${this.sourceUrl}" embed="${this.embed}" @replay-favicons=${this.onFavIcons} - @coll-loaded=${this.onCollLoaded}> + @coll-loaded=${this.onCollLoaded} + @about-show=${(e) => this.showAbout = true}> ` : html` @@ -222,42 +195,8 @@ class App extends LitElement `} - ${this.showTerms ? html` - - - ` : ``} ` + ${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` + + `; + } + + onAboutClose() { + this.showAbout = false; + } } customElements.define("replay-app-main", App); diff --git a/src/chooser.js b/src/chooser.js index 3959d38..1d3a0e0 100644 --- a/src/chooser.js +++ b/src/chooser.js @@ -1,5 +1,5 @@ import { LitElement, html, css } from 'lit-element'; -import { wrapCss } from './misc'; +import { IS_APP, wrapCss } from './misc'; import fasUpload from '@fortawesome/fontawesome-free/svgs/solid/upload.svg'; @@ -12,6 +12,14 @@ class Chooser extends LitElement this.fileDisplayName = ""; this.file = null; + + this.hasNativeFS = !!window.showOpenFilePicker && !IS_APP; + } + + static get properties() { + return { + fileDisplayName: { type: String } + } } onChooseFile(event) { @@ -22,7 +30,32 @@ class Chooser extends LitElement this.file = event.currentTarget.files[0]; // file.path only available in electron app this.fileDisplayName = "file://" + (this.file.path || this.file.name); - this.requestUpdate(); + } + + async onChooseNativeFile() { + const options = { + types: [ + { + description: 'WARC, WACZ, HAR and WBN Files', + accept: { + 'application/warc': ['.warc', '.gz'], + 'application/har': ['.har'], + 'application/wacz': ['.wacz'], + 'application/wbn': ['.wbn'] + } + } + ] + } + + const [fileHandle] = await window.showOpenFilePicker(options); + this.fileHandle = fileHandle; + + this.file = await fileHandle.getFile(); + this.fileDisplayName = "file://" + fileHandle.name; + } + + randomId() { + return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); } onStartLoad(event) { @@ -37,12 +70,17 @@ class Chooser extends LitElement const url = new URL(__APP_FILE_SERVE_PREFIX__); url.searchParams.set("filename", this.file.path); loadInfo.loadUrl = url.href; + loadInfo.noCache = true; + } else if (this.fileHandle) { + loadInfo.loadUrl = this.fileDisplayName + "-" + this.randomId(); + loadInfo.extra = {fileHandle: this.fileHandle}; + loadInfo.noCache = false; } else { loadInfo.loadUrl = URL.createObjectURL(this.file); loadInfo.blob = this.file; + loadInfo.noCache = false; } loadInfo.size = this.file.size; - loadInfo.noCache = this.file.path !== undefined; loadInfo.name = this.fileDisplayName; } @@ -116,10 +154,11 @@ class Chooser extends LitElement