diff options
-rw-r--r-- | src/main.c | 20 | ||||
-rw-r--r-- | src/status.c | 24 | ||||
-rw-r--r-- | src/status.h | 4 | ||||
-rw-r--r-- | src/timeline.c | 96 | ||||
-rw-r--r-- | src/timeline.h | 4 | ||||
-rw-r--r-- | src/timeline_window.c | 53 |
6 files changed, 77 insertions, 124 deletions
@@ -12,10 +12,19 @@ #include "timeline_window.h" #include "log.h" +static void startup(GtkApplication *app, gpointer user_data) +{ + config_load(); + if (http_init()) { + exit(EXIT_FAILURE); + } +} + static void activate(GtkApplication *app, gpointer user_data) { if (read_local_credentials()) { - create_login_window(app, user_data); + /* create_login_window(app, user_data); */ + log_msg(LOG_WARNING, "activate", "failed to read config files"); return; } create_timeline_window(app, NULL); @@ -23,21 +32,14 @@ static void activate(GtkApplication *app, gpointer user_data) int main(int argc, char **argv) { - if (http_init()) { - log_msg(LOG_ERROR, "main", "failed to load http library"); - return EXIT_FAILURE; - } - - config_load(); - GtkApplication *app; int status; app = gtk_application_new("org.gtk.ap_client", G_APPLICATION_FLAGS_NONE); + g_signal_connect(app, "startup", G_CALLBACK(startup), NULL); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); status = g_application_run(G_APPLICATION(app), argc, argv); g_object_unref(app); - http_cleanup(); config_cleanup(); diff --git a/src/status.c b/src/status.c index 139c719..69d1fa2 100644 --- a/src/status.c +++ b/src/status.c @@ -5,39 +5,40 @@ #include "status.h" #include "log.h" -struct status *status_from_json(char *json_data) +struct status *status_from_json(const char *json_data) { + struct status *s; json_t *root; json_error_t error; root = json_loads(json_data, 0, &error); if (!root) { - log_msg(LOG_ERROR, "status_from_json", "json parse error: line %d: %s", + log_msg(LOG_WARNING, "status_from_json", "json parse error: line %d: %s", error.line, error.text); return NULL; } - return status_from_json_t(root); + s = status_from_json_t(root); + json_decref(root); + return s; } -struct status *status_from_json_t(json_t *root) +struct status *status_from_json_t(const json_t *root) { struct status *s; if (!root) { - log_msg(LOG_ERROR, "status_from_json_t", "json data is null"); + log_msg(LOG_WARNING, "status_from_json_t", "json data is null"); return NULL; } if (!json_is_object(root)) { - log_msg(LOG_ERROR, "status_from_json_t", "json root is not object"); - json_decref(root); + log_msg(LOG_WARNING, "status_from_json_t", "json root is not object"); return NULL; } s = calloc(1, sizeof(struct status)); if (!s) { - err(1, NULL); - json_decref(root); + err(1, "status_from_json_t"); return NULL; } @@ -88,16 +89,11 @@ struct status *status_from_json_t(json_t *root) s->favourites_count = json_integer_value(favourites_count); } - json_decref(root); return s; } void status_free(struct status *s) { - if (!s) { - log_msg(LOG_ERROR, "status_free", "status not initializes"); - return; - } if (s->id) free(s->id); if (s->uri) diff --git a/src/status.h b/src/status.h index ede3540..a065f50 100644 --- a/src/status.h +++ b/src/status.h @@ -24,8 +24,8 @@ struct status { bool sensitive; }; -struct status *status_from_json(char *); -struct status *status_from_json_t(json_t *); +struct status *status_from_json(const char *); +struct status *status_from_json_t(const json_t *); void status_free(struct status *); #endif diff --git a/src/timeline.c b/src/timeline.c index fbd123e..753f9f1 100644 --- a/src/timeline.c +++ b/src/timeline.c @@ -13,19 +13,18 @@ static char *timeline_url = "/api/v1/timelines/home"; struct timeline *timeline_from_json(const char *json_data) { + struct timeline *t; json_t *root; json_error_t error; - struct timeline *t; root = json_loads(json_data, 0, &error); - if (!root) { - log_msg(LOG_ERROR, "timeline_free", "json root it null"); + log_msg(LOG_WARNING, "timeline_from_json", "json root it null"); return NULL; } if (!json_is_array(root)) { - log_msg(LOG_ERROR, "timeline_free", "timeline not initialized"); + log_msg(LOG_WARNING, "timeline_from_json", "json root is not array"); json_decref(root); return NULL; } @@ -41,12 +40,13 @@ struct timeline *timeline_from_json(const char *json_data) t->statuses = calloc(t->size, sizeof(struct status *)); if (!(t->statuses)) { err(1, NULL); + timeline_free(t); json_decref(root); return NULL; } + json_t *data; for (size_t i = 0; i < t->size; i++) { - json_t *data; data = json_array_get(root, i); if (!data) goto error; @@ -65,94 +65,42 @@ error: void timeline_free(struct timeline *t) { - if (!t) { - log_msg(LOG_ERROR, "timeline_free", "timeline not initialized"); - return; - } for (size_t i = 0; i < t->size; i++) { if (t->statuses[i]) status_free(t->statuses[i]); } + free(t->statuses); free(t); } -struct load_timeline_call_arg { - char *url; - void (*callback)(bool, struct timeline *t); -}; - -static void *load_timeline_call(void *req_arg) -{ - struct load_timeline_call_arg *arg; - char *resp; - struct timeline *t; - - arg = (struct load_timeline_call_arg *)req_arg; - if (!(arg->url)) { - log_msg(LOG_ERROR, "load_timeline_call", "invalid arguments"); - goto error; - } - - resp = get_request(arg->url); - if (!resp) { - log_msg(LOG_ERROR, "load_timeline_call", "failed to send http request"); - goto error; - } - - if (!resp) { - log_msg(LOG_ERROR, "load_timeline_call", "null response"); - goto error; - } - - t = timeline_from_json(resp); - if (!t) { - log_msg(LOG_ERROR, "load_timeline_call", "null response"); - goto error; - } - - free(arg->url); - free(arg); - free(resp); - - (*(arg->callback))(true, t); - return NULL; - -error: - if (arg->url) - free(arg->url); - free(arg); - if (resp) - free(resp); - (*(arg->callback))(false, NULL); - return NULL; -} - -int get_timeline(const char *max_id, const char *since_id, const char *min_id, - int limit, void (*callback)(bool success, struct timeline *t)) +struct timeline *get_timeline(const char *max_id, const char *since_id, const char *min_id, + int limit) { + char *url, *resp; size_t size; - char *url; - struct load_timeline_call_arg *arg; - pthread_t t; + struct timeline *t; size = strlen(get_instance_url()) + strlen(timeline_url) + 1; url = malloc(size); if (!url) { - err(1, NULL); - return -1; + err(1, "get_timeline"); + return NULL; } strlcpy(url, get_instance_url(), size); strlcat(url, timeline_url, size); - arg = calloc(1, sizeof(struct load_timeline_call_arg)); - if (!arg) { - err(1, NULL); - return -1; + resp = get_request(url); + free(url); + if (!resp) { + return NULL; } - arg->url = url; - arg->callback = callback; + t = timeline_from_json(resp); + free(resp); + if (!t) { + return NULL; + } - return pthread_create(&t, NULL, &load_timeline_call, arg); + return t; } diff --git a/src/timeline.h b/src/timeline.h index ea72e5c..296bbe8 100644 --- a/src/timeline.h +++ b/src/timeline.h @@ -10,7 +10,7 @@ struct timeline { struct timeline *timeline_from_json(const char *); void timeline_free(struct timeline *); -int get_timeline(const char *max_id, const char *since_id, const char *min_id, - int limit, void (*callback)(bool success, struct timeline *t)); +struct timeline *get_timeline(const char *max_id, const char *since_id, const char *min_id, + int limit); #endif diff --git a/src/timeline_window.c b/src/timeline_window.c index 10f2a84..516f2d6 100644 --- a/src/timeline_window.c +++ b/src/timeline_window.c @@ -9,46 +9,53 @@ #include "timeline.h" #include "log.h" -static GtkWidget *window; -static GtkWidget *box; -static GtkWidget *label; +static GtkWidget *window, *spinner, *list_box; -static void timeline_callback(bool success, struct timeline *t) +static gboolean timeline_loaded(gpointer data) { + struct timeline *t = data; + GtkWidget *label; for (size_t i = 0; i < t->size; i++) { - printf("status id: %s\n", t->statuses[i]->id); - printf("content: %s\n", t->statuses[i]->content); - printf("reblog count: %d\n", t->statuses[i]->reblogs_count); - printf("fav count: %d\n", t->statuses[i]->favourites_count); - printf("\n"); + label = gtk_label_new(t->statuses[i]->content); + gtk_widget_show(GTK_WIDGET(label)); + gtk_list_box_prepend(GTK_LIST_BOX(list_box), GTK_WIDGET(label)); } + gtk_spinner_stop(GTK_SPINNER(spinner)); + timeline_free(t); + return G_SOURCE_REMOVE; } -static void load_timeline() +static gpointer load_timeline(gpointer data) { - if (get_timeline(NULL, NULL, NULL, 20, &timeline_callback)) { - log_msg(LOG_ERROR, "load_timeline", "failed"); - return; + struct timeline *t; + t = get_timeline(NULL, NULL, NULL, 20); + if (!t) { + log_msg(LOG_WARNING, "load_timeline", "failed"); + return NULL; } - return; + gdk_threads_add_idle(timeline_loaded, t); + return NULL; } void create_timeline_window(GtkApplication *app, gpointer user_data) { - window = gtk_application_window_new(app); + 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); + gtk_window_set_destroy_with_parent(GTK_WINDOW(window), true); - box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); - gtk_widget_set_valign(GTK_WIDGET(box), GTK_ALIGN_CENTER); - gtk_widget_set_halign(GTK_WIDGET(box), GTK_ALIGN_CENTER); + 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); - label = gtk_label_new("timeline"); - - gtk_container_add(GTK_CONTAINER(window), box); - gtk_container_add(GTK_CONTAINER(box), label); + spinner = gtk_spinner_new(); + gtk_spinner_start(GTK_SPINNER(spinner)); + gtk_container_add(GTK_CONTAINER(list_box), spinner); + gtk_container_add(GTK_CONTAINER(window), list_box); gtk_widget_show_all(window); - load_timeline(); + + g_thread_new("load_timeline_thread", &load_timeline, NULL); } |