summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.c20
-rw-r--r--src/status.c24
-rw-r--r--src/status.h4
-rw-r--r--src/timeline.c96
-rw-r--r--src/timeline.h4
-rw-r--r--src/timeline_window.c53
6 files changed, 77 insertions, 124 deletions
diff --git a/src/main.c b/src/main.c
index bf23496..c1c97f4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);
}