diff options
author | Gary Kramlich <grim@reaperworld.com> | 2023-03-21 02:36:13 -0500 |
---|---|---|
committer | Gary Kramlich <grim@reaperworld.com> | 2023-03-21 02:36:13 -0500 |
commit | 26eb56e7957480a4d6a506cf9250d092b924f6f6 (patch) | |
tree | 161c1c14a6cca5330cec44fe01ab43fa928fe0ce | |
parent | 6bd051f03a0450bd1f7db83796381773ae148eff (diff) | |
download | pidgin-26eb56e7957480a4d6a506cf9250d092b924f6f6.tar.gz |
Add "new-status" properties to PurplePresence with fallbacks were applicable
This adds the new `emoji` and `mobile` properties to `PurplePresence`. It also makes `message` read/write and it fallsback to the active status's message if the internal message is false. Additionally the primitive property was moved `PurpleStatusPrimitive` to `PurplePresencePrimitive`.
Testing Done:
Ran the updated unit tests and connected a demo account and verified that the expected status messages were displayed.
Reviewed at https://reviews.imfreedom.org/r/2372/
-rw-r--r-- | libpurple/purplepresence.c | 164 | ||||
-rw-r--r-- | libpurple/purplepresence.h | 73 | ||||
-rw-r--r-- | libpurple/tests/test_presence.c | 114 |
3 files changed, 284 insertions, 67 deletions
diff --git a/libpurple/purplepresence.c b/libpurple/purplepresence.c index e31b8a6412..0182e54760 100644 --- a/libpurple/purplepresence.c +++ b/libpurple/purplepresence.c @@ -36,6 +36,11 @@ typedef struct { GHashTable *status_table; PurpleStatus *active_status; + + PurplePresencePrimitive primitive; + char *message; + char *emoji; + gboolean mobile; } PurplePresencePrivate; enum { @@ -46,6 +51,8 @@ enum { PROP_ACTIVE_STATUS, PROP_PRIMITIVE, PROP_MESSAGE, + PROP_EMOJI, + PROP_MOBILE, N_PROPERTIES }; static GParamSpec *properties[N_PROPERTIES]; @@ -98,6 +105,18 @@ purple_presence_set_property(GObject *obj, guint param_id, const GValue *value, purple_presence_set_active_status(presence, g_value_get_object(value)); break; + case PROP_PRIMITIVE: + purple_presence_set_primitive(presence, g_value_get_enum(value)); + break; + case PROP_MESSAGE: + purple_presence_set_message(presence, g_value_get_string(value)); + break; + case PROP_EMOJI: + purple_presence_set_emoji(presence, g_value_get_string(value)); + break; + case PROP_MOBILE: + purple_presence_set_mobile(presence, g_value_get_boolean(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); break; @@ -129,6 +148,12 @@ purple_presence_get_property(GObject *obj, guint param_id, GValue *value, case PROP_MESSAGE: g_value_set_string(value, purple_presence_get_message(presence)); break; + case PROP_EMOJI: + g_value_set_string(value, purple_presence_get_emoji(presence)); + break; + case PROP_MOBILE: + g_value_set_boolean(value, purple_presence_get_mobile(presence)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); break; @@ -157,6 +182,9 @@ purple_presence_finalize(GObject *obj) { g_clear_pointer(&priv->idle_time, g_date_time_unref); g_clear_pointer(&priv->login_time, g_date_time_unref); + g_clear_pointer(&priv->message, g_free); + g_clear_pointer(&priv->emoji, g_free); + G_OBJECT_CLASS(purple_presence_parent_class)->finalize(obj); } @@ -219,9 +247,9 @@ purple_presence_class_init(PurplePresenceClass *klass) { properties[PROP_PRIMITIVE] = g_param_spec_enum( "primitive", "primitive", "The primitive for the presence", - PURPLE_TYPE_STATUS_PRIMITIVE, - PURPLE_STATUS_UNSET, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + PURPLE_TYPE_PRESENCE_PRIMITIVE, + PURPLE_PRESENCE_PRIMITIVE_OFFLINE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * PurplePresence:message: @@ -234,7 +262,33 @@ purple_presence_class_init(PurplePresenceClass *klass) { "message", "message", "The status message", NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * PurplePresence:emoji: + * + * The emoji or mood of the presence. + * + * Since: 3.0.0 + */ + properties[PROP_EMOJI] = g_param_spec_string( + "emoji", "emoji", + "The emoji for the presence.", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * PurplePresence:mobile: + * + * Whether or not the presence is on a mobile device. + * + * Since: 3.0.0 + */ + properties[PROP_MOBILE] = g_param_spec_boolean( + "mobile", "mobile", + "Whether or not the presence is on a mobile device.", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties(obj_class, N_PROPERTIES, properties); } @@ -557,21 +611,34 @@ purple_presence_compare(PurplePresence *presence1, PurplePresence *presence2) { return 0; } -PurpleStatusPrimitive +PurplePresencePrimitive purple_presence_get_primitive(PurplePresence *presence) { PurplePresencePrivate *priv = NULL; - PurpleStatusType *type = NULL; - g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), PURPLE_STATUS_UNSET); + g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), + PURPLE_PRESENCE_PRIMITIVE_OFFLINE); priv = purple_presence_get_instance_private(presence); - type = purple_status_get_status_type(priv->active_status); - if(type != NULL) { - return purple_status_type_get_primitive(type); - } + return priv->primitive; +} + +void +purple_presence_set_primitive(PurplePresence *presence, + PurplePresencePrimitive primitive) +{ + PurplePresencePrivate *priv = NULL; + + g_return_if_fail(PURPLE_IS_PRESENCE(presence)); - return PURPLE_STATUS_UNSET; + priv = purple_presence_get_instance_private(presence); + + if(priv->primitive != primitive) { + priv->primitive = primitive; + + g_object_notify_by_pspec(G_OBJECT(presence), + properties[PROP_PRIMITIVE]); + } } const char * @@ -582,9 +649,82 @@ purple_presence_get_message(PurplePresence *presence) { priv = purple_presence_get_instance_private(presence); + if(priv->message != NULL) { + return priv->message; + } + return purple_status_get_attr_string(priv->active_status, "message"); } +void +purple_presence_set_message(PurplePresence *presence, const char *message) { + PurplePresencePrivate *priv = NULL; + + g_return_if_fail(PURPLE_IS_PRESENCE(presence)); + + priv = purple_presence_get_instance_private(presence); + + if(!purple_strequal(priv->message, message)) { + g_free(priv->message); + priv->message = g_strdup(message); + + g_object_notify_by_pspec(G_OBJECT(presence), properties[PROP_MESSAGE]); + } +} + +const char * +purple_presence_get_emoji(PurplePresence *presence) { + PurplePresencePrivate *priv = NULL; + + g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), NULL); + + priv = purple_presence_get_instance_private(presence); + + return priv->emoji; +} + +void +purple_presence_set_emoji(PurplePresence *presence, const char *emoji) { + PurplePresencePrivate *priv = NULL; + + g_return_if_fail(PURPLE_IS_PRESENCE(presence)); + + priv = purple_presence_get_instance_private(presence); + + if(!purple_strequal(priv->emoji, emoji)) { + g_free(priv->emoji); + priv->emoji = g_strdup(emoji); + + g_object_notify_by_pspec(G_OBJECT(presence), properties[PROP_EMOJI]); + } +} + +gboolean +purple_presence_get_mobile(PurplePresence *presence) { + PurplePresencePrivate *priv = NULL; + + g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), FALSE); + + priv = purple_presence_get_instance_private(presence); + + return priv->mobile; +} + +void +purple_presence_set_mobile(PurplePresence *presence, gboolean mobile) { + PurplePresencePrivate *priv = NULL; + + g_return_if_fail(PURPLE_IS_PRESENCE(presence)); + + priv = purple_presence_get_instance_private(presence); + + if(priv->mobile != mobile) { + priv->mobile = mobile; + + g_object_notify_by_pspec(G_OBJECT(presence), properties[PROP_MOBILE]); + } +} + const char * purple_presence_primitive_to_string(PurplePresencePrimitive primitive) { switch(primitive) { diff --git a/libpurple/purplepresence.h b/libpurple/purplepresence.h index 8e012fed16..09512343d5 100644 --- a/libpurple/purplepresence.h +++ b/libpurple/purplepresence.h @@ -298,13 +298,24 @@ gint purple_presence_compare(PurplePresence *presence1, PurplePresence *presence * purple_presence_get_primitive: * @presence: The instance. * - * Gets the [enum@Purple.StatusPrimitive] for @presence. + * Gets the [enum@Purple.PresencePrimitive] for @presence. * * Returns: The current primitive. * * Since: 3.0.0 */ -PurpleStatusPrimitive purple_presence_get_primitive(PurplePresence *presence); +PurplePresencePrimitive purple_presence_get_primitive(PurplePresence *presence); + +/** + * purple_presence_set_primitive: + * @presence: The instance. + * @primitive: The new primitive. + * + * Sets the [enum@Purple.StatusPrimitive] for @presence to @primitive. + * + * Since: 3.0.0 + */ +void purple_presence_set_primitive(PurplePresence *presence, PurplePresencePrimitive primitive); /** * purple_presence_get_message: @@ -319,6 +330,64 @@ PurpleStatusPrimitive purple_presence_get_primitive(PurplePresence *presence); const char *purple_presence_get_message(PurplePresence *presence); /** + * purple_presence_set_message: + * @presence: The instance. + * @message: (nullable): The new message. + * + * Sets the status message of @presence to @message. + * + * Since: 3.0.0 + */ +void purple_presence_set_message(PurplePresence *presence, const char *message); + +/** + * purple_presence_get_emoji: + * @presence: The instance. + * + * Gets the current emoji, sometimes referred to as a mood, of @presence. + * + * Returns: The current emoji or %NULL if none is set. + * + * Since: 3.0.0 + */ +const char *purple_presence_get_emoji(PurplePresence *presence); + +/** + * purple_presence_set_emoji: + * @presence: The instance. + * @emoji: (nullable): The new emoji to set. + * + * Sets the current emoji, sometimes referred to as a mood, of @presence to + * @emoji. + * + * Since: 3.0.0 + */ +void purple_presence_set_emoji(PurplePresence *presence, const char *emoji); + +/** + * purple_presence_get_mobile: + * @presence: The instance. + * + * Gets whether or not @presence is on a mobile device. + * + * Returns: %TRUE if @presence is on a mobile device, otherwise %FALSE. + * + * Since: 3.0.0 + */ +gboolean purple_presence_get_mobile(PurplePresence *presence); + +/** + * purple_presence_set_mobile: + * @presence: The instance. + * @mobile: The new mobile status. + * + * Sets whether or not @presence is on a mobile device. + * + * Since: 3.0.0 + */ +void purple_presence_set_mobile(PurplePresence *presence, gboolean mobile); + +/** * purple_presence_primitive_to_string: * @primitive: The [enum@Purple.PresencePrimitive] value. * diff --git a/libpurple/tests/test_presence.c b/libpurple/tests/test_presence.c index b1e237efc6..d376f919d4 100644 --- a/libpurple/tests/test_presence.c +++ b/libpurple/tests/test_presence.c @@ -24,65 +24,79 @@ * Main *****************************************************************************/ static void -test_purple_presence_migrate_online_without_message(void) { +test_purple_presence_new(void) { PurplePresence *presence = NULL; - PurpleStatus *status = NULL; - PurpleStatusType *type = NULL; - type = purple_status_type_new(PURPLE_STATUS_AVAILABLE, - "online", "online", TRUE); presence = purple_presence_new(); - status = purple_status_new(type, presence); - - purple_status_set_active(status, TRUE); - - /* Now verify that the presence returns the correct values for the - * properties. - */ - g_assert_cmpint(purple_presence_get_primitive(presence), ==, - PURPLE_STATUS_AVAILABLE); - g_assert_null(purple_presence_get_message(presence)); + g_assert_true(PURPLE_IS_PRESENCE(presence)); /* Cleanup. */ g_clear_object(&presence); - g_clear_object(&status); - g_clear_pointer(&type, purple_status_type_destroy); } static void -test_purple_presence_migrate_online_with_message(void) { +test_purple_presence_properties(void) { PurplePresence *presence = NULL; - PurpleStatus *status = NULL; - PurpleStatusType *type = NULL; - GHashTable *attrs = NULL; - - type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, - "online", "online", - FALSE, TRUE, TRUE, - "message", "message", - purple_value_new(G_TYPE_STRING), - NULL); - presence = purple_presence_new(); - - status = purple_status_new(type, presence); - - attrs = g_hash_table_new(g_str_hash, g_str_equal); - g_hash_table_insert(attrs, "message", "Greetings Programs!"); - purple_status_set_active_with_attributes(status, TRUE, attrs); - g_hash_table_destroy(attrs); - - /* Now verify that the presence returns the correct values for the - * properties. + PurplePresencePrimitive primitive = PURPLE_PRESENCE_PRIMITIVE_OFFLINE; + GDateTime *now = NULL; + GDateTime *login = NULL; + GDateTime *login1 = NULL; + GDateTime *idle = NULL; + GDateTime *idle1 = NULL; + char *message = NULL; + char *emoji = NULL; + gboolean mobile = FALSE; + + /* Create the login and idle times. */ + now = g_date_time_new_now_utc(); + login = g_date_time_add_hours(now, -1); + idle = g_date_time_add_minutes(now, -10); + g_clear_pointer(&now, g_date_time_unref); + + /* Create the presence using g_object_new to make sure set_property is + * wired up correctly. */ - g_assert_cmpint(purple_presence_get_primitive(presence), ==, - PURPLE_STATUS_AVAILABLE); - g_assert_cmpstr(purple_presence_get_message(presence), ==, - "Greetings Programs!"); + presence = g_object_new( + PURPLE_TYPE_PRESENCE, + "primitive", PURPLE_PRESENCE_PRIMITIVE_AVAILABLE, + "message", "I'll be back!", + "emoji", "🤖", + "login-time", login, + "idle-time", idle, + "mobile", TRUE, + NULL); + + /* Grab the values via g_object_get to make sure get_property is wired up + * correctly. + */ + g_object_get( + presence, + "primitive", &primitive, + "message", &message, + "emoji", &emoji, + "login-time", &login1, + "idle-time", &idle1, + "mobile", &mobile, + NULL); + + /* Validate! */ + g_assert_cmpint(primitive, ==, PURPLE_PRESENCE_PRIMITIVE_AVAILABLE); + g_assert_cmpstr(message, ==, "I'll be back!"); + g_assert_cmpstr(emoji, ==, "🤖"); + g_assert_nonnull(login1); + g_assert_true(g_date_time_equal(login, login1)); + g_assert_nonnull(idle1); + g_assert_true(g_date_time_equal(idle, idle1)); + g_assert_true(mobile); /* Cleanup. */ + g_clear_pointer(&message, g_free); + g_clear_pointer(&emoji, g_free); + g_clear_pointer(&login, g_date_time_unref); + g_clear_pointer(&login1, g_date_time_unref); + g_clear_pointer(&idle, g_date_time_unref); + g_clear_pointer(&idle1, g_date_time_unref); g_clear_object(&presence); - g_clear_object(&status); - g_clear_pointer(&type, purple_status_type_destroy); } /****************************************************************************** @@ -92,14 +106,8 @@ gint main(gint argc, gchar *argv[]) { g_test_init(&argc, &argv, NULL); - /* This tests verify that PurplePresence is properly notifying of property - * changes with the 2.x.y and earlier status back end. When PurplePresence - * has replaced that back end, these tests should be removed as well. - */ - g_test_add_func("/presence/migrate/online-without-message", - test_purple_presence_migrate_online_without_message); - g_test_add_func("/presence/migrate/online-with-message", - test_purple_presence_migrate_online_with_message); + g_test_add_func("/presence/new", test_purple_presence_new); + g_test_add_func("/presence/properties", test_purple_presence_properties); return g_test_run(); } |