#define _POSIX_C_SOURCE 200809L #include #include #include #include #include #include "auth.h" #include "http.h" #include "timeline.h" #include "log.h" #include "string-util.h" static GtkWidget *window, *scrolled, *list_box; static gchar *html_to_pango(const char *content) { char *str1, *str2; gchar *result; GRegex *regex = NULL; GError *error = NULL; if (!content) { return NULL; } str1 = str_replace(content, "

", ""); if (!str1) { log_msg(LOG_WARNING, "html_to_pango", "failed to parse html"); return NULL; } str2 = str_replace(str1, "

", ""); free(str1); if (!str2) { log_msg(LOG_WARNING, "html_to_pango", "failed to parse html"); return NULL; } regex = g_regex_new("(class|target|rel)=\"(.|\n)*?\"", G_REGEX_CASELESS, 0, &error); if (!regex) { log_msg(LOG_WARNING, "html_to_pango", error->message); g_free(error); return NULL; } result = g_regex_replace(regex, str2, -1, 0, "", 0, &error); free(str2); if (!result) { log_msg(LOG_WARNING, "html_to_pango", error->message); g_free(error); return NULL; } return result; } static gboolean timeline_loaded(gpointer data) { struct timeline *t = data; for (size_t i = 0; i < t->size; i++) { GtkBuilder *post_builder; GObject *post_box, *post_content_label; char *content_markup; content_markup = html_to_pango(t->statuses[i]->content); if (!content_markup) { continue; } post_builder = gtk_builder_new_from_file("data/post.ui"); post_box = gtk_builder_get_object(post_builder, "post_box"); post_content_label = gtk_builder_get_object(post_builder, "content_text"); gtk_label_set_markup(GTK_LABEL(post_content_label), content_markup); gtk_list_box_prepend(GTK_LIST_BOX(list_box), GTK_WIDGET(post_box)); gtk_widget_show_all(GTK_WIDGET(post_box)); } /* gtk_spinner_stop(GTK_SPINNER(spinner)); */ timeline_free(t); return G_SOURCE_REMOVE; } static gpointer load_timeline(gpointer data) { struct timeline *t; t = get_timeline(NULL, NULL, NULL, 20); if (!t) { log_msg(LOG_WARNING, "load_timeline", "failed"); return NULL; } gdk_threads_add_idle(timeline_loaded, t); return NULL; } void create_timeline_window(GtkApplication *app, gpointer user_data) { window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_application(GTK_WINDOW(window), GTK_APPLICATION(app)); gtk_window_set_title(GTK_WINDOW(window), "ap_client"); gtk_window_set_default_size(GTK_WINDOW(window), 800, 600); gtk_container_set_border_width(GTK_CONTAINER(window), 10); scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); list_box = gtk_list_box_new(); gtk_widget_set_valign(GTK_WIDGET(list_box), GTK_ALIGN_CENTER); gtk_widget_set_halign(GTK_WIDGET(list_box), GTK_ALIGN_CENTER); /* spinner = gtk_spinner_new(); */ /* gtk_spinner_start(GTK_SPINNER(spinner)); */ /* gtk_container_add(GTK_CONTAINER(list_box), spinner); */ gtk_container_add(GTK_CONTAINER(window), scrolled); gtk_container_add(GTK_CONTAINER(scrolled), list_box); gtk_widget_show_all(window); g_thread_new("load_timeline_thread", &load_timeline, NULL); }