Add support for receiving federated quote posts and displaying quote posts (can't source them yet)

master
teknomunk 1 year ago
parent 0bfecc9929
commit 837a3b62f9

2
.gitignore vendored

@ -6,7 +6,7 @@ src.bin
debug
release
data/
assets/soapbox/
assets/soapbox*
backup/
vgcore.*
apogee*

@ -1 +1 @@
Subproject commit 7f73d77dd53ce619d2000bec8b5a706b3ba1b366
Subproject commit 9b6e7725a6356f2a6e776dde60c18201a82d6f88

@ -46,6 +46,7 @@ static struct json_object_field status_layout[] = {
JSON_FIELD_DATETIME( published, false ),
JSON_FIELD_INTEGER( in_reply_to, false ),
JSON_FIELD_INTEGER( quote_id, false ),
JSON_FIELD_INTEGER( repost_id, false ),
JSON_FIELD_INTEGER( root_status_id, false ),
JSON_FIELD_INTEGER( reposted_status_id, false ),
@ -57,6 +58,7 @@ static struct json_object_field status_layout[] = {
JSON_FIELD_ARRAY_OF_INTS( likes, false ),
JSON_FIELD_ARRAY_OF_INTS( replies, false ),
JSON_FIELD_ARRAY_OF_INTS( reposts, false ),
JSON_FIELD_ARRAY_OF_INTS( quotes, false ),
JSON_FIELD_ARRAY_OF_INTS( mentions, false ),
JSON_FIELD_ARRAY_OF_TYPE( emoji, false, emoji_type ),
@ -229,7 +231,31 @@ void status_add_mention( struct status* s, int id )
}
void status_add_repost( struct status* s, struct status* repost )
{
// TODO: implement
if( repost->id == 0 ) { return; }
for( int i = 0; i < s->reposts.count; ++i ) {
if( s->reposts.items[i] == repost->id ) {
return;
}
}
int id = repost->id;
array_append( &s->reposts, sizeof(id), &id );
status_save(s);
}
void status_add_quote( struct status* s, struct status* quote )
{
if( quote->id == 0 ) { return; }
for( int i = 0; i < s->quotes.count; ++i ) {
if( s->quotes.items[i] == quote->id ) {
return;
}
}
int id = quote->id;
array_append( &s->quotes, sizeof(id), &id );
status_save(s);
}
bool status_sync_from_activity_pub( struct status* s, struct ap_object* act )
{
@ -260,6 +286,14 @@ bool status_sync_from_activity_pub( struct status* s, struct ap_object* act )
status_free(parent);
}
}
if( act->quote_url ) {
struct status* parent = status_from_uri_or_fetch( act->quote_url );
if( parent ) {
status_make_quote_of( s, parent->id );
// DO NOT SAVE parent! This is done inside status_make_quote_of
status_free(parent);
}
}
for( int i = 0; i < s->emoji.count; ++i ) {
emoji_free( s->emoji.items[i] );
@ -588,6 +622,7 @@ void status_free( struct status* s )
free(s->likes.items);
free(s->replies.items);
free(s->reposts.items);
free(s->quotes.items);
free(s->mentions.items);
for( int i = 0; i < s->emoji.count; ++i ) {
@ -634,26 +669,45 @@ void status_make_reply_to( struct status* s, int in_reply_to_id )
struct status* in_reply_to = status_from_id( in_reply_to_id );
if( !in_reply_to ) {
s->in_reply_to = 0;
} else {
// Setup this status's reply fields
s->in_reply_to = in_reply_to_id;
s->root_status_id = in_reply_to->root_status_id;
return;
}
// Record in parent as reply
status_add_reply( in_reply_to, s );
// Setup this status's reply fields
s->in_reply_to = in_reply_to_id;
s->root_status_id = in_reply_to->root_status_id;
// Mention the account that made the post being replied to
status_add_mention( s, in_reply_to->account_id );
// Record in parent as reply
status_add_reply( in_reply_to, s );
// Mention everytone else in that post
for( int i = 0; i < in_reply_to->mentions.count; ++i ) {
status_add_mention( s, in_reply_to->mentions.items[i] );
}
// Mention the account that made the post being replied to
status_add_mention( s, in_reply_to->account_id );
status_save(in_reply_to);
// Mention everyone else in that post
for( int i = 0; i < in_reply_to->mentions.count; ++i ) {
status_add_mention( s, in_reply_to->mentions.items[i] );
}
status_save(in_reply_to);
status_free(in_reply_to);
}
void status_make_quote_of( struct status* s, int id_quote_of )
{
struct status* quoted_post = status_from_id( id_quote_of );
if( !quoted_post ) {
s->quote_id = 0;
return;
}
// Set quoted id
s->quote_id = id_quote_of;
// Record quote in parent
status_add_quote( quoted_post, s );
// Save and cleanup
status_save( quoted_post );
status_free( quoted_post );
}
void status_get_context( struct status* s, void* ancestors_ptr, void* replies_ptr )
{
struct array_of_status {

@ -26,6 +26,7 @@ struct status
time_t published;
int in_reply_to;
int quote_id;
int repost_id;
int root_status_id;
int reposted_status_id; // if this post was reposted, this will be the id of that status
@ -60,6 +61,11 @@ struct status
int count;
} reposts;
struct {
int* items;
int count;
} quotes;
struct {
int* items;
int count;
@ -101,7 +107,9 @@ void status_get_context( struct status* s, void* ancestors, void* replies );
void status_add_reply( struct status* s, struct status* child );
void status_add_mention( struct status* s, int id );
void status_add_repost( struct status* s, struct status* repost );
void status_add_quote( struct status* s, struct status* quote );
void status_make_reply_to( struct status* s, int in_reply_to );
void status_make_quote_of( struct status* s, int id_quote_of );
void status_add_react( struct status* s, const char* react, struct account* a );
void status_remove_react( struct status* s, const char* react, struct account* a );
void status_add_like( struct status* s, struct account* a );

@ -278,6 +278,27 @@ bool is_local_callback( void* field_data, bool is_read, bool* val )
*val = !s->remote;
return true;
}
bool quote_url_callback( void* field_data, bool is_read, char** val )
{
if( is_read ) { return false; }
struct status* s = field_data;
if( s->quote_id == 0 ) { return false; }
struct status* quoted_post = status_from_id(s->quote_id);
*val = strdup(quoted_post->url );
status_free(quoted_post);
return true;
}
bool quote_visible_callback( void* field_data, bool is_read, bool* val )
{
if( is_read ) { return false; }
struct status* s = field_data;
*val = ( s->quote_id != 0 );
return true;
}
#define OBJ_TYPE struct status
static struct json_object_field content_layout[] = {
@ -332,9 +353,28 @@ static struct json_object_field pleroma_layout[] = {
},
JSON_FIELD_FIXED_BOOL( parent_visible, true ),
JSON_FIELD_FIXED_NULL( pinned_at ),
JSON_FIELD_FIXED_NULL( quote ),
JSON_FIELD_FIXED_NULL( quote_url ),
JSON_FIELD_FIXED_BOOL( quote_visible, false ),
{
.key = "quote",
.offset = offsetof( OBJ_TYPE, quote_id ),
.type = &Status_reference_type,
},
{
.key = "quote_url",
.offset = 0,
.type = &json_field_callback_string,
.string_callback = quote_url_callback,
},
{
.key = "quote_visible",
.offset = 0,
.type = &json_field_bool_callback,
.bool_callback = quote_visible_callback,
},
{
.key = "quotes_count",
.offset = offsetof( OBJ_TYPE, quotes.count ),
.type = &json_field_integer,
},
/*
"spoiler_text": {
"text/plain": ""

Loading…
Cancel
Save