# HG changeset patch
# Node ID 53b2079fcb483be0e6cce5ddefcde2c32af20e52
# Parent  7b9d197a5e1600b24e2226b518a8d6138707d2df
diff --git a/libpurple/purpleconversationmember.c b/libpurple/purpleconversationmember.c
--- a/libpurple/purpleconversationmember.c
+++ b/libpurple/purpleconversationmember.c
@@ -35,7 +35,9 @@
 
 	guint typing_timeout;
 	PurpleTypingState typing_state;
+
 	char *nickname;
+	char *color;
 };
 
 enum {
@@ -47,6 +49,7 @@
 	PROP_TYPING_STATE,
 	PROP_NICKNAME,
 	PROP_NAME_FOR_DISPLAY,
+	PROP_COLOR,
 	N_PROPERTIES,
 };
 static GParamSpec *properties[N_PROPERTIES] = {NULL, };
@@ -130,6 +133,10 @@
 		g_value_set_object(value,
 		                   purple_conversation_member_get_badges(member));
 		break;
+	case PROP_COLOR:
+		g_value_set_string(value,
+		                   purple_conversation_member_get_color(member));
+		break;
 	case PROP_CONTACT_INFO:
 		g_value_set_object(value,
 		                   purple_conversation_member_get_contact_info(member));
@@ -167,6 +174,10 @@
 		purple_conversation_member_set_alias(member,
 		                                     g_value_get_string(value));
 		break;
+	case PROP_COLOR:
+		purple_conversation_member_set_color(member,
+		                                     g_value_get_string(value));
+		break;
 	case PROP_CONTACT_INFO:
 		purple_conversation_member_set_contact_info(member,
 		                                            g_value_get_object(value));
@@ -202,6 +213,7 @@
 	PurpleConversationMember *member = PURPLE_CONVERSATION_MEMBER(obj);
 
 	g_clear_pointer(&member->alias, g_free);
+	g_clear_pointer(&member->color, g_free);
 	g_clear_object(&member->badges);
 	g_clear_object(&member->tags);
 	g_clear_pointer(&member->nickname, g_free);
