ssb: Fix various channel / unread status / show new messages bugs.

This commit is contained in:
Cory McWilliams 2024-12-22 13:16:56 -05:00
parent 8a67eba5fc
commit 79ff505963
4 changed files with 71 additions and 37 deletions

View File

@ -1,5 +1,5 @@
{ {
"type": "tildefriends-app", "type": "tildefriends-app",
"emoji": "🐌", "emoji": "🐌",
"previous": "&0gBRfD+3EaZD2S82zAnXT3hgGuNTnUncOh5vGwZwbSw=.sha256" "previous": "&jsq+9gvTsDRmi/t0t1wzftsi/IxkBwivsJEUpA7X/lE=.sha256"
} }

View File

@ -38,6 +38,8 @@ class TfElement extends LitElement {
this.channels = []; this.channels = [];
this.channels_unread = {}; this.channels_unread = {};
this.channels_latest = {}; this.channels_latest = {};
this.loading_channels_latest = 0;
this.loading_channels_latest_scheduled = 0;
tfrpc.rpc.getBroadcasts().then((b) => { tfrpc.rpc.getBroadcasts().then((b) => {
self.broadcasts = b || []; self.broadcasts = b || [];
}); });
@ -243,6 +245,7 @@ class TfElement extends LitElement {
this.unread = [...this.unread, ...messages]; this.unread = [...this.unread, ...messages];
this.unread = this.unread.slice(this.unread.length - 1024); this.unread = this.unread.slice(this.unread.length - 1024);
} }
this.schedule_load_channels_latest();
} }
async _handle_whoami_changed(event) { async _handle_whoami_changed(event) {
@ -295,6 +298,62 @@ class TfElement extends LitElement {
return -1; return -1;
} }
async load_channels_latest(following) {
this.loading_channels_latest++;
try {
let start_time = new Date();
let latest_private = this.get_latest_private(following);
let channels = await tfrpc.rpc.query(
`
SELECT channels.value AS channel, MAX(messages.rowid) AS rowid FROM messages
JOIN json_each(?1) AS channels ON messages.content ->> 'channel' = channels.value
JOIN json_each(?2) AS following ON messages.author = following.value
WHERE messages.content ->> 'type' = 'post' AND messages.content ->> 'root' IS NULL
GROUP by channel
UNION
SELECT '' AS channel, MAX(messages.rowid) AS rowid FROM messages
JOIN json_each(?2) AS following ON messages.author = following.value
UNION
SELECT '@' AS channel, MAX(messages.rowid) AS rowid FROM messages_fts(?3)
JOIN messages ON messages.rowid = messages_fts.rowid
JOIN json_each(?2) AS following ON messages.author = following.value
`,
[
JSON.stringify(this.channels),
JSON.stringify(following),
'"' + this.whoami.replace('"', '""') + '"',
]
);
this.channels_latest = Object.fromEntries(
channels.map((x) => [x.channel, x.rowid])
);
console.log('latest', this.channels_latest);
console.log('unread', this.channels_unread);
console.log('channels took', (new Date() - start_time) / 1000.0);
let self = this;
latest_private.then(function(latest) {
self.channels_latest = Object.assign({}, self.channels_latest, {'🔐': latest});
console.log('private took', (new Date() - start_time) / 1000.0);
});
} finally {
this.loading_channels_latest--;
}
}
_schedule_load_channels_latest_timer() {
--this.loading_channels_latest_scheduled;
this.schedule_load_channels_latest();
}
schedule_load_channels_latest() {
if (!this.loading_channels_latest) {
this.load_channels_latest(this.following);
} else if (!this.loading_channels_latest_scheduled) {
this.loading_channels_latest_scheduled++;
setTimeout(this._schedule_load_channels_latest_timer, 5000);
}
}
async load() { async load() {
let whoami = this.whoami; let whoami = this.whoami;
let following = await tfrpc.rpc.following([whoami], 2); let following = await tfrpc.rpc.following([whoami], 2);
@ -309,28 +368,7 @@ class TfElement extends LitElement {
}; };
by_count.push({count: v.of, id: id}); by_count.push({count: v.of, id: id});
} }
let channels = tfrpc.rpc.query( let channels_latest = this.load_channels_latest(Object.keys(following));
`
SELECT channels.value AS channel, MAX(messages.rowid) AS rowid FROM messages
JOIN json_each(?1) AS channels ON messages.content ->> 'channel' = channels.value
JOIN json_each(?2) AS following ON messages.author = following.value
WHERE messages.content ->> 'type' = 'post' AND messages.content ->> 'root' IS NULL
GROUP by channel
UNION
SELECT '' AS channel, MAX(messages.rowid) AS rowid FROM messages
JOIN json_each(?2) AS following ON messages.author = following.value
UNION
SELECT '@' AS channel, MAX(messages.rowid) AS rowid FROM messages_fts(?3)
JOIN messages ON messages.rowid = messages_fts.rowid
JOIN json_each(?2) AS following ON messages.author = following.value
`,
[
JSON.stringify(this.channels),
JSON.stringify(Object.keys(following)),
'"' + this.whoami.replace('"', '""') + '"',
]
);
let latest_private = this.get_latest_private(Object.keys(following));
this.channels_unread = JSON.parse( this.channels_unread = JSON.parse(
(await tfrpc.rpc.databaseGet('unread')) ?? '{}' (await tfrpc.rpc.databaseGet('unread')) ?? '{}'
); );
@ -344,16 +382,7 @@ class TfElement extends LitElement {
'users' 'users'
); );
start_time = new Date(); start_time = new Date();
channels = await channels; await channels_latest;
console.log('channels took', (new Date() - start_time) / 1000.0);
this.channels_latest = Object.fromEntries(
channels.map((x) => [x.channel, x.rowid])
);
let self = this;
latest_private.then(function(latest) {
self.channels_latest = Object.assign({}, self.channels_latest, {'🔐': latest});
console.log('private took', (new Date() - start_time) / 1000.0);
});
this.following = Object.keys(following); this.following = Object.keys(following);
this.users = users; this.users = users;
console.log(`load finished ${whoami} => ${this.whoami}`); console.log(`load finished ${whoami} => ${this.whoami}`);

