forked from cory/tildefriends
		
	Accrued fixes, most recently making an effort to show all mentions.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3982 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		| @@ -1 +1 @@ | ||||
| {"type":"tildefriends-app","files":{"app.js":"&viCT+Sz8weP/j5V47w0wA4sk46HM4uy6lajX5NtoqHE=.sha256","lit-all.min.js":"&N4A12AsifdQgwdpII0SFtG513BfoLpmPjdJ9VTDftpg=.sha256","index.html":"&WH8A5tF25xlfPDGei2TCQc2/HJFJf5DuRN1GRSYQhhk=.sha256","script.js":"&G8puK9Q4MngHy3D4ppcKyT49WKbHD2OCeUcAw2ghTDE=.sha256","lit-all.min.js.map":"&oFY9wO4MnujgfGNGv4VggHc5V5JwX4C8csqKZ6KJYbE=.sha256","tf-id-picker.js":"&pg1gLK150HFai73TcmAe5E/dMpMqmbhyre/+/J4XmHo=.sha256","tf-app.js":"&Zt1x1urnzk0D9TxQvgJqOjdHelW+bei7CRupODgvAsk=.sha256","tf-message.js":"&KE1fWTqPMZR0yIRXPBGy8u1chR6LTguSK6swo+lFgE4=.sha256","tf-user.js":"&L6+7BnBq+UOoTMO6o8+u5JFTl0UBtCPDw8bb8ppDrkA=.sha256","tf-utils.js":"&N2yKZwFnb2GbPeipgQtu6xFvezENNOgud9G7EhCQ/K0=.sha256","commonmark.min.js":"&bfBaMLU19d1p/vPBF9hlARqDX002KXG/UOfxOahZhe4=.sha256","tf-compose.js":"&oo0iWvT+c2rU91zWpBIfPePRzmU8qmSnVOm+QCQqG/I=.sha256","emojis.json":"&h3P4pez+AI4aYdsN0dJ3pbUEFR0276t9AM20caj/W/s=.sha256","emojis.js":"&htPMi2z6Bmgi3f9jCnECCDZRCHACnDRjOl1kgPm+W80=.sha256","tf-styles.js":"&BkvFkMpGyL0DYP6FISFKR4pe6ZBOp8t6tQEzWZ4IQYs=.sha256","tf-profile.js":"&vRKjsnYvOiHCQahzEfznCvP5YDwUPtltlpWf+pxwZ1Y=.sha256","commonmark-linkify.js":"&X+hNNkmSRvKY86khyAun+cXksquXbMakZdINbGbx30g=.sha256","tf-tab-search.js":"&Q4bstnLzTPmCKJP+cf7FfRZJVuGAltEely4oIovUVaI=.sha256","tf-tab-news.js":"&Pc/FkHOPRPyWZi/znjquVtXeykzqqFygVuNm0dxrwlI=.sha256","tf-tab-connections.js":"&jSnF/5NmgqxRze1XQAEGOW5mPzOV1/8aCyrDRZu34IQ=.sha256","tf-news.js":"&C1dKe98kQOkClnAbGvcreC15IdlTrD9J4RFohspnsSE=.sha256"}} | ||||
| {"type":"tildefriends-app","files":{"app.js":"&viCT+Sz8weP/j5V47w0wA4sk46HM4uy6lajX5NtoqHE=.sha256","lit-all.min.js":"&N4A12AsifdQgwdpII0SFtG513BfoLpmPjdJ9VTDftpg=.sha256","index.html":"&WH8A5tF25xlfPDGei2TCQc2/HJFJf5DuRN1GRSYQhhk=.sha256","script.js":"&G8puK9Q4MngHy3D4ppcKyT49WKbHD2OCeUcAw2ghTDE=.sha256","lit-all.min.js.map":"&oFY9wO4MnujgfGNGv4VggHc5V5JwX4C8csqKZ6KJYbE=.sha256","tf-id-picker.js":"&pg1gLK150HFai73TcmAe5E/dMpMqmbhyre/+/J4XmHo=.sha256","tf-app.js":"&F64EHiKTMf/65Cc0w/F7oFbBcUOn7uTAjFBPd5rymSs=.sha256","tf-message.js":"&AFDKCN+hxYDs7zG8PBKmle11gE/2AIMzYr3FYz1hCto=.sha256","tf-user.js":"&L6+7BnBq+UOoTMO6o8+u5JFTl0UBtCPDw8bb8ppDrkA=.sha256","tf-utils.js":"&N2yKZwFnb2GbPeipgQtu6xFvezENNOgud9G7EhCQ/K0=.sha256","commonmark.min.js":"&bfBaMLU19d1p/vPBF9hlARqDX002KXG/UOfxOahZhe4=.sha256","tf-compose.js":"&oo0iWvT+c2rU91zWpBIfPePRzmU8qmSnVOm+QCQqG/I=.sha256","emojis.json":"&h3P4pez+AI4aYdsN0dJ3pbUEFR0276t9AM20caj/W/s=.sha256","emojis.js":"&pqYLDE/13PyEt2ceeFqvnwZ8NqWfPfpDBt4vP8SeHbs=.sha256","tf-styles.js":"&Ab+SjsySJ74kwK3EQD/j72yXYJlFAhkJ5EqyJfYpJEk=.sha256","tf-profile.js":"&vRKjsnYvOiHCQahzEfznCvP5YDwUPtltlpWf+pxwZ1Y=.sha256","commonmark-linkify.js":"&X+hNNkmSRvKY86khyAun+cXksquXbMakZdINbGbx30g=.sha256","tf-tab-search.js":"&NUGpMnLR3eYwrdjZaJAd8s4Rj+WPazJhWWX5jkMdNRI=.sha256","tf-tab-news.js":"&ehXkzOR+kQmiTHRtu5GPDMwrB4a4Z9vVsTo4ldhdu/E=.sha256","tf-tab-connections.js":"&jSnF/5NmgqxRze1XQAEGOW5mPzOV1/8aCyrDRZu34IQ=.sha256","tf-news.js":"&C1dKe98kQOkClnAbGvcreC15IdlTrD9J4RFohspnsSE=.sha256"}} | ||||
| @@ -38,7 +38,6 @@ export function picker(callback, anchor) { | ||||
| 				list.removeChild(list.firstChild); | ||||
| 			} | ||||
| 			let search = input.value; | ||||
| 			console.log('refresh', search); | ||||
| 			Object.entries(json).forEach(function(row) { | ||||
| 				let header = document.createElement('div'); | ||||
| 				header.appendChild(document.createTextNode(row[0])); | ||||
|   | ||||
| @@ -11,6 +11,10 @@ class TfElement extends LitElement { | ||||
| 			tab: {type: String}, | ||||
| 			broadcasts: {type: Array}, | ||||
| 			connections: {type: Array}, | ||||
| 			loading: {type: Boolean}, | ||||
| 			loaded: {type: Boolean}, | ||||
| 			following: {type: Array}, | ||||
| 			users: {type: Object}, | ||||
| 		}; | ||||
| 	} | ||||
|  | ||||
| @@ -24,6 +28,9 @@ class TfElement extends LitElement { | ||||
| 		this.tab = 'news'; | ||||
| 		this.broadcasts = []; | ||||
| 		this.connections = []; | ||||
| 		this.following = []; | ||||
| 		this.users = {}; | ||||
| 		this.loaded = false; | ||||
| 		tfrpc.rpc.getBroadcasts().then(b => { self.broadcasts = b || [] }); | ||||
| 		tfrpc.rpc.getConnections().then(c => { self.connections = c || [] }); | ||||
| 		tfrpc.rpc.getHash().then(hash => self.hash = hash || '#'); | ||||
| @@ -40,9 +47,7 @@ class TfElement extends LitElement { | ||||
| 				self.connections = value; | ||||
| 			} | ||||
| 		}); | ||||
| 		tfrpc.rpc.localStorageGet('whoami').then(function(value) { | ||||
| 			self.whoami = value; | ||||
| 		}); | ||||
| 		tfrpc.rpc.localStorageGet('whoami').then(whoami => self.whoami = whoami); | ||||
| 	} | ||||
|  | ||||
| 	async contacts_internal(id, last_row_id, following, max_row_id) { | ||||
| @@ -71,31 +76,29 @@ class TfElement extends LitElement { | ||||
| 				delete result.blocking[contact.contact]; | ||||
| 			} | ||||
| 		} | ||||
| 		following[id] = result; | ||||
| 		return result; | ||||
| 	} | ||||
|  | ||||
| 	async contact(id, last_row_id, following, max_row_id, contact_cache) { | ||||
| 		let result = await this.contacts_internal(id, last_row_id, following, max_row_id); | ||||
| 		contact_cache[id] = Object.assign(contact_cache[id] || {}, result); | ||||
| 		following[id] = contact_cache[id]; | ||||
| 		return result; | ||||
| 	async contact(id, last_row_id, following, max_row_id) { | ||||
| 		return await this.contacts_internal(id, last_row_id, following, max_row_id); | ||||
| 	} | ||||
|  | ||||
| 	async following_deep_internal(ids, depth, blocking, last_row_id, following, max_row_id, contact_cache) { | ||||
| 		let contacts = await Promise.all([...new Set(ids)].map(x => this.contact(x, last_row_id, following, max_row_id, contact_cache))); | ||||
| 	async following_deep_internal(ids, depth, blocking, last_row_id, following, max_row_id) { | ||||
| 		let contacts = await Promise.all([...new Set(ids)].map(x => this.contact(x, last_row_id, following, max_row_id))); | ||||
| 		let result = {}; | ||||
| 		for (let i = 0; i < ids.length; i++) { | ||||
| 			let id = ids[i]; | ||||
| 			let contact = contacts[i]; | ||||
| 			let found = Object.keys(contact.following).filter(y => !contact.blocking[y]); | ||||
| 			let deeper = depth > 1 ? await this.following_deep_internal(found, depth - 1, Object.assign({}, contact.blocking, blocking), last_row_id, following, max_row_id, contact_cache) : []; | ||||
| 			let deeper = depth > 1 ? await this.following_deep_internal(found, depth - 1, Object.assign({}, contact.blocking, blocking), last_row_id, following, max_row_id) : []; | ||||
| 			result[id] = [id, ...found, ...deeper]; | ||||
| 		} | ||||
| 		return [...new Set(Object.values(result).flat())]; | ||||
| 	} | ||||
|  | ||||
| 	async following_deep(ids, depth, blocking) { | ||||
| 		const k_cache_version = 4; | ||||
| 		const k_cache_version = 5; | ||||
| 		let cache = await tfrpc.rpc.databaseGet('following'); | ||||
| 		cache = cache ? JSON.parse(cache) : {}; | ||||
| 		if (cache.version !== k_cache_version) { | ||||
| @@ -105,14 +108,14 @@ class TfElement extends LitElement { | ||||
| 				last_row_id: 0, | ||||
| 			}; | ||||
| 		} | ||||
| 		let contact_cache = {}; | ||||
| 		let max_row_id = (await tfrpc.rpc.query(` | ||||
| 			SELECT MAX(rowid) AS max_row_id FROM messages | ||||
| 		`, []))[0].max_row_id; | ||||
| 		let result = await this.following_deep_internal(ids, depth, blocking, cache.last_row_id, cache.following, max_row_id, contact_cache); | ||||
| 		let result = await this.following_deep_internal(ids, depth, blocking, cache.last_row_id, cache.following, max_row_id); | ||||
| 		cache.last_row_id = max_row_id; | ||||
| 		await tfrpc.rpc.databaseSet('following', JSON.stringify(cache)); | ||||
| 		return result; | ||||
| 		console.log(cache); | ||||
| 		return [result, cache.following]; | ||||
| 	} | ||||
|  | ||||
| 	async fetch_about(ids, users) { | ||||
| @@ -191,24 +194,16 @@ class TfElement extends LitElement { | ||||
| 				WHERE messages.id = ? | ||||
| 			`, | ||||
| 			[ | ||||
| 				JSON.stringify(this.allFollowing), | ||||
| 				JSON.stringify(this.following), | ||||
| 				id, | ||||
| 			]); | ||||
| 		let self = this; | ||||
| 		let mine = messages.filter(m => m.author === self.whoami); | ||||
| 		if (mine.length) { | ||||
| 			this.process_messages(mine); | ||||
| 			await this.finalize_messages(); | ||||
| 		} | ||||
| 		let other = messages.filter(m => m.author !== self.whoami); | ||||
| 		if (other.length) { | ||||
| 			this.unread = [...this.unread, ...other]; | ||||
| 		if (messages && messages.length) { | ||||
| 			this.unread = [...this.unread, ...messages]; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	_handle_whoami_changed(event) { | ||||
| 		if (this.whoami !== event.srcElement.selected) { | ||||
| 			console.log('whoami changed', event.srcElement.selected); | ||||
| 			this.whoami = event.srcElement.selected; | ||||
| 		} | ||||
| 	} | ||||
| @@ -228,26 +223,58 @@ class TfElement extends LitElement { | ||||
| 		`; | ||||
| 	} | ||||
|  | ||||
| 	async render_tab() { | ||||
| 		let following = await this.following_deep([this.whoami], 2, {}); | ||||
| 		let users = await this.fetch_about(following.sort()); | ||||
| 	async load() { | ||||
| 		let whoami = this.whoami; | ||||
| 		let [following, users] = await this.following_deep([whoami], 2, {}); | ||||
| 		users = await this.fetch_about(following.sort(), users); | ||||
| 		this.following = following; | ||||
| 		this.users = users; | ||||
| 		this.whoami = whoami; | ||||
| 		this.loaded = whoami; | ||||
| 	} | ||||
|  | ||||
| 	render_tab() { | ||||
| 		let following = this.following; | ||||
| 		let users = this.users; | ||||
| 		if (this.tab === 'news') { | ||||
| 			return html` | ||||
| 				<tf-tab-news .following=${following} whoami=${this.whoami} .users=${users} hash=${this.hash} .unread=${this.unread} @refresh=${() => this.unread = []}></tf-tab-news> | ||||
| 				<tf-tab-news .following=${this.following} whoami=${this.whoami} .users=${this.users} hash=${this.hash} .unread=${this.unread} @refresh=${() => this.unread = []}></tf-tab-news> | ||||
| 			`; | ||||
| 		} else if (this.tab === 'connections') { | ||||
| 			return html` | ||||
| 				<tf-tab-connections .users=${users} .connections=${this.connections} .broadcasts=${this.broadcasts}></tf-tab-connections> | ||||
| 				<tf-tab-connections .users=${this.users} .connections=${this.connections} .broadcasts=${this.broadcasts}></tf-tab-connections> | ||||
| 			`; | ||||
| 		} else if (this.tab === 'search') { | ||||
| 			return html` | ||||
| 				<tf-tab-search .following=${following} whoami=${this.whoami} .users=${users}></tf-tab-search> | ||||
| 				<tf-tab-search .following=${this.following} whoami=${this.whoami} .users=${this.users}></tf-tab-search> | ||||
| 			`; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	add_fake_news() { | ||||
| 		this.unread = [{ | ||||
| 			author: this.whoami, | ||||
| 			placeholder: true, | ||||
| 			id: '%fake_id', | ||||
| 			text: 'text', | ||||
| 			content: 'hello', | ||||
| 		}, ...this.unread]; | ||||
| 	} | ||||
|  | ||||
| 	render() { | ||||
| 		let self = this; | ||||
|  | ||||
| 		if (!this.loading && this.whoami && this.loaded !== this.whoami) { | ||||
| 			console.log('loading', this.whoami); | ||||
| 			this.loading = true; | ||||
| 			this.following = []; | ||||
| 			this.users = {}; | ||||
| 			this.load().finally(function() { | ||||
| 				self.loading = false; | ||||
| 				console.log('loaded'); | ||||
| 			}); | ||||
| 		} | ||||
|  | ||||
| 		let id_picker = html` | ||||
| 			${guard([this.whoami], () => until(this.render_id_picker(), html`<div>Loading...</div>`))} | ||||
| 		`; | ||||
| @@ -258,10 +285,14 @@ class TfElement extends LitElement { | ||||
| 				<input type="button" value="Search" ?disabled=${self.tab == 'search'} @click=${event => self.tab = 'search'}></input> | ||||
| 			</div> | ||||
| 		`; | ||||
| 		let contents = !this.loaded ? | ||||
| 				html`<div>Loading...</div>` : | ||||
| 				this.render_tab(); | ||||
| 		return html` | ||||
| 			${id_picker} | ||||
| 			${tabs} | ||||
| 			${until(this.render_tab(), html`<div>Loading...</div>`)} | ||||
| 			<input type="button" value="Fake News" @click=${this.add_fake_news}></input> | ||||
| 			${contents} | ||||
| 		`; | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -73,6 +73,40 @@ class TfMessageElement extends LitElement { | ||||
| 		emojis.picker(x => this.vote(x)); | ||||
| 	} | ||||
|  | ||||
| 	render_mention(mention) { | ||||
| 		if (mention.link?.startsWith('&') && | ||||
| 			mention.type?.startsWith('image/')) { | ||||
| 			return html` | ||||
| 				<img src=${'/' + mention.link + '/view'} style="max-width: 128px; max-height: 128px" title=${mention.name}> | ||||
| 			`; | ||||
| 		} else if (mention.link?.startsWith('&') && | ||||
| 			mention.name?.startsWith('audio:')) { | ||||
| 			return html` | ||||
| 				<audio controls style="height: 32px"> | ||||
| 					<source src=${'/' + mention.link + '/view'}></source> | ||||
| 				</audio> | ||||
| 			`; | ||||
| 		} 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>`; | ||||
| 		} else { | ||||
| 			return html`<pre>${JSON.stringify(mention)}</pre>`; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	render_mentions() { | ||||
| 		if (this.message?.content?.mentions?.length) { | ||||
| 			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> | ||||
| 					${(this.message?.content?.mentions || []).map(x => self.render_mention(x))} | ||||
| 				</fieldset> | ||||
| 			`; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	render() { | ||||
| 		let content = this.message?.content; | ||||
| 		let self = this; | ||||
| @@ -153,6 +187,7 @@ class TfMessageElement extends LitElement { | ||||
| 						<span>${raw_button}</span> | ||||
| 					</div> | ||||
| 					<div>${body}</div> | ||||
| 					${this.render_mentions()} | ||||
| 					${this.render_votes()} | ||||
| 					<div> | ||||
| 						${reply} | ||||
|   | ||||
| @@ -12,4 +12,9 @@ a:visited { | ||||
| a:hover { | ||||
| 	color: #ddf; | ||||
| } | ||||
|  | ||||
| img { | ||||
| 	max-width: 640px; | ||||
| 	max-height: 480px; | ||||
| } | ||||
| `; | ||||
| @@ -2,14 +2,14 @@ import {LitElement, html, unsafeHTML, until} from './lit-all.min.js'; | ||||
| import * as tfrpc from '/static/tfrpc.js'; | ||||
| import {styles} from './tf-styles.js'; | ||||
|  | ||||
| class TfTabNewsElement extends LitElement { | ||||
| class TfTabNewsFeedElement extends LitElement { | ||||
| 	static get properties() { | ||||
| 		return { | ||||
| 			whoami: {type: String}, | ||||
| 			users: {type: Object}, | ||||
| 			hash: {type: String}, | ||||
| 			unread: {type: Array}, | ||||
| 			following: {type: Array}, | ||||
| 			messages: {type: Array}, | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -21,9 +21,7 @@ class TfTabNewsElement extends LitElement { | ||||
| 		this.whoami = null; | ||||
| 		this.users = {}; | ||||
| 		this.hash = '#'; | ||||
| 		this.unread = []; | ||||
| 		this.following = []; | ||||
| 		this.cache = {}; | ||||
| 	} | ||||
|  | ||||
| 	async fetch_messages() { | ||||
| @@ -65,42 +63,86 @@ class TfTabNewsElement extends LitElement { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	async show_more() { | ||||
| 		let unread = this.unread; | ||||
| 		this.unread = []; | ||||
| 		this.process_messages(unread); | ||||
| 		await this.finalize_messages(); | ||||
| 	render() { | ||||
| 		if (!this.messages || | ||||
| 			this._messages_hash !== this.hash || | ||||
| 			this._messages_following !== this.following) { | ||||
| 			console.log('loading messages'); | ||||
| 			let self = this; | ||||
| 			this.messages = []; | ||||
| 			this._messages_hash = this.hash; | ||||
| 			this._messages_following = this.following; | ||||
| 			this.fetch_messages().then(function(messages) { | ||||
| 				self.messages = messages; | ||||
| 			}); | ||||
| 		} | ||||
| 		return html`<tf-news id="news" whoami=${this.whoami} .users=${this.users} .messages=${this.messages} .following=${this.following}></tf-news>`; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| class TfTabNewsElement extends LitElement { | ||||
| 	static get properties() { | ||||
| 		return { | ||||
| 			whoami: {type: String}, | ||||
| 			users: {type: Object}, | ||||
| 			hash: {type: String}, | ||||
| 			unread: {type: Array}, | ||||
| 			following: {type: Array}, | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	async render_news() { | ||||
| 		if (this.cache.hash !== this.hash || | ||||
| 			this.cache.whoami !== this.whoami || | ||||
| 			this.cache.users !== this.users || | ||||
| 			!this.cache.messages) { | ||||
| 			this.cache = { | ||||
| 				hash: this.hash, | ||||
| 				whoami: this.whoami, | ||||
| 				users: this.users, | ||||
| 				messages: this.fetch_messages(), | ||||
| 			}; | ||||
| 	static styles = styles; | ||||
|  | ||||
| 	constructor() { | ||||
| 		super(); | ||||
| 		let self = this; | ||||
| 		this.whoami = null; | ||||
| 		this.users = {}; | ||||
| 		this.hash = '#'; | ||||
| 		this.unread = []; | ||||
| 		this.following = []; | ||||
| 		this.cache = {}; | ||||
| 	} | ||||
|  | ||||
| 	show_more() { | ||||
| 		let unread = this.unread; | ||||
| 		let news = this.renderRoot?.getElementById('news'); | ||||
| 		if (news) { | ||||
| 			console.log('injecting messages', news.messages); | ||||
| 			news.messages = [...this.unread, ...news.messages]; | ||||
| 			this.dispatchEvent(new CustomEvent('refresh')); | ||||
| 		} | ||||
| 		let messages = await this.cache.messages; | ||||
| 		return html`<tf-news whoami=${this.whoami} .users=${this.users} .messages=${messages}></tf-news>`; | ||||
| 	} | ||||
|  | ||||
| 	new_messages_text() { | ||||
| 		if (!this.unread?.length) { | ||||
| 			return 'No new messages.'; | ||||
| 		} | ||||
| 		let counts = {}; | ||||
| 		for (let message of this.unread) { | ||||
| 			let type = 'unknown'; | ||||
| 			try { | ||||
| 				type = JSON.parse(message.content).type || type; | ||||
| 			} catch { | ||||
| 			} | ||||
| 			counts[type] = (counts[type] || 0) + 1; | ||||
| 		} | ||||
| 		return 'Show New: ' + Object.keys(counts).sort().map(x => (counts[x].toString() + ' ' + x + 's')).join(', '); | ||||
| 	} | ||||
|  | ||||
| 	render() { | ||||
| 		let profile = this.hash.startsWith('#@') ? | ||||
| 			html`<tf-profile id=${this.hash.substring(1)} whoami=${this.whoami} .users=${this.users}></tf-profile>` : undefined; | ||||
| 		return html` | ||||
| 			<div><input type="button" value=${'Show ' + this.unread.length + ' New Messages'} @click=${this.show_more}></input></div> | ||||
| 			<button id="load_button" @click=${this.load}>Load</button> | ||||
| 			<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> | ||||
| 			${profile} | ||||
| 			${until(this.render_news(), html`<div>Loading...</div>`)} | ||||
| 			<tf-tab-news-feed id="news" whoami=${this.whoami} .users=${this.users} .following=${this.following} hash=${this.hash}></tf-tab-news-feed> | ||||
| 		`; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| customElements.define('tf-tab-news-feed', TfTabNewsFeedElement); | ||||
| customElements.define('tf-tab-news', TfTabNewsElement); | ||||
| @@ -31,7 +31,7 @@ class TfTabSearchElement extends LitElement { | ||||
| 				JOIN json_each(?) AS following ON messages.author = following.value | ||||
| 				ORDER BY timestamp DESC limit 100 | ||||
| 			`, | ||||
| 			[query, JSON.stringify(this.following)]); | ||||
| 			['"' + query.replace('"', '""') + '"', JSON.stringify(this.following)]); | ||||
| 		console.log('Done.'); | ||||
| 		this.renderRoot.getElementById('search').value = ''; | ||||
| 		this.renderRoot.getElementById('news').messages = results; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user