Update mentions whenever attaching images or updating markdown. Also show them.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4011 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
Cory McWilliams 2022-10-16 19:05:22 +00:00
parent 3bbeec8ece
commit a37ad69c8b
2 changed files with 73 additions and 43 deletions

View File

@ -1 +1 @@
{"type":"tildefriends-app","files":{"app.js":"&XCpiJOtpMzQz5Zo+Hu9f3ppQON9PxFdV4XnS2Ae+Ye8=.sha256","lit-all.min.js":"&N4A12AsifdQgwdpII0SFtG513BfoLpmPjdJ9VTDftpg=.sha256","index.html":"&Vpp3ezlQiD5guf1P6yZhpcNMnO0u+uQoil3hNkwiIp4=.sha256","script.js":"&G8puK9Q4MngHy3D4ppcKyT49WKbHD2OCeUcAw2ghTDE=.sha256","lit-all.min.js.map":"&oFY9wO4MnujgfGNGv4VggHc5V5JwX4C8csqKZ6KJYbE=.sha256","tf-id-picker.js":"&9BDffV4HY9FqhL7XI4it+UQJB4cYwbDNsY3S1cxy2vw=.sha256","tf-app.js":"&qqpOZHnkJQevhLGPUEJ7br2S/LNH+nQtC91vz3CrYrE=.sha256","tf-message.js":"&fFCn+5+eRe552tiiESswbXVU2oEfibb+w0gzZKKGWkk=.sha256","tf-user.js":"&bXTedgBudTQLXEBPY9R8OLfQ/ZLpo8YRU9Oq/wuGG3Y=.sha256","tf-utils.js":"&N2yKZwFnb2GbPeipgQtu6xFvezENNOgud9G7EhCQ/K0=.sha256","commonmark.min.js":"&bfBaMLU19d1p/vPBF9hlARqDX002KXG/UOfxOahZhe4=.sha256","tf-compose.js":"&b/mMiihhTtPEmLC7qUnd9P1UY4+UR7wq+YKwRK1SU9A=.sha256","emojis.json":"&h3P4pez+AI4aYdsN0dJ3pbUEFR0276t9AM20caj/W/s=.sha256","emojis.js":"&pqYLDE/13PyEt2ceeFqvnwZ8NqWfPfpDBt4vP8SeHbs=.sha256","tf-styles.js":"&Zw90HptAvGwX/vBnEhRVfNrYjMSssFnnKpp8bzwXQH0=.sha256","tf-profile.js":"&vRKjsnYvOiHCQahzEfznCvP5YDwUPtltlpWf+pxwZ1Y=.sha256","commonmark-linkify.js":"&X+hNNkmSRvKY86khyAun+cXksquXbMakZdINbGbx30g=.sha256","tf-tab-search.js":"&ESt2vMG19sH5j6ungKua/ZuvIGslyuWyb3juXdOCecg=.sha256","tf-tab-news.js":"&6ialbh/M2eBCDH6wFyoOHyDqG9QHbyIrzvRK+CgeyRc=.sha256","tf-tab-connections.js":"&jSnF/5NmgqxRze1XQAEGOW5mPzOV1/8aCyrDRZu34IQ=.sha256","tf-news.js":"&K3azL6eFcgbM9xpLHU3L5oSOApi1fXEvJZrhPkZgDpQ=.sha256","tribute.css":"&9FogMzZHKXCfGb7mlh7z+/wiNZzBsOB/tKoh6MfYJno=.sha256","tribute.esm.js":"&P1wKqCfYULpR/ahSB98JP8xaxfikuZwwtT6I/SAo7/Y=.sha256"}} {"type":"tildefriends-app","files":{"app.js":"&XCpiJOtpMzQz5Zo+Hu9f3ppQON9PxFdV4XnS2Ae+Ye8=.sha256","lit-all.min.js":"&N4A12AsifdQgwdpII0SFtG513BfoLpmPjdJ9VTDftpg=.sha256","index.html":"&Vpp3ezlQiD5guf1P6yZhpcNMnO0u+uQoil3hNkwiIp4=.sha256","script.js":"&G8puK9Q4MngHy3D4ppcKyT49WKbHD2OCeUcAw2ghTDE=.sha256","lit-all.min.js.map":"&oFY9wO4MnujgfGNGv4VggHc5V5JwX4C8csqKZ6KJYbE=.sha256","tf-id-picker.js":"&9BDffV4HY9FqhL7XI4it+UQJB4cYwbDNsY3S1cxy2vw=.sha256","tf-app.js":"&qqpOZHnkJQevhLGPUEJ7br2S/LNH+nQtC91vz3CrYrE=.sha256","tf-message.js":"&fFCn+5+eRe552tiiESswbXVU2oEfibb+w0gzZKKGWkk=.sha256","tf-user.js":"&bXTedgBudTQLXEBPY9R8OLfQ/ZLpo8YRU9Oq/wuGG3Y=.sha256","tf-utils.js":"&N2yKZwFnb2GbPeipgQtu6xFvezENNOgud9G7EhCQ/K0=.sha256","commonmark.min.js":"&bfBaMLU19d1p/vPBF9hlARqDX002KXG/UOfxOahZhe4=.sha256","tf-compose.js":"&QTKDJcbhLICwXdBQKD1v26NziF9QnSJtcaD1vEKGaag=.sha256","emojis.json":"&h3P4pez+AI4aYdsN0dJ3pbUEFR0276t9AM20caj/W/s=.sha256","emojis.js":"&pqYLDE/13PyEt2ceeFqvnwZ8NqWfPfpDBt4vP8SeHbs=.sha256","tf-styles.js":"&Zw90HptAvGwX/vBnEhRVfNrYjMSssFnnKpp8bzwXQH0=.sha256","tf-profile.js":"&vRKjsnYvOiHCQahzEfznCvP5YDwUPtltlpWf+pxwZ1Y=.sha256","commonmark-linkify.js":"&X+hNNkmSRvKY86khyAun+cXksquXbMakZdINbGbx30g=.sha256","tf-tab-search.js":"&ESt2vMG19sH5j6ungKua/ZuvIGslyuWyb3juXdOCecg=.sha256","tf-tab-news.js":"&6ialbh/M2eBCDH6wFyoOHyDqG9QHbyIrzvRK+CgeyRc=.sha256","tf-tab-connections.js":"&jSnF/5NmgqxRze1XQAEGOW5mPzOV1/8aCyrDRZu34IQ=.sha256","tf-news.js":"&K3azL6eFcgbM9xpLHU3L5oSOApi1fXEvJZrhPkZgDpQ=.sha256","tribute.css":"&9FogMzZHKXCfGb7mlh7z+/wiNZzBsOB/tKoh6MfYJno=.sha256","tribute.esm.js":"&P1wKqCfYULpR/ahSB98JP8xaxfikuZwwtT6I/SAo7/Y=.sha256"}}

