1
0
forked from cory/tildefriends

Updated lit, starting to improve the display of mentions during editing, . to refresh, and probably some other things.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4278 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
Cory McWilliams 2023-05-02 16:47:27 +00:00
parent 9cbe895cb8
commit e092fe1399
7 changed files with 173 additions and 136 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -9,5 +9,6 @@ import * as tf_compose from './tf-compose.js';
import * as tf_news from './tf-news.js';
import * as tf_profile from './tf-profile.js';
import * as tf_tab_news from './tf-tab-news.js';
import * as tf_tab_news_feed from './tf-tab-news-feed.js';
import * as tf_tab_search from './tf-tab-search.js';
import * as tf_tab_connections from './tf-tab-connections.js';

@ -256,9 +256,18 @@ class TfComposeElement extends LitElement {
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 style="display: flex; flex-direction: row">
<div style="align-self: center; margin: 0.5em">
<input type="button" value="🚮" title="Remove ${mention.name} mention" @click=${() => self.remove_mention(mention.link)}></input>
</div>
<div style="display: flex; flex-direction: column">
<h3>${mention.name}</h3>
<div style="padding-left: 1em">
${Object.entries(mention)
.filter(x => x[0] != 'name')
.map(x => html`<div><span style="font-weight: bold">${x[0]}</span>: ${x[1]}</div>`)}
</div>
</div>
</div>`;
}

@ -0,0 +1,113 @@
import {LitElement, html, unsafeHTML, until} from './lit-all.min.js';
import * as tfrpc from '/static/tfrpc.js';
import {styles} from './tf-styles.js';
class TfTabNewsFeedElement extends LitElement {
static get properties() {
return {
whoami: {type: String},
users: {type: Object},
hash: {type: String},
following: {type: Array},
messages: {type: Array},
drafts: {type: Object},
expanded: {type: Object},
};
}
static styles = styles;
constructor() {
super();
let self = this;
this.whoami = null;
this.users = {};
this.hash = '#';
this.following = [];
this.drafts = {};
this.expanded = {};
}
async fetch_messages() {
if (this.hash.startsWith('#@')) {
let r = await tfrpc.rpc.query(
`
WITH mine AS (SELECT messages.*
FROM messages
WHERE messages.author = ?
ORDER BY sequence DESC
LIMIT 20)
SELECT messages.*
FROM mine
JOIN messages_refs ON mine.id = messages_refs.ref
JOIN messages ON messages_refs.message = messages.id
UNION
SELECT * FROM mine
`,
[
this.hash.substring(1),
]);
return r;
} else if (this.hash.startsWith('#%')) {
return await tfrpc.rpc.query(
`
SELECT messages.*
FROM messages
WHERE id = ?1
UNION
SELECT messages.*
FROM messages JOIN messages_refs
ON messages.id = messages_refs.message
WHERE messages_refs.ref = ?1
`,
[
this.hash.substring(1),
]);
} else {
return await tfrpc.rpc.query(
`
WITH news AS (SELECT messages.*
FROM messages
JOIN json_each(?) AS following ON messages.author = following.value
WHERE messages.timestamp > ?
ORDER BY messages.timestamp DESC)
SELECT messages.*
FROM news
JOIN messages_refs ON news.id = messages_refs.ref
JOIN messages ON messages_refs.message = messages.id
UNION
SELECT messages.*
FROM news
JOIN messages_refs ON news.id = messages_refs.message
JOIN messages ON messages_refs.ref = messages.id
UNION
SELECT news.* FROM news
`,
[
JSON.stringify(this.following),
new Date().valueOf() - 24 * 60 * 60 * 1000,
]);
}
}
render() {
if (!this.messages ||
this._messages_hash !== this.hash ||
this._messages_following !== this.following) {
console.log(`loading messages for ${this.whoami}`);
let self = this;
this.messages = [];
this._messages_hash = this.hash;
this._messages_following = this.following;
this.fetch_messages().then(function(messages) {
self.messages = messages;
console.log(`loading mesages done for ${self.whoami}`);
}).catch(function(error) {
alert(JSON.stringify(error, null, 2));
});
}
return html`<tf-news id="news" whoami=${this.whoami} .users=${this.users} .messages=${this.messages} .following=${this.following} .drafts=${this.drafts} .expanded=${this.expanded}></tf-news>`;
}
}
customElements.define('tf-tab-news-feed', TfTabNewsFeedElement);

@ -2,114 +2,6 @@ import {LitElement, html, unsafeHTML, until} from './lit-all.min.js';
import * as tfrpc from '/static/tfrpc.js';
import {styles} from './tf-styles.js';
class TfTabNewsFeedElement extends LitElement {
static get properties() {
return {
whoami: {type: String},
users: {type: Object},
hash: {type: String},
following: {type: Array},
messages: {type: Array},
drafts: {type: Object},
expanded: {type: Object},
};
}
static styles = styles;
constructor() {
super();
let self = this;
this.whoami = null;
this.users = {};
this.hash = '#';
this.following = [];
this.drafts = {};
this.expanded = {};
}
async fetch_messages() {
if (this.hash.startsWith('#@')) {
let r = await tfrpc.rpc.query(
`
WITH mine AS (SELECT messages.*
FROM messages
WHERE messages.author = ?
ORDER BY sequence DESC
LIMIT 20)
SELECT messages.*
FROM mine
JOIN messages_refs ON mine.id = messages_refs.ref
JOIN messages ON messages_refs.message = messages.id
UNION
SELECT * FROM mine
`,
[
this.hash.substring(1),
]);
return r;
} else if (this.hash.startsWith('#%')) {
return await tfrpc.rpc.query(
`
SELECT messages.*
FROM messages
WHERE id = ?1
UNION
SELECT messages.*
FROM messages JOIN messages_refs
ON messages.id = messages_refs.message
WHERE messages_refs.ref = ?1
`,
[
this.hash.substring(1),
]);
} else {
return await tfrpc.rpc.query(
`
WITH news AS (SELECT messages.*
FROM messages
JOIN json_each(?) AS following ON messages.author = following.value
WHERE messages.timestamp > ?
ORDER BY messages.timestamp DESC)
SELECT messages.*
FROM news
JOIN messages_refs ON news.id = messages_refs.ref
JOIN messages ON messages_refs.message = messages.id
UNION
SELECT messages.*
FROM news
JOIN messages_refs ON news.id = messages_refs.message
JOIN messages ON messages_refs.ref = messages.id
UNION
SELECT news.* FROM news
`,
[
JSON.stringify(this.following),
new Date().valueOf() - 24 * 60 * 60 * 1000,
]);
}
}
render() {
if (!this.messages ||
this._messages_hash !== this.hash ||
this._messages_following !== this.following) {
console.log(`loading messages for ${this.whoami}`);
let self = this;
this.messages = [];
this._messages_hash = this.hash;
this._messages_following = this.following;
this.fetch_messages().then(function(messages) {
self.messages = messages;
console.log(`loading mesages done for ${self.whoami}`);
}).catch(function(error) {
alert(JSON.stringify(error, null, 2));
});
}
return html`<tf-news id="news" whoami=${this.whoami} .users=${this.users} .messages=${this.messages} .following=${this.following} .drafts=${this.drafts} .expanded=${this.expanded}></tf-news>`;
}
}
class TfTabNewsElement extends LitElement {
static get properties() {
return {
@ -141,6 +33,16 @@ class TfTabNewsElement extends LitElement {
});
}
connectedCallback() {
super.connectedCallback();
document.body.addEventListener('keypress', this.on_keypress.bind(this));
}
disconnectedCallback() {
super.disconnectedCallback();
document.body.removeEventListener('keypress', this.on_keypress.bind(this));
}
show_more() {
let unread = this.unread;
let news = this.renderRoot?.getElementById('news');
@ -193,6 +95,14 @@ class TfTabNewsElement extends LitElement {
}
}
on_keypress(event) {
if (event.target === document.body &&
event.key == '.') {
console.log(this);
this.show_more();
}
}
render() {
let profile = this.hash.startsWith('#@') ?
html`<tf-profile id=${this.hash.substring(1)} whoami=${this.whoami} .users=${this.users}></tf-profile>` : undefined;
@ -207,5 +117,4 @@ class TfTabNewsElement extends LitElement {
}
}
customElements.define('tf-tab-news-feed', TfTabNewsFeedElement);
customElements.define('tf-tab-news', TfTabNewsElement);

@ -1,7 +1,6 @@
import * as linkify from './commonmark-linkify.js';
import * as hashtagify from './commonmark-hashtag.js';
function image(node, entering) {
if (node.firstChild?.type === 'text' &&
node.firstChild.literal.startsWith('video:')) {