diff --git a/.gitignore b/.gitignore
index 77dc04d..c3a6f24 100644
--- a/.gitignore
+++ b/.gitignore
@@ -69,4 +69,3 @@ Makefile.in
/src/matrix-event-call-hangup.c
/src/matrix-glib-0.0.pc
/src/matrix-message-notice.c
-/src/matrix-room.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 716828d..03ed382 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -36,7 +36,6 @@ libmatrix_glib_0_0_la_VALA_SOURCES = \
matrix-event-call-answer.vala \
matrix-event-call-hangup.vala \
matrix-message-notice.vala \
- matrix-room.vala \
$(NULL)
AM_CPPFLAGS += \
@@ -115,6 +114,7 @@ INST_H_SRC_FILES = \
matrix-event-receipt.h \
utils.h \
matrix-profile.h \
+ matrix-room.h \
$(NULL)
INST_H_BUILT_FILES = \
@@ -157,6 +157,7 @@ libmatrix_glib_0_0_la_SOURCES = \
matrix-event-room-avatar.c \
matrix-event-room-name.c \
matrix-profile.c \
+ matrix-room.c \
utils.c \
matrix-enumtypes.c \
$(INST_H_SRC_FILES) \
diff --git a/src/matrix-room.c b/src/matrix-room.c
new file mode 100644
index 0000000..10162c0
--- /dev/null
+++ b/src/matrix-room.c
@@ -0,0 +1,1629 @@
+/*
+ * 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-room.h"
+#include "matrix-enumtypes.h"
+
+/**
+ * SECTION:matrix-room
+ * @short_description: class to hold room data
+ *
+ */
+
+#define MATRIX_ROOM_TYPE_MEMBER_DATA (matrix_room_member_data_get_type ())
+
+enum {
+ PROP_0,
+ PROP_ROOM_ID,
+ PROP_ALIASES,
+ PROP_AVATAR_URL,
+ PROP_AVATAR_THUMBNAIL_URL,
+ PROP_CANONICAL_ALIAS,
+ PROP_CREATOR,
+ PROP_FEDERATE,
+ PROP_GUEST_ACCESS,
+ PROP_HISTORY_VISIBILITY,
+ PROP_JOIN_RULES,
+ PROP_NAME,
+ PROP_DEFAULT_POWER_LEVEL,
+ PROP_DEFAULT_EVENT_LEVEL,
+ PROP_DEFAULT_STATE_LEVEL,
+ PROP_BAN_LEVEL,
+ PROP_KICK_LEVEL,
+ PROP_REDACT_LEVEL,
+ PROP_INVITE_LEVEL,
+ PROP_TOPIC,
+ PROP_TYPING_USERS,
+ PROP_AVATAR_INFO,
+ PROP_AVATAR_THUMBNAIL_INFO,
+ NUM_PROPERTIES
+};
+
+static GParamSpec *matrix_room_properties[NUM_PROPERTIES];
+
+typedef struct {
+ MatrixProfile* profile;
+ gboolean thirdparty;
+} MatrixRoomMemberData;
+
+MatrixRoomMemberData *
+matrix_room_member_data_new(void)
+{
+ return g_new0(MatrixRoomMemberData, 1);
+}
+
+void
+matrix_room_member_data_free(MatrixRoomMemberData *member_data)
+{
+ g_return_if_fail(member_data != NULL);
+
+ g_object_unref(member_data->profile);
+ g_free(member_data);
+}
+
+typedef struct {
+ gchar *room_id;
+ gchar **aliases;
+ gint aliases_len;
+ gchar *avatar_url;
+ MatrixImageInfo *avatar_info;
+ gchar *avatar_thumbnail_url;
+ MatrixImageInfo *avatar_thumbnail_info;
+ gchar *canonical_alias;
+ gchar *creator;
+ gboolean federate;
+ MatrixGuestAccess guest_access;
+ MatrixHistoryVisibility history_visibility;
+ MatrixJoinRules join_rules;
+ gchar *name;
+ gint default_power_level;
+ gint default_event_level;
+ gint default_state_level;
+ gint ban_level;
+ gint kick_level;
+ gint redact_level;
+ gint invite_level;
+ gchar *topic;
+ gchar **typing_users;
+ gint typing_users_len;
+ GHashTable* event_levels;
+ GHashTable* user_levels;
+ GHashTable* members;
+} MatrixRoomPrivate;
+
+/**
+ * MatrixRoom:
+ *
+ * The #MatrixRoom class is there to hold different parameters of a room like its known aliases,
+ * its members, etc.
+ */
+G_DEFINE_TYPE_WITH_PRIVATE(MatrixRoom, matrix_room, G_TYPE_OBJECT);
+
+/**
+ * matrix_room_new:
+ * @room_id: a room ID
+ *
+ * Create a new #MatrixRoom object.
+ *
+ * Returns: (transfer full): a new #MatrixRoom object
+ */
+MatrixRoom *
+matrix_room_new(const gchar *room_id)
+{
+ g_return_val_if_fail(room_id != NULL, NULL);
+
+ return (MatrixRoom *)g_object_new(MATRIX_TYPE_ROOM,
+ "room-id", room_id,
+ NULL);
+}
+
+/**
+ * matrix_room_add_member:
+ * @room: a #MatrixRoom
+ * @user_id: the Matrix ID of the user to add
+ * @profile: a #MatrixProfile
+ * @third_party: if true, the member is marked as a pending 3rd party invitation
+ * @error: a #GError, or %NULL to ignore errors
+ *
+ * Add a member to the room member list. If a member with the same @user_id exists, @error is
+ * set to #MATRIX_ERROR_ALREADY_EXISTS.
+ */
+void
+matrix_room_add_member(MatrixRoom *matrix_room, const gchar *user_id, MatrixProfile *profile, gboolean third_party, GError **error)
+{
+ MatrixRoomPrivate *priv;
+ MatrixRoomMemberData *data = NULL;
+
+ g_return_if_fail(matrix_room != NULL);
+ g_return_if_fail(user_id != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if ((data = g_hash_table_lookup(priv->members, user_id)) != NULL) {
+ g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_ALREADY_EXISTS,
+ "User already exists in that room");
+
+ return;
+ }
+
+ data = matrix_room_member_data_new();
+
+ if (profile == NULL) {
+ data->profile = matrix_profile_new();
+ } else {
+ data->profile = profile;
+ }
+
+ data->thirdparty = third_party;
+
+ g_hash_table_insert(priv->members, g_strdup(user_id), data);
+}
+
+/**
+ * matrix_room_get_or_add_member:
+ * @room: a #MatrixRoom
+ * @user_id: the Matrix ID of the user to add
+ * @third_party: if %TRUE, the member is marked as a pending 3rd party invitation
+ * @error: a #GError, or %NULL to ignore errors
+ *
+ * Gets the profile of the room member specified in @user_id. If that user is not added to the
+ * room yet, it gets added with an empty profile and that profile is returned.
+ *
+ * Returns: (transfer none): the #MatrixProfile of the user
+ */
+MatrixProfile *
+matrix_room_get_or_add_member(MatrixRoom *matrix_room, const gchar *user_id, gboolean third_party, GError **error)
+{
+ MatrixProfile *profile;
+ GError *inner_error = NULL;
+
+ g_return_val_if_fail(matrix_room != NULL, NULL);
+ g_return_val_if_fail(user_id != NULL, NULL);
+
+ profile = matrix_room_get_member(matrix_room, user_id, NULL, &inner_error);
+
+ if (inner_error == NULL) {
+ return profile;
+ }
+
+ if ((inner_error->domain != MATRIX_ERROR) || (inner_error->code == MATRIX_ERROR_NOT_FOUND)) {
+ g_propagate_error(error, inner_error);
+
+ return NULL;
+ }
+
+ g_clear_error(&inner_error);
+
+ matrix_room_add_member(matrix_room, user_id, NULL, third_party, &inner_error);
+
+ if (inner_error != NULL) {
+ g_propagate_error(error, inner_error);
+
+ return NULL;
+ }
+
+ profile = matrix_room_get_member(matrix_room, user_id, &third_party, &inner_error);
+
+ if (inner_error != NULL) {
+ g_propagate_error(error, inner_error);
+
+ return NULL;
+ }
+
+ return profile;
+}
+
+/**
+ * matrix_room_get_member:
+ * @room: a #MatrixRoom
+ * @user_id: the Matrix ID of the user to find
+ * @third_party: gets a true value if the member is actually a pending 3rd party invitation
+ * @error: (nullable): a #GError, or %NULL to ignore errors
+ *
+ * Gets the profile of the room member specified in @user_id. If that user is not added to
+ * the room yet, @error is set to #MATRIX_ERROR_NOT_FOUND.
+ *
+ * Returns: (transfer none): the profile of the user
+ */
+MatrixProfile *
+matrix_room_get_member(MatrixRoom *matrix_room, const gchar *user_id, gboolean *third_party, GError **error)
+{
+ MatrixRoomMemberData *data;
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, NULL);
+ g_return_val_if_fail(user_id != NULL, NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if ((data = g_hash_table_lookup(priv->members, user_id)) == NULL) {
+ g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_NOT_FOUND,
+ "No such room member");
+
+ return NULL;
+ }
+
+ if (third_party != NULL) {
+ *third_party = data->thirdparty;
+ }
+
+ return data->profile;
+}
+
+/**
+ * matrix_room_remove_member:
+ * @room: a #MatrixRoom
+ * @user_id: a Matrix ID
+ * @error: (nullable): a #GError, or %NULL to ignore errors
+ *
+ * Removes @user_id from the member list.
+ */
+void
+matrix_room_remove_member(MatrixRoom *matrix_room, const gchar *user_id, GError **error)
+{
+ MatrixRoomMemberData *data;
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+ g_return_if_fail(user_id != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if ((data = g_hash_table_lookup(priv->members, user_id)) == NULL) {
+ g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_NOT_FOUND,
+ "No such room member");
+
+ return;
+ }
+
+ g_hash_table_remove(priv->members, user_id);
+}
+
+/**
+ * matrix_room_clear_user_levels:
+ * @room: a #MatrixRoom
+ *
+ * Clear the stored individual user levels. This should be called eg. when receiving a new
+ * `m.room.power_levels` event.
+ */
+void
+matrix_room_clear_user_levels(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ g_hash_table_remove_all(priv->user_levels);
+}
+
+/**
+ * matrix_room_set_user_level:
+ * @room: a #MatrixRoom
+ * @user_id: a fully qualified Matrix ID
+ * @level: the new power level
+ *
+ * Set an individual power level for a user.
+ */
+void
+matrix_room_set_user_level(MatrixRoom *matrix_room, const gchar *user_id, gint level)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+ g_return_if_fail(user_id != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ g_hash_table_insert (priv->user_levels, g_strdup(user_id), GINT_TO_POINTER(level));
+}
+
+/**
+ * matrix_room_get_user_level:
+ * @room: a #MatrixRoom
+ * @user_id: a fully qualified Matrix ID
+ *
+ * Get the power level of a user. If the user doesn’t have an individually set power level,
+ * the default value is returned.
+ *
+ * Returns: the level of the user.
+ */
+gint
+matrix_room_get_user_level(MatrixRoom *matrix_room, const gchar *user_id)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, 0);
+ g_return_val_if_fail(user_id != NULL, 0);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ gpointer level = NULL;
+
+ if (!g_hash_table_lookup_extended(priv->user_levels, user_id, NULL, &level)) {
+ return priv->default_power_level;
+ }
+
+ return GPOINTER_TO_INT(level);
+}
+
+/**
+ * matrix_room_clear_event_levels:
+ * @room: a #MatrixRoom
+ *
+ * Clear the stored event level requirements. This should be called eg. when receiving a new
+ * `m.room.power_levels` event.
+ */
+void
+matrix_room_clear_event_levels(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ g_hash_table_remove_all(priv->event_levels);
+}
+
+/**
+ * matrix_room_set_event_level:
+ * @room: a #MatrixRoom
+ * @event_type: the event type to restrict
+ * @level: the desired level for the event type
+ *
+ * Set the required level to send an event of type @event_type.
+ */
+void
+matrix_room_set_event_level(MatrixRoom *matrix_room, const gchar *event_type, gint level)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+ g_return_if_fail (event_type != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ g_hash_table_insert(priv->event_levels, g_strdup(event_type), GINT_TO_POINTER(level));
+}
+
+/**
+ * matrix_room_get_event_level:
+ * @room: a #MatrixRoom
+ * @event_type: the event type to query
+ * @error: (nullable): a #GError, or %NULL to ignore errors
+ *
+ * Get the required level to send an event of type @event_type. If there is no level
+ * requirement set for this event type, this function returns %NULL as there is no way to
+ * decide if #MatrixRoom:default-state-level or #MatrixRoom:default-event-level should be used.
+ *
+ * Returns: the level required to send a specific event
+ */
+gint
+matrix_room_get_event_level(MatrixRoom *matrix_room, const gchar *event_type, GError **error)
+{
+ MatrixRoomPrivate *priv;
+ gpointer level;
+
+ g_return_val_if_fail(matrix_room != NULL, 0);
+ g_return_val_if_fail(event_type != NULL, 0);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (!g_hash_table_lookup_extended(priv->event_levels, event_type, NULL, &level)) {
+ g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_NOT_FOUND, "No level set for this event type");
+
+ return 0;
+ }
+
+ return GPOINTER_TO_INT(level);
+}
+
+const gchar *
+matrix_room_get_room_id(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ return priv->room_id;
+}
+
+static void
+matrix_room_set_room_id(MatrixRoom *matrix_room, const gchar *room_id)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (g_strcmp0(room_id, priv->room_id) != 0) {
+ g_free(priv->room_id);
+ priv->room_id = g_strdup(room_id);
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_ROOM_ID]);
+ }
+}
+
+/**
+ * matrix_room_get_aliases:
+ * @room: a #MatrixRoom
+ * @n_aliases: (nullable): a placeholder for the length of the list
+ *
+ * Returns: (transfer none): the list of room aliases
+ */
+gchar **
+matrix_room_get_aliases(MatrixRoom *matrix_room, int *n_aliases)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (n_aliases != NULL) {
+ *n_aliases = priv->aliases_len;
+ }
+
+ return priv->aliases;
+}
+
+/**
+ * matrix_room_set_aliases:
+ * @room: a #MatrixRoom
+ * @aliases: a list of aliases to assign to @room
+ * @n_aliases: the length of @aliases
+ */
+void
+matrix_room_set_aliases(MatrixRoom *matrix_room, const gchar **aliases, int n_aliases)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ for (gint i = 0; i < priv->aliases_len; i++) {
+ g_free(priv->aliases[i]);
+ }
+
+ g_free(priv->aliases);
+
+ priv->aliases = g_new(gchar *, n_aliases);
+
+ for (gint i = 0; i < n_aliases; i++) {
+ priv->aliases[i] = g_strdup(aliases[i]);
+ }
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_ALIASES]);
+}
+
+const gchar *
+matrix_room_get_avatar_url(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ return priv->avatar_url;
+}
+
+void
+matrix_room_set_avatar_url(MatrixRoom *matrix_room, const gchar *avatar_url)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ 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_room, matrix_room_properties[PROP_AVATAR_URL]);
+ }
+}
+
+MatrixImageInfo *
+matrix_room_get_avatar_info(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ return priv->avatar_info;
+}
+
+void
+matrix_room_set_avatar_info(MatrixRoom *matrix_room, MatrixImageInfo *avatar_info)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (priv->avatar_info != avatar_info) {
+ matrix_image_info_unref(priv->avatar_info);
+ priv->avatar_info = matrix_image_info_ref(avatar_info);
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_AVATAR_INFO]);
+ }
+}
+
+const gchar *
+matrix_room_get_avatar_thumbnail_url(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ return priv->avatar_thumbnail_url;
+}
+
+void
+matrix_room_set_avatar_thumbnail_url(MatrixRoom *matrix_room, const gchar *avatar_thumbnail_url)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (g_strcmp0(avatar_thumbnail_url, priv->avatar_thumbnail_url) != 0) {
+ g_free(priv->avatar_thumbnail_url);
+ priv->avatar_thumbnail_url = g_strdup(avatar_thumbnail_url);
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_AVATAR_THUMBNAIL_URL]);
+ }
+}
+
+MatrixImageInfo *
+matrix_room_get_avatar_thumbnail_info(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ return priv->avatar_thumbnail_info;
+}
+
+void
+matrix_room_set_avatar_thumbnail_info(MatrixRoom *matrix_room, MatrixImageInfo *avatar_thumbnail_info)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (priv->avatar_thumbnail_info != avatar_thumbnail_info) {
+ matrix_image_info_unref(priv->avatar_thumbnail_info);
+ priv->avatar_thumbnail_info = matrix_image_info_ref(avatar_thumbnail_info);
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_AVATAR_THUMBNAIL_INFO]);
+ }
+}
+
+const gchar *
+matrix_room_get_canonical_alias(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ return priv->canonical_alias;
+}
+
+void
+matrix_room_set_canonical_alias(MatrixRoom *matrix_room, const gchar *canonical_alias)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (g_strcmp0(canonical_alias, priv->canonical_alias) != 0) {
+ g_free(priv->canonical_alias);
+ priv->canonical_alias = g_strdup(canonical_alias);
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_CANONICAL_ALIAS]);
+ }
+}
+
+const gchar *
+matrix_room_get_creator(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ return priv->creator;
+}
+
+void
+matrix_room_set_creator(MatrixRoom *matrix_room, const gchar *creator)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (g_strcmp0(creator, priv->creator) != 0) {
+ g_free(priv->creator);
+ priv->creator = g_strdup(creator);
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_CREATOR]);
+ }
+}
+
+gboolean
+matrix_room_get_federate(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, FALSE);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ return priv->federate;
+}
+
+void
+matrix_room_set_federate(MatrixRoom *matrix_room, gboolean federate)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (priv->federate != federate) {
+ priv->federate = federate;
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_FEDERATE]);
+ }
+}
+
+MatrixGuestAccess
+matrix_room_get_guest_access(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, 0);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ return priv->guest_access;
+}
+
+void
+matrix_room_set_guest_access(MatrixRoom *matrix_room, MatrixGuestAccess guest_access)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (priv->guest_access != guest_access) {
+ priv->guest_access = guest_access;
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_GUEST_ACCESS]);
+ }
+}
+
+MatrixHistoryVisibility
+matrix_room_get_history_visibility(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, 0);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ return priv->history_visibility;
+}
+
+void
+matrix_room_set_history_visibility(MatrixRoom *matrix_room, MatrixHistoryVisibility history_visibility)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (priv->history_visibility != history_visibility) {
+ priv->history_visibility = history_visibility;
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_HISTORY_VISIBILITY]);
+ }
+}
+
+MatrixJoinRules
+matrix_room_get_join_rules(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, 0);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ return priv->join_rules;
+}
+
+void
+matrix_room_set_join_rules(MatrixRoom *matrix_room, MatrixJoinRules join_rules)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (priv->join_rules != join_rules) {
+ priv->join_rules = join_rules;
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_JOIN_RULES]);
+ }
+}
+
+const gchar *
+matrix_room_get_name(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ return priv->name;
+}
+
+void
+matrix_room_set_name(MatrixRoom *matrix_room, const gchar *name)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (g_strcmp0(name, priv->name) != 0) {
+ g_free(priv->name);
+ priv->name = g_strdup(name);
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_NAME]);
+ }
+}
+
+gint
+matrix_room_get_default_power_level(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, 0);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ return priv->default_power_level;
+}
+
+void
+matrix_room_set_default_power_level(MatrixRoom *matrix_room, gint default_power_level)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (priv->default_power_level != default_power_level) {
+ priv->default_power_level = default_power_level;
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_DEFAULT_POWER_LEVEL]);
+ }
+}
+
+gint
+matrix_room_get_default_event_level(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, 0);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ return priv->default_event_level;
+}
+
+void
+matrix_room_set_default_event_level(MatrixRoom *matrix_room, gint default_event_level)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (priv->default_event_level != default_event_level) {
+ priv->default_event_level = default_event_level;
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_DEFAULT_EVENT_LEVEL]);
+ }
+}
+
+gint
+matrix_room_get_default_state_level(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, 0);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ return priv->default_state_level;
+}
+
+void
+matrix_room_set_default_state_level(MatrixRoom *matrix_room, gint defaul_state_level)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (priv->default_state_level != defaul_state_level) {
+ priv->default_state_level = defaul_state_level;
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_DEFAULT_STATE_LEVEL]);
+ }
+}
+
+gint
+matrix_room_get_ban_level(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, 0);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ return priv->ban_level;
+}
+
+void
+matrix_room_set_ban_level(MatrixRoom *matrix_room, gint ban_level)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (priv->ban_level != ban_level) {
+ priv->ban_level = ban_level;
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_BAN_LEVEL]);
+ }
+}
+
+gint
+matrix_room_get_kick_level(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, 0);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ return priv->kick_level;
+}
+
+void
+matrix_room_set_kick_level(MatrixRoom *matrix_room, gint kick_level)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (priv->kick_level != kick_level) {
+ priv->kick_level = kick_level;
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_KICK_LEVEL]);
+ }
+}
+
+gint
+matrix_room_get_redact_level(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, 0);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ return priv->redact_level;
+}
+
+void
+matrix_room_set_redact_level(MatrixRoom *matrix_room, gint redact_level)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (priv->redact_level != redact_level) {
+ priv->redact_level = redact_level;
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_REDACT_LEVEL]);
+ }
+}
+
+gint
+matrix_room_get_invite_level(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, 0);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ return priv->invite_level;
+}
+
+void
+matrix_room_set_invite_level(MatrixRoom *matrix_room, gint invite_level)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (priv->invite_level != invite_level) {
+ priv->invite_level = invite_level;
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_INVITE_LEVEL]);
+ }
+}
+
+const gchar *
+matrix_room_get_topic(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ return priv->topic;
+}
+
+void
+matrix_room_set_topic(MatrixRoom *matrix_room, const gchar *topic)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (g_strcmp0(topic, priv->topic) != 0) {
+ g_free(priv->topic);
+ priv->topic = g_strdup(topic);
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_TOPIC]);
+ }
+}
+
+/**
+ * matrix_room_get_typing_users:
+ * @room: a #MatrixRoom
+ * @n_typing_users: (nullable): placeholder for the length of the returned list
+ *
+ * Returns: (transfer none): the list of typing users in @room
+ */
+gchar **
+matrix_room_get_typing_users(MatrixRoom *matrix_room, int *n_typing_users)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_val_if_fail(matrix_room != NULL, NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ if (n_typing_users != NULL) {
+ *n_typing_users = priv->typing_users_len;
+ }
+
+ return priv->typing_users;
+}
+
+void
+matrix_room_set_typing_users(MatrixRoom *matrix_room, gchar **typing_users, int n_typing_users)
+{
+ MatrixRoomPrivate *priv;
+
+ g_return_if_fail(matrix_room != NULL);
+
+ priv = matrix_room_get_instance_private(matrix_room);
+
+ for (gint i = 0; i < priv->typing_users_len; i++) {
+ g_free(priv->typing_users[i]);
+ }
+
+ g_free(priv->typing_users);
+
+ priv->typing_users = g_new(gchar *, n_typing_users);
+
+ for (gint i = 0; i < n_typing_users; i++) {
+ priv->typing_users[i] = g_strdup(typing_users[i]);
+ }
+
+ g_object_notify_by_pspec((GObject *)matrix_room, matrix_room_properties[PROP_TYPING_USERS]);
+}
+
+static void
+matrix_room_finalize(GObject *gobject)
+{
+ MatrixRoomPrivate *priv = matrix_room_get_instance_private(MATRIX_ROOM(gobject));
+
+ g_free(priv->room_id);
+
+ for (gint i = 0; i < priv->aliases_len; i++) {
+ g_free(priv->aliases[i]);
+ }
+
+ g_free(priv->aliases);
+ g_free(priv->avatar_url);
+ matrix_image_info_unref(priv->avatar_info);
+ g_free(priv->avatar_thumbnail_url);
+ matrix_image_info_unref(priv->avatar_thumbnail_info);
+ g_free(priv->canonical_alias);
+ g_free(priv->creator);
+ g_free(priv->name);
+ g_free(priv->topic);
+
+ for (gint i = 0; i < priv->typing_users_len; i++) {
+ g_free(priv->typing_users[i]);
+ }
+
+ g_free(priv->typing_users);
+ g_hash_table_unref(priv->event_levels);
+ g_hash_table_unref(priv->user_levels);
+ g_hash_table_unref(priv->members);
+
+ G_OBJECT_CLASS(matrix_room_parent_class)->finalize(gobject);
+}
+
+static void
+matrix_room_get_property(GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec)
+{
+ MatrixRoom *matrix_room = MATRIX_ROOM(gobject);
+
+ switch (property_id) {
+ case PROP_ROOM_ID:
+ g_value_set_string(value, matrix_room_get_room_id(matrix_room));
+
+ break;
+ case PROP_ALIASES:
+ g_value_set_boxed(value, matrix_room_get_aliases(matrix_room, NULL));
+
+ break;
+ case PROP_AVATAR_URL:
+ g_value_set_string(value, matrix_room_get_avatar_url(matrix_room));
+
+ break;
+ case PROP_AVATAR_THUMBNAIL_URL:
+ g_value_set_string(value, matrix_room_get_avatar_thumbnail_url(matrix_room));
+
+ break;
+ case PROP_CANONICAL_ALIAS:
+ g_value_set_string(value, matrix_room_get_canonical_alias(matrix_room));
+
+ break;
+ case PROP_CREATOR:
+ g_value_set_string(value, matrix_room_get_creator(matrix_room));
+
+ break;
+ case PROP_FEDERATE:
+ g_value_set_boolean(value, matrix_room_get_federate(matrix_room));
+
+ break;
+ case PROP_GUEST_ACCESS:
+ g_value_set_enum(value, matrix_room_get_guest_access(matrix_room));
+
+ break;
+ case PROP_HISTORY_VISIBILITY:
+ g_value_set_enum(value, matrix_room_get_history_visibility(matrix_room));
+
+ break;
+ case PROP_JOIN_RULES:
+ g_value_set_enum(value, matrix_room_get_join_rules(matrix_room));
+
+ break;
+ case PROP_NAME:
+ g_value_set_string(value, matrix_room_get_name(matrix_room));
+
+ break;
+ case PROP_DEFAULT_POWER_LEVEL:
+ g_value_set_int(value, matrix_room_get_default_power_level(matrix_room));
+
+ break;
+ case PROP_DEFAULT_EVENT_LEVEL:
+ g_value_set_int(value, matrix_room_get_default_event_level(matrix_room));
+
+ break;
+ case PROP_DEFAULT_STATE_LEVEL:
+ g_value_set_int(value, matrix_room_get_default_state_level(matrix_room));
+
+ break;
+ case PROP_BAN_LEVEL:
+ g_value_set_int(value, matrix_room_get_ban_level(matrix_room));
+
+ break;
+ case PROP_KICK_LEVEL:
+ g_value_set_int(value, matrix_room_get_kick_level(matrix_room));
+
+ break;
+ case PROP_REDACT_LEVEL:
+ g_value_set_int(value, matrix_room_get_redact_level(matrix_room));
+
+ break;
+ case PROP_INVITE_LEVEL:
+ g_value_set_int(value, matrix_room_get_invite_level(matrix_room));
+
+ break;
+ case PROP_TOPIC:
+ g_value_set_string(value, matrix_room_get_topic(matrix_room));
+
+ break;
+ case PROP_TYPING_USERS:
+ g_value_set_boxed(value, matrix_room_get_typing_users(matrix_room, NULL));
+
+ break;
+ case PROP_AVATAR_INFO:
+ g_value_set_boxed(value, matrix_room_get_avatar_info(matrix_room));
+
+ break;
+ case PROP_AVATAR_THUMBNAIL_INFO:
+ g_value_set_boxed(value, matrix_room_get_avatar_thumbnail_info(matrix_room));
+
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
+
+ break;
+ }
+}
+
+static void
+matrix_room_set_property(GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ MatrixRoom * matrix_room = MATRIX_ROOM(gobject);
+
+ switch (property_id) {
+ case PROP_ROOM_ID:
+ matrix_room_set_room_id(matrix_room, g_value_get_string(value));
+
+ break;
+ case PROP_ALIASES:
+ {
+ gpointer boxed = g_value_get_boxed(value);
+
+ matrix_room_set_aliases(matrix_room, boxed, (boxed == NULL) ? 0 : g_strv_length(boxed));
+
+ break;
+ }
+ case PROP_AVATAR_URL:
+ matrix_room_set_avatar_url(matrix_room, g_value_get_string(value));
+
+ break;
+ case PROP_AVATAR_THUMBNAIL_URL:
+ matrix_room_set_avatar_thumbnail_url(matrix_room, g_value_get_string(value));
+
+ break;
+ case PROP_CANONICAL_ALIAS:
+ matrix_room_set_canonical_alias(matrix_room, g_value_get_string(value));
+
+ break;
+ case PROP_CREATOR:
+ matrix_room_set_creator(matrix_room, g_value_get_string(value));
+
+ break;
+ case PROP_FEDERATE:
+ matrix_room_set_federate(matrix_room, g_value_get_boolean(value));
+
+ break;
+ case PROP_GUEST_ACCESS:
+ matrix_room_set_guest_access(matrix_room, g_value_get_enum(value));
+
+ break;
+ case PROP_HISTORY_VISIBILITY:
+ matrix_room_set_history_visibility(matrix_room, g_value_get_enum(value));
+
+ break;
+ case PROP_JOIN_RULES:
+ matrix_room_set_join_rules(matrix_room, g_value_get_enum (value));
+
+ break;
+ case PROP_NAME:
+ matrix_room_set_name(matrix_room, g_value_get_string(value));
+
+ break;
+ case PROP_DEFAULT_POWER_LEVEL:
+ matrix_room_set_default_power_level(matrix_room, g_value_get_int(value));
+
+ break;
+ case PROP_DEFAULT_EVENT_LEVEL:
+ matrix_room_set_default_event_level(matrix_room, g_value_get_int(value));
+
+ break;
+ case PROP_DEFAULT_STATE_LEVEL:
+ matrix_room_set_default_state_level(matrix_room, g_value_get_int(value));
+
+ break;
+ case PROP_BAN_LEVEL:
+ matrix_room_set_ban_level(matrix_room, g_value_get_int(value));
+
+ break;
+ case PROP_KICK_LEVEL:
+ matrix_room_set_kick_level(matrix_room, g_value_get_int(value));
+
+ break;
+ case PROP_REDACT_LEVEL:
+ matrix_room_set_redact_level(matrix_room, g_value_get_int(value));
+
+ break;
+ case PROP_INVITE_LEVEL:
+ matrix_room_set_invite_level(matrix_room, g_value_get_int(value));
+
+ break;
+ case PROP_TOPIC:
+ matrix_room_set_topic(matrix_room, g_value_get_string(value));
+
+ break;
+ case PROP_TYPING_USERS:
+ {
+ gpointer boxed = g_value_get_boxed(value);
+
+ matrix_room_set_typing_users(matrix_room, boxed, (boxed == NULL) ? 0 : g_strv_length(boxed));
+
+ break;
+ }
+ case PROP_AVATAR_INFO:
+ matrix_room_set_avatar_info(matrix_room, g_value_get_boxed(value));
+
+ break;
+ case PROP_AVATAR_THUMBNAIL_INFO:
+ matrix_room_set_avatar_thumbnail_info(matrix_room, g_value_get_boxed(value));
+
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
+
+ break;
+ }
+}
+
+static void
+matrix_room_class_init(MatrixRoomClass *klass)
+{
+ G_OBJECT_CLASS(klass)->get_property = matrix_room_get_property;
+ G_OBJECT_CLASS(klass)->set_property = matrix_room_set_property;
+ G_OBJECT_CLASS(klass)->finalize = matrix_room_finalize;
+
+ /**
+ * MatrixRoom:room-id:
+ *
+ * The ID of the room this object belongs to.
+ */
+ matrix_room_properties[PROP_ROOM_ID] = g_param_spec_string(
+ "room-id", "room-id", "room-id",
+ NULL,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_ROOM_ID, matrix_room_properties[PROP_ROOM_ID]);
+
+ /**
+ * MatrixRoom:aliases:
+ *
+ * All the known room aliases.
+ */
+ matrix_room_properties[PROP_ALIASES] = g_param_spec_boxed(
+ "aliases", "aliases", "aliases",
+ G_TYPE_STRV,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_ALIASES, matrix_room_properties[PROP_ALIASES]);
+
+ /**
+ * MatrixRoom:avatar-url:
+ *
+ * The URL of the room’s avatar.
+ */
+ matrix_room_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_room_properties[PROP_AVATAR_URL]);
+
+ /**
+ * MatrixRoom:avatar-thumbnail-url:
+ *
+ * The URL of the room avatar’s thumbnail.
+ */
+ matrix_room_properties[PROP_AVATAR_THUMBNAIL_URL] = g_param_spec_string(
+ "avatar-thumbnail-url", "avatar-thumbnail-url", "avatar-thumbnail-url",
+ NULL,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_AVATAR_THUMBNAIL_URL, matrix_room_properties[PROP_AVATAR_THUMBNAIL_URL]);
+
+ /**
+ * MatrixRoom:canonical-alias:
+ *
+ * The canonical alias of the room.
+ */
+ matrix_room_properties[PROP_CANONICAL_ALIAS] = g_param_spec_string(
+ "canonical-alias", "canonical-alias", "canonical-alias",
+ NULL,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_CANONICAL_ALIAS, matrix_room_properties[PROP_CANONICAL_ALIAS]);
+
+ /**
+ * MatrixRoom:creator:
+ *
+ * The Matrix ID of the room’s creator.
+ */
+ matrix_room_properties[PROP_CREATOR] = g_param_spec_string(
+ "creator", "creator", "creator",
+ NULL,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_CREATOR, matrix_room_properties[PROP_CREATOR]);
+
+ /**
+ * MatrixRoom:federate:
+ *
+ * If %FALSE, the room is not federated.
+ */
+ matrix_room_properties[PROP_FEDERATE] = g_param_spec_boolean(
+ "federate", "federate", "federate",
+ FALSE,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_FEDERATE, matrix_room_properties[PROP_FEDERATE]);
+
+ /**
+ * MatrixRoom:guest-access:
+ *
+ * Wether guests are allowed to join the room.
+ */
+ matrix_room_properties[PROP_GUEST_ACCESS] = g_param_spec_enum(
+ "guest-access", "guest-access", "guest-access",
+ MATRIX_TYPE_GUEST_ACCESS, MATRIX_GUEST_ACCESS_UNKNOWN,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_GUEST_ACCESS, matrix_room_properties[PROP_GUEST_ACCESS]);
+
+ /**
+ * MatrixRoom:history-visibility:
+ * This value controls the visibility of the room’s history.
+ */
+ matrix_room_properties[PROP_HISTORY_VISIBILITY] = g_param_spec_enum(
+ "history-visibility", "history-visibility", "history-visibility",
+ MATRIX_TYPE_HISTORY_VISIBILITY, MATRIX_HISTORY_VISIBILITY_UNKNOWN,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_HISTORY_VISIBILITY, matrix_room_properties[PROP_HISTORY_VISIBILITY]);
+ /**
+ * MatrixRoom:join-rules:
+ *
+ * Controls who can join the room.
+ */
+ matrix_room_properties[PROP_JOIN_RULES] = g_param_spec_enum(
+ "join-rules", "join-rules", "join-rules",
+ MATRIX_TYPE_JOIN_RULES, MATRIX_JOIN_RULES_UNKNOWN,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_JOIN_RULES, matrix_room_properties[PROP_JOIN_RULES]);
+
+ /**
+ * MatrixRoom:name:
+ *
+ * The room’s name.
+ */
+ matrix_room_properties[PROP_NAME] = g_param_spec_string(
+ "name", "name", "name",
+ NULL,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_NAME, matrix_room_properties[PROP_NAME]);
+
+ /**
+ * MatrixRoom:default-power-level:
+ *
+ * The default power level users get upon joining the room.
+ */
+ matrix_room_properties[PROP_DEFAULT_POWER_LEVEL] = g_param_spec_int(
+ "default-power-level", "default-power-level", "default-power-level",
+ G_MININT, G_MAXINT, 0,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_DEFAULT_POWER_LEVEL, matrix_room_properties[PROP_DEFAULT_POWER_LEVEL]);
+
+ /**
+ * MatrixRoom:default-event-level:
+ *
+ * The power level required to send non-state events to the room. This gets applied if
+ * the event type doesn’t have an explicit level requirement (see
+ * matrix_room_set_event_level() and matrix_room_get_event_level() for more information).
+ */
+ matrix_room_properties[PROP_DEFAULT_EVENT_LEVEL] = g_param_spec_int(
+ "default-event-level", "default-event-level", "default-event-level",
+ G_MININT, G_MAXINT, 0,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_DEFAULT_EVENT_LEVEL, matrix_room_properties[PROP_DEFAULT_EVENT_LEVEL]);
+
+ /**
+ * MatrixRoom:default-state-level:
+ *
+ * The power level required to send state events to the room. This get applied if the
+ * event type doesn’t have an explicit level requirement (see matrix_room_set_event_level()
+ * and matrix_room_get_event_level() for more information).
+ */
+ matrix_room_properties[PROP_DEFAULT_STATE_LEVEL] = g_param_spec_int(
+ "default-state-level", "default-state-level", "default-state-level",
+ G_MININT, G_MAXINT, 10,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_DEFAULT_STATE_LEVEL, matrix_room_properties[PROP_DEFAULT_STATE_LEVEL]);
+
+ /**
+ * MatrixRoom:ban-level:
+ *
+ * The power level required to ban other users from the room.
+ */
+ matrix_room_properties[PROP_BAN_LEVEL] = g_param_spec_int(
+ "ban-level", "ban-level", "ban-level",
+ G_MININT, G_MAXINT, 5,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_BAN_LEVEL, matrix_room_properties[PROP_BAN_LEVEL]);
+
+ /**
+ * MatrixRoom:kick-level:
+ *
+ * The power level required to kick other users from the room.
+ */
+ matrix_room_properties[PROP_KICK_LEVEL] = g_param_spec_int(
+ "kick-level", "kick-level", "kick-level",
+ G_MININT, G_MAXINT, 5,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_KICK_LEVEL, matrix_room_properties[PROP_KICK_LEVEL]);
+
+ /**
+ * MatrixRoom:redact-level:
+ *
+ * The power level required to redact events in the room.
+ */
+ matrix_room_properties[PROP_REDACT_LEVEL] = g_param_spec_int(
+ "redact-level", "redact-level", "redact-level",
+ G_MININT, G_MAXINT, 20,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_REDACT_LEVEL, matrix_room_properties[PROP_REDACT_LEVEL]);
+
+ /**
+ * MatrixRoom:invite-level:
+ *
+ * The power level required to invite users to the room.
+ */
+ matrix_room_properties[PROP_INVITE_LEVEL] = g_param_spec_int(
+ "invite-level", "invite-level", "invite-level",
+ G_MININT, G_MAXINT, 0,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_INVITE_LEVEL, matrix_room_properties[PROP_INVITE_LEVEL]);
+
+ /**
+ * MatrixRoom:topic:
+ *
+ * The room’s topic.
+ */
+ matrix_room_properties[PROP_TOPIC] = g_param_spec_string(
+ "topic", "topic", "topic",
+ NULL,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TOPIC, matrix_room_properties[PROP_TOPIC]);
+
+ /**
+ * MatrixRoom:typing-users:
+ *
+ * The users currently typing in the room.
+ */
+ matrix_room_properties[PROP_TYPING_USERS] = g_param_spec_boxed(
+ "typing-users", "typing-users", "typing-users",
+ G_TYPE_STRV,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TYPING_USERS, matrix_room_properties[PROP_TYPING_USERS]);
+
+ /**
+ * MatrixRoom:avatar-info:
+ *
+ * A #MatrixImageInfo describing #MatrixRoom:avatar-url.
+ */
+ matrix_room_properties[PROP_AVATAR_INFO] = g_param_spec_boxed(
+ "avatar-info", "avatar-info", "avatar-info",
+ MATRIX_TYPE_IMAGE_INFO,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_AVATAR_INFO, matrix_room_properties[PROP_AVATAR_INFO]);
+
+ /**
+ * MatrixRoom:avatar-thumbnail-info:
+ *
+ * A #MatrixImageInfo describing #MatrixRoom:avatar-thumbnail-url:
+ */
+ matrix_room_properties[PROP_AVATAR_THUMBNAIL_INFO] = g_param_spec_boxed(
+ "avatar-thumbnail-info", "avatar-thumbnail-info", "avatar-thumbnail-info",
+ MATRIX_TYPE_IMAGE_INFO,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
+ g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_AVATAR_THUMBNAIL_INFO, matrix_room_properties[PROP_AVATAR_THUMBNAIL_INFO]);
+}
+
+static void
+matrix_room_init(MatrixRoom *matrix_room)
+{
+ MatrixRoomPrivate *priv = matrix_room_get_instance_private(matrix_room);
+
+ priv->avatar_url = NULL;
+ priv->avatar_info = NULL;
+ priv->avatar_thumbnail_url = NULL;
+ priv->avatar_thumbnail_info = NULL;
+ priv->canonical_alias = NULL;
+ priv->creator = NULL;
+ priv->federate = FALSE;
+ priv->guest_access = MATRIX_GUEST_ACCESS_UNKNOWN;
+ priv->history_visibility = MATRIX_HISTORY_VISIBILITY_UNKNOWN;
+ priv->join_rules = MATRIX_JOIN_RULES_UNKNOWN;
+ priv->name = NULL;
+ priv->default_power_level = 0;
+ priv->default_event_level = 0;
+ priv->default_state_level = 10;
+ priv->ban_level = 5;
+ priv->kick_level = 5;
+ priv->redact_level = 20;
+ priv->invite_level = 0;
+ priv->topic = NULL;
+ priv->event_levels = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+ priv->user_levels = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+ priv->members = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)matrix_room_member_data_free);
+}
diff --git a/src/matrix-room.h b/src/matrix-room.h
new file mode 100644
index 0000000..bcc2b8e
--- /dev/null
+++ b/src/matrix-room.h
@@ -0,0 +1,92 @@
+/*
+ * 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 __MATRIX_GLIB_SDK_ROOM_H__
+# define __MATRIX_GLIB_SDK_ROOM_H__
+
+# include
+# include "matrix-profile.h"
+# include "matrix-types.h"
+
+G_BEGIN_DECLS
+
+# define MATRIX_TYPE_ROOM matrix_room_get_type()
+G_DECLARE_DERIVABLE_TYPE(MatrixRoom, matrix_room, MATRIX, ROOM, GObject)
+
+struct _MatrixRoomClass {
+ GObjectClass parent_class;
+};
+
+MatrixRoom *matrix_room_new(const gchar *room_id);
+void matrix_room_add_member(MatrixRoom *room, const gchar *user_id, MatrixProfile *profile, gboolean third_party, GError **error);
+MatrixProfile *matrix_room_get_or_add_member(MatrixRoom *room, const gchar *user_id, gboolean third_party, GError **error);
+MatrixProfile *matrix_room_get_member(MatrixRoom *room, const gchar *user_id, gboolean *third_party, GError **error);
+void matrix_room_remove_member(MatrixRoom *room, const gchar *user_id, GError **error);
+void matrix_room_clear_user_levels(MatrixRoom *room);
+void matrix_room_set_user_level(MatrixRoom *room, const gchar *user_id, gint level);
+gint matrix_room_get_user_level(MatrixRoom *room, const gchar *user_id);
+void matrix_room_clear_event_levels(MatrixRoom *room);
+void matrix_room_set_event_level(MatrixRoom *room, const gchar *event_type, gint level);
+gint matrix_room_get_event_level(MatrixRoom *room, const gchar *event_type, GError **error);
+const gchar *matrix_room_get_room_id(MatrixRoom *room);
+gchar **matrix_room_get_aliases(MatrixRoom *room, int *n_aliases);
+void matrix_room_set_aliases(MatrixRoom *room, const gchar **aliases, int n_aliases);
+const gchar *matrix_room_get_avatar_url(MatrixRoom *room);
+void matrix_room_set_avatar_url(MatrixRoom *room, const gchar *avatar_url);
+MatrixImageInfo *matrix_room_get_avatar_info(MatrixRoom *room);
+void matrix_room_set_avatar_info(MatrixRoom *room, MatrixImageInfo *avatar_info);
+const gchar *matrix_room_get_avatar_thumbnail_url(MatrixRoom *room);
+void matrix_room_set_avatar_thumbnail_url(MatrixRoom *room, const gchar *avatar_thumbnail_url);
+MatrixImageInfo *matrix_room_get_avatar_thumbnail_info(MatrixRoom *room);
+void matrix_room_set_avatar_thumbnail_info(MatrixRoom *room, MatrixImageInfo *avatar_thumbnail_info);
+const gchar *matrix_room_get_canonical_alias(MatrixRoom *room);
+void matrix_room_set_canonical_alias(MatrixRoom *room, const gchar *canonical_alias);
+const gchar *matrix_room_get_creator(MatrixRoom *room);
+void matrix_room_set_creator(MatrixRoom *room, const gchar *creator);
+gboolean matrix_room_get_federate(MatrixRoom *room);
+void matrix_room_set_federate(MatrixRoom *room, gboolean federate);
+MatrixGuestAccess matrix_room_get_guest_access(MatrixRoom *room);
+void matrix_room_set_guest_access(MatrixRoom *room, MatrixGuestAccess guest_access);
+MatrixHistoryVisibility matrix_room_get_history_visibility(MatrixRoom *room);
+void matrix_room_set_history_visibility(MatrixRoom *room, MatrixHistoryVisibility history_visibility);
+MatrixJoinRules matrix_room_get_join_rules(MatrixRoom *room);
+void matrix_room_set_join_rules(MatrixRoom *room, MatrixJoinRules join_rules);
+const gchar *matrix_room_get_name(MatrixRoom *room);
+void matrix_room_set_name(MatrixRoom *room, const gchar *name);
+gint matrix_room_get_default_power_level(MatrixRoom *room);
+void matrix_room_set_default_power_level(MatrixRoom *room, gint default_power_level);
+gint matrix_room_get_default_event_level(MatrixRoom *room);
+void matrix_room_set_default_event_level(MatrixRoom *room, gint default_event_level);
+gint matrix_room_get_default_state_level(MatrixRoom *room);
+void matrix_room_set_default_state_level(MatrixRoom *room, gint default_state_level);
+gint matrix_room_get_ban_level(MatrixRoom *room);
+void matrix_room_set_ban_level(MatrixRoom *room, gint ban_level);
+gint matrix_room_get_kick_level(MatrixRoom *room);
+void matrix_room_set_kick_level(MatrixRoom *room, gint kick_level);
+gint matrix_room_get_redact_level(MatrixRoom *room);
+void matrix_room_set_redact_level(MatrixRoom *room, gint redact_level);
+gint matrix_room_get_invite_level(MatrixRoom *room);
+void matrix_room_set_invite_level(MatrixRoom *room, gint invite_level);
+const gchar *matrix_room_get_topic(MatrixRoom *room);
+void matrix_room_set_topic(MatrixRoom *room, const gchar *topic);
+gchar **matrix_room_get_typing_users(MatrixRoom *room, int *n_typing_users);
+void matrix_room_set_typing_users(MatrixRoom *room, gchar **typing_users, int n_typing_users);
+
+G_END_DECLS
+
+#endif /* __MATRIX_GLIB_SDK_ROOM_H__ */
diff --git a/src/matrix-room.vala b/src/matrix-room.vala
deleted file mode 100644
index 25279ac..0000000
--- a/src/matrix-room.vala
+++ /dev/null
@@ -1,347 +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 to hold data about rooms
- *
- * The Room class is there to hold different parameters of a room like
- * its known aliases, its members, etc.
- */
-public class Matrix.Room : GLib.Object {
- /**
- * The ID of the room this object belongs to.
- */
- public string room_id { get; construct; }
-
- /**
- * All the known room aliases.
- */
- public string[] aliases { get; set; }
-
- /**
- * The URL of the room’s avatar.
- */
- public string? avatar_url { get; set; default = null; }
-
- /**
- * ImageInfo relevant to the room avatar.
- */
- public ImageInfo? avatar_info { get; set; default = null; }
-
- /**
- * The URL of the room avatar’s thumbnail.
- */
- public string? avatar_thumbnail_url { get; set; default = null; }
-
- /**
- * ImageInfo relevant to the room avatar’s thumbnail.
- */
- public ImageInfo? avatar_thumbnail_info { get; set; default = null; }
-
- /**
- * The canonical alias of the room.
- */
- public string? canonical_alias { get; set; default = null; }
-
- /**
- * The Matrix ID of the room’s creator.
- */
- public string? creator { get; set; default = null; }
-
- /**
- * If false, the room is not federated.
- */
- public bool federate { get; set; default = false; }
-
- /**
- * Wether guests are allowed to join the room.
- */
- public GuestAccess guest_access { get; set; default = GuestAccess.UNKNOWN; }
-
- /**
- * This value controls the visibility of the room’s history.
- */
- public HistoryVisibility history_visibility {
- get; set;
- default = HistoryVisibility.UNKNOWN;
- }
-
- /**
- * Controls who can join the room.
- */
- public JoinRules join_rules { get; set; default = JoinRules.UNKNOWN; }
-
- /**
- * The room’s name.
- */
- public string? name { get; set; default = null; }
-
- /**
- * The default power level users get upon joining the room.
- */
- public int default_power_level { get; set; default = 0; }
-
- /**
- * The power level required to send non-state events to the
- * room. This gets applied if the event type doesn’t have an
- * explicit level requirement (see set_event_level() and
- * get_event_level()).
- */
- public int default_event_level { get; set; default = 0; }
-
- /**
- * The power level required to send state events to the room. This
- * get applied if the event type doesn’t have an explicit level
- * requirement (see set_event_level() and get_event_level()).
- */
- public int default_state_level { get; set; default = 10; }
-
- /**
- * The power level required to ban other users from the room.
- */
- public int ban_level { get; set; default = 5; }
-
- /**
- * The power level required to kick other users from the room.
- */
- public int kick_level { get; set; default = 5; }
-
- /**
- * The power level required to redact events in the room.
- */
- public int redact_level { get; set; default = 20; }
-
- /**
- * The power level required to invite users to the room.
- */
- public int invite_level { get; set; default = 0; }
-
- /**
- * The room’s topic.
- */
- public string? topic { get; set; default = null; }
-
- /**
- * The users currently typing in the room.
- */
- public string[] typing_users { get; set; }
-
- private HashTable _event_levels =
- new HashTable(str_hash, str_equal);
-
- private HashTable _user_levels =
- new HashTable(str_hash, str_equal);
-
- private struct MemberData {
- Profile profile;
- bool thirdparty;
- }
-
- private HashTable _members =
- new HashTable(str_hash, str_equal);
-
- /**
- * Create a new Room object.
- */
- public
- Room(string room_id)
- {
- Object(room_id : room_id);
- }
-
- /**
- * Add a member to the room member list. If a member with the
- * same @user_id exists, {@link Matrix.Error.ALREADY_EXISTS} is
- * thrown.
- *
- * @param user_id the Matrix ID of the user to add
- * @param third_party if true, the member is marked as a pending
- * 3rd party invitation
- */
- public void
- add_member(string user_id, Profile? profile, bool third_party)
- throws Matrix.Error
- {
- MemberData? data = null;
-
- if ((data = _members[user_id]) != null) {
- throw new Matrix.Error.ALREADY_EXISTS(
- "User already exists in that room");
- }
-
- data = MemberData();
-
- if (profile == null) {
- data.profile = new Profile();
- } else {
- data.profile = profile;
- }
-
- data.thirdparty = third_party;
-
- _members[user_id] = data;
- }
-
- /**
- * Gets the profile of the room member specified in @user_id. If
- * that user is not added to the room yet, it gets added with an
- * empty profile and that profile is returned.
- *
- * @param user_id the Matrix ID of the user to add
- * @param third_party if true, the member is marked as a pending
- * 3rd party invitation
- * @return the {@link Matrix.Profile} of the user
- */
- public Profile
- get_or_add_member(string user_id, bool third_party = false)
- throws Matrix.Error
- {
- try {
- return get_member(user_id, null);
- } catch (Matrix.Error e) {
- add_member(user_id, null, third_party);
-
- return get_member(user_id, null);
- }
- }
-
- /**
- * Gets the profile of the room member specified in @user_id. If
- * that user is not added to the room yet,
- * {@link Matrix.Error.NOT_FOUND} is thrown.
- *
- * @param user_id the Matrix ID of the user to find
- * @param third_party gets a true value if the member is actually
- * a pending 3rd party invitation
- * @return the profile of the user
- */
- public Profile
- get_member(string user_id, out bool third_party)
- throws Matrix.Error
- {
- MemberData? data = null;
-
- if ((data = _members[user_id]) == null) {
- throw new Matrix.Error.NOT_FOUND(
- "No such room member");
- }
-
- third_party = data.thirdparty;
-
- return data.profile;
- }
-
- /**
- * Removes a member from the member list.
- */
- public void
- remove_member(string user_id)
- throws Matrix.Error
- {
- MemberData? data = null;
-
- if ((data = _members[user_id]) == null) {
- throw new Matrix.Error.NOT_FOUND(
- "No such room member");
- }
-
- _members.remove(user_id);
- }
-
- /**
- * Clear the stored individual user levels. This should be called
- * e.g. when receiving a new m.room.power_levels event.
- */
- public void
- clear_user_levels()
- {
- _user_levels.remove_all();
- }
-
- /**
- * Set an individual power level for a user.
- *
- * @param user_id a fully qualified Matrix ID
- * @param level the new power level
- */
- public void
- set_user_level(string user_id, int level)
- {
- _user_levels[user_id] = level;
- }
-
- /**
- * Get the power level of a user.
- *
- * @param user_id a fully qualified Matrix ID
- * @return the level of the user. If the user doesn’t have an
- * individually set power level, the default value is
- * returned
- */
- public int
- get_user_level(string user_id)
- {
- int? level = _user_levels[user_id];
-
- if (level == null) {
- level = _default_power_level;
- }
-
- return level;
- }
-
- /**
- * Clear the stored event level requirements. This should be
- * called e.g. when receiving a new m.room.power_levels event.
- */
- public void
- clear_event_levels()
- {
- _event_levels.remove_all();
- }
-
- /**
- * Set the required level to send an event of
- * type @param event_type.
- *
- * @param event_type the event type to restrict
- * @param level the desired level for the event type
- */
- public void
- set_event_level(string event_type, int level)
- {
- _event_levels[event_type] = level;
- }
-
- /**
- * Get the required level to send an event of
- * type @param event_type.
- *
- * @param event_type the event type to query
- * @return the level required to send a specific event. If there
- * is no level requirement is set for this event type,
- * this function returns null as there is no way to decide
- * if {@link Matrix.Room.default_state_level} or
- * {@link Matrix.Room.default_event_level} should be used
- */
- public int?
- get_event_level(string event_type)
- {
- return _event_levels[event_type];
- }
-}
diff --git a/vapi/c-api.vapi b/vapi/c-api.vapi
index e83cca5..31a392d 100644
--- a/vapi/c-api.vapi
+++ b/vapi/c-api.vapi
@@ -405,6 +405,61 @@ namespace Matrix {
throws Matrix.Error;
}
+ [CCode (cheader_filename = "matrix-room.h")]
+ public class Room : GLib.Object {
+ public string room_id { get; construct; }
+ public string[] aliases { get; set; }
+ public string? avatar_url { get; set; default = null; }
+ public Matrix.ImageInfo? avatar_info { get; set; default = null; }
+ public string? avatar_thumbnail_url { get; set; default = null; }
+ public Matrix.ImageInfo? avatar_thumbnail_info { get; set; default = null; }
+ public string? canonical_alias { get; set; default = null; }
+ public string? creator { get; set; default = null; }
+ public bool federate { get; set; default = false; }
+ public Matrix.GuestAccess guest_access { get; set; default = Matrix.GuestAccess.UNKNOWN; }
+ public Matrix.HistoryVisibility history_visibility { get; set; default = Matrix.HistoryVisibility.UNKNOWN; }
+ public Matrix.JoinRules join_rules { get; set; default = Matrix.JoinRules.UNKNOWN; }
+ public string? name { get; set; default = null; }
+ public int default_power_level { get; set; default = 0; }
+ public int default_event_level { get; set; default = 0; }
+ public int default_state_level { get; set; default = 10; }
+ public int ban_level { get; set; default = 5; }
+ public int kick_level { get; set; default = 5; }
+ public int redact_level { get; set; default = 20; }
+ public int invite_level { get; set; default = 0; }
+ public string? topic { get; set; default = null; }
+ public string[] typing_users { get; set; }
+
+ public Room(string room_id);
+
+ public void add_member(string user_id, Profile? profile, bool third_party)
+ throws Matrix.Error;
+
+ public Profile
+ get_or_add_member(string user_id, bool third_party = false)
+ throws Matrix.Error;
+
+ public Profile
+ get_member(string user_id, out bool third_party)
+ throws Matrix.Error;
+
+ public void
+ remove_member(string user_id)
+ throws Matrix.Error;
+
+ public void clear_user_levels();
+
+ public void set_user_level(string user_id, int level);
+
+ public int get_user_level(string user_id)
+ throws Matrix.Error;
+
+ public void clear_event_levels();
+
+ public void set_event_level(string event_type, int level);
+
+ public int? get_event_level(string event_type);
+ }
/* Utilities */
[CCode (cheader_filename = "utils.h", cname = "_matrix_g_enum_to_string")]
public string? _g_enum_value_to_nick(GLib.Type enum_type, int value, char convert_dashes = '_');