diff --git a/src/command/command.c b/src/command/command.c index def2815b..6309ce93 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -703,13 +703,16 @@ static struct cmd_t command_defs[] = CMD_TAGS( CMD_TAG_PRESENCE) CMD_SYN( + "/lastactivity on|off", "/lastactivity []") CMD_DESC( - "Send a last activity query to the supplied JID, omitting the JID will send the query to your server.") + "Enable/disable sending last activity, and send last activity requests.") CMD_ARGS( - { "", "The JID of the entity to which the query will be sent." }) + { "on|off", "Enable or disable sending of last activity." }, + { "", "The JID of the entity to query, omitting the JID will query your server." }) CMD_EXAMPLES( "/lastactivity", + "/lastactivity off", "/lastactivity alice@securechat.org", "/lastactivity alice@securechat.org/laptop", "/lastactivity someserver.com") @@ -2564,7 +2567,7 @@ _cmd_complete_parameters(ProfWin *window, const char * const input) // autocomplete boolean settings gchar *boolean_choices[] = { "/beep", "/intype", "/states", "/outtype", "/flash", "/splash", "/chlog", "/grlog", "/history", "/vercheck", - "/privileges", "/presence", "/wrap", "/winstidy", "/carbons", "/encwarn" }; + "/privileges", "/presence", "/wrap", "/winstidy", "/carbons", "/encwarn", "/lastactivity" }; for (i = 0; i < ARRAY_SIZE(boolean_choices); i++) { result = autocomplete_param_with_func(input, boolean_choices[i], prefs_autocomplete_boolean_choice); diff --git a/src/command/commands.c b/src/command/commands.c index 94e768db..df730c63 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -3279,11 +3279,16 @@ cmd_lastactivity(ProfWin *window, const char * const command, gchar **args) g_string_free(jid, TRUE); jid_destroy(jidp); + + return TRUE; + + } else if ((g_strcmp0(args[0], "on") == 0) || (g_strcmp0(args[0], "off") == 0)) { + return _cmd_set_boolean_preference(args[0], command, "Last activity responses", PREF_LASTACTIVITY); + } else { iq_last_activity_request(args[0]); + return TRUE; } - - return TRUE; } gboolean diff --git a/src/config/preferences.c b/src/config/preferences.c index 9aaa9083..746e76d4 100644 --- a/src/config/preferences.c +++ b/src/config/preferences.c @@ -627,6 +627,7 @@ _get_group(preference_t pref) case PREF_AUTOAWAY_MODE: case PREF_AUTOAWAY_MESSAGE: case PREF_AUTOXA_MESSAGE: + case PREF_LASTACTIVITY: return PREF_GROUP_PRESENCE; case PREF_CONNECT_ACCOUNT: case PREF_DEFAULT_ACCOUNT: @@ -784,6 +785,8 @@ _get_key(preference_t pref) return "certpath"; case PREF_TLS_SHOW: return "tls.show"; + case PREF_LASTACTIVITY: + return "lastactivity"; default: return NULL; } @@ -821,6 +824,7 @@ _get_default_boolean(preference_t pref) case PREF_ROSTER_RESOURCE: case PREF_ROSTER_EMPTY: case PREF_TLS_SHOW: + case PREF_LASTACTIVITY: return TRUE; default: return FALSE; diff --git a/src/config/preferences.h b/src/config/preferences.h index a0b3c06e..bf5f1e46 100644 --- a/src/config/preferences.h +++ b/src/config/preferences.h @@ -113,6 +113,7 @@ typedef enum { PREF_PGP_LOG, PREF_CERT_PATH, PREF_TLS_SHOW, + PREF_LASTACTIVITY, } preference_t; typedef struct prof_alias_t { diff --git a/src/profanity.c b/src/profanity.c index bcbd8c2e..3bec7a99 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -212,7 +212,11 @@ _check_autoaway() // send away presence with last activity char *message = prefs_get_string(PREF_AUTOAWAY_MESSAGE); - cl_ev_presence_send(RESOURCE_AWAY, message, idle_ms / 1000); + if (prefs_get_boolean(PREF_LASTACTIVITY)) { + cl_ev_presence_send(RESOURCE_AWAY, message, idle_ms / 1000); + } else { + cl_ev_presence_send(RESOURCE_AWAY, message, 0); + } int pri = accounts_get_priority_for_presence_type(account, RESOURCE_AWAY); if (message) { @@ -248,7 +252,11 @@ _check_autoaway() // send extended away presence with last activity char *message = prefs_get_string(PREF_AUTOXA_MESSAGE); - cl_ev_presence_send(RESOURCE_XA, message, idle_ms / 1000); + if (prefs_get_boolean(PREF_LASTACTIVITY)) { + cl_ev_presence_send(RESOURCE_XA, message, idle_ms / 1000); + } else { + cl_ev_presence_send(RESOURCE_XA, message, 0); + } int pri = accounts_get_priority_for_presence_type(account, RESOURCE_XA); if (message) { diff --git a/src/ui/console.c b/src/ui/console.c index 319e451d..f5014013 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -1459,6 +1459,12 @@ cons_show_presence_prefs(void) cons_show(""); cons_autoaway_setting(); + if (prefs_get_boolean(PREF_LASTACTIVITY)) { + cons_show("Send last activity (/lastactivity) : ON"); + } else { + cons_show("Send last activity (/lastactivity) : OFF"); + } + cons_alert(); } diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index ba2d8e63..99327b41 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -1094,7 +1094,11 @@ _last_activity_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanz xmpp_ctx_t *ctx = connection_get_ctx(); const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); - if (from) { + if (!from) { + return 1; + } + + if (prefs_get_boolean(PREF_LASTACTIVITY)) { int idls_secs = ui_get_idle_time() / 1000; char str[50]; sprintf(str, "%d", idls_secs); @@ -1111,10 +1115,34 @@ _last_activity_get_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanz xmpp_stanza_set_attribute(query, "seconds", str); xmpp_stanza_add_child(response, query); + xmpp_stanza_release(query); + + xmpp_send(conn, response); + + xmpp_stanza_release(response); + } else { + xmpp_stanza_t *response = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(response, STANZA_NAME_IQ); + xmpp_stanza_set_id(response, xmpp_stanza_get_id(stanza)); + xmpp_stanza_set_attribute(response, STANZA_ATTR_TO, from); + xmpp_stanza_set_type(response, STANZA_TYPE_ERROR); + + xmpp_stanza_t *error = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(error, STANZA_NAME_ERROR); + xmpp_stanza_set_type(error, "cancel"); + + xmpp_stanza_t *service_unavailable = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(service_unavailable, "service-unavailable"); + xmpp_stanza_set_ns(service_unavailable, "urn:ietf:params:xml:ns:xmpp-stanzas"); + + xmpp_stanza_add_child(error, service_unavailable); + xmpp_stanza_release(service_unavailable); + + xmpp_stanza_add_child(response, error); + xmpp_stanza_release(error); xmpp_send(conn, response); - xmpp_stanza_release(query); xmpp_stanza_release(response); } diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c index 7ccc20a4..e475f599 100644 --- a/src/xmpp/presence.c +++ b/src/xmpp/presence.c @@ -243,7 +243,9 @@ presence_send(const resource_presence_t presence_type, const char * const msg, c } stanza_attach_priority(ctx, presence, pri); - stanza_attach_last_activity(ctx, presence, idle); + if (idle > 0) { + stanza_attach_last_activity(ctx, presence, idle); + } stanza_attach_caps(ctx, presence); xmpp_send(conn, presence); _send_room_presence(conn, presence); diff --git a/src/xmpp/roster.c b/src/xmpp/roster.c index 020f01f6..1138061b 100644 --- a/src/xmpp/roster.c +++ b/src/xmpp/roster.c @@ -53,6 +53,7 @@ #include "event/server_events.h" #include "event/client_events.h" #include "tools/autocomplete.h" +#include "config/preferences.h" #include "xmpp/connection.h" #include "xmpp/roster.h" #include "roster_list.h" @@ -355,7 +356,11 @@ _roster_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, v GDateTime *lastdt = g_date_time_new_from_timeval_utc(&lasttv); GTimeSpan diff_micros = g_date_time_difference(nowdt, lastdt); int diff_secs = (diff_micros / 1000) / 1000; - cl_ev_presence_send(conn_presence, NULL, diff_secs); + if (prefs_get_boolean(PREF_LASTACTIVITY)) { + cl_ev_presence_send(conn_presence, NULL, diff_secs); + } else { + cl_ev_presence_send(conn_presence, NULL, 0); + } g_date_time_unref(lastdt); } else { cl_ev_presence_send(conn_presence, NULL, 0); diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index 691441d4..765b9c4b 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -1662,16 +1662,14 @@ void stanza_attach_last_activity(xmpp_ctx_t * const ctx, xmpp_stanza_t * const presence, const int idle) { - if (idle > 0) { - xmpp_stanza_t *query = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(query, STANZA_NAME_QUERY); - xmpp_stanza_set_ns(query, STANZA_NS_LASTACTIVITY); - char idle_str[10]; - snprintf(idle_str, sizeof(idle_str), "%d", idle); - xmpp_stanza_set_attribute(query, STANZA_ATTR_SECONDS, idle_str); - xmpp_stanza_add_child(presence, query); - xmpp_stanza_release(query); - } + xmpp_stanza_t *query = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(query, STANZA_NAME_QUERY); + xmpp_stanza_set_ns(query, STANZA_NS_LASTACTIVITY); + char idle_str[10]; + snprintf(idle_str, sizeof(idle_str), "%d", idle); + xmpp_stanza_set_attribute(query, STANZA_ATTR_SECONDS, idle_str); + xmpp_stanza_add_child(presence, query); + xmpp_stanza_release(query); } void