forked from cory/tildefriends
		
	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:
		| @@ -1 +1 @@ | ||||
| {"type":"tildefriends-app","files":{"app.js":"&1HWTkyCc1doft6dyKF5FDxtRAErNeY25CBrfZbKPpyo=.sha256","lit-all.min.js":"&XKgdRySJuiZeZvchNFGjVWn0XOVhQFmG7/HTWYQ8s68=.sha256","index.html":"&TxhFekB9ov7tf/fmkAg7x5797i27oLidhgxEfDKC0T0=.sha256","script.js":"&G8puK9Q4MngHy3D4ppcKyT49WKbHD2OCeUcAw2ghTDE=.sha256","lit-all.min.js.map":"&lA9iFp1YbqSndxXZuwtgmrj7NDMkN71nJITbtjWL3VA=.sha256","tf-id-picker.js":"&maN8DUFrmRxW5nsVyOAMk5k1ekcz/pfzvSS99ac3jo8=.sha256","tf-app.js":"&7hclNu41CIoNk1JlXHiYmDPDyDIICZfMickJYtnF5eQ=.sha256","tf-message.js":"&oXFucwmn16nvKslQoGKTppO+71EoDZJE54z3WrlNUPI=.sha256","tf-user.js":"&bXTedgBudTQLXEBPY9R8OLfQ/ZLpo8YRU9Oq/wuGG3Y=.sha256","tf-utils.js":"&6RQUuxB3PkOhYEJr9+89Ptx7uijczjn0r035yCcQOQQ=.sha256","commonmark.min.js":"&bfBaMLU19d1p/vPBF9hlARqDX002KXG/UOfxOahZhe4=.sha256","tf-compose.js":"&ZFkTrACfSE3CeacnuHcpqysPuNm2TJ2ATVQfJv+qjzU=.sha256","emojis.json":"&h3P4pez+AI4aYdsN0dJ3pbUEFR0276t9AM20caj/W/s=.sha256","emojis.js":"&NC9VddNdX+ZpyIDUQJvH2y1u3ZczQub5+bNmN9ndj7I=.sha256","tf-styles.js":"&LFeL/vWgrv4N8q/mBrQAnhbaOI+dXNJYvH9bn1bXSqQ=.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":"&F7T3LVS867x7vsKhYRR7eLNdCFZmrZ3JzEMfJEEKRm0=.sha256","tf-tab-connections.js":"&ywqBz3w63R6naH09kZ+01A0SfmtuSfk8QPBXWsli0yg=.sha256","tf-news.js":"&gfG5LwXpugDkwDCOCOxQnNn0jLURZexSmvDu4SpQohA=.sha256","tribute.css":"&9FogMzZHKXCfGb7mlh7z+/wiNZzBsOB/tKoh6MfYJno=.sha256","tribute.esm.js":"&P1wKqCfYULpR/ahSB98JP8xaxfikuZwwtT6I/SAo7/Y=.sha256","commonmark-hashtag.js":"&H+V1OLA9GDdzycKclz276zAtSZLpT3rlNVa4+qQmp4o=.sha256"}} | ||||
| {"type":"tildefriends-app","files":{"app.js":"&1HWTkyCc1doft6dyKF5FDxtRAErNeY25CBrfZbKPpyo=.sha256","lit-all.min.js":"&XKgdRySJuiZeZvchNFGjVWn0XOVhQFmG7/HTWYQ8s68=.sha256","index.html":"&TxhFekB9ov7tf/fmkAg7x5797i27oLidhgxEfDKC0T0=.sha256","script.js":"&G8puK9Q4MngHy3D4ppcKyT49WKbHD2OCeUcAw2ghTDE=.sha256","lit-all.min.js.map":"&lA9iFp1YbqSndxXZuwtgmrj7NDMkN71nJITbtjWL3VA=.sha256","tf-id-picker.js":"&maN8DUFrmRxW5nsVyOAMk5k1ekcz/pfzvSS99ac3jo8=.sha256","tf-app.js":"&7hclNu41CIoNk1JlXHiYmDPDyDIICZfMickJYtnF5eQ=.sha256","tf-message.js":"&mEvBE2g6disBMLyaqu11wwGFGuBU2VmRJuwMBqORvfA=.sha256","tf-user.js":"&bXTedgBudTQLXEBPY9R8OLfQ/ZLpo8YRU9Oq/wuGG3Y=.sha256","tf-utils.js":"&6RQUuxB3PkOhYEJr9+89Ptx7uijczjn0r035yCcQOQQ=.sha256","commonmark.min.js":"&bfBaMLU19d1p/vPBF9hlARqDX002KXG/UOfxOahZhe4=.sha256","tf-compose.js":"&fTO3L8YlYTZ15ph7Sh54TY8YmAidkGjZa9rmT1YtVt4=.sha256","emojis.json":"&h3P4pez+AI4aYdsN0dJ3pbUEFR0276t9AM20caj/W/s=.sha256","emojis.js":"&NC9VddNdX+ZpyIDUQJvH2y1u3ZczQub5+bNmN9ndj7I=.sha256","tf-styles.js":"&LFeL/vWgrv4N8q/mBrQAnhbaOI+dXNJYvH9bn1bXSqQ=.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":"&+hexNqLjYcjPnpDsU962Hy4wWh++pNWVZHO4gI3f1C8=.sha256","tf-tab-connections.js":"&ywqBz3w63R6naH09kZ+01A0SfmtuSfk8QPBXWsli0yg=.sha256","tf-news.js":"&jPigwc9k+I5nMjsaw14Kdt89I/s6m9LVcKG/udR+LGw=.sha256","tribute.css":"&9FogMzZHKXCfGb7mlh7z+/wiNZzBsOB/tKoh6MfYJno=.sha256","tribute.esm.js":"&P1wKqCfYULpR/ahSB98JP8xaxfikuZwwtT6I/SAo7/Y=.sha256","commonmark-hashtag.js":"&H+V1OLA9GDdzycKclz276zAtSZLpT3rlNVa4+qQmp4o=.sha256"}} | ||||
| @@ -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))} | ||||
|   | ||||
| @@ -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> | ||||
| 				`; | ||||
|   | ||||
| @@ -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> | ||||
| 		`; | ||||
| 	} | ||||
|   | ||||
| @@ -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> | ||||
| 		`; | ||||
| 	} | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user