Experimenting with storing drafts. Fixed an old scary tfrpc bug which resulted in localStorageGet returning wrong values on subsequent calls.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4138 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
2023-01-21 00:16:18 +00:00
parent 77df158178
commit dab7050899
8 changed files with 84 additions and 50 deletions

View File

@ -1,4 +1,4 @@
import {LitElement, html} from './lit-all.min.js';
import {LitElement, html, unsafeHTML} 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';
@ -13,6 +13,7 @@ class TfComposeElement extends LitElement {
branch: {type: String},
mentions: {type: Object},
apps: {type: Object},
drafts: {type: Object},
}
}
@ -25,13 +26,13 @@ class TfComposeElement extends LitElement {
this.branch = undefined;
this.mentions = {};
this.apps = undefined;
this.drafts = {};
}
changed(event) {
let edit = this.renderRoot.getElementById('edit');
let preview = this.renderRoot.getElementById('preview');
let text = edit.value;
process_text(text) {
if (!text) {
return '';
}
/* Update mentions. */
for (let match of text.matchAll(/\[([^\[]+)]\(([@&%][^\)]+)/g)) {
let name = match[1];
@ -57,8 +58,14 @@ class TfComposeElement extends LitElement {
this.mentions[link].name = name.startsWith('@') ? name.substring(1) : name;
this.mentions = Object.assign({}, this.mentions);
}
return tfutils.markdown(text);
}
preview.innerHTML = tfutils.markdown(text);
changed(event) {
let edit = this.renderRoot.getElementById('edit');
let preview = this.renderRoot.getElementById('preview');
preview.innerHTML = this.process_text(edit.value);
this.dispatchEvent(new CustomEvent('tf-draft', {detail: {id: this.branch, draft: edit.value, bubbles: true}}));
}
convert_to_format(buffer, type, mime_type) {
@ -157,6 +164,7 @@ class TfComposeElement extends LitElement {
edit.value = '';
self.mentions = {};
self.changed();
this.dispatchEvent(new CustomEvent('tf-draft', {detail: {id: this.branch, discard: undefined}}));
}).catch(function(error) {
alert(error.message);
});
@ -166,7 +174,7 @@ class TfComposeElement extends LitElement {
let edit = this.renderRoot.getElementById('edit');
edit.value = '';
this.changed();
this.dispatchEvent(new CustomEvent('tf-discard'));
this.dispatchEvent(new CustomEvent('tf-draft', {bubble: true, composed: true, detail: {id: this.branch, discard: undefined}}));
}
attach() {
@ -258,7 +266,7 @@ class TfComposeElement extends LitElement {
let self = this;
let result = html`
<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%">${this.drafts[this.id || '']}</textarea>
<div id="preview" style="flex: 1 0 50%"></div>
</div>
${Object.values(this.mentions).map(x => self.render_mention(x))}

View File

@ -10,7 +10,7 @@ class TfMessageElement extends LitElement {
whoami: {type: String},
message: {type: Object},
users: {type: Object},
reply: {type: Boolean},
drafts: {type: Object},
raw: {type: Boolean},
collapsed: {type: Boolean},
content_warning_expanded: {type: Boolean},
@ -27,13 +27,19 @@ class TfMessageElement extends LitElement {
this.whoami = null;
this.message = {};
this.users = {};
this.reply = false;
this.drafts = {};
this.raw = false;
this.collapsed = false;
}
show_reply() {
this.reply = true;
let event = new CustomEvent('tf-draft', {bubbles: true, composed: true, detail: {id: this.message?.id, draft: ''}});
this.dispatchEvent(event);
}
discard_reply() {
console.log('discard');
this.dispatchEvent(new CustomEvent('tf-draft', {bubbles: true, composed: true, detail: {id: this.id, draft: undefined}}));
}
render_votes() {
@ -186,7 +192,7 @@ class TfMessageElement extends LitElement {
if (this.collapsed) {
return html`<input type="button" value=${this.message.child_messages?.length + ' More'} @click=${() => self.collapsed = false}></input>`;
} else {
return html`<input type="button" value="Collapse" @click=${() => self.collapsed = true}></input>${(this.message.child_messages || []).map(x => html`<tf-message .message=${x} whoami=${this.whoami} .users=${this.users}></tf-message>`)}`;
return html`<input type="button" value="Collapse" @click=${() => self.collapsed = true}></input>${(this.message.child_messages || []).map(x => html`<tf-message .message=${x} whoami=${this.whoami} .users=${this.users} .drafts=${this.drafts}></tf-message>`)}`;
}
}
}
@ -214,7 +220,7 @@ class TfMessageElement extends LitElement {
<a target="_top" href=${'#' + this.message.id}>${this.message.id}</a> (placeholder)
<div>${this.render_votes()}</div>
${(this.message.child_messages || []).map(x => html`
<tf-message .message=${x} whoami=${this.whoami} .users=${this.users} collapsed=true></tf-message>
<tf-message .message=${x} whoami=${this.whoami} .users=${this.users} .drafts=${this.drafts} collapsed=true></tf-message>
`)}
</div>`;
} else if (typeof(content?.type === 'string')) {
@ -258,14 +264,13 @@ class TfMessageElement extends LitElement {
</div>
`);
} else if (content.type == 'post') {
let reply = this.reply ? html`
let reply = (this.drafts[this.message?.id] !== undefined) ? html`
<tf-compose
?enabled=${this.reply}
whoami=${this.whoami}
.users=${this.users}
root=${this.message.content.root || this.message.id}
branch=${this.message.id}
@tf-discard=${() => this.reply = false}></tf-compose>
@tf-discard=${this.discard_reply}></tf-compose>
` : html`
<input type="button" value="Reply" @click=${this.show_reply}></input>
`;

View File

@ -9,6 +9,7 @@ class TfNewsElement extends LitElement {
users: {type: Object},
messages: {type: Array},
following: {type: Array},
drafts: {type: Object},
}
}
@ -21,6 +22,7 @@ class TfNewsElement extends LitElement {
this.users = {};
this.messages = [];
this.following = [];
this.drafts = {};
}
process_messages(messages) {
@ -145,7 +147,7 @@ class TfNewsElement extends LitElement {
let final_messages = this.finalize_messages(messages_by_id);
return html`
<div style="display: flex; flex-direction: column">
${final_messages.map(x => html`<tf-message .message=${x} whoami=${this.whoami} .users=${this.users} collapsed=true></tf-message>`)}
${final_messages.map(x => html`<tf-message .message=${x} whoami=${this.whoami} .users=${this.users} .drafts=${this.drafts} collapsed=true></tf-message>`)}
</div>
`;
}

View File

@ -10,6 +10,7 @@ class TfTabNewsFeedElement extends LitElement {
hash: {type: String},
following: {type: Array},
messages: {type: Array},
drafts: {type: Object},
}
}
@ -22,6 +23,7 @@ class TfTabNewsFeedElement extends LitElement {
this.users = {};
this.hash = '#';
this.following = [];
this.drafts = {};
}
async fetch_messages() {
@ -102,7 +104,7 @@ class TfTabNewsFeedElement extends LitElement {
alert(JSON.stringify(error, null, 2));
});
}
return html`<tf-news id="news" whoami=${this.whoami} .users=${this.users} .messages=${this.messages} .following=${this.following}></tf-news>`;
return html`<tf-news id="news" whoami=${this.whoami} .users=${this.users} .messages=${this.messages} .following=${this.following} .drafts=${this.drafts}></tf-news>`;
}
}
@ -114,6 +116,7 @@ class TfTabNewsElement extends LitElement {
hash: {type: String},
unread: {type: Array},
following: {type: Array},
drafts: {type: Object},
}
}
@ -128,6 +131,10 @@ class TfTabNewsElement extends LitElement {
this.unread = [];
this.following = [];
this.cache = {};
this.drafts = {};
tfrpc.rpc.localStorageGet('drafts').then(function(d) {
self.drafts = JSON.parse(d || '{}');
});
}
show_more() {
@ -156,6 +163,19 @@ class TfTabNewsElement extends LitElement {
return 'Show New: ' + Object.keys(counts).sort().map(x => (counts[x].toString() + ' ' + x + 's')).join(', ');
}
draft(event) {
let id = event.detail.id || '';
if (event.detail.draft !== undefined) {
let draft = {};
draft[id] = event.detail.draft;
this.drafts = Object.assign({}, this.drafts, draft);
} else {
delete this.drafts[id];
this.drafts = Object.assign({}, this.drafts);
}
tfrpc.rpc.localStorageSet('drafts', JSON.stringify(this.drafts));
}
render() {
let profile = this.hash.startsWith('#@') ?
html`<tf-profile id=${this.hash.substring(1)} whoami=${this.whoami} .users=${this.users}></tf-profile>` : undefined;
@ -163,9 +183,9 @@ class TfTabNewsElement extends LitElement {
<div><input type="button" value=${this.new_messages_text()} @click=${this.show_more}></input></div>
<a target="_top" href="#" ?hidden=${this.hash.length <= 1}>🏠Home</a>
<div>Welcome, <tf-user id=${this.whoami} .users=${this.users}></tf-user>!</div>
<div><tf-compose whoami=${this.whoami} .users=${this.users}></tf-compose></div>
<div><tf-compose whoami=${this.whoami} .users=${this.users} .drafts=${this.drafts} @tf-draft=${this.draft}></tf-compose></div>
${profile}
<tf-tab-news-feed id="news" whoami=${this.whoami} .users=${this.users} .following=${this.following} hash=${this.hash}></tf-tab-news-feed>
<tf-tab-news-feed id="news" whoami=${this.whoami} .users=${this.users} .following=${this.following} hash=${this.hash} .drafts=${this.drafts} @tf-draft=${this.draft}></tf-tab-news-feed>
`;
}
}