preliminary guild view in the side bar

This commit is contained in:
2019-07-19 20:52:12 +02:00
parent b879151e07
commit af49931b49
11 changed files with 440 additions and 8 deletions

View File

@@ -21,27 +21,27 @@ typedef enum {
/* A direct message channel for 1:1 communication
*/
CHANNEL_TYPE_DM,
CHANNEL_TYPE_DM = 1,
/* A guild voice channel
*/
CHANNEL_TYPE_GUILD_VOICE,
CHANNEL_TYPE_GUILD_VOICE = 2,
/* Group direct message channel 1:N communication
*/
CHANNEL_TYPE_GROUP_DM,
CHANNEL_TYPE_GROUP_DM = 3,
/* Category within a GUILD
*/
CHANNEL_TYPE_GUILD_CATEGORY,
CHANNEL_TYPE_GUILD_CATEGORY = 4,
/* News channel
*/
CHANNEL_TYPE_GUILD_NEWS,
CHANNEL_TYPE_GUILD_NEWS = 5,
/* Guild store, no idea what this is
*/
CHANNEL_TYPE_GUILD_STORE,
CHANNEL_TYPE_GUILD_STORE = 6,
} dc_channel_type_t;
struct dc_channel_;
@@ -51,6 +51,7 @@ dc_channel_t dc_channel_new(void);
dc_channel_t dc_channel_from_json(json_t *j);
char const *dc_channel_id(dc_channel_t c);
char const *dc_channel_name(dc_channel_t c);
dc_channel_type_t dc_channel_type(dc_channel_t c);
bool dc_channel_is_dm(dc_channel_t c);

View File

@@ -1,12 +1,21 @@
#ifndef DC_GUILD_H
#define DC_GUILD_H
#include <dc/channel.h>
#include <jansson.h>
#include <stdint.h>
/* Discords version of groups or chat servers
*/
struct dc_guild_;
typedef struct dc_guild_ *dc_guild_t;
dc_guild_t dc_guild_new(void);
dc_guild_t dc_guild_from_json(json_t *j);
size_t dc_guild_channels(dc_guild_t d);
dc_channel_t dc_guild_nth_channel(dc_guild_t d, size_t idx);
char const *dc_guild_name(dc_guild_t d);
void dc_guild_set_name(dc_guild_t d, char const *val);

View File

@@ -8,6 +8,7 @@
#include <dc/account.h>
#include <dc/channel.h>
#include <dc/gateway.h>
#include <dc/guild.h>
/**
* A session object will contain all information gathered after a user
@@ -86,6 +87,12 @@ dc_channel_t dc_session_make_channel(dc_session_t s, dc_account_t *r,
dc_channel_t dc_session_channel_recipients(dc_session_t s,
dc_account_t *r, size_t sz);
/**
* Add a guild to be managed by this session.
*/
void dc_session_add_guild(dc_session_t s, dc_guild_t g);
GHashTable *dc_session_guilds(dc_session_t s);
/**
* comparision functions for sorting, and finding
*/

View File