View File

@ -11,6 +11,7 @@ class TfComposeElement extends LitElement {
users: {type: Object}, users: {type: Object},
root: {type: String}, root: {type: String},
branch: {type: String}, branch: {type: String},
mentions: {type: Object},
} }
} }
@ -21,12 +22,62 @@ class TfComposeElement extends LitElement {
this.users = {}; this.users = {};
this.root = undefined; this.root = undefined;
this.branch = undefined; this.branch = undefined;
this.mentions = {};
} }
changed(event) { changed(event) {
let edit = this.renderRoot.getElementById('edit'); let edit = this.renderRoot.getElementById('edit');
let preview = this.renderRoot.getElementById('preview'); let preview = this.renderRoot.getElementById('preview');
preview.innerHTML = tfutils.markdown(edit.value); let text = edit.value;
/* Update mentions. */
for (let match of text.matchAll(/\[([^\[]+)]\(([@&%][^\)]+)/g)) {
let name = match[1];
let link = match[2];
let balance = 0;
let bracket_end = match.index + match[1].length + '[]'.length - 1;
for (let i = bracket_end; i >= 0; i--) {
if (text.charAt(i) == ']') {
balance++;
} else if (text.charAt(i) == '[') {
balance--;
}
if (balance <= 0) {
name = text.substring(i + 1, bracket_end);
break;
}
}
if (!this.mentions[link]) {
this.mentions[link] = {
link: link,
}
}
this.mentions[link].name = name.startsWith('@') ? name.substring(1) : name;
this.mentions = Object.assign({}, this.mentions);
}
preview.innerHTML = tfutils.markdown(text);
}
add_file(file) {
let self = this;
file.arrayBuffer().then(function(buffer) {
let bin = Array.from(new Uint8Array(buffer));
return Promise.all([tfrpc.rpc.store_blob(bin), bin]);
}).then(function([id, bin]) {
self.mentions[id] = {
link: id,
name: file.name,
type: file.type,
size: bin.length,
};
self.mentions = Object.assign({}, self.mentions);
let edit = self.renderRoot.getElementById('edit');
edit.value += `\n![${file.name}](${id})`;
self.changed();
}).catch(function(e) {
alert(e.message);
});
} }
paste(event) { paste(event) {
@ -37,16 +88,7 @@ class TfComposeElement extends LitElement {
if (!file) { if (!file) {
continue; continue;
} }
file.arrayBuffer().then(function(buffer) { self.add_file(file);
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; break;
} }
} }
@ -63,28 +105,8 @@ class TfComposeElement extends LitElement {
message.root = this.root; message.root = this.root;
message.branch = this.branch; message.branch = this.branch;
} }
for (let match of message.text.matchAll(/\[([^\[]+)]\((@[^\)]+)/g)) { if (Object.values(this.mentions).length) {
if (!message.mentions) { message.mentions = Object.values(this.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); console.log('Would post:', message);
tfrpc.rpc.appendMessage(this.whoami, message).then(function() { tfrpc.rpc.appendMessage(this.whoami, message).then(function() {
@ -109,15 +131,7 @@ class TfComposeElement extends LitElement {
input.type = 'file'; input.type = 'file';
input.onchange = function(event) { input.onchange = function(event) {
let file = event.target.files[0]; let file = event.target.files[0];
file.arrayBuffer().then(function(buffer) { self.add_file(file);
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(); input.click();
} }
@ -132,12 +146,28 @@ class TfComposeElement extends LitElement {
tribute.attach(this.renderRoot.getElementById('edit')); tribute.attach(this.renderRoot.getElementById('edit'));
} }
remove_mention(id) {
delete this.mentions[id];
this.mentions = Object.assign({}, this.mentions);
}
render_mention(mention) {
let self = this;
return html`
<div>
<pre style="white-space: pre-wrap">${JSON.stringify(mention, null, 2)}</pre>
<input type="button" value="x" @click=${() => self.remove_mention(mention.link)}></input>
</div>`;
}
render() { render() {
let self = this;
let result = html` let result = html`
<div style="display: flex; flex-direction: row; width: 100%"> <div style="display: flex; flex-direction: row; width: 100%">
<textarea id="edit" @input=${this.changed} @paste=${this.paste} style="flex: 1 0 50%"></textarea> <textarea id="edit" @input=${this.changed} @paste=${this.paste} style="flex: 1 0 50%"></textarea>
<div id="preview" style="flex: 1 0 50%"></div> <div id="preview" style="flex: 1 0 50%"></div>
</div> </div>
${Object.values(this.mentions).map(x => self.render_mention(x))}
<input type="button" value="Submit" @click=${this.submit}></input> <input type="button" value="Submit" @click=${this.submit}></input>
<input type="button" value="Attach" @click=${this.attach}></input> <input type="button" value="Attach" @click=${this.attach}></input>
<input type="button" value="Discard" @click=${this.discard}></input> <input type="button" value="Discard" @click=${this.discard}></input>