introduce a /join command for guild text channels

This commit is contained in:
Florian Stinglmayr 2019-07-20 12:51:07 +02:00
parent ec41ec2c87
commit d86a386edd
12 changed files with 164 additions and 32 deletions

View File

@ -16,6 +16,7 @@ dc_guild_t dc_guild_from_json(json_t *j);
size_t dc_guild_channels(dc_guild_t d); size_t dc_guild_channels(dc_guild_t d);
dc_channel_t dc_guild_nth_channel(dc_guild_t d, size_t idx); dc_channel_t dc_guild_nth_channel(dc_guild_t d, size_t idx);
dc_channel_t dc_guild_channel_by_name(dc_guild_t g, char const *name);
char const *dc_guild_name(dc_guild_t d); char const *dc_guild_name(dc_guild_t d);
void dc_guild_set_name(dc_guild_t d, char const *val); void dc_guild_set_name(dc_guild_t d, char const *val);

View File

@ -98,6 +98,7 @@ dc_channel_t dc_session_channel_recipients(dc_session_t s,
*/ */
void dc_session_add_guild(dc_session_t s, dc_guild_t g); void dc_session_add_guild(dc_session_t s, dc_guild_t g);
GHashTable *dc_session_guilds(dc_session_t s); GHashTable *dc_session_guilds(dc_session_t s);
dc_guild_t dc_session_guild_by_name(dc_session_t s, char const *name);
/** /**
* comparision functions for sorting, and finding * comparision functions for sorting, and finding

View File

@ -58,7 +58,7 @@ dc_guild_t dc_guild_from_json(json_t *j)
g->id = strdup(json_string_value(val)); g->id = strdup(json_string_value(val));
/* there is a ton of more information here, that we should look /* there is a ton of more information here, that we should look
* add, including "member_count", "owner_id", but for channels * to add, including "member_count", "owner_id", but for now "channels"
* will do nicely * will do nicely
*/ */
val = json_object_get(j, "channels"); val = json_object_get(j, "channels");
@ -91,6 +91,21 @@ dc_channel_t dc_guild_nth_channel(dc_guild_t d, size_t idx)
return g_ptr_array_index(d->channels, idx); return g_ptr_array_index(d->channels, idx);
} }
dc_channel_t dc_guild_channel_by_name(dc_guild_t g, char const *name)
{
return_if_true(g == NULL || name == NULL, NULL);
size_t i = 0;
for (i = 0; i < g->channels->len; i++) {
dc_channel_t c = g_ptr_array_index(g->channels, i);
if (strcmp(dc_channel_name(c), name) == 0) {
return c;
}
}
return NULL;
}
char const *dc_guild_name(dc_guild_t d) char const *dc_guild_name(dc_guild_t d)
{ {
return_if_true(d == NULL, NULL); return_if_true(d == NULL, NULL);

View File

@ -450,3 +450,21 @@ void dc_session_add_guild(dc_session_t s, dc_guild_t g)
*/ */
} }
} }
dc_guild_t dc_session_guild_by_name(dc_session_t s, char const *name)
{
return_if_true(s == NULL || s->guilds == NULL || name == NULL, NULL);
GHashTableIter iter;
gpointer key, value;
g_hash_table_iter_init(&iter, s->guilds);
while (g_hash_table_iter_next(&iter, &key, &value)) {
dc_guild_t g = (dc_guild_t)value;
if (strcmp(dc_guild_name(g), name) == 0) {
return g;
}
}
return NULL;
}

View File

