8 Commits

Author SHA1 Message Date
ddfa84f040 docs: Changlog formatting.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 31m16s
2025-04-23 17:35:16 -04:00
6b3a6ec7c1 httpd: Don't overspecify the redirects.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 34m34s
2025-04-23 12:47:21 -04:00
4d037c02bf build: Let's build 0.0.30.
Some checks failed
Build Tilde Friends / Build-All (push) Has been cancelled
2025-04-23 12:29:42 -04:00
deaeab10d8 update: CodeMirror. 2025-04-23 12:29:02 -04:00
2a5375b1e7 core: Don't start new tasks as we're shutting down. #108
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 31m40s
2025-04-20 18:26:44 -04:00
e7a03e3283 ssb: Slightly faster channel query.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 32m3s
2025-04-20 17:43:53 -04:00
efb3a12dcc ssb: Make the reactions list dialog a bit more compact/concise.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 31m53s
2025-04-20 09:35:39 -04:00
3830d695d7 docs: Getting 0.0.30 ready.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 31m39s
2025-04-20 08:50:10 -04:00
15 changed files with 69 additions and 43 deletions

View File

@ -18,7 +18,7 @@ MAKEFLAGS += --no-builtin-rules
VERSION_CODE := 35 VERSION_CODE := 35
VERSION_CODE_IOS := 12 VERSION_CODE_IOS := 12
VERSION_NUMBER := 0.0.30-wip VERSION_NUMBER := 0.0.30
VERSION_NAME := This program kills fascists. VERSION_NAME := This program kills fascists.
IPHONEOS_VERSION_MIN=14.0 IPHONEOS_VERSION_MIN=14.0

View File

@ -1,5 +1,5 @@
{ {
"type": "tildefriends-app", "type": "tildefriends-app",
"emoji": "🦀", "emoji": "🦀",
"previous": "&jko2iokTaY2t/pD9m4ekMr0wsLjov3LVl9ShysXEjkE=.sha256" "previous": "&Zv/eOewtUPxYuALmYV8v+JDKwH4+aN8zCTYFwB7oYEw=.sha256"
} }

View File

