tildefriends/apps/collections/tf-wiki-doc.js

91 lines
2.3 KiB
JavaScript

import {LitElement, html, unsafeHTML} from './lit-all.min.js';
import * as tfrpc from '/static/tfrpc.js';
class TfWikiDocElement extends LitElement {
static get properties() {
return {
whoami: {type: String},
value: {type: Object},
blob: {type: String},
blob_original: {type: String},
blob_for_value: {type: String},
is_editing: {type: Boolean},
};
}
constructor() {
super();
}
markdown(md) {
var reader = new commonmark.Parser({safe: true});
var writer = new commonmark.HtmlRenderer();
var parsed = reader.parse(md || '');
return writer.render(parsed);
}
async load_blob() {
this.blob = await tfrpc.rpc.get_blob(this.value?.blob);
this.blob_original = this.blob;
}
on_edit(event) {
this.blob = event.srcElement.value;
}
on_discard(event) {
this.blob = this.blob_original;
this.is_editing = false;
}
async on_save_draft() {
let id = await tfrpc.rpc.store_blob(this.blob);
this.dispatchEvent(new CustomEvent('publish', {
bubbles: true,
detail: {
id: id,
draft: true,
},
}));
this.is_editing = false;
}
async on_publish() {
let id = await tfrpc.rpc.store_blob(this.blob);
this.dispatchEvent(new CustomEvent('publish', {
bubbles: true,
detail: {
id: id,
},
}));
this.is_editing = false;
}
render() {
let value = JSON.stringify(this.value);
if (this.blob_for_value != value) {
this.blob_for_value = value;
this.blob = undefined;
this.blob_original = undefined;
this.load_blob();
}
let self = this;
return html`
<div style="display: inline-flex; flex-direction: row">
<button ?disabled=${!this.whoami || this.is_editing} @click=${() => self.is_editing = true}>Edit</button>
<button ?disabled=${this.blob == this.blob_original} @click=${this.on_save_draft}>Save Draft</button>
<button ?disabled=${this.blob == this.blob_original && !this.value?.draft} @click=${this.on_publish}>Publish</button>
<button ?disabled=${!this.is_editing} @click=${this.on_discard}>Discard</button>
</div>
<div style="display: flex; flex-direction: row">
<textarea
?hidden=${!this.is_editing}
style="flex: 1 1; min-height: 10em"
@input=${this.on_edit} .value=${this.blob ?? ''}></textarea>
<div style="flex: 1 1">${unsafeHTML(this.markdown(this.blob))}</div>
</div>
`;
}
}
customElements.define('tf-wiki-doc', TfWikiDocElement);