Compare commits

...

5 Commits

14 changed files with 170 additions and 152 deletions

View File

@ -1,5 +1,5 @@
{ {
"type": "tildefriends-app", "type": "tildefriends-app",
"emoji": "🦀", "emoji": "🦀",
"previous": "&jbL9Ab+XdvWnZbb50yimceFHR7XFDfBSWv9/XrbZ82I=.sha256" "previous": "&caGw+RHTGO/WBWQDiRRv/9/SDZPS3w8U4xNafZEQrYw=.sha256"
} }

View File

@ -38,8 +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_latest = 0;
this.loading_channels_latest_scheduled = 0; this.loading_latest_scheduled = 0;
tfrpc.rpc.getBroadcasts().then((b) => { tfrpc.rpc.getBroadcasts().then((b) => {
self.broadcasts = b || []; self.broadcasts = b || [];
}); });
@ -147,7 +147,8 @@ class TfElement extends LitElement {
} }
} }
async fetch_about(ids, users) { async fetch_about(following, users) {
let ids = Object.keys(following).sort();
const k_cache_version = 1; const k_cache_version = 1;
let cache = await tfrpc.rpc.databaseGet('about'); let cache = await tfrpc.rpc.databaseGet('about');
let original_cache = cache; let original_cache = cache;
@ -225,7 +226,11 @@ class TfElement extends LitElement {
} }
users = users || {}; users = users || {};
for (let id of Object.keys(cache.about)) { for (let id of Object.keys(cache.about)) {
users[id] = Object.assign(users[id] || {}, cache.about[id]); users[id] = Object.assign(
{follow_depth: following[id]?.d},
users[id] || {},
cache.about[id]
);
} }
return Object.assign({}, users); return Object.assign({}, users);
} }
@ -248,7 +253,7 @@ class TfElement extends LitElement {
this.load_channels(); this.load_channels();
} }
} }
this.schedule_load_channels_latest(); this.schedule_load_latest();
} }
async _handle_whoami_changed(event) { async _handle_whoami_changed(event) {
@ -307,7 +312,6 @@ class TfElement extends LitElement {
ranges.push([i, Math.min(i + k_chunk_size, latest), true]); ranges.push([i, Math.min(i + k_chunk_size, latest), true]);
} }
} }
console.log(cache);
for (let range of ranges) { for (let range of ranges) {
let messages = await tfrpc.rpc.query( let messages = await tfrpc.rpc.query(
` `
@ -340,112 +344,111 @@ class TfElement extends LitElement {
JSON.stringify(cache) JSON.stringify(cache)
); );
} }
console.log(cache);
return cache.latest; return cache.latest;
} }
async load_channels_latest(following) { async load_channels_latest(following) {
this.loading_channels_latest++; let start_time = new Date();
try { let latest_private = this.get_latest_private(following);
let start_time = new Date(); let channels = await tfrpc.rpc.query(
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
SELECT channels.value AS channel, MAX(messages.rowid) AS rowid FROM messages JOIN json_each(?2) AS following ON messages.author = following.value
JOIN json_each(?1) AS channels ON messages.content ->> 'channel' = channels.value WHERE
JOIN json_each(?2) AS following ON messages.author = following.value messages.content ->> 'type' = 'post' AND
WHERE messages.content ->> 'root' IS NULL AND
messages.content ->> 'type' = 'post' AND messages.author != ?4
messages.content ->> 'root' IS NULL AND GROUP by channel
messages.author != ?4 UNION
GROUP by channel SELECT '' AS channel, MAX(messages.rowid) AS rowid FROM messages
UNION JOIN json_each(?2) AS following ON messages.author = following.value
SELECT '' AS channel, MAX(messages.rowid) AS rowid FROM messages WHERE
JOIN json_each(?2) AS following ON messages.author = following.value messages.content ->> 'type' = 'post' AND
WHERE messages.content ->> 'root' IS NULL AND
messages.content ->> 'type' = 'post' AND messages.author != ?4
messages.content ->> 'root' IS NULL AND UNION
messages.author != ?4 SELECT '@' AS channel, MAX(messages.rowid) AS rowid FROM messages_fts(?3)
UNION JOIN messages ON messages.rowid = messages_fts.rowid
SELECT '@' AS channel, MAX(messages.rowid) AS rowid FROM messages_fts(?3) JOIN json_each(?2) AS following ON messages.author = following.value
JOIN messages ON messages.rowid = messages_fts.rowid WHERE messages.author != ?4
JOIN json_each(?2) AS following ON messages.author = following.value `,
WHERE messages.author != ?4 [
`, JSON.stringify(this.channels),
[ JSON.stringify(following),
JSON.stringify(this.channels), '"' + this.whoami.replace('"', '""') + '"',
JSON.stringify(following), this.whoami,
'"' + this.whoami.replace('"', '""') + '"', ]
this.whoami, );
] this.channels_latest = Object.fromEntries(
); channels.map((x) => [x.channel, x.rowid])
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('latest', this.channels_latest); console.log('channels took', (new Date() - start_time) / 1000.0);
console.log('unread', this.channels_unread); let self = this;
console.log('channels took', (new Date() - start_time) / 1000.0); latest_private.then(function (latest) {
let self = this; self.channels_latest = Object.assign({}, self.channels_latest, {
latest_private.then(function (latest) { '🔐': latest,
self.channels_latest = Object.assign({}, self.channels_latest, {
'🔐': latest,
});
console.log('private took', (new Date() - start_time) / 1000.0);
}); });
} finally { console.log('private took', (new Date() - start_time) / 1000.0);
this.loading_channels_latest--; });
}
} }
_schedule_load_channels_latest_timer() { _schedule_load_latest_timer() {
--this.loading_channels_latest_scheduled; --this.loading_latest_scheduled;
this.schedule_load_channels_latest(); this.schedule_load_latest();
} }
schedule_load_channels_latest() { schedule_load_latest() {
if (!this.loading_channels_latest) { if (!this.loading_latest) {
this.shadowRoot.getElementById('tf-tab-news')?.load_latest(); this.shadowRoot.getElementById('tf-tab-news')?.load_latest();
this.load_channels_latest(this.following); this.load();
} else if (!this.loading_channels_latest_scheduled) { } else if (!this.loading_latest_scheduled) {
this.loading_channels_latest_scheduled++; this.loading_latest_scheduled++;
setTimeout(this._schedule_load_channels_latest_timer.bind(this), 5000); setTimeout(this._schedule_load_latest_timer.bind(this), 5000);
} }
} }
async load() { async load() {
let start_time = new Date(); this.loading_latest = true;
let whoami = this.whoami; try {
let following = await tfrpc.rpc.following([whoami], 2); let start_time = new Date();
let users = {}; let whoami = this.whoami;
let by_count = []; let following = await tfrpc.rpc.following([whoami], 2);
for (let [id, v] of Object.entries(following)) { let users = {};
users[id] = { let by_count = [];
following: v.of, for (let [id, v] of Object.entries(following)) {
blocking: v.ob, users[id] = {
followed: v.if, following: v.of,
blocked: v.ib, blocking: v.ob,
}; followed: v.if,
by_count.push({count: v.of, id: id}); blocked: v.ib,
};
by_count.push({count: v.of, id: id});
}
this.load_channels_latest(Object.keys(following));
this.channels_unread = JSON.parse(
(await tfrpc.rpc.databaseGet('unread')) ?? '{}'
);
this.following = Object.keys(following);
users = await this.fetch_about(following, users);
console.log(
'about took',
(new Date() - start_time) / 1000.0,
'seconds for',
Object.keys(users).length,
'users'
);
this.users = users;
console.log(
`load finished ${whoami} => ${this.whoami} in ${(new Date() - start_time) / 1000}`
);
this.whoami = whoami;
this.loaded = whoami;
} finally {
this.loading_latest = false;
} }
this.load_channels_latest(Object.keys(following));
this.channels_unread = JSON.parse(
(await tfrpc.rpc.databaseGet('unread')) ?? '{}'
);
users = await this.fetch_about(Object.keys(following).sort(), users);
console.log(
'about took',
(new Date() - start_time) / 1000.0,
'seconds for',
Object.keys(users).length,
'users'
);
this.following = Object.keys(following);
this.users = users;
console.log(
`load finished ${whoami} => ${this.whoami} in ${(new Date() - start_time) / 1000}`
);
this.whoami = whoami;
this.loaded = whoami;
} }
channel_set_unread(event) { channel_set_unread(event) {

View File

@ -1,4 +1,4 @@
import {LitElement, html, render, unsafeHTML} from './lit-all.min.js'; import {LitElement, html, repeat, render, unsafeHTML} from './lit-all.min.js';
import * as tfrpc from '/static/tfrpc.js'; import * as tfrpc from '/static/tfrpc.js';
import * as tfutils from './tf-utils.js'; import * as tfutils from './tf-utils.js';
import * as emojis from './emojis.js'; import * as emojis from './emojis.js';
@ -313,7 +313,9 @@ class TfMessageElement extends LitElement {
@click=${() => self.set_expanded(false)} @click=${() => self.set_expanded(false)}
> >
Collapse</button Collapse</button
>${(this.message.child_messages || []).map( >${repeat(
this.message.child_messages || [],
(x) => x.id,
(x) => (x) =>
html`<tf-message html`<tf-message
.message=${x} .message=${x}
@ -589,9 +591,7 @@ class TfMessageElement extends LitElement {
let image; let image;
let description; let description;
if (content.name !== undefined) { if (content.name !== undefined) {
name = html`<div> name = html`<div><b>Name:</b> ${content.name}</div>`;
<b>Name:</b> ${content.name}
</div>`;
} }
if (content.image !== undefined) { if (content.image !== undefined) {
image = html` image = html`
@ -600,18 +600,14 @@ class TfMessageElement extends LitElement {
} }
if (content.description !== undefined) { if (content.description !== undefined) {
description = html` description = html`
<div <div style="flex: 1 0 50%; overflow-wrap: anywhere">
style="flex: 1 0 50%; overflow-wrap: anywhere"
>
<div>${unsafeHTML(tfutils.markdown(content.description))}</div> <div>${unsafeHTML(tfutils.markdown(content.description))}</div>
</div> </div>
`; `;
} }
let update = let update =
content.about == this.message.author content.about == this.message.author
? html`<div style="font-weight: bold"> ? html`<div style="font-weight: bold">Updated profile.</div>`
Updated profile.
</div>`
: html`<div style="font-weight: bold"> : html`<div style="font-weight: bold">
Updated profile for Updated profile for
<tf-user id=${content.about} .users=${this.users}></tf-user>. <tf-user id=${content.about} .users=${this.users}></tf-user>.
@ -759,10 +755,10 @@ class TfMessageElement extends LitElement {
return this.render_small_frame(html` return this.render_small_frame(html`
<div class="w3-container"> <div class="w3-container">
<p> <p>
${content.subscribed ? 'subscribed to' : 'unsubscribed from'} ${content.subscribed ? 'subscribed to' : 'unsubscribed from'}
<a href=${'#' + encodeURIComponent('#' + content.channel)} <a href=${'#' + encodeURIComponent('#' + content.channel)}
>#${content.channel}</a >#${content.channel}</a
> >
</p> </p>
</div> </div>
`); `);

View File

@ -1,4 +1,4 @@
import {LitElement, html, unsafeHTML, until} from './lit-all.min.js'; import {LitElement, html, unsafeHTML, repeat, until} from './lit-all.min.js';
import * as tfrpc from '/static/tfrpc.js'; import * as tfrpc from '/static/tfrpc.js';
import {styles} from './tf-styles.js'; import {styles} from './tf-styles.js';
@ -198,7 +198,9 @@ class TfNewsElement extends LitElement {
} }
return html` return html`
<div> <div>
${final_messages.map( ${repeat(
final_messages,
(x) => x.id,
(x) => html` (x) => html`
<tf-message <tf-message
.message=${x} .message=${x}

View File

@ -142,12 +142,16 @@ class TfTabConnectionsElement extends LitElement {
}, {}) }, {})
); );
return html` return html`
<button ${connection.connected
class="w3-button w3-theme-d1" ? html`
@click=${() => tfrpc.rpc.closeConnection(connection.id)} <button
> class="w3-button w3-theme-d1"
Close @click=${() => tfrpc.rpc.closeConnection(connection.id)}
</button> >
Close
</button>
`
: undefined}
${connection.flags.one_shot ? '🔃' : undefined} ${connection.flags.one_shot ? '🔃' : undefined}
<tf-user id=${connection.id} .users=${this.users}></tf-user> <tf-user id=${connection.id} .users=${this.users}></tf-user>
${connection.tunnel !== undefined ${connection.tunnel !== undefined
@ -264,24 +268,27 @@ class TfTabConnectionsElement extends LitElement {
)} )}
</ul> </ul>
<h2>Local Accounts</h2> <h2>Local Accounts</h2>
<ul class="w3-ul w3-border"> <div class="w3-container">
${this.identities.map( ${this.identities.map(
(x) => (x) =>
html`<li class="w3-bar"> html`<div
class="w3-tag w3-round w3-theme-l3"
style="padding: 4px; margin: 2px; max-width: 100%; text-wrap: nowrap; overflow: hidden"
>
${x == this.server_identity ${x == this.server_identity
? html`<span class="w3-tag w3-medium w3-round w3-theme-l1" ? html`<div class="w3-tag w3-medium w3-round w3-theme-l1">
>🖥 local server</span 🖥 local server
>` </div>`
: undefined} : undefined}
${this.my_identities.indexOf(x) != -1 ${this.my_identities.indexOf(x) != -1
? html`<span class="w3-tag w3-medium w3-round w3-theme-d1" ? html`<div class="w3-tag w3-medium w3-round w3-theme-d1">
>😎 you</span 😎 you
>` </div>`
: undefined} : undefined}
<tf-user id=${x} .users=${this.users}></tf-user> <tf-user id=${x} .users=${this.users}></tf-user>
</li>` </div>`
)} )}
</ul> </div>
</div> </div>
`; `;
} }

View File

@ -1,4 +1,4 @@
import {LitElement, html, unsafeHTML, until} from './lit-all.min.js'; import {LitElement, cache, html, unsafeHTML, until} from './lit-all.min.js';
import * as tfrpc from '/static/tfrpc.js'; import * as tfrpc from '/static/tfrpc.js';
import {styles} from './tf-styles.js'; import {styles} from './tf-styles.js';
@ -373,7 +373,8 @@ class TfTabNewsFeedElement extends LitElement {
if ( if (
!this.messages || !this.messages ||
this._messages_hash !== this.hash || this._messages_hash !== this.hash ||
this._messages_following !== this.following JSON.stringify(this._messages_following) !==
JSON.stringify(this.following)
) { ) {
console.log( console.log(
`loading messages for ${this.whoami} (following ${this.following.length})` `loading messages for ${this.whoami} (following ${this.following.length})`
@ -417,7 +418,7 @@ class TfTabNewsFeedElement extends LitElement {
</p> </p>
`; `;
} }
return html` return cache(html`
<button class="w3-button w3-theme-d1" @click=${this.mark_all_read}> <button class="w3-button w3-theme-d1" @click=${this.mark_all_read}>
Mark All Read Mark All Read
</button> </button>
@ -433,7 +434,7 @@ class TfTabNewsFeedElement extends LitElement {
channel_unread=${this.channels_unread?.[this.channel()]} channel_unread=${this.channels_unread?.[this.channel()]}
></tf-news> ></tf-news>
${more} ${more}
`; `);
} }
} }

View File

@ -1,4 +1,4 @@
import {LitElement, html, unsafeHTML, until} from './lit-all.min.js'; import {LitElement, cache, html, unsafeHTML, until} from './lit-all.min.js';
import * as tfrpc from '/static/tfrpc.js'; import * as tfrpc from '/static/tfrpc.js';
import {styles} from './tf-styles.js'; import {styles} from './tf-styles.js';
@ -238,7 +238,7 @@ class TfTabNewsElement extends LitElement {
name. name.
</div>`; </div>`;
} }
return html` return cache(html`
${this.render_sidebar()} ${this.render_sidebar()}
<div <div
style="margin-left: 2in; padding: 0px; top: 0; max-height: 100%; overflow: auto" style="margin-left: 2in; padding: 0px; top: 0; max-height: 100%; overflow: auto"
@ -297,7 +297,7 @@ class TfTabNewsElement extends LitElement {
></tf-tab-news-feed> ></tf-tab-news-feed>
</div> </div>
</div> </div>
`; `);
} }
} }