@@ -124,7 +124,7 @@ dc_channel_t dc_channel_from_json(json_t *j)
}
v = json_object_get(j, "name");
if (v == NULL && json_is_string(v)) {
if (v != NULL && json_is_string(v)) {
c->name = strdup(json_string_value(v));
}
@@ -237,6 +237,12 @@ json_t *dc_channel_to_json(dc_channel_t c)
return j;
}
char const *dc_channel_name(dc_channel_t c)
{
return_if_true(c == NULL, NULL);
return c->name;
}
char const *dc_channel_id(dc_channel_t c)
{
return_if_true(c == NULL, NULL);

View File

@@ -9,6 +9,8 @@ struct dc_guild_
char *name;
char *id;
GPtrArray *channels;
};
static void dc_guild_free(dc_guild_t ptr)
@@ -16,6 +18,11 @@ static void dc_guild_free(dc_guild_t ptr)
free(ptr->name);
free(ptr->id);
if (ptr->channels != NULL) {
g_ptr_array_unref(ptr->channels);
ptr->channels = NULL;
}
free(ptr);
}
@@ -26,9 +33,64 @@ dc_guild_t dc_guild_new(void)
p->ref.cleanup = (dc_cleanup_t)dc_guild_free;
p->channels = g_ptr_array_new_with_free_func((GDestroyNotify)dc_unref);
if (p->channels == NULL) {
free(p);
return NULL;
}
return dc_ref(p);
}
dc_guild_t dc_guild_from_json(json_t *j)
{
dc_guild_t g = dc_guild_new();
json_t *val = NULL;
json_t *c = NULL;
size_t idx = 0;
val = json_object_get(j, "name");
goto_if_true(val == NULL || !json_is_string(val), error);
g->name = strdup(json_string_value(val));
val = json_object_get(j, "id");
goto_if_true(val == NULL || !json_is_string(val), error);
g->id = strdup(json_string_value(val));
/* there is a ton of more information here, that we should look
* add, including "member_count", "owner_id", but for channels
* will do nicely
*/
val = json_object_get(j, "channels");
goto_if_true(val == NULL || !json_is_array(val), error);
json_array_foreach(val, idx, c) {
dc_channel_t chan = dc_channel_from_json(c);
continue_if_true(chan == NULL);
g_ptr_array_add(g->channels, chan);
}
return g;
error:
dc_unref(g);
return NULL;
}
size_t dc_guild_channels(dc_guild_t d)
{
return_if_true(d == NULL || d->channels == NULL, 0);
return d->channels->len;
}
dc_channel_t dc_guild_nth_channel(dc_guild_t d, size_t idx)
{
return_if_true(d == NULL || d->channels == NULL, NULL);
return_if_true(idx >= d->channels->len, NULL);
return g_ptr_array_index(d->channels, idx);
}
char const *dc_guild_name(dc_guild_t d)
{
return_if_true(d == NULL, NULL);

View File

@@ -12,6 +12,7 @@ struct dc_session_
GHashTable *accounts;
GHashTable *channels;
GHashTable *guilds;
};
/* event handlers
@@ -40,6 +41,11 @@ static void dc_session_free(dc_session_t s)
s->channels = NULL;
}
if (s->guilds != NULL) {
g_hash_table_unref(s->guilds);
s->guilds = NULL;
}
dc_session_logout(s);
dc_unref(s->api);
@@ -79,6 +85,7 @@ static void dc_session_handle_ready(dc_session_t s, dc_event_t e)
size_t idx = 0;
json_t *c = NULL;
json_t *channels = NULL;
json_t *guilds = NULL;
/* retrieve user information about ourselves, including snowflake,
* discriminator, and other things
@@ -127,6 +134,17 @@ static void dc_session_handle_ready(dc_session_t s, dc_event_t e)
}
}
/* load guilds
*/
guilds = json_object_get(r, "guilds");
if (guilds != NULL && json_is_array(guilds)) {
json_array_foreach(guilds, idx, c) {
dc_guild_t guild = dc_guild_from_json(c);
continue_if_true(guild == NULL);
dc_session_add_guild(s, guild);
}
}
/* load channels
*/
channels = json_object_get(r, "private_channels");
@@ -181,6 +199,11 @@ dc_session_t dc_session_new(dc_loop_t loop)
);
goto_if_true(s->channels == NULL, error);
s->guilds = g_hash_table_new_full(g_str_hash, g_str_equal,
free, dc_unref
);
goto_if_true(s->channels == NULL, error);
s->loop = dc_ref(loop);
s->api = dc_api_new();
@@ -394,3 +417,23 @@ dc_channel_t dc_session_channel_recipients(dc_session_t s,
return NULL;
}
GHashTable *dc_session_guilds(dc_session_t s)
{
return_if_true(s == NULL, NULL);
return s->guilds;
}
void dc_session_add_guild(dc_session_t s, dc_guild_t g)
{
return_if_true(s == NULL || g == NULL,);
return_if_true(dc_guild_id(g) == NULL,);
char const *id = dc_guild_id(g);
if (!g_hash_table_contains(s->guilds, id)) {
g_hash_table_insert(s->guilds, strdup(id), dc_ref(g));
/* TODO: dedup for saving storage
*/
}
}