Back to Black Site Map Editor
SOURCE / PINNED RELEASE

Made of little things.

Black Site Map Editor

Release
32a57733b7e9…
Author-recorded commit
3f54890f542f…
License
LICENSE
Author’s source reference
nostr://npub1ye5ptcxfyyxl5vjvdjar2ua3f0hynkjzpx552mu5snj3qmx5pzjscpknpr/wss%3A%2F%2Fgit.shakespeare.diy%2F/black-site-map-editor

Archive hash verified: 7a4b1abbac7db5b0…. The source-to-build association is the author’s claim; it has not been independently rebuilt.

src/components/bs-publish-dialog.ts
import { html, nothing } from 'lit';
import { editor, guard, type DialogView } from '../editor-controller';
import { LightElement } from './light-element';

/** Publication remains visible until the player acknowledges the result. */
export class BsPublishDialog extends LightElement implements DialogView {
    constructor() {
        super();
        this.watch((s) => [s.publication, s.busy, s.viewer]);
    }
    connectedCallback() {
        super.connectedCallback();
        editor.ui.publication = this;
    }
    get #dialog() {
        return this.querySelector<HTMLDialogElement>('dialog')!;
    }
    get isOpen() {
        return Boolean(this.#dialog?.open);
    }
    show() {
        if (!this.isOpen) this.#dialog.showModal();
    }
    close() {
        if (!editor.state.busy && this.isOpen) this.#dialog.close();
    }
    render() {
        const { publication: p, busy, viewer } = editor.state;
        const working = p.phase === 'working';
        return html`<dialog
            id="publication"
            aria-labelledby="publication-title"
            @close=${() => editor.confirmClosed()}
            @cancel=${(e: Event) => {
                if (busy) e.preventDefault();
            }}
        >
            <h2 id="publication-title">
                ${working ? 'Publishing map…' : p.phase === 'success' ? 'Map published' : 'Map could not be published'}
            </h2>
            <ol class="publish-stages" aria-label="Publishing stages">
                ${['Prepare map', 'Upload map', 'Publish map'].map((label, index) => html`<li class=${index < p.stage ? 'complete' : index === p.stage ? 'current' : ''} aria-current=${working && index === p.stage ? 'step' : nothing}>${index < p.stage ? '✓ ' : `${index + 1}. `}${label}</li>`)}
            </ol>
            ${
                working
                    ? html`<progress aria-label="Publishing map"></progress>
                          <p>
                              Keep this window open. If the host asks for approval, approve sharing
                              there.
                          </p>`
                    : nothing
            }
            <p
                id="publication-message"
                role=${p.phase === 'error' ? 'alert' : 'status'}
                aria-live="polite"
            >
                ${p.message}
            </p>
            ${
                p.phase === 'error'
                    ? html`<p>Your map is still open. You can retry or download a backup.</p>
                          <details class="publish-error">
                              <summary>Service error details</summary>
                              <pre data-napplet-select="text">${p.error}</pre>
                          </details>`
                    : nothing
            }
            ${p.warnings.map((w) => html`<p class="notice">${w}</p>`)}
            <div class="buttons">
                ${
                    p.phase === 'error'
                        ? html`<button
                                  id="publication-retry"
                                  class="primary"
                                  ?disabled=${busy || !viewer}
                                  @click=${guard(async () => {
                                      this.close();
                                      await editor.publish();
                                  })}
                              >
                                  Retry publishing</button
                              ><button
                                  id="publication-download"
                                  @click=${() => editor.exportJson()}
                              >
                                  Download backup
                              </button>`
                        : nothing
                }
                <button id="publication-close" ?disabled=${busy} @click=${() => this.close()}>
                    ${p.phase === 'success' ? 'Done' : 'Close'}
                </button>
            </div>
        </dialog>`;
    }
}
customElements.define('bs-publish-dialog', BsPublishDialog);