View File

@ -19,8 +19,10 @@ class TfUserElement extends LitElement {
} }
render() { render() {
let user = this.users[this.id];
let shape = user && user.follow_depth >= 2 ? 'w3-circle' : 'w3-round';
let image = html`<span let image = html`<span
class="w3-theme-light w3-circle" class=${'w3-theme-l4 ' + shape}
style="display: inline-block; width: 2em; height: 2em; text-align: center; line-height: 2em" style="display: inline-block; width: 2em; height: 2em; text-align: center; line-height: 2em"
>?</span >?</span
>`; >`;
@ -29,13 +31,13 @@ class TfUserElement extends LitElement {
>${name !== undefined ? name : this.id}</a >${name !== undefined ? name : this.id}</a
>`; >`;
if (this.users[this.id]) { if (user) {
let image_link = this.users[this.id].image; let image_link = user.image;
image_link = image_link =
typeof image_link == 'string' ? image_link : image_link?.link; typeof image_link == 'string' ? image_link : image_link?.link;
if (image_link !== undefined) { if (image_link !== undefined) {
image = html`<img image = html`<img
class="w3-circle" class=${'w3-theme-l4 ' + shape}
style="width: 2em; height: 2em; vertical-align: middle; object-fit: cover" style="width: 2em; height: 2em; vertical-align: middle; object-fit: cover"
src="/${image_link}/view" src="/${image_link}/view"
/>`; />`;

View File

@ -1356,7 +1356,7 @@ bool tf_ssb_connection_is_client(tf_ssb_connection_t* connection)
bool tf_ssb_connection_is_connected(tf_ssb_connection_t* connection) bool tf_ssb_connection_is_connected(tf_ssb_connection_t* connection)
{ {
return connection->state == k_tf_ssb_state_verified || connection->state == k_tf_ssb_state_server_verified; return (connection->state == k_tf_ssb_state_verified || connection->state == k_tf_ssb_state_server_verified) && !connection->is_closing;
} }
bool tf_ssb_connection_is_closing(tf_ssb_connection_t* connection) bool tf_ssb_connection_is_closing(tf_ssb_connection_t* connection)
@ -2795,8 +2795,6 @@ static tf_ssb_connection_t* _tf_ssb_connection_create_internal(tf_ssb_t* ssb, co
connection->next = ssb->connections; connection->next = ssb->connections;
ssb->connections = connection; ssb->connections = connection;
ssb->connections_count++; ssb->connections_count++;
_tf_ssb_notify_connections_changed(ssb, k_tf_ssb_change_create, connection);
return connection; return connection;
} }
@ -2847,6 +2845,7 @@ static tf_ssb_connection_t* _tf_ssb_connection_create(
} }
memcpy(connection->serverpub, public_key, sizeof(connection->serverpub)); memcpy(connection->serverpub, public_key, sizeof(connection->serverpub));
_tf_ssb_notify_connections_changed(ssb, k_tf_ssb_change_create, connection);
connection->tcp.data = connection; connection->tcp.data = connection;
uv_tcp_init(ssb->loop, &connection->tcp); uv_tcp_init(ssb->loop, &connection->tcp);
@ -2928,6 +2927,7 @@ tf_ssb_connection_t* tf_ssb_connection_tunnel_create(tf_ssb_t* ssb, const char*
{ {
tunnel->state = k_tf_ssb_state_server_wait_hello; tunnel->state = k_tf_ssb_state_server_wait_hello;
} }
_tf_ssb_notify_connections_changed(ssb, k_tf_ssb_change_create, connection);
return tunnel; return tunnel;
} }
@ -3058,6 +3058,7 @@ static void _tf_ssb_on_connection(uv_stream_t* stream, int status)
} }
connection->state = k_tf_ssb_state_server_wait_hello; connection->state = k_tf_ssb_state_server_wait_hello;
_tf_ssb_notify_connections_changed(ssb, k_tf_ssb_change_create, connection);
_tf_ssb_connection_read_start(connection); _tf_ssb_connection_read_start(connection);
} }

