diff --git a/HellionChat/Themes/Theme.cs b/HellionChat/Themes/Theme.cs index 591bf49..18eee74 100644 --- a/HellionChat/Themes/Theme.cs +++ b/HellionChat/Themes/Theme.cs @@ -8,5 +8,6 @@ public sealed record Theme( ThemeColors Colors, ThemeLayout Layout, ThemeTypography Typography, - bool IsBuiltIn + bool IsBuiltIn, + ThemeChatColors? ChatColors = null ); diff --git a/HellionChat/Themes/ThemeChatColors.cs b/HellionChat/Themes/ThemeChatColors.cs new file mode 100644 index 0000000..3c2ba1b --- /dev/null +++ b/HellionChat/Themes/ThemeChatColors.cs @@ -0,0 +1,11 @@ +using HellionChat.Code; + +namespace HellionChat.Themes; + +// Optional pro Theme. Wenn ein Theme ChatColors mitliefert, kann der +// User sie per Klick im Themes-Tab auf Configuration.ChatColours anwenden. +// Ein Theme ohne ChatColors (z.B. chat2-classic) lässt die User-Channel- +// Farben unverändert. +public sealed record ThemeChatColors( + IReadOnlyDictionary Channels +); diff --git a/HellionChat/Themes/ThemeJsonLoader.cs b/HellionChat/Themes/ThemeJsonLoader.cs index d73200f..e340165 100644 --- a/HellionChat/Themes/ThemeJsonLoader.cs +++ b/HellionChat/Themes/ThemeJsonLoader.cs @@ -32,10 +32,35 @@ internal static class ThemeJsonLoader var colors = ReadColors(root.GetProperty("colors")); var layout = ReadLayout(root.GetProperty("layout")); - return new Theme(slug, name, author, description, colors, layout, new ThemeTypography(), IsBuiltIn: false); + ThemeChatColors? chatColors = null; + if (root.TryGetProperty("chatChannels", out var ch) && ch.ValueKind == JsonValueKind.Object) + chatColors = ReadChatColors(ch); + + return new Theme(slug, name, author, description, colors, layout, new ThemeTypography(), IsBuiltIn: false, ChatColors: chatColors); } } + private static ThemeChatColors ReadChatColors(JsonElement el) + { + var dict = new Dictionary(); + foreach (var prop in el.EnumerateObject()) + { + // Property-Name ist der ChatType-Name als String (z.B. "Say", "Tell"), + // Value ist Hex wie bei den Theme-Colors. Unbekannte Channel-Names + // werden still übersprungen — Forward-Compat falls SE neue Channels + // einführt. + if (!Enum.TryParse(prop.Name, ignoreCase: true, out var channel)) + continue; + if (prop.Value.ValueKind != JsonValueKind.String) + continue; + var hex = prop.Value.GetString(); + if (string.IsNullOrWhiteSpace(hex)) + continue; + dict[channel] = HellionChat.Util.ColourUtil.HexToRgba(hex); + } + return new ThemeChatColors(dict); + } + public static Theme LoadFromFile(string path) { var json = File.ReadAllText(path); diff --git a/HellionChat/Themes/ThemeJsonWriter.cs b/HellionChat/Themes/ThemeJsonWriter.cs index 97523f1..9cf197a 100644 --- a/HellionChat/Themes/ThemeJsonWriter.cs +++ b/HellionChat/Themes/ThemeJsonWriter.cs @@ -52,6 +52,14 @@ internal static class ThemeJsonWriter writer.WriteNumber("frameBorderSize", theme.Layout.FrameBorderSize); writer.WriteEndObject(); + if (theme.ChatColors is { Channels.Count: > 0 } cc) + { + writer.WriteStartObject("chatChannels"); + foreach (var kvp in cc.Channels) + writer.WriteString(kvp.Key.ToString(), $"#{kvp.Value:X8}"); + writer.WriteEndObject(); + } + writer.WriteEndObject(); }