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.
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);