View File

@ -182,9 +182,10 @@ static void _tf_ssb_connections_update_work(tf_ssb_t* ssb, void* user_data)
if (sqlite3_bind_text(statement, 1, update->host, -1, NULL) == SQLITE_OK && sqlite3_bind_int(statement, 2, update->port) == SQLITE_OK && if (sqlite3_bind_text(statement, 1, update->host, -1, NULL) == SQLITE_OK && sqlite3_bind_int(statement, 2, update->port) == SQLITE_OK &&
sqlite3_bind_text(statement, 3, update->key, -1, NULL) == SQLITE_OK) sqlite3_bind_text(statement, 3, update->key, -1, NULL) == SQLITE_OK)
{ {
if (sqlite3_step(statement) != SQLITE_DONE) int r = sqlite3_step(statement);
if (r != SQLITE_DONE)
{ {
tf_printf("tf_ssb_connections_set_attempted: %s.\n", sqlite3_errmsg(db)); tf_printf("tf_ssb_connections_set_attempted: %s aka %s.\n", sqlite3_errstr(r), sqlite3_errmsg(db));
} }
} }
sqlite3_finalize(statement); sqlite3_finalize(statement);
@ -197,9 +198,10 @@ static void _tf_ssb_connections_update_work(tf_ssb_t* ssb, void* user_data)
if (sqlite3_bind_text(statement, 1, update->host, -1, NULL) == SQLITE_OK && sqlite3_bind_int(statement, 2, update->port) == SQLITE_OK && if (sqlite3_bind_text(statement, 1, update->host, -1, NULL) == SQLITE_OK && sqlite3_bind_int(statement, 2, update->port) == SQLITE_OK &&
sqlite3_bind_text(statement, 3, update->key, -1, NULL) == SQLITE_OK) sqlite3_bind_text(statement, 3, update->key, -1, NULL) == SQLITE_OK)
{ {
if (sqlite3_step(statement) != SQLITE_DONE) int r = sqlite3_step(statement);
if (r != SQLITE_DONE)
{ {
tf_printf("tf_ssb_connections_set_succeeded: %s.\n", sqlite3_errmsg(db)); tf_printf("tf_ssb_connections_set_succeeded: %s aka %s.\n", sqlite3_errstr(r), sqlite3_errmsg(db));
} }
} }
sqlite3_finalize(statement); sqlite3_finalize(statement);
@ -215,7 +217,7 @@ static void _tf_ssb_connections_update_work(tf_ssb_t* ssb, void* user_data)
int r = sqlite3_step(statement); int r = sqlite3_step(statement);
if (r != SQLITE_DONE) if (r != SQLITE_DONE)
{ {
tf_printf("tf_ssb_connections_store: %d, %s.\n", r, sqlite3_errmsg(db)); tf_printf("tf_ssb_connections_store: %s aka %s.\n", sqlite3_errstr(r), sqlite3_errmsg(db));
} }
} }
sqlite3_finalize(statement); sqlite3_finalize(statement);

