diff --git a/src/archive-now.stylesheet.css b/src/archive-now.stylesheet.css index b5c61c9..6ca06a7 100644 --- a/src/archive-now.stylesheet.css +++ b/src/archive-now.stylesheet.css @@ -1,3 +1,39 @@ @tailwind base; @tailwind components; @tailwind utilities; + +:host { + --sl-color-primary-50: theme(colors.cyan.50); + --sl-color-primary-100: theme(colors.cyan.100); + --sl-color-primary-200: theme(colors.cyan.200); + --sl-color-primary-300: theme(colors.cyan.300); + --sl-color-primary-400: theme(colors.cyan.400); + --sl-color-primary-500: theme(colors.cyan.500); + --sl-color-primary-600: theme(colors.cyan.600); + --sl-color-primary-700: theme(colors.cyan.700.DEFAULT); + --sl-color-primary-800: theme(colors.cyan.800); + --sl-color-primary-900: theme(colors.cyan.900); +} + +@layer components { + sl-button::part(base) { + @apply rounded-md shadow-md; + } + + sl-button[variant="primary"]::part(base) { + background-color: theme(colors.cyan.400); + border-color: theme(colors.cyan.400); + } + + sl-button[variant="primary"]::part(base):hover { + background-color: theme(colors.cyan.500); + } + + sl-dialog::part(panel) { + @apply rounded-lg shadow-lg shadow-cyan-800/20 ring-2 ring-cyan-300/50; + } + + sl-dialog::part(header) { + @apply text-xl font-semibold; + } +} diff --git a/src/archive-now.ts b/src/archive-now.ts index 743d2b8..f0843f4 100644 --- a/src/archive-now.ts +++ b/src/archive-now.ts @@ -6,15 +6,19 @@ import { type TemplateResult, } from "lit"; import { customElement, query, state } from "lit/decorators.js"; -import type { SlAnimation } from "@shoelace-style/shoelace"; +import type { SlAnimation, SlDialog, SlInput } from "@shoelace-style/shoelace"; +import { getFormControls } from "@shoelace-style/shoelace/dist/utilities/form.js"; import themeCSS from "./archive-now.stylesheet.css"; import linkyHelloSrc from "./assets/Linky-Hello.avif"; import linkyConcernedSrc from "./assets/Linky-Concerned.avif"; +// TODO Replace icon +import faListIconSrc from "./assets/fa-list-icon.svg"; import "./shoelace"; const PAGE_COUNT_MIN = 10; +const DEFAULT_URL = "https://example.com/"; type Hint = "first-load" | "page-load" | "error" | "over-page-min" | "finished"; @@ -32,6 +36,9 @@ class ArchiveNow extends LitElement { @state() private errorMessage = ""; + @state() + private showCreateDialog = false; + @state() private showHint = true; @@ -62,18 +69,18 @@ class ArchiveNow extends LitElement { private hintMessages: Record = { "first-load": html`

Browse and interact with the website like you would normally. Every link - that you follow will be archived. + you follow will be archived.

When you’re done, click the Finish button.

`, "page-load": html`

- All the pages visited so far will be included in your archive. + All pages visited so far will be included in your archive.

- You can also enter in a new URL to load any page that’s not linked from - the page you’re currently viewing. + You can also enter a new URL to load any page that’s not linked from the + page you’re currently viewing.

