began work on a msg command
This commit is contained in:
@@ -20,6 +20,7 @@ SET(SOURCES
|
||||
"src/input.c"
|
||||
"src/login.c"
|
||||
"src/mainwindow.c"
|
||||
"src/msg.c"
|
||||
"src/ncdc.c"
|
||||
"src/textview.c"
|
||||
"src/util.c"
|
||||
|
||||
@@ -27,5 +27,6 @@ ncdc_commands_t *ncdc_find_cmd(ncdc_commands_t *cmds, wchar_t const *name);
|
||||
bool ncdc_cmd_friends(ncdc_mainwindow_t n, size_t ac, wchar_t **av);
|
||||
bool ncdc_cmd_login(ncdc_mainwindow_t n, size_t ac, wchar_t **av);
|
||||
bool ncdc_cmd_quit(ncdc_mainwindow_t n, size_t ac, wchar_t **av);
|
||||
bool ncdc_cmd_msg(ncdc_mainwindow_t n, size_t ac, wchar_t **av);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,6 +14,9 @@ ncdc_mainwindow_t ncdc_mainwindow_new(void);
|
||||
#define LOG(n, ...) ncdc_mainwindow_log(n, __VA_ARGS__)
|
||||
void ncdc_mainwindow_log(ncdc_mainwindow_t w, wchar_t const *fmt, ...);
|
||||
|
||||
GPtrArray *ncdc_mainwindow_views(ncdc_mainwindow_t n);
|
||||
void ncdc_mainwindow_switchview(ncdc_mainwindow_t n, int idx);
|
||||
|
||||
void ncdc_mainwindow_refresh(ncdc_mainwindow_t n);
|
||||
void ncdc_mainwindow_input_ready(ncdc_mainwindow_t n);
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ char *w_convert(wchar_t const *w);
|
||||
wchar_t* wcsndup(const wchar_t* string, size_t maxlen);
|
||||
size_t w_strlenv(wchar_t **s);
|
||||
void w_strfreev(wchar_t **s);
|
||||
wchar_t *w_joinv(wchar_t const **v, size_t len);
|
||||
wchar_t **w_tokenise(wchar_t const *w);
|
||||
wchar_t *w_next_tok(wchar_t const *w);
|
||||
wchar_t const *w_next_word(wchar_t const *w, ssize_t len);
|
||||
|
||||
@@ -8,6 +8,12 @@ typedef struct ncdc_textview_ *ncdc_textview_t;
|
||||
|
||||
ncdc_textview_t ncdc_textview_new(void);
|
||||
|
||||
dc_account_t ncdc_textview_account(ncdc_textview_t v);
|
||||
void ncdc_textview_set_account(ncdc_textview_t v, dc_account_t a);
|
||||
|
||||
dc_channel_t ncdc_textview_channel(ncdc_textview_t v);
|
||||
void ncdc_textview_set_channel(ncdc_textview_t v, dc_channel_t a);
|
||||
|
||||
void ncdc_textview_append(ncdc_textview_t v, wchar_t const *w);
|
||||
wchar_t const *ncdc_textview_nthline(ncdc_textview_t v, size_t i);
|
||||
void ncdc_textview_render(ncdc_textview_t v, WINDOW *win, int lines, int cols);
|
||||
|
||||
@@ -4,6 +4,7 @@ ncdc_commands_t cmds[] = {
|
||||
{ L"/friend", ncdc_cmd_friends },
|
||||
{ L"/friends", ncdc_cmd_friends },
|
||||
{ L"/login", ncdc_cmd_login },
|
||||
{ L"/msg", ncdc_cmd_msg },
|
||||
{ L"/quit", ncdc_cmd_quit },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
@@ -34,6 +34,11 @@ bool ncdc_cmd_login(ncdc_mainwindow_t n, size_t ac, wchar_t **av)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!dc_api_get_userinfo(api, acc, acc)) {
|
||||
LOG(n, L"login: %ls: failed to get basic user information", av[1]);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
current_account = acc;
|
||||
LOG(n, L"login: %ls: authentication successful", av[1]);
|
||||
ret = true;
|
||||
|
||||
@@ -37,6 +37,9 @@ struct ncdc_mainwindow_
|
||||
WINDOW *sep2;
|
||||
|
||||
ncdc_input_t in;
|
||||
|
||||
GPtrArray *views;
|
||||
int curview;
|
||||
ncdc_textview_t log;
|
||||
|
||||
int focus;
|
||||
@@ -59,7 +62,11 @@ static void ncdc_mainwindow_free(ncdc_mainwindow_t n)
|
||||
delwin(n->sep2);
|
||||
|
||||
dc_unref(n->in);
|
||||
dc_unref(n->log);
|
||||
|
||||
if (n->views != NULL) {
|
||||
g_ptr_array_unref(n->views);
|
||||
n->views = NULL;
|
||||
}
|
||||
|
||||
free(n);
|
||||
}
|
||||
@@ -74,7 +81,11 @@ ncdc_mainwindow_t ncdc_mainwindow_new(void)
|
||||
ptr->in = ncdc_input_new();
|
||||
ncdc_input_set_callback(ptr->in, ncdc_mainwindow_callback, ptr);
|
||||
|
||||
ptr->views = g_ptr_array_new_with_free_func(
|
||||
(GDestroyNotify)dc_unref
|
||||
);
|
||||
ptr->log = ncdc_textview_new();
|
||||
g_ptr_array_add(ptr->views, ptr->log);
|
||||
|
||||
ptr->guilds = newwin(5, 5, 1, 1);
|
||||
ptr->chat = newwin(5, 5, 4, 4);
|
||||
@@ -192,11 +203,28 @@ void ncdc_mainwindow_input_ready(ncdc_mainwindow_t n)
|
||||
}
|
||||
}
|
||||
|
||||
GPtrArray *ncdc_mainwindow_views(ncdc_mainwindow_t n)
|
||||
{
|
||||
return n->views;
|
||||
}
|
||||
|
||||
void ncdc_mainwindow_switchview(ncdc_mainwindow_t n, int idx)
|
||||
{
|
||||
return_if_true(n == NULL || n->views == NULL,);
|
||||
return_if_true(idx >= n->views->len,);
|
||||
n->curview = idx;
|
||||
}
|
||||
|
||||
void ncdc_mainwindow_refresh(ncdc_mainwindow_t n)
|
||||
{
|
||||
ncdc_textview_t v = 0;
|
||||
|
||||
wnoutrefresh(n->guilds);
|
||||
|
||||
ncdc_textview_render(n->log, n->chat, n->chat_h, n->chat_w);
|
||||
/* render active text view
|
||||
*/
|
||||
v = g_ptr_array_index(n->views, n->curview);
|
||||
ncdc_textview_render(v, n->chat, n->chat_h, n->chat_w);
|
||||
wnoutrefresh(n->chat);
|
||||
|
||||
ncdc_input_draw(n->in, n->input);
|
||||
|
||||
79
ncdc/src/msg.c
Normal file
79
ncdc/src/msg.c
Normal file
@@ -0,0 +1,79 @@
|
||||
#include <ncdc/cmds.h>
|
||||
#include <ncdc/ncdc.h>
|
||||
#include <ncdc/textview.h>
|
||||
|
||||
bool ncdc_cmd_msg(ncdc_mainwindow_t n, size_t ac, wchar_t **av)
|
||||
{
|
||||
return_if_true(ac <= 1, false);
|
||||
|
||||
char * target = NULL;
|
||||
wchar_t *full_message = NULL;
|
||||
char * message = NULL;
|
||||
bool ret = false;
|
||||
dc_channel_t c = NULL;
|
||||
ncdc_textview_t v = NULL;
|
||||
size_t i = 0;
|
||||
|
||||
if (current_account == NULL || !dc_account_has_token(current_account)) {
|
||||
LOG(n, L"msg: not logged in");
|
||||
return false;
|
||||
}
|
||||
|
||||
target = w_convert(av[1]);
|
||||
goto_if_true(target == NULL, cleanup);
|
||||
|
||||
/* find out if the target is a friend we can contact
|
||||
*/
|
||||
dc_account_t f = dc_account_findfriend(current_account, target);
|
||||
if (f == NULL) {
|
||||
LOG(n, L"msg: no such friend found: \"%s\"", target);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* see if we have a channel already, that services that user
|
||||
*/
|
||||
for (i = 0; i < ncdc_mainwindow_views(n)->len; i++) {
|
||||
v = g_ptr_array_index(ncdc_mainwindow_views(n), i);
|
||||
dc_channel_t chan = ncdc_textview_channel(v);
|
||||
|
||||
if (chan != NULL &&
|
||||
dc_channel_type(chan) == CHANNEL_TYPE_DM_TEXT &&
|
||||
dc_account_equal(dc_channel_nthrecipient(chan, 1), f)) {
|
||||
c = dc_ref(chan);
|
||||
ncdc_mainwindow_switchview(n, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == NULL) {
|
||||
/* no? create a new window and switch to it
|
||||
*/
|
||||
|
||||
if (!dc_api_create_channel(api, current_account, &f, 1, &c)) {
|
||||
LOG(n, L"msg: failed to create channel");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
v = ncdc_textview_new();
|
||||
goto_if_true(v == NULL, cleanup);
|
||||
|
||||
ncdc_textview_set_account(v, dc_ref(current_account));
|
||||
ncdc_textview_set_channel(v, dc_ref(c));
|
||||
|
||||
g_ptr_array_add(ncdc_mainwindow_views(n), dc_ref(v));
|
||||
ncdc_mainwindow_switchview(n, ncdc_mainwindow_views(n)->len-1);
|
||||
}
|
||||
|
||||
ret = true;
|
||||
|
||||
cleanup:
|
||||
|
||||
dc_unref(c);
|
||||
dc_unref(v);
|
||||
|
||||
free(target);
|
||||
free(full_message);
|
||||
free(message);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -4,14 +4,24 @@
|
||||
struct ncdc_textview_
|
||||
{
|
||||
dc_refable_t ref;
|
||||
|
||||
GPtrArray *par;
|
||||
|
||||
dc_account_t account;
|
||||
dc_channel_t channel;
|
||||
};
|
||||
|
||||
static void ncdc_textview_free(ncdc_textview_t v)
|
||||
{
|
||||
return_if_true(v == NULL,);
|
||||
|
||||
g_ptr_array_unref(v->par);
|
||||
dc_unref(v->account);
|
||||
dc_unref(v->channel);
|
||||
|
||||
if (v->par != NULL) {
|
||||
g_ptr_array_unref(v->par);
|
||||
}
|
||||
|
||||
free(v);
|
||||
}
|
||||
|
||||
@@ -31,6 +41,32 @@ ncdc_textview_t ncdc_textview_new(void)
|
||||
return p;
|
||||
}
|
||||
|
||||
dc_account_t ncdc_textview_account(ncdc_textview_t v)
|
||||
{
|
||||
return_if_true(v == NULL, NULL);
|
||||
return v->account;
|
||||
}
|
||||
|
||||
void ncdc_textview_set_account(ncdc_textview_t v, dc_account_t a)
|
||||
{
|
||||
return_if_true(v == NULL || a == NULL,);
|
||||
dc_unref(v->account);
|
||||
v->account = dc_ref(a);
|
||||
}
|
||||
|
||||
dc_channel_t ncdc_textview_channel(ncdc_textview_t v)
|
||||
{
|
||||
return_if_true(v == NULL, NULL);
|
||||
return v->channel;
|
||||
}
|
||||
|
||||
void ncdc_textview_set_channel(ncdc_textview_t v, dc_channel_t a)
|
||||
{
|
||||
return_if_true(v == NULL || a == NULL,);
|
||||
dc_unref(v->channel);
|
||||
v->channel = dc_ref(a);
|
||||
}
|
||||
|
||||
void ncdc_textview_append(ncdc_textview_t v, wchar_t const *w)
|
||||
{
|
||||
return_if_true(v == NULL || w == NULL,);
|
||||
|
||||
@@ -118,6 +118,26 @@ wchar_t **w_tokenise(wchar_t const *str)
|
||||
return (wchar_t**)g_ptr_array_free(array, FALSE);
|
||||
}
|
||||
|
||||
wchar_t *w_joinv(wchar_t const **v, size_t len)
|
||||
{
|
||||
wchar_t *buf = NULL;
|
||||
size_t buflen = 0;
|
||||
FILE *f = open_wmemstream(&buf, &buflen);
|
||||
size_t i = 0;
|
||||
|
||||
return_if_true(f == NULL, NULL);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
fwprintf(f, L"%ls", v[i]);
|
||||
if (i < (len-1)) {
|
||||
fputwc(' ', f);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *w_convert(wchar_t const *w)
|
||||
{
|
||||
size_t sz = 0;
|
||||
|
||||
Reference in New Issue
Block a user