View File

@ -1455,6 +1455,7 @@ tf_ssb_following_t* tf_ssb_db_following_deep(tf_ssb_t* ssb, const char** ids, in
result[write_index].blocking_count = following[i]->blocking_count; result[write_index].blocking_count = following[i]->blocking_count;
result[write_index].followed_by_count = following[i]->ref_count; result[write_index].followed_by_count = following[i]->ref_count;
result[write_index].blocked_by_count = following[i]->block_ref_count; result[write_index].blocked_by_count = following[i]->block_ref_count;
result[write_index].depth = following[i]->depth;
write_index++; write_index++;
} }
} }

View File

@ -286,6 +286,8 @@ typedef struct _tf_ssb_following_t
int followed_by_count; int followed_by_count;
/** The number of known users blocking the account. */ /** The number of known users blocking the account. */
int blocked_by_count; int blocked_by_count;
/** Degree of separation between initial accounts and this account. */
int depth;
/** The account's identity. */ /** The account's identity. */
char id[k_id_base64_len]; char id[k_id_base64_len];
} tf_ssb_following_t; } tf_ssb_following_t;

View File

@ -1015,6 +1015,7 @@ static JSValue _tf_ssb_connections(JSContext* context, JSValueConst this_val, in
int flags = tf_ssb_connection_get_flags(connection); int flags = tf_ssb_connection_get_flags(connection);
JS_SetPropertyStr(context, flags_object, "one_shot", JS_NewBool(context, (flags & k_tf_ssb_connect_flag_one_shot) != 0)); JS_SetPropertyStr(context, flags_object, "one_shot", JS_NewBool(context, (flags & k_tf_ssb_connect_flag_one_shot) != 0));
JS_SetPropertyStr(context, object, "flags", flags_object); JS_SetPropertyStr(context, object, "flags", flags_object);
JS_SetPropertyStr(context, object, "connected", JS_NewBool(context, tf_ssb_connection_is_connected(connection)));
const char* destroy_reason = tf_ssb_connection_get_destroy_reason(connection); const char* destroy_reason = tf_ssb_connection_get_destroy_reason(connection);
if (destroy_reason) if (destroy_reason)
{ {
@ -2186,6 +2187,7 @@ static void _tf_ssb_following_after_work(tf_ssb_t* ssb, int status, void* user_d
JS_SetPropertyStr(context, entry, "ob", JS_NewInt32(context, following->out_following[i].blocking_count)); JS_SetPropertyStr(context, entry, "ob", JS_NewInt32(context, following->out_following[i].blocking_count));
JS_SetPropertyStr(context, entry, "if", JS_NewInt32(context, following->out_following[i].followed_by_count)); JS_SetPropertyStr(context, entry, "if", JS_NewInt32(context, following->out_following[i].followed_by_count));
JS_SetPropertyStr(context, entry, "ib", JS_NewInt32(context, following->out_following[i].blocked_by_count)); JS_SetPropertyStr(context, entry, "ib", JS_NewInt32(context, following->out_following[i].blocked_by_count));
JS_SetPropertyStr(context, entry, "d", JS_NewInt32(context, following->out_following[i].depth));
JS_SetPropertyStr(context, object, following->out_following[i].id, entry); JS_SetPropertyStr(context, object, following->out_following[i].id, entry);
} }
JSValue result = JS_Call(context, following->promise[0], JS_UNDEFINED, 1, &object); JSValue result = JS_Call(context, following->promise[0], JS_UNDEFINED, 1, &object);

View File

@ -446,8 +446,7 @@ static void _tf_ssb_rpc_send_endpoints(tf_ssb_t* ssb)
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
char id[k_id_base64_len] = { 0 }; char id[k_id_base64_len] = { 0 };
if ((tf_ssb_connection_is_attendant(connections[i]) || tf_ssb_connection_is_endpoint(connections[i])) && if ((tf_ssb_connection_is_attendant(connections[i]) || tf_ssb_connection_is_endpoint(connections[i])) && tf_ssb_connection_is_connected(connections[i]) &&
tf_ssb_connection_is_connected(connections[i]) &&
tf_ssb_connection_get_id(connections[i], id, sizeof(id))) tf_ssb_connection_get_id(connections[i], id, sizeof(id)))
{ {
JS_SetPropertyUint32(context, endpoints, id_count++, JS_NewString(context, id)); JS_SetPropertyUint32(context, endpoints, id_count++, JS_NewString(context, id));