@@ -252,6 +264,22 @@
 		G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
 
 	/**
+	 * PurpleConversationMember:color:
+	 *
+	 * The hex color code for the member.
+	 *
+	 * This color code should be used by user interfaces when displaying the
+	 * member. It may be modified by the user interface to increase contrast
+	 * ratios.
+	 *
+	 * Since: 3.0
+	 */
+	properties[PROP_COLOR] = g_param_spec_string(
+		"color", NULL, NULL,
+		NULL,
+		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+	/**
 	 * PurpleConversationMember:contact-info:
 	 *
 	 * The contact info that this member is for.
@@ -363,6 +391,24 @@
 	return member->badges;
 }
 
+const char *
+purple_conversation_member_get_color(PurpleConversationMember *member) {
+	g_return_val_if_fail(PURPLE_IS_CONVERSATION_MEMBER(member), NULL);
+
+	return member->color;
+}
+
+void
+purple_conversation_member_set_color(PurpleConversationMember *member,
+                                     const char *color)
+{
+	g_return_if_fail(PURPLE_IS_CONVERSATION_MEMBER(member));
+
+	if(g_set_str(&member->color, color)) {
+		g_object_notify_by_pspec(G_OBJECT(member), properties[PROP_COLOR]);
+	}
+}
+
 PurpleContactInfo *
 purple_conversation_member_get_contact_info(PurpleConversationMember *member) {
 	g_return_val_if_fail(PURPLE_IS_CONVERSATION_MEMBER(member), NULL);
diff --git a/libpurple/purpleconversationmember.h b/libpurple/purpleconversationmember.h
--- a/libpurple/purpleconversationmember.h
+++ b/libpurple/purpleconversationmember.h
@@ -115,6 +115,35 @@
 PurpleBadges *purple_conversation_member_get_badges(PurpleConversationMember *member);
 
 /**
+ * purple_conversation_member_get_color:
+ *
+ * Gets the color that should be used to display the member.
+ *
+ * This is a hex color code in the format of `#RRGGBB`.
+ *
+ * User interfaces may adjust this color to increase contrast ratios.
+ *
+ * Returns: (nullable): The color.
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+const char *purple_conversation_member_get_color(PurpleConversationMember *member);
+
+/**
+ * purple_conversation_member_set_color:
+ * @color: (nullable): the new color
+ *
+ * Sets the color that the member should be displayed with.
+ *
+ * @color should be a hex color code in the format for `#RRGGBB`.
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+void purple_conversation_member_set_color(PurpleConversationMember *member, const char *color);
+
+/**
  * purple_conversation_member_get_contact_info:
  * @conversation_member: The instance.
  *
diff --git a/libpurple/purplemessage.c b/libpurple/purplemessage.c
--- a/libpurple/purplemessage.c
+++ b/libpurple/purplemessage.c
@@ -32,8 +32,6 @@
 	char *id;
 	PurpleConversationMember *author;
 
-	char *author_name_color;
-
 	char *contents;
 
 	guint action : 1;
@@ -102,8 +100,10 @@
 		g_value_set_object(value, purple_message_get_author(message));
 		break;
 	case PROP_AUTHOR_NAME_COLOR:
+		G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 		g_value_set_string(value,
 		                   purple_message_get_author_name_color(message));
+		G_GNUC_END_IGNORE_DEPRECATIONS
 		break;
 	case PROP_CONTENTS:
 		g_value_set_string(value, purple_message_get_contents(message));
@@ -158,8 +158,10 @@
 		purple_message_set_author(message, g_value_get_object(value));
 		break;
 	case PROP_AUTHOR_NAME_COLOR:
+		G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 		purple_message_set_author_name_color(message,
 		                                     g_value_get_string(value));
+		G_GNUC_END_IGNORE_DEPRECATIONS
 		break;
 	case PROP_CONTENTS:
 		purple_message_set_contents(message, g_value_get_string(value));
@@ -206,7 +208,6 @@
 
 	g_free(message->id);
 	g_clear_object(&message->author);
-	g_free(message->author_name_color);
 	g_free(message->contents);
 
 	g_clear_error(&message->error);
@@ -269,11 +270,13 @@
 	 * The hex color for the author's name.
 	 *
 	 * Since: 3.0
+	 *
+	 * Deprecated: 3.0
 	 */
 	properties[PROP_AUTHOR_NAME_COLOR] = g_param_spec_string(
 		"author-name-color", NULL, NULL,
 		NULL,
-		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_DEPRECATED);
 
 	/**
 	 * PurpleMessage:contents:
@@ -475,9 +478,8 @@
 {
 	g_return_if_fail(PURPLE_IS_MESSAGE(message));
 
-	if(g_set_str(&message->author_name_color, color)) {
-		g_object_notify_by_pspec(G_OBJECT(message),
-		                         properties[PROP_AUTHOR_NAME_COLOR]);
+	if(PURPLE_IS_CONVERSATION_MEMBER(message->author)) {
+		purple_conversation_member_set_color(message->author, color);
 	}
 }
 
@@ -485,7 +487,11 @@
 purple_message_get_author_name_color(PurpleMessage *message) {
 	g_return_val_if_fail(PURPLE_IS_MESSAGE(message), NULL);
 
-	return message->author_name_color;
+	if(PURPLE_IS_CONVERSATION_MEMBER(message->author)) {
+		return purple_conversation_member_get_color(message->author);
+	}
+
+	return NULL;
 }
 
 void
diff --git a/libpurple/purplemessage.h b/libpurple/purplemessage.h
--- a/libpurple/purplemessage.h
+++ b/libpurple/purplemessage.h
@@ -110,8 +110,10 @@
  * Returns: (transfer none): The hex color for the author of @message's name.
  *
  * Since: 3.0
+ *
+ * Deprecated: 3.0
  */
-PURPLE_AVAILABLE_IN_3_0
+PURPLE_DEPRECATED_FOR(purple_conversation_member_get_color)
 const char *purple_message_get_author_name_color(PurpleMessage *message);
 
 /**
@@ -125,8 +127,10 @@
  * contrast or limits on the number of colors.
  *
  * Since: 3.0
+ *
+ * Deprecated: 3.0
  */
-PURPLE_AVAILABLE_IN_3_0
+PURPLE_DEPRECATED_FOR(purple_conversation_member_set_color)
 void purple_message_set_author_name_color(PurpleMessage *message, const char *color);
 
 /**
diff --git a/libpurple/purplesqlitehistoryadapter.c b/libpurple/purplesqlitehistoryadapter.c
--- a/libpurple/purplesqlitehistoryadapter.c
+++ b/libpurple/purplesqlitehistoryadapter.c
@@ -312,7 +312,6 @@
 		GDateTime *g_date_time = NULL;
 		const char *account_id = NULL;
 		const char *author = NULL;
-		const char *author_name_color = NULL;
 		const char *author_alias = NULL;
 		const char *content = NULL;
 		const char *conversation_id = NULL;
@@ -323,10 +322,9 @@
 		conversation_id = (const char *)sqlite3_column_text(prepared_statement, 1);
 		message_id = (const char *)sqlite3_column_text(prepared_statement, 2);
 		author = (const char *)sqlite3_column_text(prepared_statement, 3);
-		author_name_color = (const char *)sqlite3_column_text(prepared_statement, 4);
-		author_alias = (const char *)sqlite3_column_text(prepared_statement, 5);
-		content = (const char *)sqlite3_column_text(prepared_statement, 6);
-		timestamp = (const char *)sqlite3_column_text(prepared_statement, 7);
+		author_alias = (const char *)sqlite3_column_text(prepared_statement, 4);
+		content = (const char *)sqlite3_column_text(prepared_statement, 5);
+		timestamp = (const char *)sqlite3_column_text(prepared_statement, 6);
 		g_date_time = g_date_time_new_from_iso8601(timestamp, NULL);
 
 		/* This is gross but necessary until we finish rethinking history.
@@ -367,7 +365,6 @@
 
 		message = purple_message_new(member, content);
 		purple_message_set_id(message, message_id);
-		purple_message_set_author_name_color(message, author_name_color);
 		purple_message_set_timestamp(message, g_date_time);
 
 		results = g_list_prepend(results, message);
@@ -442,9 +439,9 @@
 	int result = 0;
 
 	script = "INSERT INTO message_log(protocol, account, conversation_id, "
-			 "message_id, author, author_name_color, author_alias, "
+			 "message_id, author, author_alias, "
 			 "content, client_timestamp) "
-	         "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)";
+	         "VALUES(?, ?, ?, ?, ?, ?, ?, ?)";
 
 	sqlite_adapter = PURPLE_SQLITE_HISTORY_ADAPTER(adapter);
 
@@ -490,16 +487,13 @@
 	                  5, purple_contact_info_get_id(info), -1,
 	                  SQLITE_STATIC);
 	sqlite3_bind_text(prepared_statement,
-	                  6, purple_message_get_author_name_color(message), -1,
+	                  6, purple_conversation_member_get_name_for_display(author), -1,
 	                  SQLITE_STATIC);
 	sqlite3_bind_text(prepared_statement,
-	                  7, purple_conversation_member_get_name_for_display(author), -1,
-	                  SQLITE_STATIC);
-	sqlite3_bind_text(prepared_statement,
-	                  8, purple_message_get_contents(message), -1,
+	                  7, purple_message_get_contents(message), -1,
 	                  SQLITE_STATIC);
 	timestamp = g_date_time_format_iso8601(purple_message_get_timestamp(message));
-	sqlite3_bind_text(prepared_statement, 9, timestamp, -1, g_free);
+	sqlite3_bind_text(prepared_statement, 8, timestamp, -1, g_free);
 
 	result = sqlite3_step(prepared_statement);
 
diff --git a/libpurple/tests/test_conversation_member.c b/libpurple/tests/test_conversation_member.c
--- a/libpurple/tests/test_conversation_member.c
+++ b/libpurple/tests/test_conversation_member.c
@@ -62,6 +62,7 @@
 	PurpleTags *tags = NULL;
 	PurpleTypingState typing_state = PURPLE_TYPING_STATE_NONE;
 	char *alias = NULL;
+	char *color = NULL;
 	char *name_for_display = NULL;
 	char *nickname = NULL;
 
@@ -74,6 +75,7 @@
 	member = g_object_new(
 		PURPLE_TYPE_CONVERSATION_MEMBER,
 		"alias", "pidgy1",
+		"color", "#55aaff",
 		"contact-info", info,
 		"nickname", "pidgy",
 		"typing-state", PURPLE_TYPING_STATE_TYPING,
@@ -84,6 +86,7 @@
 		member,
 		"alias", &alias,
 		"badges", &badges,
+		"color", &color,
 		"contact-info", &info1,
 		"name-for-display", &name_for_display,
 		"nickname", &nickname,
@@ -97,6 +100,9 @@
 	g_assert_true(PURPLE_IS_BADGES(badges));
 	g_clear_object(&badges);
 
+	g_assert_cmpstr(color, ==, "#55aaff");
+	g_clear_pointer(&color, g_free);
+
 	g_assert_true(info1 == info);
 	g_clear_object(&info1);
 
diff --git a/libpurple/tests/test_message.c b/libpurple/tests/test_message.c
--- a/libpurple/tests/test_message.c
+++ b/libpurple/tests/test_message.c
@@ -51,7 +51,6 @@
 	GError *error = NULL;
 	GError *error1 = NULL;
 	char *id = NULL;
-	char *author_name_color = NULL;
 	char *contents = NULL;
 	gboolean action = FALSE;
 	gboolean delivered = FALSE;
@@ -80,7 +79,6 @@
 		PURPLE_TYPE_MESSAGE,
 		"action", TRUE,
 		"author", author,
-		"author-name-color", "purple",
 		"contents", "Now that is a big door",
 		"delivered", TRUE,
 		"edited", TRUE,
@@ -96,7 +94,6 @@
 		message,
 		"action", &action,
 		"author", &author1,
-		"author-name-color", &author_name_color,
 		"contents", &contents,
 		"delivered", &delivered,
 		"delivered-at", &delivered_at1,
@@ -115,9 +112,6 @@
 	g_assert_true(author1 == author);
 	g_clear_object(&author1);
 
-	g_assert_cmpstr(author_name_color, ==, "purple");
-	g_clear_pointer(&author_name_color, g_free);
-
 	g_assert_cmpstr(contents, ==, "Now that is a big door");
 	g_clear_pointer(&contents, g_free);
 
