mirror of
https://github.com/profanity-im/profanity.git
synced 2025-02-02 15:08:15 -05:00
Use Jid datatype in chat rooms
This commit is contained in:
parent
d827abddb7
commit
ec75b5e04a
@ -36,6 +36,7 @@
|
||||
#include "chat_log.h"
|
||||
#include "history.h"
|
||||
#include "jabber.h"
|
||||
#include "jid.h"
|
||||
#include "log.h"
|
||||
#include "parser.h"
|
||||
#include "preferences.h"
|
||||
@ -1592,34 +1593,37 @@ _cmd_info(gchar **args, struct cmd_help_t help)
|
||||
static gboolean
|
||||
_cmd_join(gchar **args, struct cmd_help_t help)
|
||||
{
|
||||
jabber_conn_status_t conn_status = jabber_get_connection_status();
|
||||
|
||||
if (conn_status != JABBER_CONNECTED) {
|
||||
cons_show("You are not currently connected.");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (ui_windows_full()) {
|
||||
cons_bad_show("Windows all used, close a window and try again.");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
char *room = args[0];
|
||||
char *nick = NULL;
|
||||
|
||||
int num_args = g_strv_length(args);
|
||||
if (num_args == 2) {
|
||||
nick = args[1];
|
||||
}
|
||||
|
||||
jabber_conn_status_t conn_status = jabber_get_connection_status();
|
||||
|
||||
if (conn_status != JABBER_CONNECTED) {
|
||||
cons_show("You are not currently connected.");
|
||||
} else if (ui_windows_full()) {
|
||||
cons_bad_show("Windows all used, close a window and try again.");
|
||||
} else {
|
||||
// if no nick, set to first part of jid
|
||||
if (nick == NULL) {
|
||||
const char *jid = jabber_get_jid();
|
||||
char jid_cpy[strlen(jid) + 1];
|
||||
strcpy(jid_cpy, jid);
|
||||
nick = strdup(strtok(jid_cpy, "@"));
|
||||
}
|
||||
if (!muc_room_is_active(room)) {
|
||||
jabber_join(room, nick);
|
||||
}
|
||||
win_join_chat(room, nick);
|
||||
Jid *jid = jid_create(jabber_get_jid());
|
||||
nick = strdup(jid->localpart);
|
||||
jid_destroy(jid);
|
||||
}
|
||||
|
||||
Jid *room_jid = jid_create_room_jid(room, nick);
|
||||
|
||||
if (!muc_room_is_active(room_jid)) {
|
||||
jabber_join(room_jid);
|
||||
}
|
||||
win_join_chat(room_jid);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
175
src/jabber.c
175
src/jabber.c
@ -313,17 +313,14 @@ jabber_get_subscription_requests(void)
|
||||
}
|
||||
|
||||
void
|
||||
jabber_join(const char * const room, const char * const nick)
|
||||
jabber_join(Jid *jid)
|
||||
{
|
||||
char *full_room_jid = create_full_room_jid(room, nick);
|
||||
xmpp_stanza_t *presence = stanza_create_room_join_presence(jabber_conn.ctx,
|
||||
full_room_jid);
|
||||
jid->fulljid);
|
||||
xmpp_send(jabber_conn.conn, presence);
|
||||
xmpp_stanza_release(presence);
|
||||
|
||||
muc_join_room(room, nick);
|
||||
|
||||
free(full_room_jid);
|
||||
muc_join_room(jid->barejid, jid->resourcepart);
|
||||
}
|
||||
|
||||
void
|
||||
@ -563,18 +560,16 @@ _groupchat_message_handler(xmpp_stanza_t * const stanza)
|
||||
}
|
||||
}
|
||||
|
||||
// room jid not of form room/nick
|
||||
if (!parse_room_jid(room_jid, &room, &nick)) {
|
||||
log_error("Could not parse room jid: %s", room_jid);
|
||||
Jid *jid = jid_create(room_jid);
|
||||
|
||||
if (!jid_is_valid_room_form(jid)) {
|
||||
log_error("Invalid room JID: %s", jid->str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// room not active in profanity
|
||||
if (!muc_room_is_active(room_jid)) {
|
||||
log_error("Message recieved for inactive groupchat: %s", room_jid);
|
||||
free(room);
|
||||
free(nick);
|
||||
|
||||
if (!muc_room_is_active(jid)) {
|
||||
log_error("Message recieved for inactive chat room: %s", jid->str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -641,72 +636,80 @@ _error_handler(xmpp_stanza_t * const stanza)
|
||||
static int
|
||||
_chat_message_handler(xmpp_stanza_t * const stanza)
|
||||
{
|
||||
gboolean priv = FALSE;
|
||||
gchar *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
|
||||
|
||||
char from_cpy[strlen(from) + 1];
|
||||
strcpy(from_cpy, from);
|
||||
char *short_from = strtok(from_cpy, "/");
|
||||
char *jid = NULL;
|
||||
Jid *jid = jid_create(from);
|
||||
|
||||
// private message from chat room use full jid (room/nick)
|
||||
if (muc_room_is_active(short_from)) {
|
||||
jid = strdup(from);
|
||||
priv = TRUE;
|
||||
if (muc_room_is_active(jid)) {
|
||||
// determine if the notifications happened whilst offline
|
||||
GTimeVal tv_stamp;
|
||||
gboolean delayed = stanza_get_delay(stanza, &tv_stamp);
|
||||
|
||||
// check for and deal with message
|
||||
xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY);
|
||||
if (body != NULL) {
|
||||
char *message = xmpp_stanza_get_text(body);
|
||||
if (delayed) {
|
||||
prof_handle_delayed_message(jid->str, message, tv_stamp, TRUE);
|
||||
} else {
|
||||
prof_handle_incoming_message(jid->str, message, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
free(jid);
|
||||
return 1;
|
||||
|
||||
// standard chat message, use jid without resource
|
||||
} else {
|
||||
jid = strdup(short_from);
|
||||
priv = FALSE;
|
||||
}
|
||||
|
||||
// determine chatstate support of recipient
|
||||
gboolean recipient_supports = FALSE;
|
||||
if (stanza_contains_chat_state(stanza)) {
|
||||
recipient_supports = TRUE;
|
||||
}
|
||||
|
||||
// create or update chat session
|
||||
if (!chat_session_exists(jid)) {
|
||||
chat_session_start(jid, recipient_supports);
|
||||
} else {
|
||||
chat_session_set_recipient_supports(jid, recipient_supports);
|
||||
}
|
||||
|
||||
// determine if the notifications happened whilst offline
|
||||
GTimeVal tv_stamp;
|
||||
gboolean delayed = stanza_get_delay(stanza, &tv_stamp);
|
||||
|
||||
// deal with chat states if recipient supports them
|
||||
if (recipient_supports && (!delayed)) {
|
||||
if (xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_COMPOSING) != NULL) {
|
||||
if (prefs_get_notify_typing() || prefs_get_intype()) {
|
||||
prof_handle_typing(jid);
|
||||
}
|
||||
} else if (xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_GONE) != NULL) {
|
||||
prof_handle_gone(jid);
|
||||
} else if (xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_PAUSED) != NULL) {
|
||||
// do something
|
||||
} else if (xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_INACTIVE) != NULL) {
|
||||
// do something
|
||||
} else { // handle <active/>
|
||||
// do something
|
||||
// determine chatstate support of recipient
|
||||
gboolean recipient_supports = FALSE;
|
||||
if (stanza_contains_chat_state(stanza)) {
|
||||
recipient_supports = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// check for and deal with message
|
||||
xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY);
|
||||
if (body != NULL) {
|
||||
char *message = xmpp_stanza_get_text(body);
|
||||
if (delayed) {
|
||||
prof_handle_delayed_message(jid, message, tv_stamp, priv);
|
||||
// create or update chat session
|
||||
if (!chat_session_exists(jid->barejid)) {
|
||||
chat_session_start(jid->barejid, recipient_supports);
|
||||
} else {
|
||||
prof_handle_incoming_message(jid, message, priv);
|
||||
chat_session_set_recipient_supports(jid->barejid, recipient_supports);
|
||||
}
|
||||
|
||||
// determine if the notifications happened whilst offline
|
||||
GTimeVal tv_stamp;
|
||||
gboolean delayed = stanza_get_delay(stanza, &tv_stamp);
|
||||
|
||||
// deal with chat states if recipient supports them
|
||||
if (recipient_supports && (!delayed)) {
|
||||
if (xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_COMPOSING) != NULL) {
|
||||
if (prefs_get_notify_typing() || prefs_get_intype()) {
|
||||
prof_handle_typing(jid->barejid);
|
||||
}
|
||||
} else if (xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_GONE) != NULL) {
|
||||
prof_handle_gone(jid->barejid);
|
||||
} else if (xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_PAUSED) != NULL) {
|
||||
// do something
|
||||
} else if (xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_INACTIVE) != NULL) {
|
||||
// do something
|
||||
} else { // handle <active/>
|
||||
// do something
|
||||
}
|
||||
}
|
||||
|
||||
// check for and deal with message
|
||||
xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BODY);
|
||||
if (body != NULL) {
|
||||
char *message = xmpp_stanza_get_text(body);
|
||||
if (delayed) {
|
||||
prof_handle_delayed_message(jid->barejid, message, tv_stamp, FALSE);
|
||||
} else {
|
||||
prof_handle_incoming_message(jid->barejid, message, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
free(jid);
|
||||
return 1;
|
||||
}
|
||||
|
||||
free(jid);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1029,24 +1032,22 @@ _presence_handler(xmpp_conn_t * const conn,
|
||||
xmpp_stanza_t * const stanza, void * const userdata)
|
||||
{
|
||||
const char *jid = xmpp_conn_get_jid(jabber_conn.conn);
|
||||
char jid_cpy[strlen(jid) + 1];
|
||||
strcpy(jid_cpy, jid);
|
||||
char *short_jid = strtok(jid_cpy, "/");
|
||||
|
||||
char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
|
||||
char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE);
|
||||
|
||||
Jid *my_jid = jid_create(jid);
|
||||
Jid *from_jid = jid_create(from);
|
||||
|
||||
if ((type != NULL) && (strcmp(type, STANZA_TYPE_ERROR) == 0)) {
|
||||
return _error_handler(stanza);
|
||||
}
|
||||
|
||||
// handle chat room presence
|
||||
if (muc_room_is_active(from)) {
|
||||
return _room_presence_handler(from, stanza);
|
||||
if (muc_room_is_active(from_jid)) {
|
||||
return _room_presence_handler(from_jid->str, stanza);
|
||||
|
||||
// handle regular presence
|
||||
} else {
|
||||
char *short_from = strtok(from, "/");
|
||||
char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE);
|
||||
char *show_str, *status_str;
|
||||
int idle_seconds = stanza_get_idle_time(stanza);
|
||||
@ -1071,12 +1072,12 @@ _presence_handler(xmpp_conn_t * const conn,
|
||||
else
|
||||
show_str = "online";
|
||||
|
||||
if (strcmp(short_jid, short_from) !=0) {
|
||||
prof_handle_contact_online(short_from, show_str, status_str, last_activity);
|
||||
if (strcmp(my_jid->barejid, from_jid->barejid) !=0) {
|
||||
prof_handle_contact_online(from_jid->barejid, show_str, status_str, last_activity);
|
||||
}
|
||||
} else if (strcmp(type, STANZA_TYPE_UNAVAILABLE) == 0) {
|
||||
if (strcmp(short_jid, short_from) !=0) {
|
||||
prof_handle_contact_offline(short_from, "offline", status_str);
|
||||
if (strcmp(my_jid->barejid, from_jid->barejid) !=0) {
|
||||
prof_handle_contact_offline(from_jid->barejid, "offline", status_str);
|
||||
}
|
||||
|
||||
if (last_activity != NULL) {
|
||||
@ -1085,14 +1086,14 @@ _presence_handler(xmpp_conn_t * const conn,
|
||||
|
||||
// subscriptions
|
||||
} else if (strcmp(type, STANZA_TYPE_SUBSCRIBE) == 0) {
|
||||
prof_handle_subscription(short_from, PRESENCE_SUBSCRIBE);
|
||||
g_hash_table_insert(sub_requests, strdup(short_from), strdup(short_from));
|
||||
prof_handle_subscription(from_jid->barejid, PRESENCE_SUBSCRIBE);
|
||||
g_hash_table_insert(sub_requests, strdup(from_jid->barejid), strdup(from_jid->barejid));
|
||||
} else if (strcmp(type, STANZA_TYPE_SUBSCRIBED) == 0) {
|
||||
prof_handle_subscription(short_from, PRESENCE_SUBSCRIBED);
|
||||
g_hash_table_remove(sub_requests, short_from);
|
||||
prof_handle_subscription(from_jid->barejid, PRESENCE_SUBSCRIBED);
|
||||
g_hash_table_remove(sub_requests, from_jid->barejid);
|
||||
} else if (strcmp(type, STANZA_TYPE_UNSUBSCRIBED) == 0) {
|
||||
prof_handle_subscription(short_from, PRESENCE_UNSUBSCRIBED);
|
||||
g_hash_table_remove(sub_requests, short_from);
|
||||
prof_handle_subscription(from_jid->barejid, PRESENCE_UNSUBSCRIBED);
|
||||
g_hash_table_remove(sub_requests, from_jid->barejid);
|
||||
} else { /* unknown type */
|
||||
log_debug("Received presence with unknown type '%s'", type);
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#define JABBER_H
|
||||
|
||||
#include "accounts.h"
|
||||
#include "jid.h"
|
||||
|
||||
typedef enum {
|
||||
JABBER_UNDEFINED,
|
||||
@ -59,7 +60,7 @@ jabber_conn_status_t jabber_connect_with_account(ProfAccount *account,
|
||||
const char * const passwd);
|
||||
void jabber_disconnect(void);
|
||||
void jabber_process_events(void);
|
||||
void jabber_join(const char * const room, const char * const nick);
|
||||
void jabber_join(Jid *jid);
|
||||
void jabber_change_room_nick(const char * const room, const char * const nick);
|
||||
void jabber_leave_chat_room(const char * const room_jid);
|
||||
void jabber_subscription(const char * const jid, jabber_subscr_t action);
|
||||
|
@ -55,6 +55,7 @@ jid_create(const gchar * const str)
|
||||
// has resourcepart
|
||||
if (slashp != NULL) {
|
||||
result = malloc(sizeof(struct jid_t));
|
||||
result->str = strdup(trimmed);
|
||||
result->resourcepart = g_strdup(slashp + 1);
|
||||
result->barejid = g_strndup(trimmed, strlen(trimmed) - strlen(result->resourcepart) - 1);
|
||||
result->fulljid = g_strdup(trimmed);
|
||||
@ -78,6 +79,7 @@ jid_create(const gchar * const str)
|
||||
// no resourcepart
|
||||
} else {
|
||||
result = malloc(sizeof(struct jid_t));
|
||||
result->str = strdup(trimmed);
|
||||
result->resourcepart = NULL;
|
||||
result->barejid = g_strdup(trimmed);
|
||||
result->fulljid = NULL;
|
||||
@ -114,6 +116,7 @@ jid_create_room_jid(const char * const room, const char * const nick)
|
||||
void
|
||||
jid_destroy(Jid *jid)
|
||||
{
|
||||
FREE_SET_NULL(jid->str);
|
||||
FREE_SET_NULL(jid->localpart);
|
||||
FREE_SET_NULL(jid->domainpart);
|
||||
FREE_SET_NULL(jid->resourcepart);
|
||||
@ -122,6 +125,12 @@ jid_destroy(Jid *jid)
|
||||
FREE_SET_NULL(jid);
|
||||
}
|
||||
|
||||
gboolean
|
||||
jid_is_valid_room_form(Jid *jid)
|
||||
{
|
||||
return (jid->fulljid != NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a full room JID of the form
|
||||
* room@server/nick
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <glib.h>
|
||||
|
||||
struct jid_t {
|
||||
char *str;
|
||||
char *localpart;
|
||||
char *domainpart;
|
||||
char *resourcepart;
|
||||
@ -37,7 +38,9 @@ typedef struct jid_t Jid;
|
||||
|
||||
Jid * jid_create(const gchar * const str);
|
||||
Jid * jid_create_room_jid(const char * const room, const char * const nick);
|
||||
void jid_destroy(Jid *jid);
|
||||
|
||||
gboolean jid_is_valid_room_form(Jid *jid);
|
||||
gboolean jid_is_room(const char * const room_jid);
|
||||
char * create_full_room_jid(const char * const room,
|
||||
const char * const nick);
|
||||
|
@ -26,10 +26,10 @@
|
||||
#include <glib.h>
|
||||
|
||||
#include "contact.h"
|
||||
#include "jid.h"
|
||||
#include "prof_autocomplete.h"
|
||||
|
||||
typedef struct _muc_room_t {
|
||||
|
||||
char *room; // e.g. test@conference.server
|
||||
char *nick; // e.g. Some User
|
||||
char *subject;
|
||||
@ -82,13 +82,10 @@ muc_leave_room(const char * const room)
|
||||
* Returns TRUE if the user is currently in the room
|
||||
*/
|
||||
gboolean
|
||||
muc_room_is_active(const char * const full_room_jid)
|
||||
muc_room_is_active(Jid *jid)
|
||||
{
|
||||
char **tokens = g_strsplit(full_room_jid, "/", 0);
|
||||
char *room_part = tokens[0];
|
||||
|
||||
if (rooms != NULL) {
|
||||
ChatRoom *chat_room = g_hash_table_lookup(rooms, room_part);
|
||||
ChatRoom *chat_room = g_hash_table_lookup(rooms, jid->barejid);
|
||||
|
||||
if (chat_room != NULL) {
|
||||
return TRUE;
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
void muc_join_room(const char * const room, const char * const nick);
|
||||
void muc_leave_room(const char * const room);
|
||||
gboolean muc_room_is_active(const char * const full_room_jid);
|
||||
gboolean muc_room_is_active(Jid *jid);
|
||||
GList* muc_get_active_room_list(void);
|
||||
char * muc_get_room_nick(const char * const room);
|
||||
|
||||
|
3
src/ui.h
3
src/ui.h
@ -36,6 +36,7 @@
|
||||
#endif
|
||||
|
||||
#include "jabber.h"
|
||||
#include "jid.h"
|
||||
|
||||
#define INP_WIN_MAX 1000
|
||||
#define PAD_SIZE 1000
|
||||
@ -113,7 +114,7 @@ void win_show_outgoing_msg(const char * const from, const char * const to,
|
||||
const char * const message);
|
||||
void win_new_chat_win(const char * const to);
|
||||
|
||||
void win_join_chat(const char * const room, const char * const nick);
|
||||
void win_join_chat(Jid *jid);
|
||||
void win_show_room_roster(const char * const room);
|
||||
void win_show_room_history(const char * const room_jid, const char * const nick,
|
||||
GTimeVal tv_stamp, const char * const message);
|
||||
|
@ -753,13 +753,16 @@ win_show_outgoing_msg(const char * const from, const char * const to,
|
||||
|
||||
// create new window
|
||||
if (win_index == NUM_WINS) {
|
||||
Jid *jid = jid_create(to);
|
||||
|
||||
if (muc_room_is_active(to)) {
|
||||
if (muc_room_is_active(jid)) {
|
||||
win_index = _new_prof_win(to, WIN_PRIVATE);
|
||||
} else {
|
||||
win_index = _new_prof_win(to, WIN_CHAT);
|
||||
}
|
||||
|
||||
jid_destroy(jid);
|
||||
|
||||
win = windows[win_index]->win;
|
||||
|
||||
if (prefs_get_chlog() && prefs_get_history()) {
|
||||
@ -794,13 +797,13 @@ win_show_outgoing_msg(const char * const from, const char * const to,
|
||||
}
|
||||
|
||||
void
|
||||
win_join_chat(const char * const room, const char * const nick)
|
||||
win_join_chat(Jid *jid)
|
||||
{
|
||||
int win_index = _find_prof_win_index(room);
|
||||
int win_index = _find_prof_win_index(jid->barejid);
|
||||
|
||||
// create new window
|
||||
if (win_index == NUM_WINS) {
|
||||
win_index = _new_prof_win(room, WIN_MUC);
|
||||
win_index = _new_prof_win(jid->barejid, WIN_MUC);
|
||||
}
|
||||
|
||||
ui_switch_win(win_index);
|
||||
|
Loading…
x
Reference in New Issue
Block a user