diff --git a/src/ap b/src/ap index 70380d7..4257ba4 160000 --- a/src/ap +++ b/src/ap @@ -1 +1 @@ -Subproject commit 70380d76001d6f7c82206fec5e0575fd3eb8b0d7 +Subproject commit 4257ba45412070f3d6a7ac2bd42b4f488b4c5761 diff --git a/src/model/account.h b/src/model/account.h index 57903c8..1da95aa 100644 --- a/src/model/account.h +++ b/src/model/account.h @@ -17,6 +17,8 @@ enum { owner_account_id = 0, home_timeline_id = 1, public_timeline_id = 2, + + poll_vote_unknown_id = 3, }; struct string_pair diff --git a/src/model/status.c b/src/model/status.c index 1962149..0902ae9 100644 --- a/src/model/status.c +++ b/src/model/status.c @@ -321,6 +321,64 @@ void status_add_quote( struct status* s, struct status* quote ) array_append( &s->quotes, sizeof(id), &id ); status_save(s); } + +static void sync_poll( struct status* s, void* poll_data_ptr ) +{ + struct { + struct ap_object_ptr_or_ref* items; + int count; + } *poll_data = poll_data_ptr; + + // Pull in options + for( int i = 0; i < poll_data->count; ++i ) { + if( poll_data->items[i].tag == apaot_ref ) { + printf( "TODO: automatically dereference poll option data at %s\n", poll_data->items[i].ref ); + } else if( poll_data->items[i].tag != apaot_object ) { + continue; + } + + printf( "Processing option[%d]\n", i ); + struct ap_object* option = poll_data->items[i].ptr; + + // Expand options if there aren't enough already + struct status_poll_option* o; + if( s->poll->options.count <= i ) { + o = malloc(sizeof(*o)); + memset(o,0,sizeof(*o)); + + array_append( &s->poll->options, sizeof(o), &o ); + } + o = s->poll->options.items[i]; + + // Update option title + if( option->name ) { + if( o->title ) { + free( o->title ); + } + o->title = strdup(option->name); + printf( "Option[%d] is %s\n", i, o->title ); + } + + // Pull out vote counts + if( option->replies.tag == apaot_object ) { + printf( "Syncing reply count..\n" ); + struct ap_object* replies = option->replies.ptr; + + while( s->poll->options.items[i]->votes.count < replies->total_items ) { + int id = poll_vote_unknown_id; + array_append( &o->votes, sizeof(id), &id ); + } + } + } + + // Rebuild votes_count + s->poll->votes_count = 0; + for( int i = 0; i < s->poll->options.count; ++i ) { + s->poll->votes_count += s->poll->options.items[i]->votes.count; + } +} + +// TODO: Move to src/model/status/ap_sync.c bool status_sync_from_activity_pub( struct status* s, struct ap_object* act ) { if( !act->actor && act->attributed_to ) { @@ -399,6 +457,35 @@ bool status_sync_from_activity_pub( struct status* s, struct ap_object* act ) } } + // TODO: move this out to another function to use same code for any_of and one_of + if( act->one_of.count > 0 ) { + if( !s->poll ) { + struct status_poll* poll; + poll = malloc(sizeof(*poll)); + memset(poll,0,sizeof(*poll)); + + poll->id = 1; + poll->multiple_choice = false; + + s->poll = poll; + } + + sync_poll( s, &act->one_of ); + } else if( act->any_of.count > 0 ) { + if( !s->poll ) { + struct status_poll* poll; + poll = malloc(sizeof(*poll)); + memset(poll,0,sizeof(*poll)); + + poll->id = 1; + poll->multiple_choice = true; + + s->poll = poll; + } + + sync_poll( s, &act->any_of ); + } + for( int i = 0; i < s->emoji.count; ++i ) { emoji_free( s->emoji.items[i] ); } @@ -425,7 +512,7 @@ bool status_sync_from_activity_pub( struct status* s, struct ap_object* act ) array_append( &s->emoji, sizeof(e), &e ); } else if( tag->type == aptag_hashtag && tag->name ) { char* tag_name = safe_strdup( &tag->name[1] ); - array_append( &s->tags, sizeof(tag_name), &tag_name ); + status_add_tag( s, tag_name ); } }