Click @@ -82,8 +89,8 @@ class ArchiveNow extends LitElement {

`, error: html`

- Some pages may not work as expected in this limited demo. For more - comprehensive archiving, try our + This is a limited demo, and some pages may not work as expected. For + more comprehensive archiving, try our browser extension (it’s free, too!)

-

Or, try another page by entering a different URL.

+

Or try another page by entering a different URL.

`, "over-page-min": html`

@@ -112,17 +119,17 @@ class ArchiveNow extends LitElement { `, finished: html`

- Everything you can see here is now being rendered from your web archive - without the involvement of the original server. -

-

- To share a link to this archive, import it to - Browsertrix and add it to a - collection. + Click a page under Page Title to + load it directly from your web archive!

- You can also download your archive and view it at any time with - ReplayWeb.page. + Once a page is loaded, you can click the + Browse Contents + icon to view a list of all archived pages.

`, }; @@ -201,10 +208,10 @@ class ArchiveNow extends LitElement { "It looks like this site is blocking us from loading it."; } else if (event.data.status > 500) { this.errorMessage = - "It looks like this might not be a valid URL or the site is down."; + "It looks like this might not be a valid URL, or the site is down."; } else if (event.data.status === 429) { this.errorMessage = - "It looks like you’ve been rate limited (by the site, not by us.)"; + "It looks like this site is rate limiting or blocking you."; } else { this.errorMessage = "It looks like this page could not be loaded."; } @@ -218,7 +225,7 @@ class ArchiveNow extends LitElement { case "rate-limited": this.errorMessage = - "It looks like you’ve been rate limited (by this site, not by us.)"; + "It looks like this site is rate limiting or blocking you."; break; case "post-request-failed": @@ -283,7 +290,7 @@ class ArchiveNow extends LitElement {
@@ -293,11 +300,13 @@ class ArchiveNow extends LitElement { sandbox="true" coll=${this.collId} deepLink="true" - url="https://example.com/" + url=${DEFAULT_URL} >` : html` `}
-
+

@@ -311,20 +320,82 @@ class ArchiveNow extends LitElement {
- ${this.renderLinky()} + ${this.renderLinky()} ${this.renderUrlDialog()} `; } private renderFinished() { return html` -
+
+

+ Download your archive and view it at any time with + ReplayWeb.page. +

Download Archive + + Download Archive (.wacz) + + +
+ +

+ Share your archive +

+

+ To share your archive, create a public web archive collection with + Browsertrix, our complete + archiving platform. +

+
    +
  1. + Log in or + sign up for Browsertrix +
  2. +
  3. + Import your archive +
  4. +
  5. + Create a public collection +
  6. +
+ +
+ +
+ +
`; } @@ -335,11 +406,11 @@ class ArchiveNow extends LitElement { if (pageCount < 1) return; return html` -

+

Archiving ${pageCount.toLocaleString()} ${pageCount === 1 ? "page" : "pages"}

-
    +
      ${Array.from(this.pageUrls.values()).map( (url) => html`
    • (this.showCreateDialog = false)} + > +
      { + e.preventDefault(); + + const form = e.currentTarget as HTMLFormElement; + const input = getFormControls(form)[0] as SlInput; + + if ("invalid" in input.dataset) { + return; + } + + await this.startNewArchive(input.value); + + input.value = ""; + this.showCreateDialog = false; + }} + > +
      + + Start Archiving +
      +
      + + `; + } + private renderBackdrop() { return html`
      `; } @@ -561,6 +676,19 @@ class ArchiveNow extends LitElement { this.showHint = false; } + + private async startNewArchive(archiveUrl: string) { + this.hint = "first-load"; + this.isFinished = false; + this.downloadUrl = ""; + this.collId = randomId(); + this.pageCount = 0; + this.pageUrls = []; + + await this.updateComplete; + + window.location.hash = `url=${window.encodeURIComponent(archiveUrl)}`; + } } function randomId() { diff --git a/src/assets/fa-list-icon.svg b/src/assets/fa-list-icon.svg new file mode 100644 index 0000000..b1f7dac --- /dev/null +++ b/src/assets/fa-list-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/global.css b/src/global.css index e863d13..2681d8b 100644 --- a/src/global.css +++ b/src/global.css @@ -56,7 +56,7 @@ @layer components { archive-now { - @apply grid h-full gap-x-4 gap-y-3; + @apply grid h-full gap-4; grid-template-areas: "header" "archive" @@ -77,8 +77,11 @@ @media screen(xl) { archive-now { - @apply gap-x-10; grid-template-columns: 1fr theme(size.96); } } + + sl-button[variant="primary"]::part(base) { + background-color: theme(colors.cyan.500); + } }