| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | import {LitElement, html, unsafeHTML} from './lit-all.min.js'; | 
					
						
							|  |  |  | import * as tfrpc from '/static/tfrpc.js'; | 
					
						
							|  |  |  | import * as tfutils from './tf-utils.js'; | 
					
						
							|  |  |  | import * as emojis from './emojis.js'; | 
					
						
							|  |  |  | import {styles} from './tf-styles.js'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TfMessageElement extends LitElement { | 
					
						
							|  |  |  | 	static get properties() { | 
					
						
							|  |  |  | 		return { | 
					
						
							|  |  |  | 			whoami: {type: String}, | 
					
						
							|  |  |  | 			message: {type: Object}, | 
					
						
							|  |  |  | 			users: {type: Object}, | 
					
						
							| 
									
										
										
										
											2023-01-21 00:16:18 +00:00
										 |  |  | 			drafts: {type: Object}, | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 			raw: {type: Boolean}, | 
					
						
							| 
									
										
										
										
											2022-12-03 02:18:48 +00:00
										 |  |  | 			blog_data: {type: String}, | 
					
						
							| 
									
										
										
										
											2023-01-25 00:56:10 +00:00
										 |  |  | 			expanded: {type: Object}, | 
					
						
							| 
									
										
										
										
											2023-05-17 14:10:49 +00:00
										 |  |  | 			decrypted: {type: Object}, | 
					
						
							| 
									
										
										
										
											2023-03-29 22:02:12 +00:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	static styles = styles; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	constructor() { | 
					
						
							|  |  |  | 		super(); | 
					
						
							|  |  |  | 		let self = this; | 
					
						
							|  |  |  | 		this.whoami = null; | 
					
						
							|  |  |  | 		this.message = {}; | 
					
						
							|  |  |  | 		this.users = {}; | 
					
						
							| 
									
										
										
										
											2023-01-21 00:16:18 +00:00
										 |  |  | 		this.drafts = {}; | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 		this.raw = false; | 
					
						
							| 
									
										
										
										
											2023-01-25 00:56:10 +00:00
										 |  |  | 		this.expanded = {}; | 
					
						
							| 
									
										
										
										
											2023-05-17 14:10:49 +00:00
										 |  |  | 		this.decrypted = undefined; | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	show_reply() { | 
					
						
							| 
									
										
										
										
											2023-01-21 00:16:18 +00:00
										 |  |  | 		let event = new CustomEvent('tf-draft', {bubbles: true, composed: true, detail: {id: this.message?.id, draft: ''}}); | 
					
						
							|  |  |  | 		this.dispatchEvent(event); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	discard_reply() { | 
					
						
							|  |  |  | 		this.dispatchEvent(new CustomEvent('tf-draft', {bubbles: true, composed: true, detail: {id: this.id, draft: undefined}})); | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	render_votes() { | 
					
						
							|  |  |  | 		function normalize_expression(expression) { | 
					
						
							|  |  |  | 			if (expression === 'Like' || !expression) { | 
					
						
							|  |  |  | 				return '👍'; | 
					
						
							| 
									
										
										
										
											2022-09-10 02:56:15 +00:00
										 |  |  | 			} else if (expression === 'Unlike') { | 
					
						
							|  |  |  | 				return '👎'; | 
					
						
							|  |  |  | 			} else if (expression === 'heart') { | 
					
						
							|  |  |  | 				return '❤️'; | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				return expression; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 		return html`<div>${(this.message.votes || []).map( | 
					
						
							|  |  |  | 			vote => html`
 | 
					
						
							|  |  |  | 				<span title="${this.users[vote.author]?.name ?? vote.author} ${new Date(vote.timestamp)}"> | 
					
						
							|  |  |  | 					${normalize_expression(vote.content.vote.expression)} | 
					
						
							|  |  |  | 				</span> | 
					
						
							|  |  |  | 			`)}</div>`; | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	render_raw() { | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 		let raw = { | 
					
						
							|  |  |  | 			id: this.message?.id, | 
					
						
							|  |  |  | 			previous: this.message?.previous, | 
					
						
							|  |  |  | 			author: this.message?.author, | 
					
						
							|  |  |  | 			sequence: this.message?.sequence, | 
					
						
							|  |  |  | 			timestamp: this.message?.timestamp, | 
					
						
							|  |  |  | 			hash: this.message?.hash, | 
					
						
							|  |  |  | 			content: this.message?.content, | 
					
						
							|  |  |  | 			signature: this.message?.signature, | 
					
						
							| 
									
										
										
										
											2023-03-29 22:02:12 +00:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 		return html`<div style="white-space: pre-wrap">${JSON.stringify(raw, null, 2)}</div>`; | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vote(emoji) { | 
					
						
							| 
									
										
										
										
											2023-05-04 00:32:50 +00:00
										 |  |  | 		let reaction = emoji; | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 		let message = this.message.id; | 
					
						
							|  |  |  | 		if (confirm('Are you sure you want to react with ' + reaction + ' to ' + message + '?')) { | 
					
						
							|  |  |  | 			tfrpc.rpc.appendMessage( | 
					
						
							|  |  |  | 				this.whoami, | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					type: 'vote', | 
					
						
							|  |  |  | 					vote: { | 
					
						
							|  |  |  | 						link: message, | 
					
						
							|  |  |  | 						value: 1, | 
					
						
							|  |  |  | 						expression: reaction, | 
					
						
							|  |  |  | 					}, | 
					
						
							|  |  |  | 				}).catch(function(error) { | 
					
						
							|  |  |  | 					alert(error?.message); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	react(event) { | 
					
						
							|  |  |  | 		emojis.picker(x => this.vote(x)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-14 23:49:25 +00:00
										 |  |  | 	show_image(link) { | 
					
						
							|  |  |  | 		let div = document.createElement('div'); | 
					
						
							|  |  |  | 		div.style.left = 0; | 
					
						
							|  |  |  | 		div.style.top = 0; | 
					
						
							|  |  |  | 		div.style.width = '100%'; | 
					
						
							|  |  |  | 		div.style.height = '100%'; | 
					
						
							|  |  |  | 		div.style.position = 'fixed'; | 
					
						
							|  |  |  | 		div.style.background = '#000'; | 
					
						
							|  |  |  | 		div.style.zIndex = 100; | 
					
						
							|  |  |  | 		div.style.display = 'grid'; | 
					
						
							|  |  |  | 		let img = document.createElement('img'); | 
					
						
							|  |  |  | 		img.src = link; | 
					
						
							|  |  |  | 		img.style.maxWidth = '100%'; | 
					
						
							|  |  |  | 		img.style.maxHeight = '100%'; | 
					
						
							|  |  |  | 		img.style.display = 'block'; | 
					
						
							|  |  |  | 		img.style.margin = 'auto'; | 
					
						
							|  |  |  | 		img.style.objectFit = 'contain'; | 
					
						
							|  |  |  | 		img.style.width = '100%'; | 
					
						
							|  |  |  | 		div.appendChild(img); | 
					
						
							|  |  |  | 		function image_close(event) { | 
					
						
							|  |  |  | 			document.body.removeChild(div); | 
					
						
							|  |  |  | 			window.removeEventListener('keydown', image_close); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		div.onclick = image_close; | 
					
						
							|  |  |  | 		window.addEventListener('keydown', image_close); | 
					
						
							|  |  |  | 		document.body.appendChild(div); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 	body_click(event) { | 
					
						
							|  |  |  | 		if (event.srcElement.tagName == 'IMG') { | 
					
						
							|  |  |  | 			this.show_image(event.srcElement.src); | 
					
						
							| 
									
										
										
										
											2023-04-13 00:03:22 +00:00
										 |  |  | 		} else if (event.srcElement.tagName == 'DIV' && event.srcElement.classList.contains('img_caption')) { | 
					
						
							|  |  |  | 			let next = event.srcElement.nextSibling; | 
					
						
							|  |  |  | 			if (next.style.display == 'block') { | 
					
						
							|  |  |  | 				next.style.display = 'none'; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				next.style.display = 'block'; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-14 23:33:57 +00:00
										 |  |  | 	render_mention(mention) { | 
					
						
							| 
									
										
										
										
											2022-09-15 00:16:37 +00:00
										 |  |  | 		if (!mention?.link || typeof(mention.link) != 'string') { | 
					
						
							| 
									
										
										
										
											2022-10-21 23:31:32 +00:00
										 |  |  | 			return html` <pre>${JSON.stringify(mention)}</pre>`; | 
					
						
							| 
									
										
										
										
											2022-09-15 00:16:37 +00:00
										 |  |  | 		} else if (mention?.link?.startsWith('&') && | 
					
						
							|  |  |  | 			mention?.type?.startsWith('image/')) { | 
					
						
							| 
									
										
										
										
											2022-09-14 23:33:57 +00:00
										 |  |  | 			return html`
 | 
					
						
							| 
									
										
										
										
											2022-09-14 23:49:25 +00:00
										 |  |  | 				<img src=${'/' + mention.link + '/view'} style="max-width: 128px; max-height: 128px" title=${mention.name} @click=${() => this.show_image('/' + mention.link + '/view')}> | 
					
						
							| 
									
										
										
										
											2022-09-14 23:33:57 +00:00
										 |  |  | 			`;
 | 
					
						
							|  |  |  | 		} else if (mention.link?.startsWith('&') && | 
					
						
							|  |  |  | 			mention.name?.startsWith('audio:')) { | 
					
						
							|  |  |  | 			return html`
 | 
					
						
							|  |  |  | 				<audio controls style="height: 32px"> | 
					
						
							|  |  |  | 					<source src=${'/' + mention.link + '/view'}></source> | 
					
						
							|  |  |  | 				</audio> | 
					
						
							|  |  |  | 			`;
 | 
					
						
							| 
									
										
										
										
											2022-11-30 02:37:27 +00:00
										 |  |  | 		} else if (mention.link?.startsWith('&') && | 
					
						
							|  |  |  | 			mention.name?.startsWith('video:')) { | 
					
						
							|  |  |  | 			return html`
 | 
					
						
							| 
									
										
										
										
											2023-03-19 23:31:08 +00:00
										 |  |  | 				<video controls style="max-height: 240px; max-width: 128px"> | 
					
						
							| 
									
										
										
										
											2022-11-30 02:37:27 +00:00
										 |  |  | 					<source src=${'/' + mention.link + '/view'}></source> | 
					
						
							|  |  |  | 				</video> | 
					
						
							|  |  |  | 			`;
 | 
					
						
							| 
									
										
										
										
											2022-10-16 00:54:16 +00:00
										 |  |  | 		} else if (mention.link?.startsWith('&') && | 
					
						
							|  |  |  | 			mention?.type === 'application/tildefriends') { | 
					
						
							| 
									
										
										
										
											2022-10-21 23:31:32 +00:00
										 |  |  | 			return html` <a href=${`/${mention.link}/`}>😎 ${mention.name}</a>`; | 
					
						
							| 
									
										
										
										
											2022-09-14 23:33:57 +00:00
										 |  |  | 		} else if (mention.link?.startsWith('%') || mention.link?.startsWith('@')) { | 
					
						
							|  |  |  | 			return html` <a href=${'#' + encodeURIComponent(mention.link)}>${mention.name}</a>`; | 
					
						
							|  |  |  | 		} else if (mention.link?.startsWith('#')) { | 
					
						
							|  |  |  | 			return html` <a href=${'#q=' + encodeURIComponent(mention.link)}>${mention.link}</a>`; | 
					
						
							| 
									
										
										
										
											2022-10-21 23:31:32 +00:00
										 |  |  | 		} else if (Object.keys(mention).length == 2 && mention.link && mention.name) { | 
					
						
							|  |  |  | 			return html` <a href=${`/${mention.link}/view`}>${mention.name}</a>`; | 
					
						
							| 
									
										
										
										
											2022-09-14 23:33:57 +00:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2022-10-21 23:31:32 +00:00
										 |  |  | 			return html` <pre style="white-space: pre-wrap">${JSON.stringify(mention, null, 2)}</pre>`; | 
					
						
							| 
									
										
										
										
											2022-09-14 23:33:57 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	render_mentions() { | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 		let mentions = this.message?.content?.mentions || []; | 
					
						
							| 
									
										
										
										
											2023-04-12 00:32:14 +00:00
										 |  |  | 		mentions = mentions.filter(x => this.message?.content?.text?.indexOf(x.link) === -1); | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 		if (mentions.length) { | 
					
						
							| 
									
										
										
										
											2022-09-14 23:33:57 +00:00
										 |  |  | 			let self = this; | 
					
						
							|  |  |  | 			return html`
 | 
					
						
							|  |  |  | 				<fieldset style="background-color: rgba(0, 0, 0, 0.1); padding: 0.5em; border: 1px solid black"> | 
					
						
							|  |  |  | 					<legend>Mentions</legend> | 
					
						
							| 
									
										
										
										
											2022-10-16 00:54:16 +00:00
										 |  |  | 					${mentions.map(x => self.render_mention(x))} | 
					
						
							| 
									
										
										
										
											2022-09-14 23:33:57 +00:00
										 |  |  | 				</fieldset> | 
					
						
							|  |  |  | 			`;
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-21 18:58:49 +00:00
										 |  |  | 	total_child_messages(message) { | 
					
						
							|  |  |  | 		if (!message.child_messages) { | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		let total = message.child_messages.length; | 
					
						
							|  |  |  | 		for (let m of message.child_messages) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			total += this.total_child_messages(m); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return total; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-26 02:08:14 +00:00
										 |  |  | 	set_expanded(expanded, tag) { | 
					
						
							|  |  |  | 		this.dispatchEvent(new CustomEvent('tf-expand', {bubbles: true, composed: true, detail: {id: (this.message.id || '') + (tag || ''), expanded: expanded}})); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	toggle_expanded(tag) { | 
					
						
							|  |  |  | 		this.set_expanded(!this.expanded[(this.message.id || '') + (tag || '')], tag); | 
					
						
							| 
									
										
										
										
											2023-01-25 00:56:10 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-18 22:31:54 +00:00
										 |  |  | 	render_children() { | 
					
						
							|  |  |  | 		let self = this; | 
					
						
							| 
									
										
										
										
											2022-12-28 17:17:44 +00:00
										 |  |  | 		if (this.message.child_messages?.length) { | 
					
						
							| 
									
										
										
										
											2023-01-25 00:56:10 +00:00
										 |  |  | 			if (!this.expanded[this.message.id]) { | 
					
						
							|  |  |  | 				return html`<input type="button" value=${this.total_child_messages(this.message) + ' More'} @click=${() => self.set_expanded(true)}></input>`; | 
					
						
							| 
									
										
										
										
											2022-12-28 17:17:44 +00:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2023-01-25 00:56:10 +00:00
										 |  |  | 				return html`<input type="button" value="Collapse" @click=${() => self.set_expanded(false)}></input>${(this.message.child_messages || []).map(x => html`<tf-message .message=${x} whoami=${this.whoami} .users=${this.users} .drafts=${this.drafts} .expanded=${this.expanded}></tf-message>`)}`; | 
					
						
							| 
									
										
										
										
											2022-12-28 17:17:44 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2022-10-18 22:31:54 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-17 14:10:49 +00:00
										 |  |  | 	async try_decrypt(content) { | 
					
						
							|  |  |  | 		this.decrypted = JSON.parse(await tfrpc.rpc.try_decrypt(this.whoami, content)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 	render() { | 
					
						
							|  |  |  | 		let content = this.message?.content; | 
					
						
							| 
									
										
										
										
											2023-05-17 14:10:49 +00:00
										 |  |  | 		if (this.decrypted?.type == 'post') { | 
					
						
							|  |  |  | 			content = this.decrypted; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 		let self = this; | 
					
						
							|  |  |  | 		let raw_button = this.raw ? | 
					
						
							|  |  |  | 				html`<input type="button" value="Message" @click=${() => self.raw = false}></input>` : | 
					
						
							|  |  |  | 				html`<input type="button" value="Raw" @click=${() => self.raw = true}></input>`; | 
					
						
							|  |  |  | 		function small_frame(inner) { | 
					
						
							|  |  |  | 			return html`
 | 
					
						
							| 
									
										
										
										
											2023-03-19 23:31:08 +00:00
										 |  |  | 				<div style="border: 1px solid black; background-color: rgba(255, 255, 255, 0.1); margin-top: 8px; padding: 16px; display: inline-block; overflow-wrap: anywhere"> | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 					<tf-user id=${self.message.author} .users=${self.users}></tf-user> | 
					
						
							| 
									
										
										
										
											2022-10-09 12:23:25 +00:00
										 |  |  | 					<span style="padding-right: 8px"><a tfarget="_top" href=${'#' + self.message.id}>%</a> ${new Date(self.message.timestamp).toLocaleString()}</span> | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 					${raw_button} | 
					
						
							|  |  |  | 					${self.raw ? self.render_raw() : inner} | 
					
						
							|  |  |  | 					${self.render_votes()} | 
					
						
							|  |  |  | 				</div> | 
					
						
							| 
									
										
										
										
											2023-03-29 22:02:12 +00:00
										 |  |  | 			`;
 | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-03-19 23:31:08 +00:00
										 |  |  | 		if (this.message?.type === 'contact_group') { | 
					
						
							|  |  |  | 			return html`
 | 
					
						
							|  |  |  | 				<div style="border: 1px solid black; background-color: rgba(255, 255, 255, 0.1); margin-top: 8px; padding: 16px; overflow-wrap: anywhere"> | 
					
						
							|  |  |  | 					${this.message.messages.map(x =>  | 
					
						
							|  |  |  | 						html`<tf-message .message=${x} whoami=${this.whoami} .users=${this.users} .drafts=${this.drafts} .expanded=${this.expanded}></tf-message>` | 
					
						
							|  |  |  | 					)} | 
					
						
							|  |  |  | 				</div>`; | 
					
						
							|  |  |  | 		} else if (this.message.placeholder) { | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 			return html`
 | 
					
						
							| 
									
										
										
										
											2022-10-05 02:11:46 +00:00
										 |  |  | 				<div style="border: 1px solid black; background-color: rgba(255, 255, 255, 0.1); margin-top: 8px; padding: 16px; overflow-wrap: anywhere"> | 
					
						
							| 
									
										
										
										
											2022-10-18 22:31:54 +00:00
										 |  |  | 					<a target="_top" href=${'#' + this.message.id}>${this.message.id}</a> (placeholder) | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 					<div>${this.render_votes()}</div> | 
					
						
							|  |  |  | 					${(this.message.child_messages || []).map(x => html`
 | 
					
						
							| 
									
										
										
										
											2023-01-25 00:56:10 +00:00
										 |  |  | 						<tf-message .message=${x} whoami=${this.whoami} .users=${this.users} .drafts=${this.drafts} .expanded=${this.expanded}></tf-message> | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 					`)}
 | 
					
						
							|  |  |  | 				</div>`; | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 		} else if (typeof(content?.type === 'string')) { | 
					
						
							|  |  |  | 			if (content.type == 'about') { | 
					
						
							| 
									
										
										
										
											2022-12-24 18:50:01 +00:00
										 |  |  | 				let name; | 
					
						
							|  |  |  | 				let image; | 
					
						
							|  |  |  | 				let description; | 
					
						
							|  |  |  | 				if (content.name !== undefined) { | 
					
						
							|  |  |  | 					name = html`<div><b>Name:</b> ${content.name}</div>`; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (content.image !== undefined) { | 
					
						
							|  |  |  | 					image = html`
 | 
					
						
							| 
									
										
										
										
											2023-01-21 00:21:26 +00:00
										 |  |  | 						<div><img src=${'/' + (typeof(content.image?.link) == 'string' ? content.image.link : content.image) + '/view'} style="width: 256px; height: auto"></img></div> | 
					
						
							| 
									
										
										
										
											2022-12-24 18:50:01 +00:00
										 |  |  | 					`;
 | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (content.description !== undefined) { | 
					
						
							|  |  |  | 					description = html`
 | 
					
						
							| 
									
										
										
										
											2023-01-22 17:25:37 +00:00
										 |  |  | 						<div style="flex: 1 0 50%; overflow-wrap: anywhere"> | 
					
						
							| 
									
										
										
										
											2022-12-24 18:50:01 +00:00
										 |  |  | 							<div>${unsafeHTML(tfutils.markdown(content.description))}</div> | 
					
						
							|  |  |  | 						</div> | 
					
						
							| 
									
										
										
										
											2023-03-29 22:02:12 +00:00
										 |  |  | 					`;
 | 
					
						
							| 
									
										
										
										
											2022-12-24 18:50:01 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2023-01-22 17:25:37 +00:00
										 |  |  | 				let update = content.about == this.message.author ? | 
					
						
							|  |  |  | 					html`<div style="font-weight: bold">Updated profile.</div>` : | 
					
						
							|  |  |  | 					html`<div style="font-weight: bold">Updated profile for <tf-user id=${content.about} .users=${this.users}></tf-user>.</div>`; | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 				return small_frame(html`
 | 
					
						
							| 
									
										
										
										
											2023-01-22 17:25:37 +00:00
										 |  |  | 					${update} | 
					
						
							| 
									
										
										
										
											2022-12-24 18:50:01 +00:00
										 |  |  | 					${name} | 
					
						
							|  |  |  | 					${image} | 
					
						
							|  |  |  | 					${description} | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 				`);
 | 
					
						
							|  |  |  | 			} else if (content.type == 'contact') { | 
					
						
							| 
									
										
										
										
											2023-03-19 23:31:08 +00:00
										 |  |  | 				return html`
 | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 					<div> | 
					
						
							| 
									
										
										
										
											2023-03-19 23:31:08 +00:00
										 |  |  | 						<tf-user id=${this.message.author} .users=${this.users}></tf-user> | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 						is | 
					
						
							|  |  |  | 						${ | 
					
						
							|  |  |  | 							content.blocking === true ? 'blocking' : | 
					
						
							|  |  |  | 							content.blocking === false ? 'no longer blocking' : | 
					
						
							|  |  |  | 							content.following === true ? 'following' : | 
					
						
							|  |  |  | 							content.following === false ? 'no longer following' : | 
					
						
							|  |  |  | 							'?' | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						<tf-user id=${this.message.content.contact} .users=${this.users}></tf-user> | 
					
						
							|  |  |  | 					</div> | 
					
						
							| 
									
										
										
										
											2023-03-19 23:31:08 +00:00
										 |  |  | 				`;
 | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 			} else if (content.type == 'post') { | 
					
						
							| 
									
										
										
										
											2023-01-21 00:16:18 +00:00
										 |  |  | 				let reply = (this.drafts[this.message?.id] !== undefined) ? html`
 | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 					<tf-compose | 
					
						
							|  |  |  | 						whoami=${this.whoami} | 
					
						
							|  |  |  | 						.users=${this.users} | 
					
						
							|  |  |  | 						root=${this.message.content.root || this.message.id} | 
					
						
							|  |  |  | 						branch=${this.message.id} | 
					
						
							| 
									
										
										
										
											2023-01-21 19:12:55 +00:00
										 |  |  | 						.drafts=${this.drafts} | 
					
						
							| 
									
										
										
										
											2023-01-21 00:16:18 +00:00
										 |  |  | 						@tf-discard=${this.discard_reply}></tf-compose> | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 				` : html` | 
					
						
							|  |  |  | 					<input type="button" value="Reply" @click=${this.show_reply}></input> | 
					
						
							|  |  |  | 				`;
 | 
					
						
							|  |  |  | 				let self = this; | 
					
						
							|  |  |  | 				let body = this.raw ? | 
					
						
							|  |  |  | 					this.render_raw() : | 
					
						
							|  |  |  | 					unsafeHTML(tfutils.markdown(content.text)); | 
					
						
							| 
									
										
										
										
											2022-11-19 02:06:23 +00:00
										 |  |  | 				let content_warning = html`
 | 
					
						
							| 
									
										
										
										
											2023-01-30 01:45:23 +00:00
										 |  |  | 					<div class="content_warning" @click=${x => this.toggle_expanded(':cw')}>${content.contentWarning}</div> | 
					
						
							| 
									
										
										
										
											2022-11-19 02:06:23 +00:00
										 |  |  | 					`;
 | 
					
						
							|  |  |  | 				let content_html = | 
					
						
							|  |  |  | 					html`
 | 
					
						
							|  |  |  | 						<div @click=${this.body_click}>${body}</div> | 
					
						
							|  |  |  | 						${this.render_mentions()} | 
					
						
							|  |  |  | 					`;
 | 
					
						
							|  |  |  | 				let payload = | 
					
						
							|  |  |  | 					content.contentWarning ? | 
					
						
							| 
									
										
										
										
											2023-01-26 02:08:14 +00:00
										 |  |  | 						self.expanded[(this.message.id || '') + ':cw'] ? | 
					
						
							| 
									
										
										
										
											2022-11-19 02:06:23 +00:00
										 |  |  | 							html`
 | 
					
						
							|  |  |  | 								${content_warning} | 
					
						
							|  |  |  | 								${content_html} | 
					
						
							|  |  |  | 							` :
 | 
					
						
							|  |  |  | 							content_warning : | 
					
						
							|  |  |  | 						content_html; | 
					
						
							| 
									
										
										
										
											2023-05-17 14:10:49 +00:00
										 |  |  | 				let is_encrypted = this.decrypted ? html`<span style="align-self: center">🔓</span>` : undefined; | 
					
						
							|  |  |  | 				let style_background = this.decrypted ? 'rgba(255, 0, 0, 0.2)' : 'rgba(255, 255, 255, 0.1)'; | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 				return html`
 | 
					
						
							|  |  |  | 					<style> | 
					
						
							|  |  |  | 						code { | 
					
						
							|  |  |  | 							white-space: pre-wrap; | 
					
						
							|  |  |  | 							overflow-wrap: break-word; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2022-10-05 02:11:46 +00:00
										 |  |  | 						div { | 
					
						
							|  |  |  | 							overflow-wrap: anywhere; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 						img { | 
					
						
							|  |  |  | 							max-width: 100%; | 
					
						
							|  |  |  | 							height: auto; | 
					
						
							| 
									
										
										
										
											2022-11-17 00:30:58 +00:00
										 |  |  | 							display: block; | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					</style> | 
					
						
							| 
									
										
										
										
											2023-05-17 14:10:49 +00:00
										 |  |  | 					<div style="border: 1px solid black; background-color: ${style_background}; margin-top: 8px; padding: 16px"> | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 						<div style="display: flex; flex-direction: row"> | 
					
						
							|  |  |  | 							<tf-user id=${this.message.author} .users=${this.users}></tf-user> | 
					
						
							| 
									
										
										
										
											2023-05-17 14:10:49 +00:00
										 |  |  | 							${is_encrypted} | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 							<span style="flex: 1"></span> | 
					
						
							|  |  |  | 							<span style="padding-right: 8px"><a target="_top" href=${'#' + self.message.id}>%</a> ${new Date(this.message.timestamp).toLocaleString()}</span> | 
					
						
							|  |  |  | 							<span>${raw_button}</span> | 
					
						
							|  |  |  | 						</div> | 
					
						
							| 
									
										
										
										
											2022-11-19 02:06:23 +00:00
										 |  |  | 						${payload} | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 						${this.render_votes()} | 
					
						
							|  |  |  | 						<div> | 
					
						
							|  |  |  | 							${reply} | 
					
						
							|  |  |  | 							<input type="button" value="React" @click=${this.react}></input> | 
					
						
							|  |  |  | 						</div> | 
					
						
							| 
									
										
										
										
											2022-10-18 22:31:54 +00:00
										 |  |  | 						${this.render_children()} | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 					</div> | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 				`;
 | 
					
						
							| 
									
										
										
										
											2022-12-03 02:18:48 +00:00
										 |  |  | 			} else if (content.type === 'blog') { | 
					
						
							|  |  |  | 				let self = this; | 
					
						
							|  |  |  | 				tfrpc.rpc.get_blob(content.blog).then(function(data) { | 
					
						
							|  |  |  | 					self.blog_data = data; | 
					
						
							|  |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2022-12-03 14:58:44 +00:00
										 |  |  | 				let payload = | 
					
						
							| 
									
										
										
										
											2023-01-26 02:08:14 +00:00
										 |  |  | 						this.expanded[(this.message.id || '') + ':blog'] ? | 
					
						
							| 
									
										
										
										
											2022-12-03 14:58:44 +00:00
										 |  |  | 						html`<div>${this.blog_data ? unsafeHTML(tfutils.markdown(this.blog_data)) : 'Loading...'}</div>` : | 
					
						
							|  |  |  | 						undefined; | 
					
						
							| 
									
										
										
										
											2022-12-03 02:18:48 +00:00
										 |  |  | 				let body = this.raw ? | 
					
						
							|  |  |  | 						this.render_raw() : | 
					
						
							|  |  |  | 						html`
 | 
					
						
							| 
									
										
										
										
											2022-12-03 14:58:44 +00:00
										 |  |  | 							<div | 
					
						
							|  |  |  | 								style="border: 1px solid #fff; border-radius: 1em; padding: 8px; margin: 4px; cursor: pointer" | 
					
						
							| 
									
										
										
										
											2023-01-26 02:08:14 +00:00
										 |  |  | 								@click=${x => self.toggle_expanded(':blog')}> | 
					
						
							| 
									
										
										
										
											2022-12-03 14:58:44 +00:00
										 |  |  | 								<h2>${content.title}</h2> | 
					
						
							|  |  |  | 								<div style="display: flex; flex-direction: row"> | 
					
						
							|  |  |  | 									<img src=/${content.thumbnail}/view></img> | 
					
						
							|  |  |  | 									<span>${content.summary}</span> | 
					
						
							|  |  |  | 								</div> | 
					
						
							| 
									
										
										
										
											2022-12-03 02:18:48 +00:00
										 |  |  | 							</div> | 
					
						
							| 
									
										
										
										
											2022-12-03 14:58:44 +00:00
										 |  |  | 							${payload} | 
					
						
							| 
									
										
										
										
											2022-12-03 02:18:48 +00:00
										 |  |  | 						`;
 | 
					
						
							|  |  |  | 				return html`
 | 
					
						
							|  |  |  | 					<style> | 
					
						
							|  |  |  | 						code { | 
					
						
							|  |  |  | 							white-space: pre-wrap; | 
					
						
							|  |  |  | 							overflow-wrap: break-word; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						div { | 
					
						
							|  |  |  | 							overflow-wrap: anywhere; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						img { | 
					
						
							|  |  |  | 							max-width: 100%; | 
					
						
							|  |  |  | 							height: auto; | 
					
						
							|  |  |  | 							display: block; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					</style> | 
					
						
							|  |  |  | 					<div style="border: 1px solid black; background-color: rgba(255, 255, 255, 0.1); margin-top: 8px; padding: 16px"> | 
					
						
							|  |  |  | 						<div style="display: flex; flex-direction: row"> | 
					
						
							|  |  |  | 							<tf-user id=${this.message.author} .users=${this.users}></tf-user> | 
					
						
							|  |  |  | 							<span style="flex: 1"></span> | 
					
						
							|  |  |  | 							<span style="padding-right: 8px"><a target="_top" href=${'#' + self.message.id}>%</a> ${new Date(this.message.timestamp).toLocaleString()}</span> | 
					
						
							|  |  |  | 							<span>${raw_button}</span> | 
					
						
							|  |  |  | 						</div> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						<div>${body}</div> | 
					
						
							|  |  |  | 						${this.render_mentions()} | 
					
						
							|  |  |  | 						${this.render_votes()} | 
					
						
							|  |  |  | 					</div> | 
					
						
							|  |  |  | 				`;
 | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 			} else if (content.type === 'pub') { | 
					
						
							|  |  |  | 				return small_frame(html`
 | 
					
						
							| 
									
										
										
										
											2023-02-23 01:29:54 +00:00
										 |  |  | 				<style> | 
					
						
							|  |  |  | 					span { | 
					
						
							|  |  |  | 						overflow-wrap: anywhere; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				</style> | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 				<span> | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 					<div> | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 						🍻 <tf-user .users=${this.users} id=${content.address.key}></tf-user> | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 					</div> | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 					<pre>${content.address.host}:${content.address.port}</pre> | 
					
						
							|  |  |  | 				</span>`); | 
					
						
							| 
									
										
										
										
											2022-12-07 23:37:06 +00:00
										 |  |  | 			} else if (content.type === 'channel') { | 
					
						
							|  |  |  | 				return small_frame(html`
 | 
					
						
							|  |  |  | 					<div> | 
					
						
							|  |  |  | 						${content.subscribed ? 'subscribed to' : 'unsubscribed from'} <a href=${'#q=' + encodeURIComponent('#' + content.channel)}>#${content.channel}</a> | 
					
						
							|  |  |  | 					</div> | 
					
						
							|  |  |  | 				`);
 | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 			} else if (typeof(this.message.content) == 'string') { | 
					
						
							| 
									
										
										
										
											2023-05-17 14:10:49 +00:00
										 |  |  | 				if (this.decrypted !== undefined) { | 
					
						
							|  |  |  | 					return small_frame(html`<span>🔓</span><pre>${JSON.stringify(this.decrypted, null, 2)}</pre>`); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					this.try_decrypt(content); | 
					
						
							|  |  |  | 					return small_frame(html`<span>🔐</span>`); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2022-09-25 12:33:54 +00:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				return small_frame(html`<div><b>type</b>: ${content.type}</div>`); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2022-09-06 23:26:43 +00:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			return small_frame(this.render_raw()); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | customElements.define('tf-message', TfMessageElement); |