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

173 lines
4.2 KiB
JavaScript

import {LitElement, html, keyed} from './lit-all.min.js';
import * as tfrpc from '/static/tfrpc.js';
class TfCollectionsAppElement extends LitElement {
static get properties() {
return {
ids: {type: Array},
owner_ids: {type: Array},
whoami: {type: String},
wikis: {type: Object},
wiki_docs: {type: Object},
wiki: {type: Object},
wiki_doc: {type: Object},
hash: {type: String},
};
}
constructor() {
super();
this.ids = [];
this.owner_ids = [];
this.load();
let self = this;
tfrpc.register(function hash_changed(hash) {
self.notify_hash_changed(hash);
});
tfrpc.rpc.get_hash().then(hash => self.notify_hash_changed(hash));
}
async load() {
this.ids = await tfrpc.rpc.getIdentities();
this.owner_ids = await tfrpc.rpc.getOwnerIdentities();
this.whoami = await tfrpc.rpc.localStorageGet('collections_whoami');
await this.read_wikis();
await this.read_Wiki_docs();
}
async read_wikis() {
let max_rowid;
let wikis;
while (true)
{
[max_rowid, wikis] = await tfrpc.rpc.collection(this.owner_ids, 'wiki', undefined, max_rowid, wikis);
this.wikis = wikis;
this.update_wiki();
}
}
async read_wiki_docs() {
if (!this.wiki?.id) {
return;
}
let max_rowid;
let wiki_docs;
while (true)
{
[max_rowid, wiki_docs] = await tfrpc.rpc.collection(this.owner_ids, 'wiki-doc', this.wiki?.id, max_rowid, wiki_docs);
this.wiki_docs = wiki_docs;
this.update_wiki_doc();
}
}
hash_wiki() {
let hash = this.hash ?? '';
hash = hash.charAt(0) == '#' ? hash.substring(1) : hash;
let parts = hash.split('/');
return parts[0];
}
hash_wiki_doc() {
let hash = this.hash ?? '';
hash = hash.charAt(0) == '#' ? hash.substring(1) : hash;
let slash = hash.indexOf('/');
return slash != -1 ? hash.substring(slash + 1) : undefined;
}
update_wiki() {
let want_wiki = this.hash_wiki();
for (let wiki of Object.values(this.wikis ?? {})) {
if (wiki.name === want_wiki) {
this.wiki = wiki;
this.read_wiki_docs();
break;
}
}
}
update_wiki_doc() {
let want_wiki_doc = this.hash_wiki_doc();
for (let wiki_doc of Object.values(this.wiki_docs ?? {})) {
if (wiki_doc.name === want_wiki_doc) {
this.wiki_doc = wiki_doc;
}
}
}
notify_hash_changed(hash) {
this.hash = hash;
this.update_wiki();
this.update_wiki_doc();
}
async on_whoami_changed(event) {
let new_id = event.srcElement.selected;
await tfrpc.rpc.localStorageSet('collections_whoami', new_id);
this.whoami = new_id;
}
update_hash() {
tfrpc.rpc.set_hash(this.wiki_doc ? `${this.wiki.name}/${this.wiki_doc.name}` : `${this.wiki.name}`);
}
async on_wiki_changed(event) {
this.wiki = event.detail.value;
this.wiki_doc = undefined;
this.wiki_docs = undefined;
this.update_hash();
this.read_wiki_docs();
}
async on_wiki_doc_changed(event) {
this.wiki_doc = event.detail.value;
this.update_hash();
}
async on_wiki_publish(event) {
let blob_id = event.detail.id;
let message = {
type: 'wiki-doc',
key: this.wiki_doc.id,
parent: this.wiki_doc.parent,
blob: blob_id,
};
if (event.detail.draft) {
message.recps = this.wiki_doc.editors;
print(message);
message = await tfrpc.rpc.encrypt(this.whoami, this.wiki_doc.editors, JSON.stringify(message));
}
print(message);
await tfrpc.rpc.appendMessage(this.whoami, message);
return this.shadowRoot.getElementById('docs').load();
}
render() {
let self = this;
return html`
<div>
<tf-id-picker .ids=${this.ids} selected=${this.whoami} @change=${this.on_whoami_changed}></tf-id-picker>
</div>
<div>
<tf-collection
.collection=${this.wikis}
selected_id=${this.wiki?.id}
@change=${this.on_wiki_changed}></tf-collection>
${keyed(this.wiki_doc?.id, html`<tf-collection
.collection=${this.wiki_docs}
selected_id=${(this.wiki_doc && this.wiki_doc?.parent == this.wiki?.id) ? this.wiki_doc?.id : ''}
@change=${this.on_wiki_doc_changed}></tf-collection>`)}
</div>
${this.wiki_doc && this.wiki_doc.parent === this.wiki?.id ? html`
<tf-wiki-doc
whoami=${this.whoami}
.value=${this.wiki_doc}
@publish=${this.on_wiki_publish}></tf-wiki-doc>
` : undefined}
`;
}
}
customElements.define('tf-collections-app', TfCollectionsAppElement);