From 486e8d162325e8801ff6ce83c384c2a154da1a65 Mon Sep 17 00:00:00 2001 From: "me@ow.nekobit.net" Date: Wed, 4 May 2022 19:38:45 +0000 Subject: [PATCH] Highlight search results FossilOrigin-Name: 07c38c75955f3af6c80852b40b0665f7edd48054ef8d688e0981b5a0971b2d6b --- dist/treebird20.css | 5 +++++ src/account.c | 6 +++--- src/notifications.c | 2 +- src/search.c | 5 ++++- src/status.c | 38 +++++++++++++++++++++++++++++++------- src/status.h | 18 ++++++++++++++++-- src/timeline.c | 8 ++++---- 7 files changed, 64 insertions(+), 18 deletions(-) diff --git a/dist/treebird20.css b/dist/treebird20.css index e9d3daa..3d4b57c 100644 --- a/dist/treebird20.css +++ b/dist/treebird20.css @@ -260,6 +260,11 @@ table.present th, table.present td font-weight: bold; } +.search-highlight +{ + background-color: yellow; +} + /************************************************* * BUTTONS * *************************************************/ diff --git a/src/account.c b/src/account.c index 7c54796..37f4365 100644 --- a/src/account.c +++ b/src/account.c @@ -72,7 +72,7 @@ static char* account_statuses_cb(struct session* ssn, statuses_html = construct_error(storage.error, E_ERROR, 1, NULL); } else { - statuses_html = construct_statuses(api, statuses, statuses_len, NULL); + statuses_html = construct_statuses(api, statuses, statuses_len, NULL, NULL); if (!statuses_html) statuses_html = construct_error("No statuses", E_NOTICE, 1, NULL); } @@ -438,7 +438,7 @@ void content_account_bookmarks(struct session* ssn, mastodont_t* api, char** dat } else { // Construct statuses into HTML - status_format = construct_statuses(api, statuses, status_count, &statuses_html_count); + status_format = construct_statuses(api, statuses, status_count, NULL, &statuses_html_count); if (!status_format) status_format = construct_error("Couldn't load posts", E_ERROR, 1, NULL); } @@ -498,7 +498,7 @@ void content_account_favourites(struct session* ssn, mastodont_t* api, char** da } else { // Construct statuses into HTML - status_format = construct_statuses(api, statuses, status_count, &statuses_html_count); + status_format = construct_statuses(api, statuses, status_count, NULL, &statuses_html_count); if (!status_format) status_format = construct_error("Couldn't load posts", E_ERROR, 1, NULL); } diff --git a/src/notifications.c b/src/notifications.c index b97bfd8..9ecdd4b 100644 --- a/src/notifications.c +++ b/src/notifications.c @@ -53,7 +53,7 @@ char* construct_notification(mastodont_t* api, if (notif->status) { // Construct status with notification_info - notif_html = construct_status(api, notif->status, &s, notif, 0); + notif_html = construct_status(api, notif->status, &s, notif, NULL, 0); } else { notif_html = construct_notification_action(notif, &s); diff --git a/src/search.c b/src/search.c index 1057476..abfd1f8 100644 --- a/src/search.c +++ b/src/search.c @@ -83,7 +83,10 @@ void content_search_statuses(struct session* ssn, mastodont_t* api, char** data) &args, &results) == 0) { - statuses_html = construct_statuses(api, results.statuses, results.statuses_len, NULL); + struct construct_statuses_args statuses_args = { + .highlight_word = ssn->query.query, + }; + statuses_html = construct_statuses(api, results.statuses, results.statuses_len, &statuses_args, NULL); if (!statuses_html) statuses_html = construct_error("No statuses", E_ERROR, 1, NULL); } diff --git a/src/status.c b/src/status.c index b7948ce..02304a9 100644 --- a/src/status.c +++ b/src/status.c @@ -50,6 +50,7 @@ struct status_args { mastodont_t* api; struct mstdnt_status* status; + struct construct_statuses_args* args; }; int try_post_status(struct session* ssn, mastodont_t* api) @@ -348,6 +349,7 @@ char* construct_status(mastodont_t* api, struct mstdnt_status* local_status, int* size, struct mstdnt_notification* local_notif, + struct construct_statuses_args* args, uint8_t flags) { char* stat_html; @@ -409,7 +411,24 @@ char* construct_status(mastodont_t* api, notif_reblog.type = MSTDNT_NOTIFICATION_REBLOG; notif = ¬if_reblog; } + + // Format status char* parse_content = reformat_status(status->content, status->emojis, status->emojis_len); + // Find and replace + if (args && args->highlight_word) + { + char* parse_content_tmp; + char* repl_str; + easprintf(&repl_str, "%s", args->highlight_word); + parse_content_tmp = parse_content; + parse_content = strrepl(parse_content, args->highlight_word, repl_str, STRREPL_ALL); + if (parse_content != parse_content_tmp) + free(parse_content_tmp); + else // No results, move back + parse_content = parse_content_tmp; + + free(repl_str); + } if (status->replies_count) easprintf(&reply_count, NUM_STR, status->replies_count); @@ -498,17 +517,22 @@ char* construct_status(mastodont_t* api, static char* construct_status_voidwrap(void* passed, size_t index, int* res) { struct status_args* args = passed; - return construct_status(args->api, args->status + index, res, NULL, 0); + return construct_status(args->api, args->status + index, res, NULL, args->args, 0); } -char* construct_statuses(mastodont_t* api, struct mstdnt_status* statuses, size_t size, size_t* ret_size) +char* construct_statuses(mastodont_t* api, + struct mstdnt_status* statuses, + size_t size, + struct construct_statuses_args* args, + size_t* ret_size) { if (!(statuses && size)) return NULL; - struct status_args args = { + struct status_args stat_args = { .api = api, .status = statuses, + .args = args, }; - return construct_func_strings(construct_status_voidwrap, &args, size, ret_size); + return construct_func_strings(construct_status_voidwrap, &stat_args, size, ret_size); } void status_interact(struct session* ssn, mastodont_t* api, char** data) @@ -556,10 +580,10 @@ void content_status(struct session* ssn, mastodont_t* api, char** data, int is_r stat_html = construct_error("Status not found", E_ERROR, 1, NULL); } else { - before_html = construct_statuses(api, statuses_before, stat_before_len, NULL); + before_html = construct_statuses(api, statuses_before, stat_before_len, NULL, 0); // Current status - stat_html = construct_status(api, &status, NULL, NULL, STATUS_FOCUSED); + stat_html = construct_status(api, &status, NULL, NULL, NULL, STATUS_FOCUSED); if (is_reply) { stat_reply = reply_status(data[0], @@ -568,7 +592,7 @@ void content_status(struct session* ssn, mastodont_t* api, char** data, int is_r } // After... - after_html = construct_statuses(api, statuses_after, stat_after_len, NULL); + after_html = construct_statuses(api, statuses_after, stat_after_len, NULL, 0); easprintf(&output, "%s%s%s%s", before_html ? before_html : "", diff --git a/src/status.h b/src/status.h index 90a7bee..24082df 100644 --- a/src/status.h +++ b/src/status.h @@ -27,6 +27,11 @@ #define STATUS_FOCUSED (1<<0) #define STATUS_EMOJI_PICKER (1<<1) +struct construct_statuses_args +{ + char* highlight_word; +}; + struct interact_profile_args { struct mstdnt_account* reblogs; @@ -43,8 +48,17 @@ void content_status_create(struct session* ssn, mastodont_t* api, char** data); char* construct_post_box(char* reply_id, char* default_content, int* size); -char* construct_status(mastodont_t* api, struct mstdnt_status* status, int* size, struct mstdnt_notification* notif, uint8_t flags); -char* construct_statuses(mastodont_t* api, struct mstdnt_status* statuses, size_t size, size_t* ret_size); +char* construct_status(mastodont_t* api, + struct mstdnt_status* status, + int* size, + struct mstdnt_notification* notif, + struct construct_statuses_args* args, + uint8_t flags); +char* construct_statuses(mastodont_t* api, + struct mstdnt_status* statuses, + size_t size, + struct construct_statuses_args* args, + size_t* ret_size); // Reply to char* get_in_reply_to(mastodont_t* api, struct mstdnt_status* status, size_t* size); diff --git a/src/timeline.c b/src/timeline.c index 26b9042..937bbb7 100644 --- a/src/timeline.c +++ b/src/timeline.c @@ -61,7 +61,7 @@ void tl_home(struct session* ssn, mastodont_t* api, int local) } else { // Construct statuses into HTML - status_format = construct_statuses(api, statuses, status_count, &statuses_html_count); + status_format = construct_statuses(api, statuses, status_count, NULL, &statuses_html_count); if (!status_format) status_format = construct_error("Couldn't load posts", E_ERROR, 1, NULL); } @@ -126,7 +126,7 @@ void tl_direct(struct session* ssn, mastodont_t* api) } else { // Construct statuses into HTML - status_format = construct_statuses(api, statuses, status_count, &statuses_html_count); + status_format = construct_statuses(api, statuses, status_count, NULL, &statuses_html_count); if (!status_format) status_format = construct_error("Couldn't load posts", E_ERROR, 1, NULL); } @@ -196,7 +196,7 @@ void tl_public(struct session* ssn, mastodont_t* api, int local, enum base_categ } else { // Construct statuses into HTML - status_format = construct_statuses(api, statuses, status_count, &statuses_html_count); + status_format = construct_statuses(api, statuses, status_count, NULL, &statuses_html_count); if (!status_format) status_format = construct_error("Couldn't load posts", E_ERROR, 1, NULL); } @@ -259,7 +259,7 @@ void tl_list(struct session* ssn, mastodont_t* api, char* list_id) } else { // Construct statuses into HTML - status_format = construct_statuses(api, statuses, status_count, &statuses_html_count); + status_format = construct_statuses(api, statuses, status_count, NULL, &statuses_html_count); if (!status_format) status_format = construct_error("No statuses", E_ERROR, 1, NULL); }