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}, ids: {type: Array}, collections: {type: Array}, collections_loading: {type: Number}, type: {type: String}, parent: {type: String}, selectname: {type: String}, selectid: {type: String}, is_creating: {type: Boolean}, is_renaming: {type: Boolean}, }; } constructor() { super(); this.ids = []; this.loaded = this.load(); this.type = 'collection'; this.collections_loading = 0; } async process_message(message) { let content = JSON.parse(message.content); if (typeof content == 'string') { let x = await tfrpc.rpc.try_decrypt(this.whoami, content); if (x) { content = JSON.parse(x); content.draft = true; } else { return; } if (content.type !== this.type || (this.parent && content.parent !== this.parent)) { return; } } else { content.draft = false; } 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.ids) { let visible = this.ids; this.visible = visible; 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) OR content LIKE '"%' ORDER BY timestamp `, [JSON.stringify(visible), this.type, this.parent]); this.by_id = {}; for (let collection of collections) { await this.process_message(collection); } this.collections = Object.values(this.by_id); } } } 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) { if (this.visible && this.visible.indexOf(message.author) != -1 && JSON.parse(message.content).type == this.type) { let self = this; this.process_message(message).then(function() { self.collections = [...Object.values(self.by_id)]; }); } } async on_create(event) { let name = this.shadowRoot.getElementById('create_name').value; if (name) { await this.create(name, [this.whoami]); } } async on_rename(id) { let name = this.shadowRoot.getElementById('rename_name').value; let message = { type: this.type, key: this.selectid, parent: this.parent, name: name, }; print(message); await tfrpc.rpc.appendMessage(this.whoami, message); } async on_tombstone(event) { if (confirm(`Are you sure you want to delete this ${this.type}?`)) { let message = { type: this.type, key: this.selectid, parent: this.parent, tombstone: { date: new Date().valueOf(), reason: 'archived', }, }; print(message); await tfrpc.rpc.appendMessage(this.whoami, message); } } set_selected(id, value, by_user) { this.selectid = id; console.log('SEND', id, value?.name); this.dispatchEvent(new CustomEvent('selected', { bubbles: true, detail: { id: id, value: value, by_user: by_user, }, })); } set_selected_by_name(name) { console.log('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 = undefined; return; } } } this._select_by_name = name; } render_collection(collection) { return html`
${collection.id}
${collection.editors.map(id => html`${id}`)}
`; } on_selected(event) { if (this.collections) { for (let collection of this.collections) { if (collection.id === event.srcElement.value) { this.set_selected(collection.id, collection, true); break; } } } } render() { let self = this; let state = JSON.stringify([this.whoami, this.ids, this.parent]); if (state !== this.loaded_for) { this.loaded_for = state; this.loaded = this.load(); } if (this.collections) { if (this.selectname) { for (let collection of this.collections) { if (collection.name === this.selectname) { this.set_selected(collection.id, collection); break; } } } else { for (let collection of this.collections) { if (collection.id === this.selectid) { this.set_selected(collection.id, collection); break; } } } } return html` ${this.collections_loading > 0 ? html`
Loading...
` : html` `}
`; } } customElements.define('tf-collection', TfCollectionElement);