@ -41,18 +41,21 @@ class TfReactionsModalElement extends LitElement {
> >
</header> </header>
<ul class="w3-theme-dark w3-container w3-ul"> <ul class="w3-theme-dark w3-container w3-ul">
${this.votes.map( ${this.votes
.sort((x, y) => y.timestamp - x.timestamp)
.map(
(x) => html` (x) => html`
<li class="w3-bar"> <li style="display: flex; flex-direction: row; gap: 4px">
<span class="w3-bar-item" <span style="flex-basis: 3em"
>${x?.content?.vote?.expression}</span >${x?.content?.vote?.expression}</span
> >
<tf-user <tf-user
class="w3-bar-item" style="flex: 1 1"
id=${x.author} id=${x.author}
.users=${this.users} .users=${this.users}
></tf-user> ></tf-user>
<span class="w3-bar-item w3-right" <span
style="flex-shrink: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis"
>${new Date(x?.timestamp).toLocaleString()}</span >${new Date(x?.timestamp).toLocaleString()}</span
> >
</li> </li>

View File

@ -179,11 +179,10 @@ class TfTabNewsFeedElement extends LitElement {
JOIN messages ON messages.rowid = messages_fts.rowid JOIN messages ON messages.rowid = messages_fts.rowid
JOIN json_each(?1) AS following ON messages.author = following.value JOIN json_each(?1) AS following ON messages.author = following.value
JOIN json_tree(messages.content, '$.mentions') AS mention ON mention.value = '#' || ?4 JOIN json_tree(messages.content, '$.mentions') AS mention ON mention.value = '#' || ?4
), )
news AS (SELECT * FROM all_news SELECT TRUE AS is_primary, all_news.* FROM all_news
WHERE (?2 IS NULL OR all_news.timestamp >= ?2) AND all_news.timestamp < ?3 WHERE (?2 IS NULL OR all_news.timestamp >= ?2) AND all_news.timestamp < ?3
ORDER BY all_news.timestamp DESC LIMIT 20) ORDER BY all_news.timestamp DESC LIMIT 20
SELECT TRUE AS is_primary, news.* FROM news
`, `,
[ [
JSON.stringify(this.following), JSON.stringify(this.following),

File diff suppressed because one or more lines are too long

View File

@ -245,9 +245,9 @@
} }
}, },
"node_modules/@lezer/javascript": { "node_modules/@lezer/javascript": {
"version": "1.4.21", "version": "1.5.1",
"resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.21.tgz", "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.5.1.tgz",
"integrity": "sha512-lL+1fcuxWYPURMM/oFZLEDm0XuLN128QPV+VuGtKpeaOGdcl9F2LYC3nh1S9LkPqx9M0mndZFdXCipNAZpzIkQ==", "integrity": "sha512-ATOImjeVJuvgm3JQ/bpo2Tmv55HSScE2MTPnKRMRIPx2cLhHGyX2VnqpHhtIV1tVzIjZDbcWQm+NCTF40ggZVw==",
"dependencies": { "dependencies": {
"@lezer/common": "^1.2.0", "@lezer/common": "^1.2.0",
"@lezer/highlight": "^1.1.3", "@lezer/highlight": "^1.1.3",

View File

@ -0,0 +1,12 @@
* Faster loads.
* Replication fixes.
* Shutdown fixes.
* Consolidated message actions into a % menu.
* Fixed and tested handling of user permissions.
* Add a very work in progress "web" app.
* Updates:
* CodeMirror
* Lit 3.3.0
* OpenSSL 3.5.0
* c-ares 1.34.5
* libbacktrace

View File

@ -2,7 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.unprompted.tildefriends" package="com.unprompted.tildefriends"
android:versionCode="35" android:versionCode="35"
android:versionName="0.0.30-wip"> android:versionName="0.0.30">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<application <application

View File

@ -1486,17 +1486,9 @@ static void _httpd_endpoint_delete(tf_http_request_t* request)
static void _httpd_endpoint_root_callback(const char* path, void* user_data) static void _httpd_endpoint_root_callback(const char* path, void* user_data)
{ {
tf_http_request_t* request = user_data; tf_http_request_t* request = user_data;
const char* host = tf_http_request_get_header(request, "x-forwarded-host");
if (!host)
{
host = tf_http_request_get_header(request, "host");
}
char url[1024];
snprintf(url, sizeof(url), "%s%s%s", request->is_tls ? "https://" : "http://", host, path ? path : "/~core/apps/");
const char* headers[] = { const char* headers[] = {
"Location", "Location",
url, path ? path : "/~core/apps/",
}; };
tf_http_respond(request, 303, headers, tf_countof(headers) / 2, NULL, 0); tf_http_respond(request, 303, headers, tf_countof(headers) / 2, NULL, 0);
tf_http_request_unref(request); tf_http_request_unref(request);

View File

@ -196,9 +196,8 @@ void tf_ssb_db_init(tf_ssb_t* ssb)
_tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_timestamp_index ON messages (timestamp)"); _tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_timestamp_index ON messages (timestamp)");
_tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_type_timestamp_index ON messages (content ->> 'type', timestamp)"); _tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_type_timestamp_index ON messages (content ->> 'type', timestamp)");
_tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_size_by_author_index ON messages (author, length(content))"); _tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_size_by_author_index ON messages (author, length(content))");
_tf_ssb_db_exec(db, _tf_ssb_db_exec(db, "DROP INDEX IF EXISTS messages_type_author_channel_root_timestamp_index ");
"CREATE INDEX IF NOT EXISTS messages_type_author_channel_root_timestamp_index ON messages (author, timestamp, content ->> 'type', content ->> 'channel', content ->> " _tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_channel_author_timestamp_root_index ON messages (content ->> 'channel', author, timestamp, content ->> 'root')");
"'root')");
_tf_ssb_db_exec(db, "DROP INDEX IF EXISTS messages_type_author_channel_index"); _tf_ssb_db_exec(db, "DROP INDEX IF EXISTS messages_type_author_channel_index");
_tf_ssb_db_exec(db, "DROP INDEX IF EXISTS messages_author_id_index"); _tf_ssb_db_exec(db, "DROP INDEX IF EXISTS messages_author_id_index");
_tf_ssb_db_exec(db, "DROP INDEX IF EXISTS messages_by_author_index"); _tf_ssb_db_exec(db, "DROP INDEX IF EXISTS messages_by_author_index");

View File

@ -165,7 +165,8 @@ static bool _tf_ssb_register_app(tf_ssb_t* ssb, const char* user, const char* ap
bool result = false; bool result = false;
sqlite3_stmt* statement; sqlite3_stmt* statement;
sqlite3* db = tf_ssb_acquire_db_writer(ssb); sqlite3* db = tf_ssb_acquire_db_writer(ssb);
if (sqlite3_prepare(db, "INSERT INTO properties (id, key, value) VALUES (?1, 'path:' || ?2, ?3) ON CONFLICT DO UPDATE SET value = excluded.value WHERE value != excluded.value", -1, &statement, NULL) == SQLITE_OK) if (sqlite3_prepare(db, "INSERT INTO properties (id, key, value) VALUES (?1, 'path:' || ?2, ?3) ON CONFLICT DO UPDATE SET value = excluded.value WHERE value != excluded.value",
-1, &statement, NULL) == SQLITE_OK)
{ {
if (sqlite3_bind_text(statement, 1, user, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, app, -1, NULL) == SQLITE_OK && if (sqlite3_bind_text(statement, 1, user, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, app, -1, NULL) == SQLITE_OK &&
sqlite3_bind_text(statement, 3, id, -1, NULL) == SQLITE_OK && sqlite3_step(statement) == SQLITE_DONE) sqlite3_bind_text(statement, 3, id, -1, NULL) == SQLITE_OK && sqlite3_step(statement) == SQLITE_DONE)

View File

@ -119,6 +119,7 @@ typedef struct _tf_task_t
bool _trusted; bool _trusted;
bool _one_proc; bool _one_proc;
bool _killed; bool _killed;
bool _shutting_down;
char _scriptName[256]; char _scriptName[256];
int _global_exception_count; int _global_exception_count;
@ -1818,6 +1819,8 @@ JSValue tf_taskstub_kill(tf_taskstub_t* stub);
void tf_task_destroy(tf_task_t* task) void tf_task_destroy(tf_task_t* task)
{ {
task->_shutting_down = true;
while (task->_children) while (task->_children)
{ {
for (task_child_node_t* node = task->_children; node; node = node->next) for (task_child_node_t* node = task->_children; node; node = node->next)
@ -2162,6 +2165,11 @@ void tf_task_set_android_service_callbacks(tf_android_start_service_t* start_ser
s_android_stop_service = stop_service; s_android_stop_service = stop_service;
} }
bool tf_task_is_shutting_down(tf_task_t* task)
{
return task && task->_shutting_down;
}
tf_android_start_service_t* tf_task_get_android_start_service() tf_android_start_service_t* tf_task_get_android_start_service()
{ {
return s_android_start_service; return s_android_start_service;

View File

@ -364,4 +364,11 @@ tf_android_stop_service_t* tf_task_get_android_stop_service();
*/ */
void tf_task_check_jobs(tf_task_t* task); void tf_task_check_jobs(tf_task_t* task);
/**
** Check whether tf_task_destroy has been called already.
** @param task The task.
** @return true if the task is in the process of shutting down.
*/
bool tf_task_is_shutting_down(tf_task_t* task);
/** @} */ /** @} */

View File

@ -125,6 +125,11 @@ static void _tf_taskstub_packetstream_close(void* user_data)
static JSValue _taskstub_create(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) static JSValue _taskstub_create(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{ {
tf_task_t* parent = tf_task_get(context); tf_task_t* parent = tf_task_get(context);
if (parent && tf_task_is_shutting_down(parent))
{
return JS_UNDEFINED;
}
tf_taskstub_t* stub = tf_malloc(sizeof(tf_taskstub_t)); tf_taskstub_t* stub = tf_malloc(sizeof(tf_taskstub_t));
memset(stub, 0, sizeof(*stub)); memset(stub, 0, sizeof(*stub));
stub->_stream = tf_packetstream_create(); stub->_stream = tf_packetstream_create();

View File

@ -1,2 +1,2 @@
#define VERSION_NUMBER "0.0.30-wip" #define VERSION_NUMBER "0.0.30"
#define VERSION_NAME "This program kills fascists." #define VERSION_NAME "This program kills fascists."