View File

@ -165,7 +165,7 @@ class TfTabNewsFeedElement extends LitElement {
`, `,
[JSON.stringify(this.following), start_time, end_time] [JSON.stringify(this.following), start_time, end_time]
); );
result = (await this.decrypt(result)).filter(x => x.decrypted); result = (await this.decrypt(result)).filter((x) => x.decrypted);
} else { } else {
let promises = []; let promises = [];
const k_following_limit = 256; const k_following_limit = 256;
@ -274,7 +274,10 @@ class TfTabNewsFeedElement extends LitElement {
let end_time = now + 24 * 60 * 60 * 1000; let end_time = now + 24 * 60 * 60 * 1000;
let messages = []; let messages = [];
try { try {
messages = await this.fetch_messages(this.time_range[1], end_time); messages = await this.fetch_messages(
this.time_range[1] - 24 * 60 * 60 * 1000,
end_time
);
messages = await this.decrypt(messages); messages = await this.decrypt(messages);
this.update_time_range_from_messages( this.update_time_range_from_messages(
messages.filter( messages.filter(
@ -284,7 +287,9 @@ class TfTabNewsFeedElement extends LitElement {
} finally { } finally {
this.loading--; this.loading--;
} }
this.messages = [...this.messages, ...messages]; this.messages = Object.values(
Object.fromEntries([...this.messages, ...messages].map((x) => [x.id, x]))
);
console.log('done loading latest messages.'); console.log('done loading latest messages.');
} }

View File

@ -113,7 +113,7 @@ class TfTabNewsElement extends LitElement {
if ( if (
this.channels_latest[channel] && this.channels_latest[channel] &&
(this.channels_unread[channel] === undefined || (this.channels_unread[channel] === undefined ||
this.channels_unread[channel] < this.channels_latest[channel]) this.channels_unread[channel] <= this.channels_latest[channel])
) { ) {
return '🔵'; return '🔵';
} }