forked from cory/tildefriends
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:
parent
3bbeec8ece
commit
a37ad69c8b
@ -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"}}
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user