import {LitElement, html} from './lit-all.min.js'; import * as tfutils from './tf-utils.js'; import * as tfrpc from '/static/tfrpc.js'; import {styles} from './tf-styles.js'; import Tribute from './tribute.esm.js'; class TfComposeElement extends LitElement { static get properties() { return { whoami: {type: String}, users: {type: Object}, root: {type: String}, branch: {type: String}, } } static styles = styles; constructor() { super(); this.users = {}; this.root = undefined; this.branch = undefined; } changed(event) { let edit = this.renderRoot.getElementById('edit'); let preview = this.renderRoot.getElementById('preview'); preview.innerHTML = tfutils.markdown(edit.value); } paste(event) { let self = this; for(let item of event.clipboardData.items) { if (item.type?.startsWith('image/')) { let file = item.getAsFile(); if (!file) { continue; } file.arrayBuffer().then(function(buffer) { let bin = Array.from(new Uint8Array(buffer)); return tfrpc.rpc.store_blob(bin); }).then(function(id) { let edit = self.renderRoot.getElementById('edit'); edit.value += `\n![${file.name}](${id})`; self.changed(); }).catch(function(e) { alert(e.message); }); break; } } } submit() { let self = this; let edit = this.renderRoot.getElementById('edit'); let message = { type: 'post', text: edit.value, }; if (this.root || this.branch) { message.root = this.root; message.branch = this.branch; } for (let match of message.text.matchAll(/\[([^\[]+)]\((@[^\)]+)/g)) { if (!message.mentions) { message.mentions = []; } let name = match[1].length; let balance = 0; let bracket_end = match.index + match[1].length + '[]'.length - 1; for (let i = bracket_end; i >= 0; i--) { if (message.text.charAt(i) == ']') { balance++; } else if (message.text.charAt(i) == '[') { balance--; } if (balance <= 0) { name = message.text.substring(i + 1, bracket_end - i); break; } } message.mentions.push({ link: match[2], name: name.charAt(0) == '@' ? name.substring(1) : name, }); } console.log('Would post:', message); tfrpc.rpc.appendMessage(this.whoami, message).then(function() { edit.value = ''; self.changed(); }).catch(function(error) { alert(error.message); }); } discard() { let edit = this.renderRoot.getElementById('edit'); edit.value = ''; this.changed(); this.dispatchEvent(new CustomEvent('tf-discard')); } attach() { let self = this; let edit = this.renderRoot.getElementById('edit'); let input = document.createElement('input'); input.type = 'file'; input.onchange = function(event) { let file = event.target.files[0]; file.arrayBuffer().then(function(buffer) { let bin = Array.from(new Uint8Array(buffer)); return tfrpc.rpc.store_blob(bin); }).then(function(id) { edit.value += `\n![${file.name}](${id})`; self.changed(); }).catch(function(e) { alert(e.message); }); }; input.click(); } firstUpdated() { let tribute = new Tribute({ values: Object.entries(this.users).map(x => ({key: x[1].name, value: x[0]})), selectTemplate: function(item) { return `[@${item.original.key}](${item.original.value})`; }, }); tribute.attach(this.renderRoot.getElementById('edit')); } render() { let result = html`
`; return result; } } customElements.define('tf-compose', TfComposeElement);