Experimenting with ordering. Handful of small fixes.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3989 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
2022-09-25 12:33:54 +00:00
parent 828f61c4e9
commit c0ecdaae12
7 changed files with 134 additions and 74 deletions

View File

@ -54,6 +54,8 @@ class TfElement extends LitElement {
this.hash = hash || '#';
if (this.hash.startsWith('#q=')) {
this.tab = 'search';
} else if (this.hash === '#connections') {
this.tab = 'connections';
} else {
this.tab = 'news';
}
@ -270,6 +272,15 @@ class TfElement extends LitElement {
}, ...this.unread];
}
async set_tab(tab) {
this.tab = tab;
if (tab === 'news') {
await tfrpc.rpc.setHash('#');
} else if (tab === 'connections') {
await tfrpc.rpc.setHash('#connections');
}
}
render() {
let self = this;
@ -289,9 +300,9 @@ class TfElement extends LitElement {
`;
let tabs = html`
<div>
<input type="button" value="News" ?disabled=${self.tab == 'news'} @click=${event => self.tab = 'news'}></input>
<input type="button" value="Connections" ?disabled=${self.tab == 'connections'} @click=${event => self.tab = 'connections'}></input>
<input type="button" value="Search" ?disabled=${self.tab == 'search'} @click=${event => self.tab = 'search'}></input>
<input type="button" value="News" ?disabled=${self.tab == 'news'} @click=${() => self.set_tab('news')}></input>
<input type="button" value="Connections" ?disabled=${self.tab == 'connections'} @click=${() => self.set_tab('connections')}></input>
<input type="button" value="Search" ?disabled=${self.tab == 'search'} @click=${() => self.set_tab('search')}></input>
</div>
`;
let contents = !this.loaded ?

View File

@ -43,11 +43,26 @@ class TfMessageElement extends LitElement {
return expression;
}
}
return html`<div>${(this.message.votes || []).map(vote => html`<span title="${this.users[vote.author]?.name ?? vote.author}">${normalize_expression(vote.content.vote.expression)}</span>`)}</div>`;
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>`;
}
render_raw() {
return html`<div style="white-space: pre-wrap">${JSON.stringify(this.message, null, 2)}</div>`
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,
}
return html`<div style="white-space: pre-wrap">${JSON.stringify(raw, null, 2)}</div>`
}
vote(emoji) {
@ -101,6 +116,12 @@ class TfMessageElement extends LitElement {
document.body.appendChild(div);
}
body_click(event) {
if (event.srcElement.tagName == 'IMG') {
this.show_image(event.srcElement.src);
}
}
render_mention(mention) {
if (!mention?.link || typeof(mention.link) != 'string') {
return html`<pre>${JSON.stringify(mention)}</pre>`;
@ -121,12 +142,15 @@ class TfMessageElement extends LitElement {
} else if (mention.link?.startsWith('#')) {
return html` <a href=${'#q=' + encodeURIComponent(mention.link)}>${mention.link}</a>`;
} else {
return html`<pre>${JSON.stringify(mention)}</pre>`;
return html`<pre style="white-space: pre-wrap">${JSON.stringify(mention, null, 2)}</pre>`;
}
}
render_mentions() {
if (this.message?.content?.mentions?.length) {
let mentions = this.message?.content?.mentions || [];
let content = JSON.stringify(this.message?.content);
mentions = mentions.filter(x => content.indexOf(x.link) === -1);
if (mentions.length) {
let self = this;
return html`
<fieldset style="background-color: rgba(0, 0, 0, 0.1); padding: 0.5em; border: 1px solid black">
@ -163,71 +187,83 @@ class TfMessageElement extends LitElement {
<tf-message .message=${x} whoami=${this.whoami} .users=${this.users}></tf-message>
`)}
</div>`;
} else if (content.type == 'about') {
return small_frame(html`
<div style="font-weight: bold">Updated profile:</div>
<pre style="white-space: pre-wrap">${JSON.stringify(content, null, 2)}</pre>
`);
} else if (content.type == 'contact') {
return small_frame(html`
<div>
is now
${
content.blocking === true ? 'blocking' :
content.blocking === false ? 'unblocking' :
content.following === true ? 'following' :
content.following === false ? 'unfollowing' :
'?'
}
<tf-user id=${this.message.content.contact} .users=${this.users}></tf-user>
</div>
`);
} else if (content.type == 'post') {
let reply = this.reply ? 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>
` : 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));
return html`
<style>
code {
white-space: pre-wrap;
overflow-wrap: break-word;
}
img {
max-width: 100%;
height: auto;
}
</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()}
} else if (typeof(content?.type === 'string')) {
if (content.type == 'about') {
return small_frame(html`
<div style="font-weight: bold">Updated profile:</div>
<pre style="white-space: pre-wrap">${JSON.stringify(content, null, 2)}</pre>
`);
} else if (content.type == 'contact') {
return small_frame(html`
<div>
${reply}
<input type="button" value="React" @click=${this.react}></input>
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>
${(this.message.child_messages || []).map(x => html`<tf-message .message=${x} whoami=${this.whoami} .users=${this.users}></tf-message>`)}
</div>
`;
} else if (typeof(this.message.content) == 'string') {
return small_frame(html`<span>🔒</span>`);
`);
} else if (content.type == 'post') {
let reply = this.reply ? 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>
` : 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));
return html`
<style>
code {
white-space: pre-wrap;
overflow-wrap: break-word;
}
img {
max-width: 100%;
height: auto;
}
</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 @click=${this.body_click}>${body}</div>
${this.render_mentions()}
${this.render_votes()}
<div>
${reply}
<input type="button" value="React" @click=${this.react}></input>
</div>
${(this.message.child_messages || []).map(x => html`<tf-message .message=${x} whoami=${this.whoami} .users=${this.users}></tf-message>`)}
</div>
`;
} else if (content.type === 'pub') {
return small_frame(html`
<span>
<div>
🍻 <tf-user .users=${this.users} id=${content.address.key}></tf-user>
</div>
<pre>${content.address.host}:${content.address.port}</pre>
</span>`);
} else if (typeof(this.message.content) == 'string') {
return small_frame(html`<span>🔒</span>`);
} else {
return small_frame(html`<div><b>type</b>: ${content.type}</div>`);
}
} else {
return small_frame(this.render_raw());
}

View File

@ -115,11 +115,22 @@ class TfNewsElement extends LitElement {
]);
}
update_latest_subtree_timestamp(messages) {
let latest = 0;
for (let message of messages || []) {
if (message.latest_subtree_timestamp === undefined) {
message.latest_subtree_timestamp = Math.max(message.timestamp, this.update_latest_subtree_timestamp(message.child_messages));
}
latest = Math.max(latest, message.latest_subtree_timestamp);
}
return latest;
}
finalize_messages(messages_by_id) {
function recursive_sort(messages, top) {
if (messages) {
if (top) {
messages.sort((a, b) => b.timestamp - a.timestamp);
messages.sort((a, b) => b.latest_subtree_timestamp - a.latest_subtree_timestamp);
} else {
messages.sort((a, b) => a.timestamp - b.timestamp);
}
@ -133,6 +144,7 @@ class TfNewsElement extends LitElement {
}
let roots = Object.values(messages_by_id).filter(x => !x.parent_message);
this.update_latest_subtree_timestamp(roots);
return recursive_sort(roots, true);
}

View File

@ -120,7 +120,7 @@ class TfTabNewsElement extends LitElement {
}
let counts = {};
for (let message of this.unread) {
let type = 'unknown';
let type = 'private';
try {
type = JSON.parse(message.content).type || type;
} catch {