@ -19,6 +19,7 @@ SET(SOURCES
"src/config.c" "src/config.c"
"src/friends.c" "src/friends.c"
"src/input.c" "src/input.c"
"src/join.c"
"src/keycodes.c" "src/keycodes.c"
"src/login.c" "src/login.c"
"src/logout.c" "src/logout.c"

View File

@ -32,6 +32,7 @@ ncdc_commands_t *ncdc_find_cmd(ncdc_commands_t *cmds, wchar_t const *name);
bool ncdc_cmd_ack(ncdc_mainwindow_t n, size_t ac, wchar_t **av, wchar_t const *f); bool ncdc_cmd_ack(ncdc_mainwindow_t n, size_t ac, wchar_t **av, wchar_t const *f);
bool ncdc_cmd_friends(ncdc_mainwindow_t n, size_t ac, wchar_t **av, wchar_t const *f); bool ncdc_cmd_friends(ncdc_mainwindow_t n, size_t ac, wchar_t **av, wchar_t const *f);
bool ncdc_cmd_join(ncdc_mainwindow_t n, size_t ac, wchar_t **av, wchar_t const *f);
bool ncdc_cmd_login(ncdc_mainwindow_t n, size_t ac, wchar_t **av, wchar_t const *f); bool ncdc_cmd_login(ncdc_mainwindow_t n, size_t ac, wchar_t **av, wchar_t const *f);
bool ncdc_cmd_logout(ncdc_mainwindow_t n, size_t ac, wchar_t **av, wchar_t const *f); bool ncdc_cmd_logout(ncdc_mainwindow_t n, size_t ac, wchar_t **av, wchar_t const *f);
bool ncdc_cmd_msg(ncdc_mainwindow_t n, size_t ac, wchar_t **av, wchar_t const *f); bool ncdc_cmd_msg(ncdc_mainwindow_t n, size_t ac, wchar_t **av, wchar_t const *f);

View File

@ -2,6 +2,7 @@
#define NCDC_MAINWINDOW_H #define NCDC_MAINWINDOW_H
#include <ncdc/ncdc.h> #include <ncdc/ncdc.h>
#include <ncdc/textview.h>
#include <stdarg.h> #include <stdarg.h>
struct ncdc_mainwindow_; struct ncdc_mainwindow_;
@ -16,7 +17,12 @@ void ncdc_mainwindow_log(ncdc_mainwindow_t w, wchar_t const *fmt, ...);
GPtrArray *ncdc_mainwindow_views(ncdc_mainwindow_t n); GPtrArray *ncdc_mainwindow_views(ncdc_mainwindow_t n);
dc_channel_t ncdc_mainwindow_current_channel(ncdc_mainwindow_t n); dc_channel_t ncdc_mainwindow_current_channel(ncdc_mainwindow_t n);
void ncdc_mainwindow_switchview(ncdc_mainwindow_t n, int idx); //void ncdc_mainwindow_switchview(ncdc_mainwindow_t n, int idx);
void ncdc_mainwindow_switch_view(ncdc_mainwindow_t n, ncdc_textview_t v);
ncdc_textview_t ncdc_mainwindow_channel_view(ncdc_mainwindow_t n,
dc_channel_t c);
ncdc_textview_t ncdc_mainwindow_switch_or_add(ncdc_mainwindow_t n,
dc_channel_t c);
void ncdc_mainwindow_refresh(ncdc_mainwindow_t n); void ncdc_mainwindow_refresh(ncdc_mainwindow_t n);
void ncdc_mainwindow_input_ready(ncdc_mainwindow_t n); void ncdc_mainwindow_input_ready(ncdc_mainwindow_t n);

View File

@ -5,6 +5,7 @@ ncdc_commands_t cmds[] = {
{ L"/connect", ncdc_cmd_login }, { L"/connect", ncdc_cmd_login },
{ L"/friend", ncdc_cmd_friends }, { L"/friend", ncdc_cmd_friends },
{ L"/friends", ncdc_cmd_friends }, { L"/friends", ncdc_cmd_friends },
{ L"/join", ncdc_cmd_join },
{ L"/login", ncdc_cmd_login }, { L"/login", ncdc_cmd_login },
{ L"/logout", ncdc_cmd_logout }, { L"/logout", ncdc_cmd_logout },
{ L"/markread", ncdc_cmd_ack }, { L"/markread", ncdc_cmd_ack },

62
ncdc/src/join.c Normal file
View File

@ -0,0 +1,62 @@
#include <ncdc/cmds.h>
#include <ncdc/ncdc.h>
bool
ncdc_cmd_join(ncdc_mainwindow_t n, size_t ac, wchar_t **av, wchar_t const *f)
{
char *guild = NULL;
char *channel = NULL;
bool ret = true;
dc_guild_t g = NULL;
dc_channel_t c = NULL;
if (ac <= 2) {
LOG(n, L"join: not enough arguments given");
return false;
}
if (!is_logged_in()) {
return false;
}
guild = w_convert(av[1]);
channel = w_convert(av[2]);
g = dc_session_guild_by_name(current_session, guild);
if (g == NULL) {
LOG(n, L"join: no such guild: %s", guild);
goto cleanup;
}
c = dc_guild_channel_by_name(g, channel);
if (c == NULL) {
LOG(n, L"join: no such channel %s in guild %s", channel, guild);
goto cleanup;
}
if (dc_channel_messages(c) == 0) {
bool ret = false;
ret = dc_api_get_messages(dc_session_api(current_session),
dc_session_me(current_session),
c
);
if (!ret) {
LOG(n, L"join: failed to fetch messages for channel %s", channel);
goto cleanup;
}
}
/* this adds a channel, or switches to the channel if a view already exists
*/
ncdc_mainwindow_switch_or_add(n, c);
ret = true;
cleanup:
free(guild);
free(channel);
return ret;
}

View File

@ -418,6 +418,16 @@ void ncdc_mainwindow_switchview(ncdc_mainwindow_t n, int idx)
n->curview = idx; n->curview = idx;
} }
void ncdc_mainwindow_switch_view(ncdc_mainwindow_t n, ncdc_textview_t v)
{
return_if_true(n == NULL || n->views == NULL || v == NULL,);
guint idx = 0;
if (g_ptr_array_find(n->views, v, &idx)) {
n->curview = idx;
}
}
void ncdc_mainwindow_refresh(ncdc_mainwindow_t n) void ncdc_mainwindow_refresh(ncdc_mainwindow_t n)
{ {
ncdc_textview_t v = 0; ncdc_textview_t v = 0;
@ -458,6 +468,49 @@ void ncdc_mainwindow_log(ncdc_mainwindow_t w, wchar_t const *fmt, ...)
ncdc_textview_append(w->log, buf); ncdc_textview_append(w->log, buf);
} }
ncdc_textview_t
ncdc_mainwindow_switch_or_add(ncdc_mainwindow_t n, dc_channel_t c)
{
ncdc_textview_t v = NULL;
return_if_true(n == NULL || c == NULL, NULL);
return_if_true(!is_logged_in(), NULL);
v = ncdc_mainwindow_channel_view(n, c);
if (v == NULL) {
v = ncdc_textview_new();
if (v == NULL) {
return NULL;
}
ncdc_textview_set_account(v, dc_session_me(current_session));
ncdc_textview_set_channel(v, c);
g_ptr_array_add(n->views, v);
ncdc_mainwindow_switch_view(n, v);
}
ncdc_mainwindow_switch_view(n, v);
return v;
}
ncdc_textview_t
ncdc_mainwindow_channel_view(ncdc_mainwindow_t n, dc_channel_t c)
{
size_t i = 0;
for (i = 0; i < n->views->len; i++) {
ncdc_textview_t v = g_ptr_array_index(n->views, i);
dc_channel_t vc = ncdc_textview_channel(v);
if (dc_channel_compare(vc, c)) {
return v;
}
}
return NULL;
}
static void ncdc_mainwindow_ack_view(ncdc_mainwindow_t n) static void ncdc_mainwindow_ack_view(ncdc_mainwindow_t n)
{ {
#if 0 #if 0

View File

@ -13,9 +13,6 @@ bool ncdc_cmd_msg(ncdc_mainwindow_t n, size_t ac,
dc_message_t m = NULL; dc_message_t m = NULL;
bool ret = false; bool ret = false;
dc_channel_t c = NULL; dc_channel_t c = NULL;
ncdc_textview_t v = NULL;
dc_account_t current_account = NULL;
size_t i = 0;
if (!is_logged_in()) { if (!is_logged_in()) {
LOG(n, L"msg: not logged in"); LOG(n, L"msg: not logged in");
@ -25,8 +22,6 @@ bool ncdc_cmd_msg(ncdc_mainwindow_t n, size_t ac,
target = w_convert(av[1]); target = w_convert(av[1]);
goto_if_true(target == NULL, cleanup); goto_if_true(target == NULL, cleanup);
current_account = dc_session_me(current_session);
/* find out if the target is a friend we can contact /* find out if the target is a friend we can contact
*/ */
dc_account_t f = dc_session_account_fullname(current_session, target); dc_account_t f = dc_session_account_fullname(current_session, target);
@ -41,30 +36,9 @@ bool ncdc_cmd_msg(ncdc_mainwindow_t n, size_t ac,
goto cleanup; goto cleanup;
} }
/* see if we have a channel already, that services that user /* this adds a channel, or switches to the channel if a view already exists
* if so we set v to something non-NIL and it should be good
*/ */
for (i = 0; i < ncdc_mainwindow_views(n)->len; i++) { ncdc_mainwindow_switch_or_add(n, c);
ncdc_textview_t view = g_ptr_array_index(ncdc_mainwindow_views(n), i);
dc_channel_t chan = ncdc_textview_channel(view);
if (dc_channel_compare(chan, c)) {
ncdc_mainwindow_switchview(n, i);
v = view;
break;
}
}
if (v == NULL) {
v = ncdc_textview_new();
goto_if_true(v == NULL, cleanup);
ncdc_textview_set_account(v, current_account);
ncdc_textview_set_channel(v, c);
g_ptr_array_add(ncdc_mainwindow_views(n), dc_ref(v));
ncdc_mainwindow_switchview(n, ncdc_mainwindow_views(n)->len-1);
}
if (ac > 2) { if (ac > 2) {
/* also post the rest of the content as a message to the channel /* also post the rest of the content as a message to the channel
@ -90,7 +64,6 @@ bool ncdc_cmd_msg(ncdc_mainwindow_t n, size_t ac,
cleanup: cleanup:
dc_unref(c); dc_unref(c);
dc_unref(v);
dc_unref(m); dc_unref(m);
free(target); free(target);

View File

@ -122,7 +122,7 @@ wchar_t **w_tokenise(wchar_t const *str)
case IN_STRING: case IN_STRING:
{ {
if (c == '"') { if (c == '"') {
size_t len = (p - 2 - start_of_word); size_t len = (p - start_of_word);
wchar_t *s = wcsndup(start_of_word, len); wchar_t *s = wcsndup(start_of_word, len);
g_ptr_array_add(array, s); g_ptr_array_add(array, s);
state = DULL; state = DULL;