From 79d65ec3d9036430b01115adcab435242733b11c Mon Sep 17 00:00:00 2001 From: Juan Date: Fri, 9 May 2025 11:52:29 -0500 Subject: [PATCH 1/4] new html layout --- src/argo-archive-list.ts | 6 +- src/sidepanel.ts | 445 ++++++++++++++++++++++++++++++--------- static/sidepanel.html | 71 +------ 3 files changed, 347 insertions(+), 175 deletions(-) diff --git a/src/argo-archive-list.ts b/src/argo-archive-list.ts index 855ee38..3a024a4 100644 --- a/src/argo-archive-list.ts +++ b/src/argo-archive-list.ts @@ -21,6 +21,9 @@ export class ArgoArchiveList extends LitElement { padding: 0; overflow: visible; } + .card-container { + padding: 0 1rem; + } md-elevated-card > details { border-radius: inherit; @@ -56,9 +59,6 @@ export class ArgoArchiveList extends LitElement { height: 100%; } - .card-container { - padding: 0 1rem; - } img.favicon { width: 20px !important; diff --git a/src/sidepanel.ts b/src/sidepanel.ts index 42e9dbd..fde00cb 100644 --- a/src/sidepanel.ts +++ b/src/sidepanel.ts @@ -1,11 +1,14 @@ import "@material/web/all.js"; import { styles as typescaleStyles } from "@material/web/typography/md-typescale-styles.js"; -import { LitElement, html } from "lit"; +import { LitElement, html, css, CSSResultGroup } from "lit"; import { unsafeSVG } from "lit/directives/unsafe-svg.js"; import "./argo-archive-list"; import "@material/web/textfield/outlined-text-field.js"; import "@material/web/icon/icon.js"; + +import wrRec from "./assets/icons/recLogo.svg"; + import { getLocalOption, // removeLocalOption, @@ -13,8 +16,8 @@ import { } from "./localstorage"; import { BEHAVIOR_WAIT_LOAD, + BEHAVIOR_RUNNING, // BEHAVIOR_READY_START, - // BEHAVIOR_RUNNING, // BEHAVIOR_PAUSED, // BEHAVIOR_DONE, } from "./consts"; @@ -26,53 +29,112 @@ import "@material/web/divider/divider.js"; document.adoptedStyleSheets.push(typescaleStyles.styleSheet!); class ArgoViewer extends LitElement { + + static styles: CSSResultGroup = [ + typescaleStyles as unknown as CSSResultGroup, + css` + + md-tabs { + background-color: white; + } + + .search-container { + margin: 16px 12px; + height: 32px; + background: #ece7f8; + border-radius: 9999px; + display: flex; + align-items: center; + overflow: hidden; + } + + .search-field { + width: 100%; + --md-filled-text-field-container-color: transparent; + --md-ref-shape-corner-radius: 9999px; + overflow: hidden; + } + + + .search-field::part(container), + .search-field::part(hover-overlay), + .search-field::part(focus-overlay) { + border-radius: 9999px; + } + + .search-field::part(input-area) { + padding: 0; + } + + .search-field md-icon, + .search-field input::placeholder { + color: #6b6b6b; + }, + + md-elevated-card { + display: block; + margin: 1rem 0; + padding: 0; + overflow: visible; + } + .card-container { + padding: 0 1rem; + } + + .summary { + background: transparent !important; + padding: 0.75rem 1rem; + } + ` + ]; + constructor() { super(); - // @ts-expect-error - TS2339 - Property 'collections' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'collections' does not exist on type 'ArgoViewer'. this.collections = []; - // @ts-expect-error - TS2339 - Property 'collTitle' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'collTitle' does not exist on type 'ArgoViewer'. this.collTitle = ""; - // @ts-expect-error - TS2339 - Property 'collId' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'collId' does not exist on type 'ArgoViewer'. this.collId = ""; - // @ts-expect-error - TS2339 - Property 'tabId' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'tabId' does not exist on type 'ArgoViewer'. this.tabId = 0; - // @ts-expect-error - TS2339 - Property 'recording' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'recording' does not exist on type 'ArgoViewer'. this.recording = false; - // @ts-expect-error - TS2339 - Property 'status' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'status' does not exist on type 'ArgoViewer'. this.status = null; - // @ts-expect-error - TS2339 - Property 'port' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'port' does not exist on type 'ArgoViewer'. this.port = null; - // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'ArgoViewer'. this.pageUrl = ""; - // @ts-expect-error - TS2339 - Property 'pageTs' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'pageTs' does not exist on type 'ArgoViewer'. this.pageTs = 0; - // @ts-expect-error - TS2339 - Property 'replayUrl' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'replayUrl' does not exist on type 'ArgoViewer'. this.replayUrl = ""; - // @ts-expect-error - TS2339 - Property 'canRecord' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'canRecord' does not exist on type 'ArgoViewer'. this.canRecord = false; - // @ts-expect-error - TS2339 - Property 'failureMsg' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'failureMsg' does not exist on type 'ArgoViewer'. this.failureMsg = null; - // @ts-expect-error - TS2339 - Property 'collDrop' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'collDrop' does not exist on type 'ArgoViewer'. this.collDrop = ""; - // @ts-expect-error - TS2339 - Property 'allowCreate' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'allowCreate' does not exist on type 'ArgoViewer'. this.allowCreate = true; - // @ts-expect-error - TS2339 - Property 'waitingForStart' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'waitingForStart' does not exist on type 'ArgoViewer'. this.waitingForStart = false; - // @ts-expect-error - TS2339 - Property 'waitingForStop' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'waitingForStop' does not exist on type 'ArgoViewer'. this.waitingForStop = false; - // @ts-expect-error - TS2339 - Property 'behaviorState' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'behaviorState' does not exist on type 'ArgoViewer'. this.behaviorState = BEHAVIOR_WAIT_LOAD; - // @ts-expect-error - TS2339 - Property 'behaviorMsg' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'behaviorMsg' does not exist on type 'ArgoViewer'. this.behaviorMsg = ""; - // @ts-expect-error - TS2339 - Property 'autorun' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'autorun' does not exist on type 'ArgoViewer'. this.autorun = false; } @@ -99,6 +161,22 @@ class ArgoViewer extends LitElement { behaviorMsg: { type: String }, autorun: { type: Boolean }, }; + } + + // @ts-expect-error - TS7006 - Parameter 'match' implicitly has an 'any' type. + findTitleFor(match) { + if (!match) { + return ""; + } + // @ts-expect-error - TS2339 - Property 'collections' does not exist on type 'ArgoViewer'. + for (const coll of this.collections) { + // @ts-expect-error - TS2339 - Property 'collId' does not exist on type 'ArgoViewer'. + if (coll.id === this.collId) { + return coll.title; + } + } + + return ""; } firstUpdated() { @@ -106,29 +184,29 @@ class ArgoViewer extends LitElement { } registerMessages() { - // @ts-expect-error - TS2339 - Property 'port' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'port' does not exist on type 'ArgoViewer'. this.port = chrome.runtime.connect({ name: "sidepanel-port" }); // @ts-expect-error - TS7006 - Parameter 'tabs' implicitly has an 'any' type. chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { if (tabs.length) { - // @ts-expect-error - TS2339 - Property 'tabId' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'tabId' does not exist on type 'ArgoViewer'. this.tabId = tabs[0].id; - // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'ArgoViewer'. this.pageUrl = tabs[0].url; - // @ts-expect-error - TS2339 - Property 'tabId' does not exist on type 'RecPopup'. | TS7006 - Parameter 'result' implicitly has an 'any' type. + // @ts-expect-error - TS2339 - Property 'tabId' does not exist on type 'ArgoViewer'. | TS7006 - Parameter 'result' implicitly has an 'any' type. chrome.action.getTitle({ tabId: this.tabId }, (result) => { - // @ts-expect-error - TS2339 - Property 'recording' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'recording' does not exist on type 'ArgoViewer'. this.recording = result.indexOf("Recording:") >= 0; }); - // @ts-expect-error - TS2339 - Property 'tabId' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'tabId' does not exist on type 'ArgoViewer'. this.sendMessage({ tabId: this.tabId, type: "startUpdates" }); } }); // this.sendMessage({ type: "getPages" }); - // @ts-expect-error - TS2339 - Property 'port' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'port' does not exist on type 'ArgoViewer'. this.port.onMessage.addListener((message) => { this.onMessage(message); }); @@ -136,78 +214,78 @@ class ArgoViewer extends LitElement { // @ts-expect-error - TS7006 - Parameter 'message' implicitly has an 'any' type. sendMessage(message) { - // @ts-expect-error - TS2339 - Property 'port' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'port' does not exist on type 'ArgoViewer'. this.port.postMessage(message); } // @ts-expect-error - TS7006 - Parameter 'message' implicitly has an 'any' type. async onMessage(message) { switch (message.type) { case "status": - // @ts-expect-error - TS2339 - Property 'recording' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'recording' does not exist on type 'ArgoViewer'. this.recording = message.recording; - // @ts-expect-error - TS2339 - Property 'waitingForStart' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'waitingForStart' does not exist on type 'ArgoViewer'. if (this.waitingForStart && message.firstPageStarted) { - // @ts-expect-error - TS2339 - Property 'waitingForStart' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'waitingForStart' does not exist on type 'ArgoViewer'. this.waitingForStart = false; } - // @ts-expect-error - TS2339 - Property 'waitingForStop' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'waitingForStop' does not exist on type 'ArgoViewer'. if (this.waitingForStop && !message.recording && !message.stopping) { - // @ts-expect-error - TS2339 - Property 'waitingForStop' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'waitingForStop' does not exist on type 'ArgoViewer'. this.waitingForStop = false; } - // @ts-expect-error - TS2339 - Property 'status' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'status' does not exist on type 'ArgoViewer'. this.status = message; - // @ts-expect-error - TS2339 - Property 'behaviorState' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'behaviorState' does not exist on type 'ArgoViewer'. this.behaviorState = message.behaviorState; - // @ts-expect-error - TS2339 - Property 'behaviorMsg' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'behaviorMsg' does not exist on type 'ArgoViewer'. this.behaviorMsg = message.behaviorData?.msg || "Starting..."; - // @ts-expect-error - TS2339 - Property 'behaviorResults' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'behaviorResults' does not exist on type 'ArgoViewer'. this.behaviorResults = message.behaviorData?.state; - // @ts-expect-error - TS2339 - Property 'autorun' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'autorun' does not exist on type 'ArgoViewer'. this.autorun = message.autorun; if (message.pageUrl) { - // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'ArgoViewer'. this.pageUrl = message.pageUrl; } if (message.pageTs) { - // @ts-expect-error - TS2339 - Property 'pageTs' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'pageTs' does not exist on type 'ArgoViewer'. this.pageTs = message.pageTs; } - // @ts-expect-error - TS2339 - Property 'failureMsg' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'failureMsg' does not exist on type 'ArgoViewer'. this.failureMsg = message.failureMsg; - // @ts-expect-error - TS2339 - Property 'collId' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'collId' does not exist on type 'ArgoViewer'. if (this.collId !== message.collId) { - // @ts-expect-error - TS2339 - Property 'collId' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'collId' does not exist on type 'ArgoViewer'. this.collId = message.collId; - // @ts-expect-error - TS2339 - Property 'collTitle' does not exist on type 'RecPopup'. | TS2339 - Property 'collId' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'collTitle' does not exist on type 'ArgoViewer'. | TS2339 - Property 'collId' does not exist on type 'ArgoViewer'. this.collTitle = this.findTitleFor(this.collId); - // @ts-expect-error - TS2339 - Property 'tabId' does not exist on type 'RecPopup'. | TS2339 - Property 'collId' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'tabId' does not exist on type 'ArgoViewer'. | TS2339 - Property 'collId' does not exist on type 'ArgoViewer'. await setLocalOption(`${this.tabId}-collId`, this.collId); } break; case "collections": - // @ts-expect-error - TS2339 - Property 'collections' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'collections' does not exist on type 'ArgoViewer'. this.collections = message.collections; - // @ts-expect-error - TS2339 - Property 'collId' does not exist on type 'RecPopup'. | TS2339 - Property 'tabId' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'collId' does not exist on type 'ArgoViewer'. | TS2339 - Property 'tabId' does not exist on type 'ArgoViewer'. this.collId = await getLocalOption(`${this.tabId}-collId`); - // @ts-expect-error - TS2339 - Property 'collTitle' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'collTitle' does not exist on type 'ArgoViewer'. this.collTitle = ""; - // @ts-expect-error - TS2339 - Property 'collId' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'collId' does not exist on type 'ArgoViewer'. if (this.collId) { - // @ts-expect-error - TS2339 - Property 'collTitle' does not exist on type 'RecPopup'. | TS2339 - Property 'collId' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'collTitle' does not exist on type 'ArgoViewer'. | TS2339 - Property 'collId' does not exist on type 'ArgoViewer'. this.collTitle = this.findTitleFor(this.collId); } // may no longer be valid, try default id - // @ts-expect-error - TS2339 - Property 'collTitle' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'collTitle' does not exist on type 'ArgoViewer'. if (!this.collTitle) { - // @ts-expect-error - TS2339 - Property 'collId' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'collId' does not exist on type 'ArgoViewer'. this.collId = message.collId; - // @ts-expect-error - TS2339 - Property 'collTitle' does not exist on type 'RecPopup'. | TS2339 - Property 'collId' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'collTitle' does not exist on type 'ArgoViewer'. | TS2339 - Property 'collId' does not exist on type 'ArgoViewer'. this.collTitle = this.findTitleFor(this.collId); } - // @ts-expect-error - TS2339 - Property 'collTitle' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'collTitle' does not exist on type 'ArgoViewer'. if (!this.collTitle) { - // @ts-expect-error - TS2339 - Property 'collTitle' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'collTitle' does not exist on type 'ArgoViewer'. this.collTitle = "[No Title]"; } break; @@ -215,16 +293,16 @@ class ArgoViewer extends LitElement { } get actionButtonDisabled() { - // @ts-expect-error - TS2339 - Property 'recording' does not exist on type 'RecPopup'. | TS2339 - Property 'waitingForStart' does not exist on type 'RecPopup'. | TS2339 - Property 'waitingForStop' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'recording' does not exist on type 'ArgoViewer'. | TS2339 - Property 'waitingForStart' does not exist on type 'ArgoViewer'. | TS2339 - Property 'waitingForStop' does not exist on type 'ArgoViewer'. return !this.recording ? this.waitingForStart : this.waitingForStop; } // @ts-expect-error - TS7006 - Parameter 'changedProperties' implicitly has an 'any' type. updated(changedProperties) { if ( - // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'ArgoViewer'. this.pageUrl && - // @ts-expect-error - TS2339 - Property 'pageTs' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'pageTs' does not exist on type 'ArgoViewer'. this.pageTs && (changedProperties.has("pageUrl") || changedProperties.has("pageTs") || @@ -232,29 +310,29 @@ class ArgoViewer extends LitElement { changedProperties.has("collId")) ) { const params = new URLSearchParams(); - // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'ArgoViewer'. params.set("url", this.pageUrl); params.set( "ts", - // @ts-expect-error - TS2339 - Property 'pageTs' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'pageTs' does not exist on type 'ArgoViewer'. new Date(this.pageTs).toISOString().replace(/[-:TZ.]/g, ""), ); params.set("view", "pages"); - // @ts-expect-error - TS2339 - Property 'replayUrl' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'replayUrl' does not exist on type 'ArgoViewer'. this.replayUrl = this.getCollPage() + "#" + params.toString(); } if (changedProperties.has("pageUrl") || changedProperties.has("failureMsg")) { - // @ts-expect-error - TS2339 - Property 'canRecord' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'canRecord' does not exist on type 'ArgoViewer'. this.canRecord = - // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'ArgoViewer'. this.pageUrl && - // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'ArgoViewer'. (this.pageUrl === "about:blank" || - // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'ArgoViewer'. this.pageUrl.startsWith("http:") || - // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'ArgoViewer'. this.pageUrl.startsWith("https:")); } } @@ -267,7 +345,7 @@ class ArgoViewer extends LitElement { getCollPage() { const sourceParams = new URLSearchParams(); - // @ts-expect-error - TS2339 - Property 'collId' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'collId' does not exist on type 'ArgoViewer'. sourceParams.set("source", "local://" + this.collId); return this.getHomePage() + "?" + sourceParams.toString(); @@ -276,62 +354,219 @@ class ArgoViewer extends LitElement { onStart() { this.sendMessage({ type: "startRecording", - // @ts-expect-error - TS2339 - Property 'collId' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'collId' does not exist on type 'ArgoViewer'. collId: this.collId, - // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'ArgoViewer'. url: this.pageUrl, - // @ts-expect-error - TS2339 - Property 'autorun' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'autorun' does not exist on type 'ArgoViewer'. autorun: this.autorun, }); - // @ts-expect-error - TS2339 - Property 'waitingForStart' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'waitingForStart' does not exist on type 'ArgoViewer'. this.waitingForStart = true; - // @ts-expect-error - TS2339 - Property 'waitingForStop' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'waitingForStop' does not exist on type 'ArgoViewer'. this.waitingForStop = false; } onStop() { this.sendMessage({ type: "stopRecording" }); - // @ts-expect-error - TS2339 - Property 'waitingForStart' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'waitingForStart' does not exist on type 'ArgoViewer'. this.waitingForStart = false; - // @ts-expect-error - TS2339 - Property 'waitingForStop' does not exist on type 'RecPopup'. + // @ts-expect-error - TS2339 - Property 'waitingForStop' does not exist on type 'ArgoViewer'. this.waitingForStop = true; } - render() { + + get notRecordingMessage() { + return "Not Archiving this Tab"; + } + + renderStatusCard() { return html` - -
+
+ +
+ ${this.renderStatus()} +
+
+
+ `; + } + + + renderStatus() { + // @ts-expect-error - TS2339 - Property 'behaviorState' does not exist on type 'ArgoViewer'. + if (this.behaviorState === BEHAVIOR_RUNNING) { + return html`Auto Recording, ${ - // @ts-expect-error - TS2339 - Property 'recording' does not exist on type 'RecPopup'. - !this.recording + // @ts-expect-error - TS2339 - Property 'behaviorMsg' does not exist on type 'ArgoViewer'. + this.behaviorMsg + }`; + } + + // @ts-expect-error - TS2339 - Property 'recording' does not exist on type 'ArgoViewer'. + if (this.recording) { + return html`${ + // @ts-expect-error - TS2339 - Property 'waitingForStop' does not exist on type 'ArgoViewer'. + this.waitingForStop ? "Finishing " : "" + } + Archiving: ${ + // @ts-expect-error - TS2339 - Property 'status' does not exist on type 'ArgoViewer'. | TS2339 - Property 'status' does not exist on type 'ArgoViewer'. + this.status?.numPending ? html` - - public - Resume Archiving - - ` - : html` - ${ + // @ts-expect-error - TS2339 - Property 'status' does not exist on type 'ArgoViewer'. + this.status.numPending + } + URLs + pending${ + // @ts-expect-error - TS2339 - Property 'waitingForStop' does not exist on type 'ArgoViewer'. + this.waitingForStop + ? "." + : ", please wait before loading a new page." + } - pause - Pause Archiving - ` - } + : html` Idle, Continue Browsing` + }`; + } + + // @ts-expect-error - TS2339 - Property 'failureMsg' does not exist on type 'ArgoViewer'. + if (this.failureMsg) { + return html` +
+

+ Sorry, there was an error starting archiving on this page. Please + try again or try a different page. +

+

+ Error Details: + ${ + // @ts-expect-error - TS2339 - Property 'failureMsg' does not exist on type 'ArgoViewer'. + this.failureMsg + } +

+

+ If the error persists, check the + Common Errors and Issues + page in the guide for known issues and possible solutions. +

+
+ `; + } + + // @ts-expect-error - TS2339 - Property 'canRecord' does not exist on type 'ArgoViewer'. + if (!this.canRecord) { + // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'ArgoViewer'. | TS2339 - Property 'pageUrl' does not exist on type 'ArgoViewer'. + if (this.pageUrl?.startsWith(this.extRoot)) { + return html` +

+ This page is part of the extension. You can view existing archived + items from here. To start a new archiving session, click the + Start Archiving button and enter + a new URL. +

+ `; + } + + return html`Can't archive this page.`; + } + + // @ts-expect-error - TS2339 - Property 'waitingForStart' does not exist on type 'ArgoViewer'. + if (this.waitingForStart) { + return html`Archiving will start after the page reloads...`; + } + + return html`${this.notRecordingMessage}`; + } + + renderSearch() { + return html` +
+ + search + +
+ `; + } + + renderTabs() { + return html` + + My Archives + My Shared Archives + + +
+
+ +
+
+ +
+
+ `; + } + + render() { + return html` + ${this.renderSearch()} + ${this.renderStatusCard()} + ${this.renderTabs()} +
+ +
+ ${ + // @ts-expect-error - TS2339 - Property 'recording' does not exist on type 'ArgoViewer'. + !this.recording + ? html` + + public + Resume Archiving + + ` + : html` + + pause + Pause Archiving + + ` + } - - settings - + + settings + +
`; } diff --git a/static/sidepanel.html b/static/sidepanel.html index ed57b29..8cfed38 100644 --- a/static/sidepanel.html +++ b/static/sidepanel.html @@ -19,81 +19,18 @@ --md-sys-color-background: white; --md-sys-color-surface-container: white; --md-elevated-card-container-color: white; - } - - md-tabs { - background-color: white; - } - - .search-container { - margin: 16px 12px; - height: 32px; - background: #ece7f8; - border-radius: 9999px; - display: flex; - align-items: center; - overflow: hidden; - } - - .search-field { - width: 100%; - --md-filled-text-field-container-color: transparent; - --md-ref-shape-corner-radius: 9999px; - overflow: hidden; - } - - - .search-field::part(container), - .search-field::part(hover-overlay), - .search-field::part(focus-overlay) { - border-radius: 9999px; - } - - .search-field::part(input-area) { - padding: 0; - } - - .search-field md-icon, - .search-field input::placeholder { - color: #6b6b6b; + } -
- - search - -
- - - - - My Archives - My Shared Archives - - -
-
- -
-
- -
-
- - \ No newline at end of file + From 3e7964b295c736e57ba567c8cc9c046aebf65d36 Mon Sep 17 00:00:00 2001 From: Juan Date: Wed, 14 May 2025 12:09:07 -0500 Subject: [PATCH 2/4] status card and status update on tab change --- src/ext/bg.ts | 119 ++++++++++--------------------- src/recorder.ts | 6 ++ src/sidepanel.ts | 162 +++++++++++++++++++++++++++++++++--------- src/utils.ts | 27 +++++++ static/sidepanel.html | 5 +- 5 files changed, 203 insertions(+), 116 deletions(-) diff --git a/src/ext/bg.ts b/src/ext/bg.ts index 172af1a..deb510f 100644 --- a/src/ext/bg.ts +++ b/src/ext/bg.ts @@ -26,6 +26,9 @@ const collLoader = new CollectionLoader(); const disabledCSPTabs = new Set(); +// @ts-expect-error - TS7034 - Variable 'sidepanelPort' implicitly has type 'any' in some locations where its type cannot be determined. +let sidepanelPort = null; + // =========================================================================== function main() { @@ -54,72 +57,13 @@ chrome.sidePanel // @ts-expect-error - TS7006 - Parameter 'port' implicitly has an 'any' type. chrome.runtime.onConnect.addListener((port) => { switch (port.name) { - case "popup-port": - popupHandler(port); - break; case "sidepanel-port": sidepanelHandler(port); break; } }); -// @ts-expect-error - TS7006 - Parameter 'port' implicitly has an 'any' type. -function popupHandler(port) { - if (!port.sender || port.sender.url !== chrome.runtime.getURL("popup.html")) { - return; - } - - // @ts-expect-error - TS7034 - Variable 'tabId' implicitly has type 'any' in some locations where its type cannot be determined. - let tabId = null; - - // @ts-expect-error - TS7006 - Parameter 'message' implicitly has an 'any' type. - port.onMessage.addListener(async (message) => { - switch (message.type) { - case "startUpdates": - tabId = message.tabId; - if (self.recorders[tabId]) { - // @ts-expect-error - TS2339 - Property 'port' does not exist on type 'BrowserRecorder'. - self.recorders[tabId].port = port; - self.recorders[tabId].doUpdateStatus(); - } - port.postMessage(await listAllMsg(collLoader)); - break; - - case "startRecording": { - const { collId, autorun } = message; - // @ts-expect-error - TS2554 - Expected 2 arguments, but got 3. - startRecorder(tabId, { collId, port, autorun }, message.url); - break; - } - - case "stopRecording": - // @ts-expect-error - TS7005 - Variable 'tabId' implicitly has an 'any' type. - stopRecorder(tabId); - break; - - case "toggleBehaviors": - // @ts-expect-error - TS7005 - Variable 'tabId' implicitly has an 'any' type. - toggleBehaviors(tabId); - break; - - case "newColl": { - const { name } = await collLoader.initNewColl({ title: message.title }); - defaultCollId = name; - port.postMessage(await listAllMsg(collLoader, { defaultCollId })); - await setLocalOption("defaultCollId", defaultCollId); - break; - } - } - }); - port.onDisconnect.addListener(() => { - // @ts-expect-error - TS2538 - Type 'null' cannot be used as an index type. - if (self.recorders[tabId]) { - // @ts-expect-error - TS2538 - Type 'null' cannot be used as an index type. - self.recorders[tabId].port = null; - } - }); -} // @ts-expect-error - TS7006 - Parameter 'port' implicitly has an 'any' type. function sidepanelHandler(port) { if (!port.sender || port.sender.url !== chrome.runtime.getURL("sidepanel.html")) { @@ -134,6 +78,7 @@ function sidepanelHandler(port) { switch (message.type) { case "startUpdates": tabId = message.tabId; + sidepanelPort = port; if (self.recorders[tabId]) { // @ts-expect-error - TS2339 - Property 'port' does not exist on type 'BrowserRecorder'. self.recorders[tabId].port = port; @@ -226,8 +171,32 @@ function sidepanelHandler(port) { self.recorders[tabId].port = null; } }); + + } +// =========================================================================== +chrome.runtime.onMessage.addListener( + // @ts-expect-error - TS7006 - Parameter 'message' implicitly has an 'any' type. + (message /*sender, sendResponse*/) => { + console.log("onMessage", message); + switch (message.msg) { + case "startNew": + (async () => { + newRecUrl = message.url; + newRecCollId = message.collId; + autorun = message.autorun; + defaultCollId = await getLocalOption("defaultCollId"); + chrome.tabs.create({ url: "about:blank" }); + })(); + break; + case "disableCSP": + disableCSPForTab(message.tabId); + break; + } + return true; + }, +); // =========================================================================== // @ts-expect-error - TS7006 - Parameter 'tab' implicitly has an 'any' type. | TS7006 - Parameter 'reason' implicitly has an 'any' type. chrome.debugger.onDetach.addListener((tab, reason) => { @@ -239,16 +208,20 @@ chrome.debugger.onDetach.addListener((tab, reason) => { // @ts-expect-error - TS7006 - Parameter 'tab' implicitly has an 'any' type. chrome.tabs.onActivated.addListener(async ({ tabId }) => { + + // @ts-expect-error - TS7034 - Variable 'err' implicitly has type 'any' in some locations where its type cannot be determined. + if (sidepanelPort) { + sidepanelPort.postMessage({ type: "update" }); + } if (!isRecordingEnabled) return; // @ts-expect-error - chrome doesn't have type definitions const tab = await new Promise((resolve) => chrome.tabs.get(tabId, resolve)); if (!isValidUrl(tab.url)) return; - if (!self.recorders[tabId]) { // @ts-expect-error - TS2554 - Expected 2 arguments, but got 3. - startRecorder(tabId, { collId: defaultCollId, port: null, autorun }, tab.url); + await startRecorder(tabId, { collId: defaultCollId, port: null, autorun }, tab.url); } }); @@ -384,9 +357,13 @@ async function startRecorder(tabId, opts) { } let err = null; - + // @ts-expect-error - TS7034 - Variable 'err' implicitly has type 'any' in some locations where its type cannot be determined. + if (sidepanelPort) { + sidepanelPort.postMessage({ type: "update" }); + } const { waitForTabUpdate } = opts; + // @ts-expect-error - TS2339 - Property 'running' does not exist on type 'BrowserRecorder'. if (!waitForTabUpdate && !self.recorders[tabId].running) { try { @@ -435,25 +412,7 @@ function isValidUrl(url) { return url && (url === "about:blank" || url.startsWith("https:") || url.startsWith("http:")); } -// =========================================================================== -chrome.runtime.onMessage.addListener( - // @ts-expect-error - TS7006 - Parameter 'message' implicitly has an 'any' type. - async (message /*sender, sendResponse*/) => { - switch (message.msg) { - case "startNew": - newRecUrl = message.url; - newRecCollId = message.collId; - autorun = message.autorun; - defaultCollId = await getLocalOption("defaultCollId"); - chrome.tabs.create({ url: "about:blank" }); - break; - case "disableCSP": - disableCSPForTab(message.tabId); - break; - } - }, -); // =========================================================================== // @ts-expect-error - TS7006 - Parameter 'tabId' implicitly has an 'any' type. diff --git a/src/recorder.ts b/src/recorder.ts index f807b8d..d0cfd5b 100644 --- a/src/recorder.ts +++ b/src/recorder.ts @@ -424,6 +424,10 @@ class Recorder { // @ts-expect-error - TS2339 - Property 'numPending' does not exist on type 'Recorder'. numPending: this.numPending, // @ts-expect-error - TS2339 - Property 'pageInfo' does not exist on type 'Recorder'. + favIconUrl: this.pageInfo.favIconUrl, + // @ts-expect-error - TS2339 - Property 'pageInfo' does not exist on type 'Recorder'. + pageTitle: this.pageInfo.title, + // @ts-expect-error - TS2339 - Property 'pageInfo' does not exist on type 'Recorder'. pageUrl: this.pageInfo.url, // @ts-expect-error - TS2339 - Property 'pageInfo' does not exist on type 'Recorder'. pageTs: this.pageInfo.ts, @@ -433,6 +437,8 @@ class Recorder { collId: this.collId, // @ts-expect-error - TS2339 - Property 'stopping' does not exist on type 'Recorder'. stopping: this.stopping, + // @ts-expect-error - TS2339 - Property 'tabId' does not exist on type 'Recorder'. + tabId: this.tabId, type: "status", }; } diff --git a/src/sidepanel.ts b/src/sidepanel.ts index fde00cb..e37e1fd 100644 --- a/src/sidepanel.ts +++ b/src/sidepanel.ts @@ -25,6 +25,7 @@ import { import "@material/web/button/filled-button.js"; import "@material/web/button/outlined-button.js"; import "@material/web/divider/divider.js"; +import { mapIntegerToRange, truncateString } from "./utils"; document.adoptedStyleSheets.push(typescaleStyles.styleSheet!); @@ -85,6 +86,42 @@ class ArgoViewer extends LitElement { background: transparent !important; padding: 0.75rem 1rem; } + .status-current-page { + display: flex; + flex-direction: column; + align-items: start; + justify-content: space-between; + } + + .status-title { + font-size: 12px; + font-weight: 500; + color: #6b6b6b; + margin-bottom: 4px; + } + + .status-ready { + font-size: 11px; + font-weight: 500; + color: #6b6b6b; + margin-bottom: 4px; + } + + .status-page-title { + font-size: 14px; + font-weight: 500; + color: #000; + margin-bottom: 8px; + } + + img.favicon { + width: 20px !important; + height: 20px !important; + flex: 0 0 auto; + object-fit: cover; + border-radius: 4px; + filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.6)); + } ` ]; @@ -108,6 +145,10 @@ class ArgoViewer extends LitElement { // @ts-expect-error - TS2339 - Property 'port' does not exist on type 'ArgoViewer'. this.port = null; + // @ts-expect-error - TS2339 - Property 'favIconUrl' does not exist on type 'ArgoViewer'. + this.favIconUrl = ""; + // @ts-expect-error - TS2339 - Property 'pageTitle' does not exist on type 'ArgoViewer'. + this.pageTitle = ""; // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'ArgoViewer'. this.pageUrl = ""; // @ts-expect-error - TS2339 - Property 'pageTs' does not exist on type 'ArgoViewer'. @@ -150,6 +191,7 @@ class ArgoViewer extends LitElement { waitingForStart: { type: Boolean }, replayUrl: { type: String }, + pageTitle: { type: String }, pageUrl: { type: String }, pageTs: { type: Number }, @@ -183,9 +225,7 @@ class ArgoViewer extends LitElement { this.registerMessages(); } - registerMessages() { - // @ts-expect-error - TS2339 - Property 'port' does not exist on type 'ArgoViewer'. - this.port = chrome.runtime.connect({ name: "sidepanel-port" }); + updateTabInfo() { // @ts-expect-error - TS7006 - Parameter 'tabs' implicitly has an 'any' type. chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { if (tabs.length) { @@ -198,13 +238,17 @@ class ArgoViewer extends LitElement { // @ts-expect-error - TS2339 - Property 'recording' does not exist on type 'ArgoViewer'. this.recording = result.indexOf("Recording:") >= 0; }); - // @ts-expect-error - TS2339 - Property 'tabId' does not exist on type 'ArgoViewer'. this.sendMessage({ tabId: this.tabId, type: "startUpdates" }); } }); + } + + registerMessages() { + // @ts-expect-error - TS2339 - Property 'port' does not exist on type 'ArgoViewer'. + this.port = chrome.runtime.connect({ name: "sidepanel-port" }); - // this.sendMessage({ type: "getPages" }); + this.updateTabInfo(); // @ts-expect-error - TS2339 - Property 'port' does not exist on type 'ArgoViewer'. this.port.onMessage.addListener((message) => { @@ -220,7 +264,14 @@ class ArgoViewer extends LitElement { // @ts-expect-error - TS7006 - Parameter 'message' implicitly has an 'any' type. async onMessage(message) { switch (message.type) { + case "update": + this.updateTabInfo(); + break; case "status": + // @ts-expect-error - TS2339 - Property 'tabId' does not exist on type 'ArgoViewer'. + if (this.tabId !== message.tabId) { + return; + } // @ts-expect-error - TS2339 - Property 'recording' does not exist on type 'ArgoViewer'. this.recording = message.recording; // @ts-expect-error - TS2339 - Property 'waitingForStart' does not exist on type 'ArgoViewer'. @@ -243,6 +294,15 @@ class ArgoViewer extends LitElement { this.behaviorResults = message.behaviorData?.state; // @ts-expect-error - TS2339 - Property 'autorun' does not exist on type 'ArgoViewer'. this.autorun = message.autorun; + + if (message.favIconUrl) { + // @ts-expect-error - TS2339 - Property 'favIconUrl' does not exist on type 'ArgoViewer'. + this.favIconUrl = message.favIconUrl; + } + if (message.pageTitle) { + // @ts-expect-error - TS2339 - Property 'pageTitle' does not exist on type 'ArgoViewer'. + this.pageTitle = message.pageTitle; + } if (message.pageUrl) { // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'ArgoViewer'. this.pageUrl = message.pageUrl; @@ -406,37 +466,59 @@ class ArgoViewer extends LitElement { // @ts-expect-error - TS2339 - Property 'recording' does not exist on type 'ArgoViewer'. if (this.recording) { - return html`${ - // @ts-expect-error - TS2339 - Property 'waitingForStop' does not exist on type 'ArgoViewer'. - this.waitingForStop ? "Finishing " : "" - } - Archiving: ${ + return html`
+ Current page + ${ + // @ts-expect-error - TS2339 - Property 'favIconUrl' does not exist on type 'ArgoViewer'. + this.favIconUrl || + // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'ArgoViewer'. + this.pageTitle ? html` +
+ Favicon + ${ + //@ts-expect-error - TS2339 - Property 'pageTitle' does not exist on type 'ArgoViewer'. + truncateString(this.pageTitle) + } +
+ ` : "" + } + Status + ${ + // @ts-expect-error - TS2339 - Property 'status' does not exist on type 'ArgoViewer'. + this.status?.numPending ? html` + + ` : "" + } + ${ // @ts-expect-error - TS2339 - Property 'status' does not exist on type 'ArgoViewer'. | TS2339 - Property 'status' does not exist on type 'ArgoViewer'. - this.status?.numPending - ? html` - ${ - // @ts-expect-error - TS2339 - Property 'status' does not exist on type 'ArgoViewer'. - this.status.numPending - } - URLs - pending${ - // @ts-expect-error - TS2339 - Property 'waitingForStop' does not exist on type 'ArgoViewer'. - this.waitingForStop - ? "." - : ", please wait before loading a new page." - } - ` - : html` Idle, Continue Browsing` - }`; + !this.status?.numPending + ? html`All resources archived` : "" + }
`; } // @ts-expect-error - TS2339 - Property 'failureMsg' does not exist on type 'ArgoViewer'. if (this.failureMsg) { return html` + Status

Sorry, there was an error starting archiving on this page. Please @@ -469,6 +551,7 @@ class ArgoViewer extends LitElement { // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'ArgoViewer'. | TS2339 - Property 'pageUrl' does not exist on type 'ArgoViewer'. if (this.pageUrl?.startsWith(this.extRoot)) { return html` + Status

This page is part of the extension. You can view existing archived items from here. To start a new archiving session, click the @@ -478,15 +561,24 @@ class ArgoViewer extends LitElement { `; } - return html`Can't archive this page.`; + return html` + Status +
+

Can't archive this page.

`; } // @ts-expect-error - TS2339 - Property 'waitingForStart' does not exist on type 'ArgoViewer'. if (this.waitingForStart) { - return html`Archiving will start after the page reloads...`; + return html` + Status +
+

Archiving will start after the page reloads...

`; } - return html`${this.notRecordingMessage}`; + return html` + Status +
+

${this.notRecordingMessage}

`; } renderSearch() { @@ -511,7 +603,7 @@ class ArgoViewer extends LitElement { My Shared Archives -
+
@@ -527,7 +619,7 @@ class ArgoViewer extends LitElement { ${this.renderSearch()} ${this.renderStatusCard()} ${this.renderTabs()} -
+
${ diff --git a/src/utils.ts b/src/utils.ts index 74a8710..0f6500d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -62,3 +62,30 @@ export async function listAllMsg(collLoader, { defaultCollId = null } = {}) { return msg; } + + +export function mapIntegerToRange(integer: number) { + // Calculate distance from 0 (use absolute value for negative numbers) + const distance = Math.abs(integer); + + // Use our calculated decay constant for appropriate distribution + const decayConstant = 0.014505; + + // Calculate result using exponential decay + const result = 0.1 + 0.9 * Math.exp(-decayConstant * distance); + + // Ensure the result is between 0.1 and 1 + return Math.max(0.1, Math.min(1, result)); +} + +export function truncateString(str: string) { + const maxLength = 100; + // If string is shorter than or equal to maxLength, return it as is + if (str.length <= maxLength) { + return str; + } + + // Otherwise, truncate to maxLength - 3 characters and add "..." + // This ensures the total length (including "...") doesn't exceed maxLength + return str.substring(0, maxLength - 3) + "..."; +} \ No newline at end of file diff --git a/static/sidepanel.html b/static/sidepanel.html index 8cfed38..a8e35bd 100644 --- a/static/sidepanel.html +++ b/static/sidepanel.html @@ -20,6 +20,7 @@ --md-sys-color-surface-container: white; --md-elevated-card-container-color: white; + --md-linear-progress-track-height: 8px; } @@ -28,9 +29,11 @@ From abac8742620a0eb896ece07688dc2400da714651 Mon Sep 17 00:00:00 2001 From: Juan Date: Wed, 14 May 2025 12:15:18 -0500 Subject: [PATCH 3/4] ts comment fix --- src/ext/bg.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ext/bg.ts b/src/ext/bg.ts index deb510f..658f01e 100644 --- a/src/ext/bg.ts +++ b/src/ext/bg.ts @@ -357,7 +357,7 @@ async function startRecorder(tabId, opts) { } let err = null; - // @ts-expect-error - TS7034 - Variable 'err' implicitly has type 'any' in some locations where its type cannot be determined. + // @ts-expect-error - TS7034 - Variable 'sidepanelPort' implicitly has type 'any' in some locations where its type cannot be determined. if (sidepanelPort) { sidepanelPort.postMessage({ type: "update" }); } From 67116b0f4fe76a6badc1824f1cf1d8b97e6c5746 Mon Sep 17 00:00:00 2001 From: Juan Date: Wed, 14 May 2025 13:56:46 -0500 Subject: [PATCH 4/4] fix element selection --- src/sidepanel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sidepanel.ts b/src/sidepanel.ts index 57275eb..bd95d44 100644 --- a/src/sidepanel.ts +++ b/src/sidepanel.ts @@ -352,7 +352,7 @@ class ArgoViewer extends LitElement { } firstUpdated() { - this.archiveList = document.getElementById( + this.archiveList = this.shadowRoot?.getElementById( "archive-list", ) as ArgoArchiveList;