import {LitElement, html} from './lit-all.min.js'; import * as tfrpc from '/static/tfrpc.js'; class TfCollectionElement extends LitElement { static get properties() { return { whoami: {type: String}, collections: {type: Object}, collections_loading: {type: Number}, type: {type: String}, parent: {type: String}, selectname: {type: String}, }; } constructor() { super(); this.ids = []; this.loaded = this.load(); this.type = 'collection'; this.collections_loading = 0; } process_message(message) { let content = JSON.parse(message.content); if (content?.key) { if (content?.tombstone) { delete this.by_id[content.key]; } else if (this.by_id[content.key]) { this.by_id[content.key] = Object.assign(this.by_id[content.key], content); } } else { this.by_id[message.id] = Object.assign(content, {id: message.id}); } } async load() { try { this.collections_loading++; if (this.whoami) { let following = await tfrpc.rpc.following([this.whoami], 2); this.following = following; if (this.type) { let collections = await tfrpc.rpc.query(` SELECT messages.id, author, content, timestamp FROM messages JOIN json_each(?1) AS id ON messages.author = id.value WHERE json_extract(content, '$.type') = ?2 AND (?3 IS NULL OR json_extract(content, '$.parent') = ?3) ORDER BY timestamp `, [JSON.stringify(following), this.type, this.parent]); this.by_id = {}; for (let collection of collections) { this.process_message(collection); } this.collections = Object.values(this.by_id); } } console.log('loaded', this.collections); } finally { this.collections_loading--; } if (this.selectname) { this.set_selected_by_name(this.selectname); } } async create(name, editors) { let message = { type: this.type, name: name, parent: this.parent, editors: editors, }; print('will append', message); await tfrpc.rpc.appendMessage(this.whoami, message); } notify_new_message(message) { console.log('got notify new message', message); if (this.following && this.following.indexOf(message.author) != -1 && JSON.parse(message.content).type == this.type) { console.log('processing message', message); this.process_message(message); this.collections = [...Object.values(this.by_id)]; } } async on_create(event) { let name = this.shadowRoot.getElementById('create_name').value; if (name) { await this.create(name, [this.whoami]); } } async on_tombstone(id) { let message = { type: this.type, key: id, parent: this.parent, tombstone: { date: new Date().valueOf(), reason: 'archived', }, }; print(message); await tfrpc.rpc.appendMessage(this.whoami, message); //return this.load(); } set_selected(id, value, by_user) { this.dispatchEvent(new CustomEvent('selected', { bubbles: true, detail: { id: id, value: value, by_user: by_user, }, })); } set_selected_by_name(name) { if (this.collections) { for (let collection of this.collections) { if (collection.name === name) { this.set_selected(collection.id, collection); } } } this._select_by_name = name; } render_collection(collection) { return html`
${collection.id}
${collection.editors.map(id => html`${id}`)}
`; } render() { let state = JSON.stringify([this.whoami, this.ids, this.parent]); if (state !== this.loaded_for) { this.loaded_for = state; console.log('start load', state); this.loaded = this.load(); } return html`

${this.type}s

${this.whoami} ${this.selectname}
${this.parent}
${this.collections_loading ? html`
Loading...
` : html` `} `; } } customElements.define('tf-collection', TfCollectionElement);