2022-09-11 13:42:41 -04:00
|
|
|
import {LitElement, html, unsafeHTML, until} from './lit-all.min.js';
|
|
|
|
import * as tfrpc from '/static/tfrpc.js';
|
|
|
|
import {styles} from './tf-styles.js';
|
|
|
|
|
|
|
|
class TfNewsElement extends LitElement {
|
|
|
|
static get properties() {
|
|
|
|
return {
|
|
|
|
whoami: {type: String},
|
|
|
|
users: {type: Object},
|
|
|
|
messages: {type: Array},
|
|
|
|
following: {type: Array},
|
2023-01-20 19:16:18 -05:00
|
|
|
drafts: {type: Object},
|
2023-01-24 19:56:10 -05:00
|
|
|
expanded: {type: Object},
|
2024-11-30 15:05:14 -05:00
|
|
|
channel: {type: String},
|
|
|
|
channel_unread: {type: Number},
|
2023-03-29 18:02:12 -04:00
|
|
|
};
|
2022-09-11 13:42:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static styles = styles;
|
|
|
|
|
|
|
|
constructor() {
|
|
|
|
super();
|
|
|
|
let self = this;
|
|
|
|
this.whoami = null;
|
|
|
|
this.users = {};
|
|
|
|
this.messages = [];
|
|
|
|
this.following = [];
|
2023-01-20 19:16:18 -05:00
|
|
|
this.drafts = {};
|
2023-01-24 19:56:10 -05:00
|
|
|
this.expanded = {};
|
2024-11-30 15:05:14 -05:00
|
|
|
this.channel_unread = -1;
|
2022-09-11 13:42:41 -04:00
|
|
|
}
|
|
|
|
|
2022-12-07 18:37:06 -05:00
|
|
|
process_messages(messages) {
|
2022-09-11 13:42:41 -04:00
|
|
|
let self = this;
|
2022-12-07 18:37:06 -05:00
|
|
|
let messages_by_id = {};
|
|
|
|
|
|
|
|
console.log('processing', messages.length, 'messages');
|
2022-09-11 13:42:41 -04:00
|
|
|
|
2024-12-18 12:43:25 -05:00
|
|
|
function ensure_message(id, rowid) {
|
2022-09-11 13:42:41 -04:00
|
|
|
let found = messages_by_id[id];
|
|
|
|
if (found) {
|
|
|
|
return found;
|
|
|
|
} else {
|
|
|
|
let added = {
|
2024-12-18 12:43:25 -05:00
|
|
|
rowid: rowid,
|
2022-09-11 13:42:41 -04:00
|
|
|
id: id,
|
|
|
|
placeholder: true,
|
|
|
|
content: '"placeholder"',
|
|
|
|
parent_message: undefined,
|
|
|
|
child_messages: [],
|
|
|
|
votes: [],
|
|
|
|
};
|
|
|
|
messages_by_id[id] = added;
|
|
|
|
return added;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function link_message(message) {
|
|
|
|
if (message.content.type === 'vote') {
|
2024-12-18 12:43:25 -05:00
|
|
|
let parent = ensure_message(message.content.vote.link, message.rowid);
|
2022-09-11 13:42:41 -04:00
|
|
|
if (!parent.votes) {
|
|
|
|
parent.votes = [];
|
|
|
|
}
|
|
|
|
parent.votes.push(message);
|
|
|
|
message.parent_message = message.content.vote.link;
|
|
|
|
} else if (message.content.type == 'post') {
|
|
|
|
if (message.content.root) {
|
2024-02-24 11:09:34 -05:00
|
|
|
if (typeof message.content.root === 'string') {
|
2024-12-18 12:43:25 -05:00
|
|
|
let m = ensure_message(message.content.root, message.rowid);
|
2022-09-11 13:42:41 -04:00
|
|
|
if (!m.child_messages) {
|
|
|
|
m.child_messages = [];
|
|
|
|
}
|
|
|
|
m.child_messages.push(message);
|
|
|
|
message.parent_message = message.content.root;
|
|
|
|
} else {
|
2024-12-18 12:43:25 -05:00
|
|
|
let m = ensure_message(message.content.root[0], message.rowid);
|
2022-09-11 13:42:41 -04:00
|
|
|
if (!m.child_messages) {
|
|
|
|
m.child_messages = [];
|
|
|
|
}
|
|
|
|
m.child_messages.push(message);
|
|
|
|
message.parent_message = message.content.root[0];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-30 19:43:54 -05:00
|
|
|
for (let message of messages) {
|
2023-01-25 21:08:14 -05:00
|
|
|
message.votes = [];
|
2022-11-30 19:43:54 -05:00
|
|
|
message.parent_message = undefined;
|
|
|
|
message.child_messages = undefined;
|
|
|
|
}
|
|
|
|
|
2022-09-11 13:42:41 -04:00
|
|
|
for (let message of messages) {
|
|
|
|
try {
|
|
|
|
message.content = JSON.parse(message.content);
|
2024-02-24 11:09:34 -05:00
|
|
|
} catch {}
|
2022-09-11 13:42:41 -04:00
|
|
|
if (!messages_by_id[message.id]) {
|
|
|
|
messages_by_id[message.id] = message;
|
|
|
|
link_message(message);
|
|
|
|
} else if (messages_by_id[message.id].placeholder) {
|
|
|
|
let placeholder = messages_by_id[message.id];
|
|
|
|
messages_by_id[message.id] = message;
|
|
|
|
message.parent_message = placeholder.parent_message;
|
|
|
|
message.child_messages = placeholder.child_messages;
|
|
|
|
message.votes = placeholder.votes;
|
2024-02-24 11:09:34 -05:00
|
|
|
if (
|
|
|
|
placeholder.parent_message &&
|
|
|
|
messages_by_id[placeholder.parent_message]
|
|
|
|
) {
|
|
|
|
let children =
|
|
|
|
messages_by_id[placeholder.parent_message].child_messages;
|
2022-09-11 13:42:41 -04:00
|
|
|
children.splice(children.indexOf(placeholder), 1);
|
|
|
|
children.push(message);
|
|
|
|
}
|
|
|
|
link_message(message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return messages_by_id;
|
|
|
|
}
|
|
|
|
|
2022-09-25 08:33:54 -04:00
|
|
|
update_latest_subtree_timestamp(messages) {
|
|
|
|
let latest = 0;
|
|
|
|
for (let message of messages || []) {
|
|
|
|
if (message.latest_subtree_timestamp === undefined) {
|
2024-02-24 11:09:34 -05:00
|
|
|
message.latest_subtree_timestamp = Math.max(
|
|
|
|
message.timestamp ?? 0,
|
|
|
|
this.update_latest_subtree_timestamp(message.child_messages)
|
|
|
|
);
|
2022-09-25 08:33:54 -04:00
|
|
|
}
|
|
|
|
latest = Math.max(latest, message.latest_subtree_timestamp);
|
|
|
|
}
|
|
|
|
return latest;
|
|
|
|
}
|
|
|
|
|
2022-09-11 13:42:41 -04:00
|
|
|
finalize_messages(messages_by_id) {
|
|
|
|
function recursive_sort(messages, top) {
|
|
|
|
if (messages) {
|
|
|
|
if (top) {
|
2024-02-24 11:09:34 -05:00
|
|
|
messages.sort(
|
|
|
|
(a, b) => b.latest_subtree_timestamp - a.latest_subtree_timestamp
|
|
|
|
);
|
2022-09-11 13:42:41 -04:00
|
|
|
} else {
|
|
|
|
messages.sort((a, b) => a.timestamp - b.timestamp);
|
|
|
|
}
|
|
|
|
for (let message of messages) {
|
|
|
|
recursive_sort(message.child_messages, false);
|
|
|
|
}
|
2024-02-24 11:09:34 -05:00
|
|
|
return messages.map((x) => Object.assign({}, x));
|
2022-09-11 13:42:41 -04:00
|
|
|
} else {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-24 11:09:34 -05:00
|
|
|
let roots = Object.values(messages_by_id).filter((x) => !x.parent_message);
|
2022-09-25 08:33:54 -04:00
|
|
|
this.update_latest_subtree_timestamp(roots);
|
2022-09-11 13:42:41 -04:00
|
|
|
return recursive_sort(roots, true);
|
|
|
|
}
|
|
|
|
|
2023-03-19 19:31:08 -04:00
|
|
|
group_following(messages) {
|
|
|
|
let result = [];
|
|
|
|
let group = [];
|
|
|
|
for (let message of messages) {
|
|
|
|
if (message?.content?.type === 'contact') {
|
|
|
|
group.push(message);
|
|
|
|
} else {
|
|
|
|
if (group.length > 0) {
|
|
|
|
result.push({
|
2024-12-11 20:35:32 -05:00
|
|
|
rowid: Math.max(...group.map((x) => x.rowid)),
|
2023-03-19 19:31:08 -04:00
|
|
|
type: 'contact_group',
|
|
|
|
messages: group,
|
|
|
|
});
|
|
|
|
group = [];
|
|
|
|
}
|
|
|
|
result.push(message);
|
|
|
|
}
|
|
|
|
}
|
2024-12-07 14:08:53 -05:00
|
|
|
if (group.length > 0) {
|
|
|
|
result.push({
|
2024-12-11 20:35:32 -05:00
|
|
|
rowid: Math.max(...group.map((x) => x.rowid)),
|
2024-12-07 14:08:53 -05:00
|
|
|
type: 'contact_group',
|
|
|
|
messages: group,
|
|
|
|
});
|
|
|
|
}
|
2023-03-19 19:31:08 -04:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2023-02-22 20:29:54 -05:00
|
|
|
load_and_render(messages) {
|
2022-09-11 13:42:41 -04:00
|
|
|
let messages_by_id = this.process_messages(messages);
|
2024-02-24 11:09:34 -05:00
|
|
|
let final_messages = this.group_following(
|
|
|
|
this.finalize_messages(messages_by_id)
|
|
|
|
);
|
2024-12-01 12:56:31 -05:00
|
|
|
let unread_rowid = -1;
|
|
|
|
for (let message of final_messages) {
|
2024-12-18 12:43:25 -05:00
|
|
|
if (message.rowid >= this.channel_unread) {
|
2024-12-01 12:56:31 -05:00
|
|
|
unread_rowid = message.rowid;
|
|
|
|
}
|
|
|
|
}
|
2022-09-11 13:42:41 -04:00
|
|
|
return html`
|
2024-11-30 15:05:14 -05:00
|
|
|
<div>
|
2024-02-24 11:09:34 -05:00
|
|
|
${final_messages.map(
|
|
|
|
(x) =>
|
2024-12-18 12:43:25 -05:00
|
|
|
html`
|
|
|
|
${x.rowid == unread_rowid && x != final_messages[0]
|
2024-12-05 20:47:02 -05:00
|
|
|
? html`<div style="display: flex; flex-direction: row">
|
|
|
|
<div
|
|
|
|
style="border-bottom: 1px solid #f00; flex: 1; align-self: center; height: 1px"
|
|
|
|
></div>
|
|
|
|
<div style="color: #f00; padding: 8px">unread</div>
|
|
|
|
<div
|
|
|
|
style="border-bottom: 1px solid #f00; flex: 1; align-self: center; height: 1px"
|
|
|
|
></div>
|
|
|
|
</div>`
|
|
|
|
: undefined}
|
|
|
|
<tf-message
|
|
|
|
.message=${x}
|
|
|
|
whoami=${this.whoami}
|
|
|
|
.users=${this.users}
|
|
|
|
.drafts=${this.drafts}
|
|
|
|
.expanded=${this.expanded}
|
|
|
|
collapsed="true"
|
|
|
|
channel=${this.channel}
|
|
|
|
channel_unread=${this.channel_unread}
|
|
|
|
></tf-message>`
|
2024-02-24 11:09:34 -05:00
|
|
|
)}
|
2022-10-04 22:11:46 -04:00
|
|
|
</div>
|
2022-09-11 13:42:41 -04:00
|
|
|
`;
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
2023-02-22 20:29:54 -05:00
|
|
|
return this.load_and_render(this.messages || []);
|
2022-09-11 13:42:41 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-24 11:09:34 -05:00
|
|
|
customElements.define('tf-news', TfNewsElement);
|