diff --git a/.gitignore b/.gitignore
index 0e60f6f..96f3923 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,7 +51,6 @@ Makefile.in
/src/matrix-client.c
/src/matrix-http-api.c
/src/matrix-http-client.c
-/src/matrix-event-room-member.c
/src/matrix-event-room-message.c
/src/namespace-info.vala
/src/namespace-info.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 3a15c60..d82471d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -21,7 +21,6 @@ libmatrix_glib_0_0_la_VALA_SOURCES = \
matrix-client.vala \
matrix-http-api.vala \
matrix-http-client.vala \
- matrix-event-room-member.vala \
matrix-event-room-message.vala \
matrix-event-room-topic.vala \
matrix-event-typing.vala \
@@ -113,6 +112,7 @@ INST_H_SRC_FILES = \
matrix-event-state-base.h \
matrix-event-tag.h \
matrix-event-presence.h \
+ matrix-event-room-member.h \
utils.h \
matrix-profile.h \
$(NULL)
@@ -138,6 +138,7 @@ libmatrix_glib_0_0_la_SOURCES = \
matrix-event-base.c \
matrix-event-tag.c \
matrix-event-presence.c \
+ matrix-event-room-member.c \
matrix-event-room-base.c \
matrix-event-state-base.c \
matrix-profile.c \
diff --git a/src/matrix-event-room-member.c b/src/matrix-event-room-member.c
new file mode 100644
index 0000000..ef4356b
--- /dev/null
+++ b/src/matrix-event-room-member.c
@@ -0,0 +1,994 @@
+/*
+ * This file is part of matrix-glib-sdk
+ *
+ * matrix-glib-sdk is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * matrix-glib-sdk is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with matrix-glib-sdk. If not, see
+ * .
+ */
+
+#include "matrix-event-room-member.h"
+#include "config.h"
+#include "matrix-enumtypes.h"
+#include "utils.h"
+
+/**
+ * SECTION:matrix-event-room-member
+ * @short_description: event representing room membership
+ *
+ * This is the default event handler for `m.room.member` events.
+ *
+ * Adjusts the membership state for a user in a room. It is preferable to use the membership
+ * APIs like matrix_api_invite_user() when performing membership actions rather than adjusting
+ * the state directly as there are a restricted set of valid transformations. For example,
+ * user A cannot force user B to join a room, and trying to force this state change directly
+ * will fail.
+ *
+ * The following membership states are specified:
+ *
+ * * `invite` - The user has been invited to join a room, but has not yet joined it. They may
+ * not participate in the room until they join.
+ * * `join` - The user has joined the room (possibly after accepting an invite), and may
+ * participate in it.
+ * * `leave` - The user was once joined to the room, but has since left (possibly by choice,
+ * or possibly by being kicked).
+ * * `ban` - The user has been banned from the room, and is no longer allowed to join it until
+ * they are un-banned from the room (by having their membership state set to a value other
+ * than ban).
+ * * `knock` - This is a reserved word, which currently has no meaning.
+ *
+ * See also #MatrixRoomMembership for more information.
+ *
+ * The MatrixEventRoomMember:third-party-invite property will be set if this invite is an
+ * invite event and is the successor of an `m.room.third_party_invite` event, and absent
+ * otherwise.
+ *
+ * This event may also include an `invite_room_state` key outside the content key. If present,
+ * this contains an array of stripped state events. These events provide information on a few
+ * select state events such as the room name.
+ */
+
+enum {
+ PROP_0,
+ PROP_MEMBERSHIP,
+ PROP_AVATAR_URL,
+ PROP_DISPLAY_NAME,
+ PROP_TPI_DISPLAY_NAME,
+ PROP_TPI_SIGNED_MXID,
+ PROP_TPI_SIGNED_TOKEN,
+ PROP_TPI_SIGNATURE,
+ PROP_USER_ID,
+ NUM_PROPERTIES
+};
+
+static GParamSpec* matrix_event_room_member_properties[NUM_PROPERTIES];
+
+typedef struct {
+ MatrixRoomMembership _membership;
+ gchar* _avatar_url;
+ gchar* _display_name;
+ gchar* _tpi_display_name;
+ gchar* _tpi_signed_mxid;
+ gchar* _tpi_signed_token;
+ JsonNode* _tpi_signature;
+ MatrixEventState** _invite_room_state;
+ gint _invite_room_state_len;
+ gint __invite_room_state_size_;
+} MatrixEventRoomMemberPrivate;
+
+/**
+ * MatrixEventRoomMember:
+ */
+G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventRoomMember, matrix_event_room_member, MATRIX_EVENT_TYPE_STATE);
+
+static void
+matrix_event_room_member_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
+{
+ MatrixEventRoomMemberPrivate *priv;
+ JsonObject *root;
+ JsonObject *content_root;
+ JsonNode *content_node;
+ JsonNode *node;
+ GError *inner_error = NULL;
+
+ g_return_if_fail(json_data != NULL);
+
+ priv = matrix_event_room_member_get_instance_private(MATRIX_EVENT_ROOM_MEMBER(matrix_event_base));
+ root = json_node_get_object(json_data);
+ content_node = json_object_get_member(root, "content");
+ content_root = json_node_get_object(content_node);
+
+ // Even though the state_key is handled by the parent class,
+ // in this event type this actually means the sender
+ if ((node = json_object_get_member(root, "state_key")) != NULL) {
+ matrix_event_state_set_state_key(MATRIX_EVENT_STATE(matrix_event_base), json_node_get_string(node));
+ } else {
+ g_warning("state_key is missing from a m.room.member event");
+ }
+
+ if ((node = json_object_get_member(content_root, "membership")) != NULL) {
+ MatrixRoomMembership membership;
+
+ membership = _matrix_g_enum_nick_to_value(MATRIX_TYPE_ROOM_MEMBERSHIP, json_node_get_string(node), &inner_error);
+
+ if (inner_error != NULL) {
+ g_clear_error(&inner_error);
+ priv->_membership = MATRIX_ROOM_MEMBERSHIP_UNKNOWN;
+
+ if (DEBUG) {
+ g_warning("Unknown membership value %s", json_node_get_string(node));
+ }
+ } else {
+ priv->_membership = membership;
+ }
+ } else if (DEBUG) {
+ g_warning("membership key is missing from the m.room.member event");
+ }
+
+ if ((node = json_object_get_member(content_root, "avatar_url")) != NULL) {
+ g_free(priv->_avatar_url);
+ priv->_avatar_url = g_strdup(json_node_get_string(node));
+ }
+
+ if ((node = json_object_get_member(content_root, "displayname")) != NULL) {
+ g_free(priv->_display_name);
+ priv->_display_name = g_strdup(json_node_get_string(node));
+ }
+
+ if ((node = json_object_get_member(content_root, "third_party_invite")) != NULL) {
+ JsonObject *tpi_root = json_node_get_object(node);
+
+ if ((node = json_object_get_member(tpi_root, "display_name")) != NULL) {
+ g_free(priv->_tpi_display_name);
+ priv->_tpi_display_name = g_strdup(json_node_get_string(node));
+ } else {
+ g_warning("content.third_party_invite.display_name is missing from a m.room.member event");
+ }
+
+ if ((node = json_object_get_member(tpi_root, "signed")) != NULL) {
+ JsonObject *signed_root = json_node_get_object(node);
+
+ if ((node = json_object_get_member(signed_root, "mxid")) != NULL) {
+ g_free(priv->_tpi_signed_mxid);
+ priv->_tpi_signed_mxid = g_strdup(json_node_get_string(node));
+ } else {
+ g_warning("content.third_party_invit.signed.mxid is missing from a m.room.member event");
+ }
+
+ if ((node = json_object_get_member(signed_root, "token")) != NULL) {
+ g_free(priv->_tpi_signed_token);
+ priv->_tpi_signed_token = g_strdup(json_node_get_string(node));
+ } else {
+ g_warning("content.third_party_invite.signed.token is missing from a m.room.member event");
+ }
+
+ if ((node = json_object_get_member(signed_root, "signatures")) != NULL) {
+ json_node_unref(priv->_tpi_signature);
+ priv->_tpi_signature = json_node_ref(node);
+ } else {
+ g_warning("content.third_party_invite.signed.signatures is missing from a m.room.member event");
+ }
+ } else {
+ g_warning("content.third_party_invite.signed is missing from a m.room.member event");
+ }
+ }
+
+ if ((node = json_object_get_member(root, "invite_room_state")) != NULL) {
+ JsonArray *events = json_node_get_array(node);
+ gint events_len;
+
+ if ((events_len = json_array_get_length(events)) > 0) {
+ for (gint i = 0; i < priv->_invite_room_state_len; i++) {
+ g_object_unref(priv->_invite_room_state[i]);
+ }
+
+ g_free(priv->_invite_room_state);
+
+ priv->_invite_room_state_len = events_len;
+ priv->_invite_room_state = g_new(MatrixEventState *, events_len);
+
+ for (gint i = 0; i < events_len; i++) {
+ JsonNode *member_node = json_array_get_element(events, i);
+ MatrixEventState *event;
+ GError *error = NULL;
+
+ event = (MatrixEventState *)matrix_event_base_new_from_json(NULL, member_node, &error);
+
+ if (error == NULL) {
+ priv->_invite_room_state[i] = g_object_ref(event);
+ }
+
+ g_object_unref(event);
+ }
+ }
+ }
+
+ // Chain up
+ MATRIX_EVENT_BASE_CLASS(matrix_event_room_member_parent_class)->from_json(matrix_event_base, json_data, &inner_error);
+
+ if (inner_error != NULL) {
+ g_propagate_error(error, inner_error);
+ }
+}
+
+static void
+matrix_event_room_member_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
+{
+ MatrixEventRoomMemberPrivate *priv;
+ const gchar *state_key;
+ gchar *membership;
+ JsonObject *root;
+ JsonObject *content_root;
+ JsonObject *tpi_root;
+ JsonObject *tpi_signed_root;
+ JsonNode *content_node;
+ GError *inner_error = NULL;
+
+ priv = matrix_event_room_member_get_instance_private(MATRIX_EVENT_ROOM_MEMBER(matrix_event_base));
+
+ if (priv->_membership == MATRIX_ROOM_MEMBERSHIP_UNKNOWN) {
+ g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_UNKNOWN_VALUE,
+ "Unknown membership value cannot be added to a room member event");
+
+ return;
+ }
+
+ state_key = matrix_event_state_get_state_key(MATRIX_EVENT_STATE(matrix_event_base));
+
+ if ((state_key == NULL) || (*state_key == 0)) {
+ g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
+ "Won't generate a m.room.member event with an empty state_key");
+
+ return;
+ }
+
+ root = json_node_get_object(json_data);
+ content_node = json_object_get_member(root, "content");
+ content_root = json_node_get_object(content_node);
+ membership = _matrix_g_enum_to_string(MATRIX_TYPE_ROOM_MEMBERSHIP, priv->_membership, '_');
+
+ if (membership != NULL) {
+ json_object_set_string_member(content_root, "membership", membership);
+ g_free(membership);
+ } else {
+ g_critical("Won't generate a m.room.member event with an unknown membership");
+ }
+
+ if (priv->_avatar_url != NULL) {
+ json_object_set_string_member(content_root, "avatar_url", priv->_avatar_url);
+ }
+
+ if (priv->_display_name != NULL) {
+ json_object_set_string_member(content_root, "displayname", priv->_display_name);
+ }
+
+ tpi_root = json_object_new();
+
+ if (priv->_tpi_display_name != NULL) {
+ json_object_set_string_member(tpi_root, "display_name", priv->_tpi_display_name);
+ }
+
+ tpi_signed_root = json_object_new();
+
+ if (priv->_tpi_signed_mxid != NULL) {
+ json_object_set_string_member(tpi_signed_root, "mxid", priv->_tpi_signed_mxid);
+ }
+
+ if (priv->_tpi_signed_token != NULL) {
+ json_object_set_string_member(tpi_signed_root, "token", priv->_tpi_signed_token);
+ }
+
+ if (priv->_tpi_signature != NULL) {
+ json_object_set_member(tpi_signed_root, "signature", priv->_tpi_signature);
+ }
+
+ if ((json_object_get_size(tpi_signed_root) != 3) &&
+ (json_object_get_size(tpi_signed_root) != 0)) {
+ g_warning("3rd party invite data is not filled; ignoring");
+
+ tpi_signed_root = (json_object_unref(tpi_signed_root), NULL);
+ }
+
+ if ((tpi_signed_root != NULL) && (priv->_tpi_display_name != NULL)) {
+ JsonNode *tpi_signed_node = json_node_new(JSON_NODE_OBJECT);
+
+ json_node_set_object(tpi_signed_node, tpi_signed_root);
+ json_object_set_member(tpi_root, "signed", tpi_signed_node);
+ }
+
+ if (json_object_get_size(tpi_root) == 2) {
+ JsonNode *tpi_node = json_node_new(JSON_NODE_OBJECT);
+
+ json_node_set_object(tpi_node, tpi_root);
+ json_object_set_member(content_root, "third_party_invite", tpi_node);
+ } else if (json_object_get_size(tpi_root) != 0) {
+ tpi_root = (json_object_unref(tpi_root), NULL);
+ g_warning("3rd party invite data is incomplete; ignoring");
+ }
+
+ if (priv->_invite_room_state != NULL) {
+ JsonArray *state_ary = json_array_new();
+
+ for (gint i = 0; i < priv->_invite_room_state_len; i++) {
+ JsonNode *state_node = matrix_event_state_get_stripped_node(priv->_invite_room_state[i]);
+
+ json_array_add_element(state_ary, state_node);
+ }
+
+ if (json_array_get_length(state_ary) > 0) {
+ JsonNode *state_node = json_node_new(JSON_TYPE_ARRAY);
+
+ json_node_set_array(state_node, state_ary);
+ json_object_set_member(root, "invite_room_state", state_node);
+ }
+ }
+
+ MATRIX_EVENT_BASE_CLASS(matrix_event_room_member_parent_class)->to_json(matrix_event_base, json_data, &inner_error);
+
+ if (inner_error != NULL) {
+ g_propagate_error(error, inner_error);
+ }
+}
+
+/**
+ * matrix_event_room_member_new:
+ *
+ * Create a new #MatrixEventRoomMember object.
+ *
+ * Returns: (transfer full): a new #MatrixEventRoomMember object
+ */
+MatrixEventRoomMember *
+matrix_event_room_member_new(void)
+{
+ return (MatrixEventRoomMember *)matrix_event_state_construct(MATRIX_EVENT_TYPE_ROOM_MEMBER);
+}
+
+/**
+ * matrix_event_room_member_get_membership:
+ * @event: a #MatrixEventRoomMember
+ *
+ * Get the membership status from @event.
+ *
+ * Returns: a #MatrixRoomMembership value
+ */
+MatrixRoomMembership
+matrix_event_room_member_get_membership(MatrixEventRoomMember *matrix_event_room_member)
+{
+ MatrixEventRoomMemberPrivate *priv;
+
+ g_return_val_if_fail(matrix_event_room_member != NULL, 0);
+
+ priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
+
+ return priv->_membership;
+}
+
+/**
+ * matrix_event_room_member_set_membership:
+ * @event: a #MatrixEventRoomMember
+ * @membership: a #MatrixRoomMembership value
+ *
+ * Set the membership value in @event.
+ */
+void
+matrix_event_room_member_set_membership(MatrixEventRoomMember *matrix_event_room_member, MatrixRoomMembership membership)
+{
+ MatrixEventRoomMemberPrivate *priv;
+
+ g_return_if_fail(matrix_event_room_member != NULL);
+
+ priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
+
+ if (priv->_membership != membership) {
+ priv->_membership = membership;
+
+ g_object_notify_by_pspec((GObject *)matrix_event_room_member, matrix_event_room_member_properties[PROP_MEMBERSHIP]);
+ }
+}
+
+/**
+ * matrix_event_room_member_get_avatar_url:
+ * @event: a #MatrixEventRoomMember
+ *
+ * Get the avatar URL from @event.
+ *
+ * The returned value is owned by @event and should not be freed.
+ *
+ * Returns: (transfer none) (nullable): an avatar URL
+ */
+const gchar *
+matrix_event_room_member_get_avatar_url(MatrixEventRoomMember *matrix_event_room_member)
+{
+ MatrixEventRoomMemberPrivate *priv;
+
+ g_return_val_if_fail(matrix_event_room_member != NULL, NULL);
+
+ priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
+
+ return priv->_avatar_url;
+}
+
+/**
+ * matrix_event_room_member_set_avatar_url:
+ * @event: a #MatrixEventRoomMember
+ * @avatar_url: (transfer none) (nullable): the avatar URL for @event
+ *
+ * Set the avatar URL in @event.
+ */
+void
+matrix_event_room_member_set_avatar_url(MatrixEventRoomMember *matrix_event_room_member, const gchar *avatar_url)
+{
+ MatrixEventRoomMemberPrivate *priv;
+
+ g_return_if_fail(matrix_event_room_member != NULL);
+
+ priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
+
+ if (g_strcmp0(avatar_url, priv->_avatar_url) != 0) {
+ g_free(priv->_avatar_url);
+ priv->_avatar_url = g_strdup(avatar_url);
+
+ g_object_notify_by_pspec((GObject *)matrix_event_room_member, matrix_event_room_member_properties[PROP_AVATAR_URL]);
+ }
+}
+
+/**
+ * matrix_event_room_member_get_display_name:
+ * @event: a #MatrixEventRoomMember
+ *
+ * Get the display name from @event.
+ *
+ * The returned value is owned by @event and should not be freed.
+ *
+ * Returns: (transfer none) (nullable): a display name
+ */
+const gchar *
+matrix_event_room_member_get_display_name(MatrixEventRoomMember *matrix_event_room_member)
+{
+ MatrixEventRoomMemberPrivate *priv;
+
+ g_return_val_if_fail(matrix_event_room_member != NULL, NULL);
+
+ priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
+
+ return priv->_display_name;
+}
+
+/**
+ * matrix_event_room_member_set_display_name:
+ * @event: a #MatrixEventRoomMember
+ * @display_name: (transfer none) (nullable): a display name
+ *
+ * Set the display name in @event.
+ */
+void
+matrix_event_room_member_set_display_name(MatrixEventRoomMember *matrix_event_room_member, const gchar *display_name)
+{
+ MatrixEventRoomMemberPrivate *priv;
+
+ g_return_if_fail(matrix_event_room_member != NULL);
+
+ priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
+
+ if (g_strcmp0(display_name, priv->_display_name) != 0) {
+ g_free(priv->_display_name);
+ priv->_display_name = g_strdup(display_name);
+
+ g_object_notify_by_pspec((GObject *)matrix_event_room_member, matrix_event_room_member_properties[PROP_DISPLAY_NAME]);
+ }
+}
+
+/**
+ * matrix_event_room_member_get_tpi_display_name:
+ * @event: a #MatrixEventRoomMember
+ *
+ * Get the 3rd party display name from @event. It will be %NULL if the member was not invited
+ * by a 3rd party ID.
+ *
+ * The returned value is owned by @event, and should not be freed.
+ *
+ * Returns: (transfer none) (nullable): a 3rd party display name
+ */
+const gchar *
+matrix_event_room_member_get_tpi_display_name(MatrixEventRoomMember *matrix_event_room_member)
+{
+ MatrixEventRoomMemberPrivate *priv;
+
+ g_return_val_if_fail(matrix_event_room_member != NULL, NULL);
+
+ priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
+
+ return priv->_tpi_display_name;
+}
+
+/**
+ * matrix_event_room_member_set_tpi_display_name:
+ * @event: a #MatrixEventRoomMember
+ * @tpi_display_name: a 3rd party display name
+ *
+ * Set the 3rd party display name in @event.
+ */
+void
+matrix_event_room_member_set_tpi_display_name(MatrixEventRoomMember *matrix_event_room_member, const gchar *tpi_display_name)
+{
+ MatrixEventRoomMemberPrivate *priv;
+
+ g_return_if_fail(matrix_event_room_member != NULL);
+
+ priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
+
+ if (g_strcmp0(tpi_display_name, priv->_tpi_display_name) != 0) {
+ g_free(priv->_tpi_display_name);
+ priv->_tpi_display_name = g_strdup(tpi_display_name);
+
+ g_object_notify_by_pspec((GObject *)matrix_event_room_member, matrix_event_room_member_properties[PROP_TPI_DISPLAY_NAME]);
+ }
+}
+
+/**
+ * matrix_event_room_member_get_tpi_signed_mxid:
+ * @event: a #MatrixEventRoomMember
+ *
+ * Get the signed 3rd party Matrix ID.
+ *
+ * The returned value is owned by @event and should not be freed.
+ *
+ * Returns: (transfer none) (nullable): a 3rd party Matrix ID
+ */
+const gchar *
+matrix_event_room_member_get_tpi_signed_mxid(MatrixEventRoomMember *matrix_event_room_member)
+{
+ MatrixEventRoomMemberPrivate *priv;
+
+ g_return_val_if_fail(matrix_event_room_member != NULL, NULL);
+
+ priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
+
+ return priv->_tpi_signed_mxid;
+}
+
+/**
+ * matrix_event_room_member_set_tpi_signed_mxid:
+ * @event: a #MatrixEventRoomMember
+ * @tpi_signed_mxid: a 3rd party signed Matrix ID
+ *
+ * Set the signed 3rd party Matrix ID.
+ */
+void
+matrix_event_room_member_set_tpi_signed_mxid(MatrixEventRoomMember *matrix_event_room_member, const gchar *tpi_signed_mxid)
+{
+ MatrixEventRoomMemberPrivate *priv;
+
+ g_return_if_fail(matrix_event_room_member != NULL);
+
+ priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
+
+ if (g_strcmp0(tpi_signed_mxid, priv->_tpi_signed_mxid) != 0) {
+ g_free(priv->_tpi_signed_mxid);
+ priv->_tpi_signed_mxid = g_strdup(tpi_signed_mxid);
+
+ g_object_notify_by_pspec((GObject *)matrix_event_room_member, matrix_event_room_member_properties[PROP_TPI_SIGNED_MXID]);
+ }
+}
+
+/**
+ * matrix_event_room_member_get_tpi_signed_token:
+ * @event: a #MatrixEventRoomMember
+ *
+ * Get the signed 3rd party token.
+ *
+ * The returned value is owned by @event and should not be freed.
+ *
+ * Returns: (transfer none) (nullable): a signed 3rd party token
+ */
+const gchar *
+matrix_event_room_member_get_tpi_signed_token(MatrixEventRoomMember *matrix_event_room_member)
+{
+ MatrixEventRoomMemberPrivate *priv;
+
+ g_return_val_if_fail(matrix_event_room_member != NULL, NULL);
+
+ priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
+
+ return priv->_tpi_signed_token;
+}
+
+/**
+ * matrix_event_room_member_set_tpi_signed_token:
+ * @event: a #MatrixEventRoomMember
+ * @tpi_signed_token: a signed 3rd party token
+ *
+ * Set the signed 3rd party token in @event.
+ */
+void
+matrix_event_room_member_set_tpi_signed_token(MatrixEventRoomMember *matrix_event_room_member, const gchar *tpi_signed_token)
+{
+ MatrixEventRoomMemberPrivate *priv;
+
+ g_return_if_fail(matrix_event_room_member != NULL);
+
+ priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
+
+ if (g_strcmp0(tpi_signed_token, priv->_tpi_signed_token) != 0) {
+ g_free(priv->_tpi_signed_token);
+ priv->_tpi_signed_token = g_strdup(tpi_signed_token);
+
+ g_object_notify_by_pspec((GObject *)matrix_event_room_member, matrix_event_room_member_properties[PROP_TPI_SIGNED_TOKEN]);
+ }
+}
+
+/**
+ * matrix_event_room_member_get_tpi_signature:
+ * @event: a #MatrixEventRoomMember
+ *
+ * Get the 3rd party signature from @event.
+ *
+ * The returned value is owned by @event and should not be freed.
+ *
+ * Returns: (transfer none) (nullable): a 3rd party signature.
+ */
+JsonNode *
+matrix_event_room_member_get_tpi_signature(MatrixEventRoomMember *matrix_event_room_member)
+{
+ MatrixEventRoomMemberPrivate *priv;
+
+ g_return_val_if_fail(matrix_event_room_member != NULL, NULL);
+
+ priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
+
+ return priv->_tpi_signature;
+}
+
+/**
+ * matrix_event_room_member_set_tpi_signature:
+ * @event: a #MatrixEventRoomMember
+ * @tpi_signature: a 3rd party signature
+ *
+ * Set the 3rd party signature in @event.
+ */
+void
+matrix_event_room_member_set_tpi_signature(MatrixEventRoomMember *matrix_event_room_member, JsonNode *tpi_signature)
+{
+ MatrixEventRoomMemberPrivate *priv;
+
+ g_return_if_fail(matrix_event_room_member != NULL);
+
+ priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
+
+ if (priv->_tpi_signature != tpi_signature) {
+ json_node_unref(priv->_tpi_signature);
+ priv->_tpi_signature = json_node_ref(tpi_signature);
+
+ g_object_notify_by_pspec((GObject *)matrix_event_room_member, matrix_event_room_member_properties[PROP_TPI_SIGNATURE]);
+ }
+}
+
+/**
+ * matrix_event_room_member_get_invite_room_state:
+ * @event: a #MatrixEventRoomMember
+ * @n_invite_room_state: placeholder for the returned list, or %NULL to ignore
+ *
+ * Get the initial state events from @event.
+ *
+ * The returned value is owned by @event and should not be freed.
+ *
+ * Returns: (transfer none) (nullable): the list of initial state events
+ */
+MatrixEventState **
+matrix_event_room_member_get_invite_room_state(MatrixEventRoomMember *matrix_event_room_member, int *n_invite_room_state)
+{
+ MatrixEventRoomMemberPrivate *priv;
+
+ g_return_val_if_fail(matrix_event_room_member != NULL, NULL);
+
+ priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
+
+ if (n_invite_room_state != NULL) {
+ *n_invite_room_state = priv->_invite_room_state_len;
+ }
+
+ return priv->_invite_room_state;
+}
+
+/**
+ * matrix_event_room_member_set_invite_room_state:
+ * @event: a #MatrixEventRoomMember
+ * @invite_room_state: a list of initial state events
+ * @n_invite_room_state: the length of @invite_room_state
+ *
+ * Set the initial state events in @event.
+ */
+void
+matrix_event_room_member_set_invite_room_state(MatrixEventRoomMember *matrix_event_room_member, MatrixEventState **invite_room_state, int n_invite_room_state)
+{
+ MatrixEventRoomMemberPrivate *priv;
+
+ g_return_if_fail(matrix_event_room_member != NULL);
+
+ priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
+
+ for (gint i = 0; i < priv->_invite_room_state_len; i++) {
+ g_object_unref(priv->_invite_room_state[i]);
+ }
+
+ g_free(priv->_invite_room_state);
+
+ priv->_invite_room_state = g_new(MatrixEventState *, n_invite_room_state);
+
+ for (gint i = 0; i < n_invite_room_state; i++) {
+ priv->_invite_room_state[i] = g_object_ref(invite_room_state[i]);
+ }
+
+ priv->_invite_room_state_len = n_invite_room_state;
+}
+
+/**
+ * matrix_event_room_member_get_user_id:
+ * @event: a #MatrixEventRoomMember
+ *
+ * Get the user ID from @event.
+ *
+ * The returned value is owned by @event and should not be freed.
+ *
+ * Returns: (transfer none) (nullable): a user ID
+ */
+const gchar *
+matrix_event_room_member_get_user_id(MatrixEventRoomMember *matrix_event_room_member)
+{
+ g_return_val_if_fail(matrix_event_room_member != NULL, NULL);
+
+ return matrix_event_state_get_state_key(MATRIX_EVENT_STATE(matrix_event_room_member));
+}
+
+/**
+ * matrix_event_room_member_set_user_id:
+ * @event: a #MatrixEventRoomMember
+ * @user_id: a Matrix user ID
+ *
+ * Set the user ID in @event.
+ */
+void
+matrix_event_room_member_set_user_id(MatrixEventRoomMember *matrix_event_room_member, const gchar *user_id)
+{
+ const gchar *state_key = matrix_event_state_get_state_key(MATRIX_EVENT_STATE(matrix_event_room_member));
+
+ if (g_strcmp0(state_key, user_id) != 0) {
+ matrix_event_state_set_state_key(MATRIX_EVENT_STATE(matrix_event_room_member), user_id);
+
+ g_object_notify_by_pspec((GObject *)matrix_event_room_member, matrix_event_room_member_properties[PROP_USER_ID]);
+ }
+}
+
+static void
+matrix_event_room_member_finalize(GObject *gobject)
+{
+ MatrixEventRoomMemberPrivate *priv = matrix_event_room_member_get_instance_private(MATRIX_EVENT_ROOM_MEMBER(gobject));
+
+ g_free(priv->_avatar_url);
+ g_free(priv->_display_name);
+ g_free(priv->_tpi_display_name);
+ g_free(priv->_tpi_signed_mxid);
+ g_free(priv->_tpi_signed_token);
+ json_node_unref(priv->_tpi_signature);
+
+ for (gint i = 0; i < priv->_invite_room_state_len; i++) {
+ g_object_unref(priv->_invite_room_state[i]);
+ }
+
+ g_free(priv->_invite_room_state);
+
+ G_OBJECT_CLASS(matrix_event_room_member_parent_class)->finalize(gobject);
+}
+
+static void
+matrix_event_room_member_get_property(GObject *gobject, guint property_id, GValue* value, GParamSpec* pspec)
+{
+ MatrixEventRoomMember *matrix_event_room_member = MATRIX_EVENT_ROOM_MEMBER(gobject);
+
+ switch (property_id) {
+ case PROP_MEMBERSHIP:
+ g_value_set_enum(value, matrix_event_room_member_get_membership(matrix_event_room_member));
+
+ break;
+ case PROP_AVATAR_URL:
+ g_value_set_string(value, matrix_event_room_member_get_avatar_url(matrix_event_room_member));
+
+ break;
+ case PROP_DISPLAY_NAME:
+ g_value_set_string(value, matrix_event_room_member_get_display_name(matrix_event_room_member));
+
+ break;
+ case PROP_TPI_DISPLAY_NAME:
+ g_value_set_string(value, matrix_event_room_member_get_tpi_display_name(matrix_event_room_member));
+
+ break;
+ case PROP_TPI_SIGNED_MXID:
+ g_value_set_string(value, matrix_event_room_member_get_tpi_signed_mxid(matrix_event_room_member));
+
+ break;
+ case PROP_TPI_SIGNED_TOKEN:
+ g_value_set_string(value, matrix_event_room_member_get_tpi_signed_token(matrix_event_room_member));
+
+ break;
+ case PROP_TPI_SIGNATURE:
+ g_value_set_boxed(value, matrix_event_room_member_get_tpi_signature(matrix_event_room_member));
+
+ break;
+ case PROP_USER_ID:
+ g_value_set_string(value, matrix_event_room_member_get_user_id(matrix_event_room_member));
+
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
+
+ break;
+ }
+}
+
+static void
+matrix_event_room_member_set_property(GObject *gobject, guint property_id, const GValue* value, GParamSpec* pspec)
+{
+ MatrixEventRoomMember * matrix_event_room_member = MATRIX_EVENT_ROOM_MEMBER(gobject);
+
+ switch (property_id) {
+ case PROP_MEMBERSHIP:
+ matrix_event_room_member_set_membership (matrix_event_room_member, g_value_get_enum (value));
+
+ break;
+ case PROP_AVATAR_URL:
+ matrix_event_room_member_set_avatar_url (matrix_event_room_member, g_value_get_string (value));
+
+ break;
+ case PROP_DISPLAY_NAME:
+ matrix_event_room_member_set_display_name (matrix_event_room_member, g_value_get_string (value));
+
+ break;
+ case PROP_TPI_DISPLAY_NAME:
+ matrix_event_room_member_set_tpi_display_name (matrix_event_room_member, g_value_get_string (value));
+
+ break;
+ case PROP_TPI_SIGNED_MXID:
+ matrix_event_room_member_set_tpi_signed_mxid (matrix_event_room_member, g_value_get_string (value));
+
+ break;
+ case PROP_TPI_SIGNED_TOKEN:
+ matrix_event_room_member_set_tpi_signed_token (matrix_event_room_member, g_value_get_string (value));
+
+ break;
+ case PROP_TPI_SIGNATURE:
+ matrix_event_room_member_set_tpi_signature (matrix_event_room_member, g_value_get_boxed (value));
+
+ break;
+ case PROP_USER_ID:
+ matrix_event_room_member_set_user_id (matrix_event_room_member, g_value_get_string (value));
+
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
+
+ break;
+ }
+}
+
+static void
+matrix_event_room_member_class_init (MatrixEventRoomMemberClass *klass)
+{
+ ((MatrixEventBaseClass *)klass)->from_json = matrix_event_room_member_real_from_json;
+ ((MatrixEventBaseClass *)klass)->to_json = matrix_event_room_member_real_to_json;
+ G_OBJECT_CLASS(klass)->get_property = matrix_event_room_member_get_property;
+ G_OBJECT_CLASS(klass)->set_property = matrix_event_room_member_set_property;
+ G_OBJECT_CLASS(klass)->finalize = matrix_event_room_member_finalize;
+
+ /**
+ * MatrixEventRoomMember:membership:
+ *
+ * The membership state of the user.
+ */
+ matrix_event_room_member_properties[PROP_MEMBERSHIP] = g_param_spec_enum(
+ "membership", "membership", "membership",
+ MATRIX_TYPE_ROOM_MEMBERSHIP, MATRIX_ROOM_MEMBERSHIP_UNKNOWN,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_MEMBERSHIP, matrix_event_room_member_properties[PROP_MEMBERSHIP]);
+
+ /**
+ * MatrixEventRoomMember:avatar-url:
+ *
+ * The avatar URL for this user, if any. This is added by the homeserver.
+ */
+ matrix_event_room_member_properties[PROP_AVATAR_URL] = g_param_spec_string(
+ "avatar-url", "avatar-url", "avatar-url",
+ NULL,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_AVATAR_URL, matrix_event_room_member_properties[PROP_AVATAR_URL]);
+
+ /**
+ * MatrixEventRoomMember:display-name:
+ *
+ * The display name for this user, if any. This is added by the homeserver.
+ */
+ matrix_event_room_member_properties[PROP_DISPLAY_NAME] = g_param_spec_string(
+ "display-name", "display-name", "display-name",
+ NULL,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_DISPLAY_NAME, matrix_event_room_member_properties[PROP_DISPLAY_NAME]);
+
+ /**
+ * MatrixEventRoomMember:tpi-display-name:
+ *
+ * A name which can be displayed to represent the user instead of their third party identifier.
+ */
+ matrix_event_room_member_properties[PROP_TPI_DISPLAY_NAME] = g_param_spec_string(
+ "tpi-display-name", "tpi-display-name", "tpi-display-name",
+ NULL,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TPI_DISPLAY_NAME, matrix_event_room_member_properties[PROP_TPI_DISPLAY_NAME]);
+
+ /**
+ * MatrixEventRoomMember:tpi-signed-mxid:
+ * The invited matrix user ID. Must be equal to the `user_id` property of the event.
+ */
+ matrix_event_room_member_properties[PROP_TPI_SIGNED_MXID] = g_param_spec_string(
+ "tpi-signed-mxid", "tpi-signed-mxid", "tpi-signed-mxid",
+ NULL,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TPI_SIGNED_MXID, matrix_event_room_member_properties[PROP_TPI_SIGNED_MXID]);
+
+ /**
+ * MatrixEventRoomMember:tpi-signed-token:
+ *
+ * The token property of the containing third_party_invite object.
+ */
+ matrix_event_room_member_properties[PROP_TPI_SIGNED_TOKEN] = g_param_spec_string(
+ "tpi-signed-token", "tpi-signed-token", "tpi-signed-token",
+ NULL,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TPI_SIGNED_TOKEN, matrix_event_room_member_properties[PROP_TPI_SIGNED_TOKEN]);
+
+ /**
+ * MatrixEventRoomMember:tpi-signature:
+ *
+ * A single signature from the verifying server, in the format specified by the Signing
+ * Events section of the server-server API.
+ */
+ matrix_event_room_member_properties[PROP_TPI_SIGNATURE] = g_param_spec_boxed(
+ "tpi-signature", "tpi-signature", "tpi-signature",
+ JSON_TYPE_NODE,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TPI_SIGNATURE, matrix_event_room_member_properties[PROP_TPI_SIGNATURE]);
+
+ /**
+ * MatrixEventRoomMember:user-id:
+ *
+ * The user ID whom this event relates to.
+ */
+ matrix_event_room_member_properties[PROP_USER_ID] = g_param_spec_string(
+ "user-id", "user-id", "user-id",
+ NULL,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_USER_ID, matrix_event_room_member_properties[PROP_USER_ID]);
+}
+
+static void
+matrix_event_room_member_init(MatrixEventRoomMember *matrix_event_room_member)
+{
+ MatrixEventRoomMemberPrivate *priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
+
+ priv->_membership = MATRIX_ROOM_MEMBERSHIP_UNKNOWN;
+ priv->_avatar_url = NULL;
+ priv->_display_name = NULL;
+ priv->_tpi_display_name = NULL;
+ priv->_tpi_signed_mxid = NULL;
+ priv->_tpi_signed_token = NULL;
+ priv->_tpi_signature = NULL;
+
+ matrix_event_room_member_set_user_id(matrix_event_room_member, NULL);
+}
diff --git a/src/matrix-event-room-member.h b/src/matrix-event-room-member.h
new file mode 100644
index 0000000..c69f435
--- /dev/null
+++ b/src/matrix-event-room-member.h
@@ -0,0 +1,57 @@
+/*
+ * This file is part of matrix-glib-sdk
+ *
+ * matrix-glib-sdk is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * matrix-glib-sdk is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with matrix-glib-sdk. If not, see
+ * .
+ */
+
+#ifndef __MATRX_GLIB_SDK_EVENT_ROOM_MEMBER_H__
+# define __MATRX_GLIB_SDK_EVENT_ROOM_MEMBER_H__
+
+# include
+# include "matrix-event-state-base.h"
+# include "matrix-types.h"
+
+G_BEGIN_DECLS
+
+# define MATRIX_EVENT_TYPE_ROOM_MEMBER matrix_event_room_member_get_type()
+G_DECLARE_DERIVABLE_TYPE(MatrixEventRoomMember, matrix_event_room_member, MATRIX_EVENT, ROOM_MEMBER, MatrixEventState)
+
+struct _MatrixEventRoomMemberClass {
+ MatrixEventStateClass parent_class;
+};
+
+MatrixEventRoomMember *matrix_event_room_member_new (void);
+MatrixRoomMembership matrix_event_room_member_get_membership (MatrixEventRoomMember *event);
+void matrix_event_room_member_set_membership (MatrixEventRoomMember *event, MatrixRoomMembership membership);
+const gchar *matrix_event_room_member_get_avatar_url (MatrixEventRoomMember *event);
+void matrix_event_room_member_set_avatar_url (MatrixEventRoomMember *event, const gchar *avatar_url);
+const gchar *matrix_event_room_member_get_display_name (MatrixEventRoomMember *event);
+void matrix_event_room_member_set_display_name (MatrixEventRoomMember *event, const gchar *display_name);
+const gchar *matrix_event_room_member_get_tpi_display_name (MatrixEventRoomMember *event);
+void matrix_event_room_member_set_tpi_display_name (MatrixEventRoomMember *event, const gchar *tpi_display_name);
+const gchar *matrix_event_room_member_get_tpi_signed_mxid (MatrixEventRoomMember *event);
+void matrix_event_room_member_set_tpi_signed_mxid (MatrixEventRoomMember *event, const gchar *tpi_signed_mxid);
+const gchar *matrix_event_room_member_get_tpi_signed_token (MatrixEventRoomMember *event);
+void matrix_event_room_member_set_tpi_signed_token (MatrixEventRoomMember *event, const gchar *tpi_signed_token);
+JsonNode *matrix_event_room_member_get_tpi_signature (MatrixEventRoomMember *event);
+void matrix_event_room_member_set_tpi_signature (MatrixEventRoomMember *event, JsonNode *tpi_signature);
+MatrixEventState **matrix_event_room_member_get_invite_room_state (MatrixEventRoomMember *event, int *n_invite_room_state);
+void matrix_event_room_member_set_invite_room_state (MatrixEventRoomMember *event, MatrixEventState **invite_room_state, int n_invite_room_state);
+const gchar *matrix_event_room_member_get_user_id (MatrixEventRoomMember *event);
+void matrix_event_room_member_set_user_id (MatrixEventRoomMember *event, const gchar *user_id);
+
+G_END_DECLS
+
+#endif /* __MATRX_GLIB_SDK_EVENT_ROOM_MEMBER_H__ */
diff --git a/src/matrix-event-room-member.vala b/src/matrix-event-room-member.vala
deleted file mode 100644
index ce2cf00..0000000
--- a/src/matrix-event-room-member.vala
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * This file is part of matrix-glib-sdk
- *
- * matrix-glib-sdk is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation, either
- * version 3 of the License, or (at your option) any later version.
- *
- * matrix-glib-sdk is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied
- * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with matrix-glib-sdk. If not, see
- * .
- */
-
-/**
- * Class for representing a room membership events
- *
- * Adjusts the membership state for a user in a room. It is preferable
- * to use the membership APIs (`/rooms//invite` etc) when
- * performing membership actions rather than adjusting the state
- * directly as there are a restricted set of valid
- * transformations. For example, user A cannot force user B to join a
- * room, and trying to force this state change directly will
- * fail.
- *
- * The following membership states are specified:
- *
- * - invite - The user has been invited to join a room, but has not
- * yet joined it. They may not participate in the room until they
- * join.
- *
- * - join - The user has joined the room (possibly after accepting an
- * invite), and may participate in it.
- *
- * - leave - The user was once joined to the room, but has since left
- * (possibly by choice, or possibly by being kicked).
- *
- * - ban - The user has been banned from the room, and is no longer
- * allowed to join it until they are un-banned from the room (by
- * having their membership state set to a value other than ban).
- *
- * - knock - This is a reserved word, which currently has no meaning.
- *
- * The third_party_invite property will be set if this invite is an
- * invite event and is the successor of an m.room.third_party_invite
- * event, and absent otherwise.
- *
- * This event may also include an invite_room_state key outside the
- * content key. If present, this contains an array of stripped state
- * events. These events provide information on a few select state
- * events such as the room name.
- */
-public class Matrix.Event.RoomMember : Matrix.Event.State {
- /**
- * The membership state of the user.
- */
- public RoomMembership membership {
- get; set;
-
- default = RoomMembership.UNKNOWN;
- }
-
- /**
- * The avatar URL for this user, if any. This is added by the
- * homeserver.
- */
- public string? avatar_url { get; set; default = null; }
-
- /**
- * The display name for this user, if any. This is added by the
- * homeserver.
- */
- public string? display_name { get; set; default = null; }
-
- /**
- * A name which can be displayed to represent the user instead of
- * their third party identifier
- */
- public string? tpi_display_name { get; set; default = null; }
-
- /**
- * The invited matrix user ID. Must be equal to the user_id
- * property of the event.
- */
- public string? tpi_signed_mxid { get; set; default = null; }
-
- /**
- * The token property of the containing third_party_invite object.
- */
- public string? tpi_signed_token { get; set; default = null; }
-
- /**
- * A single signature from the verifying server, in the format
- * specified by the Signing Events section of the server-server
- * API.
- */
- public Json.Node? tpi_signature { get; set; default = null; }
-
- /**
- * A subset of the state of the room at the time of the invite, if
- * membership is invite.
- */
- public Matrix.Event.State[] invite_room_state { get; set; }
-
- /**
- * The user ID whom this event relates to.
- */
- public string? user_id {
- get {
- return _state_key;
- }
-
- set {
- _state_key = value;
- }
-
- default = null;
- }
-
- protected override void
- from_json(Json.Node json_data)
- throws Matrix.Error
- {
- Json.Object root = json_data.get_object();
- Json.Object content_root = root.get_member("content").get_object();
- Json.Node? node;
-
- // Even though the state_key is handled by the parent class,
- // in this event type this actually means the sender
- if ((node = root.get_member("state_key")) != null) {
- _state_key = node.get_string();
- } else {
- warning("state_key is missing from a m.room.member event");
- }
-
- if ((node = content_root.get_member("membership")) != null) {
- try {
- _membership = (Matrix.RoomMembership)_g_enum_nick_to_value(
- typeof(Matrix.RoomMembership), node.get_string());
- } catch (Matrix.Error e) {
- _membership = Matrix.RoomMembership.UNKNOWN;
-
- if (Config.DEBUG) {
- warning("Unknown membership value %s", node.get_string());
- }
- }
- } else if (Config.DEBUG) {
- warning("membership key is missing from the m.room.member event");
- }
-
- if ((node = content_root.get_member("avatar_url")) != null) {
- _avatar_url = node.get_string();
- }
-
- if ((node = content_root.get_member("displayname")) != null) {
- _display_name = node.get_string();
- }
-
- if ((node = content_root.get_member("third_party_invite")) != null) {
- var tpi_root = node.get_object();
-
- if ((node = tpi_root.get_member("display_name")) != null) {
- _tpi_display_name = node.get_string();
- } else {
- warning("content.third_party_invite.display_name is missing from a m.room.member event");
- }
-
- if ((node = tpi_root.get_member("signed")) != null) {
- var signed_root = node.get_object();
-
- if ((node = signed_root.get_member("mxid")) != null) {
- tpi_signed_mxid = node.get_string();
- } else {
- warning("content.third_party_invit.signed.mxid is missing from a m.room.member event");
- }
-
- if ((node = signed_root.get_member("token")) != null) {
- tpi_signed_token = node.get_string();
- } else {
- warning("content.third_party_invite.signed.token is missing from a m.room.member event");
- }
-
- if ((node = signed_root.get_member("signatures")) != null) {
- tpi_signature = node;
- } else {
- warning("content.third_party_invite.signed.signatures is missing from a m.room.member event");
- }
- } else {
- warning("content.third_party_invite.signed is missing from a m.room.member event");
- }
- }
-
- if ((node = root.get_member("invite_room_state")) != null) {
- var events = node.get_array();
-
- if (events.get_length() > 0) {
- _invite_room_state = new Matrix.Event.State[node.get_array().get_length()];
-
- events.foreach_element((ary, idx, member_node) => {
- try {
- var evt = Matrix.Event.Base.new_from_json(
- null, member_node);
-
- _invite_room_state[idx] = (Matrix.Event.State)evt;
- } catch (GLib.Error e) {}
- });
- }
- }
-
- // Chain up
- base.from_json(json_data);
- }
-
- protected override void
- to_json(Json.Node json_data)
- throws Matrix.Error
- {
- if (membership == RoomMembership.UNKNOWN) {
- throw new Matrix.Error.UNKNOWN_VALUE(
- "Unknown membership value cannot be added to a room member event");
- }
-
- if (_state_key == "") {
- throw new Matrix.Error.INCOMPLETE(
- "Won't generate a m.room.member event with an empty state_key");
- }
-
- var root = json_data.get_object();
- var content_root = root.get_member("content").get_object();
- string? mship;
-
- mship = _g_enum_value_to_nick(typeof(Matrix.RoomMembership),
- membership);
-
- if (mship != null) {
- content_root.set_string_member("membership", mship);
- } else {
- throw new Matrix.Error.UNKNOWN_VALUE(
- "Won't generate a m.room.member event with an unknown membership");
- }
-
- if (avatar_url != null) {
- content_root.set_string_member("avatar_url", avatar_url);
- }
-
- if (display_name != null) {
- content_root.set_string_member("displayname", display_name);
- }
-
- var tpi_root = new Json.Object();
-
- if (_tpi_display_name != null) {
- tpi_root.set_string_member("display_name", tpi_display_name);
- }
-
- var tpi_signed_root = new Json.Object();
-
- if (_tpi_signed_mxid != null) {
- tpi_signed_root.set_string_member("mxid", tpi_signed_mxid);
- }
-
- if (_tpi_signed_token != null) {
- tpi_signed_root.set_string_member("token", tpi_signed_token);
- }
-
- if (_tpi_signature != null) {
- tpi_signed_root.set_member("signature", tpi_signature);
- }
-
- if ((tpi_signed_root.get_size() != 3)
- && (tpi_signed_root.get_size() != 0)) {
- warning("3rd party invite data is not filled; ignoring");
-
- tpi_signed_root = null;
- }
-
- if ((_tpi_display_name != null) && (tpi_signed_root.get_size() == 3)) {
- var tpi_signed_node = new Json.Node(Json.NodeType.OBJECT);
- tpi_signed_node.set_object(tpi_signed_root);
- tpi_root.set_member("signed", tpi_signed_node);
- }
-
- if (tpi_root.get_size() == 2) {
- var tpi_node = new Json.Node(Json.NodeType.OBJECT);
- tpi_node.set_object(tpi_root);
- content_root.set_member("third_party_invite", tpi_node);
- } else if (tpi_root.get_size() != 0) {
- warning("3rd party invite data is incomplete; ignoring");
- }
-
- if (_invite_room_state != null) {
- var state_ary = new Json.Array();
-
- foreach (var entry in _invite_room_state) {
- var state_node = entry.get_stripped_node();
-
- if (state_node != null) {
- state_ary.add_element(state_node);
- }
- }
-
- if (state_ary.get_length() > 0) {
- var state_node = new Json.Node(Json.NodeType.ARRAY);
- state_node.set_array(state_ary);
- root.set_member("invite_room_state", state_node);
- }
- }
-
- base.to_json(json_data);
- }
-}
diff --git a/src/matrix-event-types.c b/src/matrix-event-types.c
index 521ca05..46b079d 100644
--- a/src/matrix-event-types.c
+++ b/src/matrix-event-types.c
@@ -20,6 +20,7 @@
#include "matrix-marshalers.h"
#include "matrix-event-tag.h"
#include "matrix-event-presence.h"
+#include "matrix-event-room-member.h"
/*
Borrowed from GLib
diff --git a/src/test-client.c b/src/test-client.c
index d13f6de..a0bc2a4 100644
--- a/src/test-client.c
+++ b/src/test-client.c
@@ -21,6 +21,7 @@
#include "matrix-glib.h"
#include "matrix-event-presence.h"
+#include "matrix-event-room-member.h"
static gchar *user = NULL;
static gchar *password = NULL;
diff --git a/vapi/c-api.vapi b/vapi/c-api.vapi
index 3f71861..c5f65e8 100644
--- a/vapi/c-api.vapi
+++ b/vapi/c-api.vapi
@@ -549,5 +549,26 @@ namespace Matrix {
protected override void to_json(Json.Node json_data)
throws Matrix.Error;
}
+
+ [CCode (cheader_filename = "matrix-event-room-member.h")]
+ public class RoomMember : State {
+ public RoomMembership membership { get; set; default = RoomMembership.UNKNOWN; }
+ public string? avatar_url { get; set; default = null; }
+ public string? display_name { get; set; default = null; }
+ public string? tpi_display_name { get; set; default = null; }
+ public string? tpi_signed_mxid { get; set; default = null; }
+ public string? tpi_signed_token { get; set; default = null; }
+ public Json.Node? tpi_signature { get; set; default = null; }
+ public Matrix.Event.State[] invite_room_state { get; set; }
+ public string? user_id { get; set; default = null; }
+
+ protected override void
+ from_json(Json.Node json_data)
+ throws Matrix.Error;
+
+ protected override void
+ to_json(Json.Node json_data)
+ throws Matrix.Error;
+ }
}
}