Compare commits
5 Commits
e59a00922b
...
aa15da50ab
Author | SHA1 | Date | |
---|---|---|---|
aa15da50ab | |||
02759c6f83 | |||
6b0c49752c | |||
2e4f792fc3 | |||
17eba059f0 |
@ -1,5 +1,5 @@
|
||||
{
|
||||
"type": "tildefriends-app",
|
||||
"emoji": "🦀",
|
||||
"previous": "&jbL9Ab+XdvWnZbb50yimceFHR7XFDfBSWv9/XrbZ82I=.sha256"
|
||||
"previous": "&caGw+RHTGO/WBWQDiRRv/9/SDZPS3w8U4xNafZEQrYw=.sha256"
|
||||
}
|
||||
|
@ -38,8 +38,8 @@ class TfElement extends LitElement {
|
||||
this.channels = [];
|
||||
this.channels_unread = {};
|
||||
this.channels_latest = {};
|
||||
this.loading_channels_latest = 0;
|
||||
this.loading_channels_latest_scheduled = 0;
|
||||
this.loading_latest = 0;
|
||||
this.loading_latest_scheduled = 0;
|
||||
tfrpc.rpc.getBroadcasts().then((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;
|
||||
let cache = await tfrpc.rpc.databaseGet('about');
|
||||
let original_cache = cache;
|
||||
@ -225,7 +226,11 @@ class TfElement extends LitElement {
|
||||
}
|
||||
users = users || {};
|
||||
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);
|
||||
}
|
||||
@ -248,7 +253,7 @@ class TfElement extends LitElement {
|
||||
this.load_channels();
|
||||
}
|
||||
}
|
||||
this.schedule_load_channels_latest();
|
||||
this.schedule_load_latest();
|
||||
}
|
||||
|
||||
async _handle_whoami_changed(event) {
|
||||
@ -307,7 +312,6 @@ class TfElement extends LitElement {
|
||||
ranges.push([i, Math.min(i + k_chunk_size, latest), true]);
|
||||
}
|
||||
}
|
||||
console.log(cache);
|
||||
for (let range of ranges) {
|
||||
let messages = await tfrpc.rpc.query(
|
||||
`
|
||||
@ -340,13 +344,10 @@ class TfElement extends LitElement {
|
||||
JSON.stringify(cache)
|
||||
);
|
||||
}
|
||||
console.log(cache);
|
||||
return cache.latest;
|
||||
}
|
||||
|
||||
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(
|
||||
@ -392,27 +393,26 @@ class TfElement extends LitElement {
|
||||
});
|
||||
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_latest_timer() {
|
||||
--this.loading_latest_scheduled;
|
||||
this.schedule_load_latest();
|
||||
}
|
||||
|
||||
schedule_load_channels_latest() {
|
||||
if (!this.loading_channels_latest) {
|
||||
schedule_load_latest() {
|
||||
if (!this.loading_latest) {
|
||||
this.shadowRoot.getElementById('tf-tab-news')?.load_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.bind(this), 5000);
|
||||
this.load();
|
||||
} else if (!this.loading_latest_scheduled) {
|
||||
this.loading_latest_scheduled++;
|
||||
setTimeout(this._schedule_load_latest_timer.bind(this), 5000);
|
||||
}
|
||||
}
|
||||
|
||||
async load() {
|
||||
this.loading_latest = true;
|
||||
try {
|
||||
let start_time = new Date();
|
||||
let whoami = this.whoami;
|
||||
let following = await tfrpc.rpc.following([whoami], 2);
|
||||
@ -431,7 +431,8 @@ class TfElement extends LitElement {
|
||||
this.channels_unread = JSON.parse(
|
||||
(await tfrpc.rpc.databaseGet('unread')) ?? '{}'
|
||||
);
|
||||
users = await this.fetch_about(Object.keys(following).sort(), users);
|
||||
this.following = Object.keys(following);
|
||||
users = await this.fetch_about(following, users);
|
||||
console.log(
|
||||
'about took',
|
||||
(new Date() - start_time) / 1000.0,
|
||||
@ -439,13 +440,15 @@ class TfElement extends LitElement {
|
||||
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;
|
||||
} finally {
|
||||
this.loading_latest = false;
|
||||
}
|
||||
}
|
||||
|
||||
channel_set_unread(event) {
|
||||
|
@ -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 tfutils from './tf-utils.js';
|
||||
import * as emojis from './emojis.js';
|
||||
@ -313,7 +313,9 @@ class TfMessageElement extends LitElement {
|
||||
@click=${() => self.set_expanded(false)}
|
||||
>
|
||||
Collapse</button
|
||||
>${(this.message.child_messages || []).map(
|
||||
>${repeat(
|
||||
this.message.child_messages || [],
|
||||
(x) => x.id,
|
||||
(x) =>
|
||||
html`<tf-message
|
||||
.message=${x}
|
||||
@ -589,9 +591,7 @@ class TfMessageElement extends LitElement {
|
||||
let image;
|
||||
let description;
|
||||
if (content.name !== undefined) {
|
||||
name = html`<div>
|
||||
<b>Name:</b> ${content.name}
|
||||
</div>`;
|
||||
name = html`<div><b>Name:</b> ${content.name}</div>`;
|
||||
}
|
||||
if (content.image !== undefined) {
|
||||
image = html`
|
||||
@ -600,18 +600,14 @@ class TfMessageElement extends LitElement {
|
||||
}
|
||||
if (content.description !== undefined) {
|
||||
description = html`
|
||||
<div
|
||||
style="flex: 1 0 50%; overflow-wrap: anywhere"
|
||||
>
|
||||
<div style="flex: 1 0 50%; overflow-wrap: anywhere">
|
||||
<div>${unsafeHTML(tfutils.markdown(content.description))}</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
let update =
|
||||
content.about == this.message.author
|
||||
? html`<div style="font-weight: bold">
|
||||
Updated profile.
|
||||
</div>`
|
||||
? html`<div style="font-weight: bold">Updated profile.</div>`
|
||||
: html`<div style="font-weight: bold">
|
||||
Updated profile for
|
||||
<tf-user id=${content.about} .users=${this.users}></tf-user>.
|
||||
|
@ -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 {styles} from './tf-styles.js';
|
||||
|
||||
@ -198,7 +198,9 @@ class TfNewsElement extends LitElement {
|
||||
}
|
||||
return html`
|
||||
<div>
|
||||
${final_messages.map(
|
||||
${repeat(
|
||||
final_messages,
|
||||
(x) => x.id,
|
||||
(x) => html`
|
||||
<tf-message
|
||||
.message=${x}
|
||||
|
@ -142,12 +142,16 @@ class TfTabConnectionsElement extends LitElement {
|
||||
}, {})
|
||||
);
|
||||
return html`
|
||||
${connection.connected
|
||||
? html`
|
||||
<button
|
||||
class="w3-button w3-theme-d1"
|
||||
@click=${() => tfrpc.rpc.closeConnection(connection.id)}
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
`
|
||||
: undefined}
|
||||
${connection.flags.one_shot ? '🔃' : undefined}
|
||||
<tf-user id=${connection.id} .users=${this.users}></tf-user>
|
||||
${connection.tunnel !== undefined
|
||||
@ -264,24 +268,27 @@ class TfTabConnectionsElement extends LitElement {
|
||||
)}
|
||||
</ul>
|
||||
<h2>Local Accounts</h2>
|
||||
<ul class="w3-ul w3-border">
|
||||
<div class="w3-container">
|
||||
${this.identities.map(
|
||||
(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
|
||||
? html`<span class="w3-tag w3-medium w3-round w3-theme-l1"
|
||||
>🖥 local server</span
|
||||
>`
|
||||
? html`<div class="w3-tag w3-medium w3-round w3-theme-l1">
|
||||
🖥 local server
|
||||
</div>`
|
||||
: undefined}
|
||||
${this.my_identities.indexOf(x) != -1
|
||||
? html`<span class="w3-tag w3-medium w3-round w3-theme-d1"
|
||||
>😎 you</span
|
||||
>`
|
||||
? html`<div class="w3-tag w3-medium w3-round w3-theme-d1">
|
||||
😎 you
|
||||
</div>`
|
||||
: undefined}
|
||||
<tf-user id=${x} .users=${this.users}></tf-user>
|
||||
</li>`
|
||||
</div>`
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
@ -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 {styles} from './tf-styles.js';
|
||||
|
||||
@ -373,7 +373,8 @@ class TfTabNewsFeedElement extends LitElement {
|
||||
if (
|
||||
!this.messages ||
|
||||
this._messages_hash !== this.hash ||
|
||||
this._messages_following !== this.following
|
||||
JSON.stringify(this._messages_following) !==
|
||||
JSON.stringify(this.following)
|
||||
) {
|
||||
console.log(
|
||||
`loading messages for ${this.whoami} (following ${this.following.length})`
|
||||
@ -417,7 +418,7 @@ class TfTabNewsFeedElement extends LitElement {
|
||||
</p>
|
||||
`;
|
||||
}
|
||||
return html`
|
||||
return cache(html`
|
||||
<button class="w3-button w3-theme-d1" @click=${this.mark_all_read}>
|
||||
Mark All Read
|
||||
</button>
|
||||
@ -433,7 +434,7 @@ class TfTabNewsFeedElement extends LitElement {
|
||||
channel_unread=${this.channels_unread?.[this.channel()]}
|
||||
></tf-news>
|
||||
${more}
|
||||
`;
|
||||
`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {styles} from './tf-styles.js';
|
||||
|
||||
@ -238,7 +238,7 @@ class TfTabNewsElement extends LitElement {
|
||||
name.
|
||||
</div>`;
|
||||
}
|
||||
return html`
|
||||
return cache(html`
|
||||
${this.render_sidebar()}
|
||||
<div
|
||||
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>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,8 +19,10 @@ class TfUserElement extends LitElement {
|
||||
}
|
||||
|
||||
render() {
|
||||
let user = this.users[this.id];
|
||||
let shape = user && user.follow_depth >= 2 ? 'w3-circle' : 'w3-round';
|
||||
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"
|
||||
>?</span
|
||||
>`;
|
||||
@ -29,13 +31,13 @@ class TfUserElement extends LitElement {
|
||||
>${name !== undefined ? name : this.id}</a
|
||||
>`;
|
||||
|
||||
if (this.users[this.id]) {
|
||||
let image_link = this.users[this.id].image;
|
||||
if (user) {
|
||||
let image_link = user.image;
|
||||
image_link =
|
||||
typeof image_link == 'string' ? image_link : image_link?.link;
|
||||
if (image_link !== undefined) {
|
||||
image = html`<img
|
||||
class="w3-circle"
|
||||
class=${'w3-theme-l4 ' + shape}
|
||||
style="width: 2em; height: 2em; vertical-align: middle; object-fit: cover"
|
||||
src="/${image_link}/view"
|
||||
/>`;
|
||||
|
@ -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)
|
||||
{
|
||||
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)
|
||||
@ -2795,8 +2795,6 @@ static tf_ssb_connection_t* _tf_ssb_connection_create_internal(tf_ssb_t* ssb, co
|
||||
connection->next = ssb->connections;
|
||||
ssb->connections = connection;
|
||||
ssb->connections_count++;
|
||||
_tf_ssb_notify_connections_changed(ssb, k_tf_ssb_change_create, connection);
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
@ -2847,6 +2845,7 @@ static tf_ssb_connection_t* _tf_ssb_connection_create(
|
||||
}
|
||||
|
||||
memcpy(connection->serverpub, public_key, sizeof(connection->serverpub));
|
||||
_tf_ssb_notify_connections_changed(ssb, k_tf_ssb_change_create, connection);
|
||||
|
||||
connection->tcp.data = connection;
|
||||
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;
|
||||
}
|
||||
_tf_ssb_notify_connections_changed(ssb, k_tf_ssb_change_create, connection);
|
||||
|
||||
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;
|
||||
_tf_ssb_notify_connections_changed(ssb, k_tf_ssb_change_create, connection);
|
||||
_tf_ssb_connection_read_start(connection);
|
||||
}
|
||||
|
||||
|
@ -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 &&
|
||||
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);
|
||||
@ -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 &&
|
||||
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);
|
||||
@ -215,7 +217,7 @@ static void _tf_ssb_connections_update_work(tf_ssb_t* ssb, void* user_data)
|
||||
int r = sqlite3_step(statement);
|
||||
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);
|
||||
|
@ -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].followed_by_count = following[i]->ref_count;
|
||||
result[write_index].blocked_by_count = following[i]->block_ref_count;
|
||||
result[write_index].depth = following[i]->depth;
|
||||
write_index++;
|
||||
}
|
||||
}
|
||||
|
@ -286,6 +286,8 @@ typedef struct _tf_ssb_following_t
|
||||
int followed_by_count;
|
||||
/** The number of known users blocking the account. */
|
||||
int blocked_by_count;
|
||||
/** Degree of separation between initial accounts and this account. */
|
||||
int depth;
|
||||
/** The account's identity. */
|
||||
char id[k_id_base64_len];
|
||||
} tf_ssb_following_t;
|
||||
|
@ -1015,6 +1015,7 @@ static JSValue _tf_ssb_connections(JSContext* context, JSValueConst this_val, in
|
||||
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, 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);
|
||||
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, "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, "d", JS_NewInt32(context, following->out_following[i].depth));
|
||||
JS_SetPropertyStr(context, object, following->out_following[i].id, entry);
|
||||
}
|
||||
JSValue result = JS_Call(context, following->promise[0], JS_UNDEFINED, 1, &object);
|
||||
|
@ -446,8 +446,7 @@ static void _tf_ssb_rpc_send_endpoints(tf_ssb_t* ssb)
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
char id[k_id_base64_len] = { 0 };
|
||||
if ((tf_ssb_connection_is_attendant(connections[i]) || tf_ssb_connection_is_endpoint(connections[i])) &&
|
||||
tf_ssb_connection_is_connected(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_get_id(connections[i], id, sizeof(id)))
|
||||
{
|
||||
JS_SetPropertyUint32(context, endpoints, id_count++, JS_NewString(context, id));
|
||||
|
Loading…
x
Reference in New Issue
Block a user