diff --git a/BouyomiPlugin/ConfigView.xaml b/BouyomiPlugin/ConfigView.xaml index 0da9875a..11baa566 100644 --- a/BouyomiPlugin/ConfigView.xaml +++ b/BouyomiPlugin/ConfigView.xaml @@ -8,6 +8,9 @@ d:DesignHeight="1500" d:DataContext="{d:DesignInstance local:ConfigViewModel, IsDesignTimeCreatable=True}" Title="棒読みちゃん連携プラグイン" Width="439" Background="#F0F0F0"> + + + @@ -61,8 +64,8 @@ - - + + @@ -106,6 +109,8 @@ + + @@ -121,6 +126,8 @@ + + @@ -135,6 +142,8 @@ + + @@ -164,6 +173,8 @@ + + @@ -187,15 +198,38 @@ + + + + + + + + + + + + + + + @@ -226,6 +260,8 @@ + + @@ -240,6 +276,8 @@ + + @@ -273,6 +311,8 @@ + + @@ -287,6 +327,8 @@ + + @@ -316,6 +358,8 @@ + + @@ -346,6 +390,8 @@ + + @@ -360,6 +406,8 @@ + + @@ -391,6 +439,8 @@ + + @@ -424,6 +474,8 @@ + + @@ -457,6 +509,8 @@ + + @@ -492,6 +546,8 @@ + + @@ -509,6 +565,8 @@ + + @@ -542,6 +600,8 @@ + + @@ -575,6 +635,8 @@ + + @@ -602,6 +664,8 @@ + + @@ -626,6 +690,8 @@ + + diff --git a/BouyomiPlugin/ConfigView.xaml.cs b/BouyomiPlugin/ConfigView.xaml.cs index bd014282..23f3760d 100644 --- a/BouyomiPlugin/ConfigView.xaml.cs +++ b/BouyomiPlugin/ConfigView.xaml.cs @@ -3,6 +3,7 @@ using System.ComponentModel; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; @@ -23,6 +24,7 @@ public partial class ConfigView : Window public ConfigView() { InitializeComponent(); + DataObject.AddPastingHandler(TwitchMaxEmotes, TextBoxPastingEventHandler); _isForceClose = false; } protected override void OnClosing(CancelEventArgs e) @@ -46,5 +48,43 @@ public void ForceClose() _isForceClose = true; this.Close(); } + + private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e) + { + // 数字のみ入力可 + if (!Regex.IsMatch(e.Text, "[0-9]")) + { + e.Handled = true; + } + } + + private void TextBox_TextChanged(object sender, TextChangedEventArgs e) + { + if (e.Source is TextBox t) + { + if ((0 < t.MaxLength) && (t.MaxLength < t.Text.Length)) + { + int start = t.SelectionStart; + t.Text = t.Text.Substring(0, 3); + t.SelectionStart = start; + } + } + } + + private static void TextBoxPastingEventHandler(object sender, DataObjectPastingEventArgs e) + { + if (e.Source is TextBox t) + { + if (e.DataObject.GetData(typeof(string)) is string s) + { + // 数字のみ貼り付け可 + t.SelectedText = Regex.Replace(s, "[^0-9]", ""); + t.SelectionStart += t.SelectionLength; + t.SelectionLength = 0; + e.CancelCommand(); + e.Handled = true; + } + } + } } } diff --git a/BouyomiPlugin/ConfigViewModel.cs b/BouyomiPlugin/ConfigViewModel.cs index 79fc7354..9a54030c 100644 --- a/BouyomiPlugin/ConfigViewModel.cs +++ b/BouyomiPlugin/ConfigViewModel.cs @@ -297,6 +297,30 @@ public bool IsTwitchCommentNickname get => _options.IsTwitchCommentNickname; set => _options.IsTwitchCommentNickname = value; } + /// + /// TwitchのコメントのエモートIDを読み上げるか + /// + public bool IsTwitchCommentEmoteId + { + get => _options.IsTwitchCommentEmoteId; + set => _options.IsTwitchCommentEmoteId = value; + } + /// + /// TwitchのコメントのエモートIDを何個まで読み上げるか + /// + public int TwitchMaxEmotes + { + get { return _options.TwitchMaxEmotes; } + set { _options.TwitchMaxEmotes = value; } + } + /// + /// Twitchのコメントの連続する同一エモートを省略するか + /// + public bool IsTwitchSkipSameEmote + { + get { return _options.IsTwitchSkipSameEmote; } + set { _options.IsTwitchSkipSameEmote = value; } + } ///// ///// Twitchのアイテムを読み上げるか ///// diff --git a/BouyomiPlugin/Converter.cs b/BouyomiPlugin/Converter.cs new file mode 100644 index 00000000..9efee51a --- /dev/null +++ b/BouyomiPlugin/Converter.cs @@ -0,0 +1,19 @@ +using System; +using System.Globalization; +using System.Linq; +using System.Windows.Data; +namespace BouyomiPlugin +{ + public class AndConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + return values?.All(value => (bool)value) == true; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/BouyomiPlugin/Options.cs b/BouyomiPlugin/Options.cs index f4d5fa22..2cbc6ca5 100644 --- a/BouyomiPlugin/Options.cs +++ b/BouyomiPlugin/Options.cs @@ -53,6 +53,9 @@ class Options : DynamicOptionsBase public bool IsTwitchDisconnect { get { return GetValue(); } set { SetValue(value); } } public bool IsTwitchComment { get { return GetValue(); } set { SetValue(value); } } public bool IsTwitchCommentNickname { get { return GetValue(); } set { SetValue(value); } } + public bool IsTwitchCommentEmoteId { get { return GetValue(); } set { SetValue(value); } } + public bool IsTwitchSkipSameEmote { get { return GetValue(); } set { SetValue(value); } } + public int TwitchMaxEmotes { get { return GetValue(); } set { SetValue(value); } } //ニコ生 public bool IsNicoConnect { get { return GetValue(); } set { SetValue(value); } } @@ -178,6 +181,9 @@ protected override void Init() Dict.Add(nameof(IsTwitchDisconnect), new Item { DefaultValue = false, Predicate = b => true, Serializer = b => b.ToString(), Deserializer = s => bool.Parse(s) }); Dict.Add(nameof(IsTwitchComment), new Item { DefaultValue = true, Predicate = b => true, Serializer = b => b.ToString(), Deserializer = s => bool.Parse(s) }); Dict.Add(nameof(IsTwitchCommentNickname), new Item { DefaultValue = true, Predicate = b => true, Serializer = b => b.ToString(), Deserializer = s => bool.Parse(s) }); + Dict.Add(nameof(IsTwitchCommentEmoteId), new Item { DefaultValue = false, Predicate = b => true, Serializer = b => b.ToString(), Deserializer = s => bool.Parse(s) }); + Dict.Add(nameof(IsTwitchSkipSameEmote), new Item { DefaultValue = true, Predicate = b => true, Serializer = b => b.ToString(), Deserializer = s => bool.Parse(s) }); + Dict.Add(nameof(TwitchMaxEmotes), new Item { DefaultValue = 3, Predicate = n => true, Serializer = n => n.ToString(), Deserializer = n => int.Parse(n) }); //ニコ生 Dict.Add(nameof(IsNicoConnect), new Item { DefaultValue = false, Predicate = b => true, Serializer = b => b.ToString(), Deserializer = s => bool.Parse(s) }); diff --git a/BouyomiPlugin/main.cs b/BouyomiPlugin/main.cs index 280a3cc8..2ae0874a 100644 --- a/BouyomiPlugin/main.cs +++ b/BouyomiPlugin/main.cs @@ -52,6 +52,49 @@ public static string ToTextWithImageAlt(this IEnumerable parts) } return s; } + public static string ToTextWithImageAlt(this IEnumerable parts, int maxImages, bool skipSameImage) + { + int n = 0; + string s = ""; + string previousImage = ""; + if (parts != null) + { + foreach (var part in parts) + { + if (part is IMessageText text) + { + if (!string.IsNullOrWhiteSpace(text.Text)) + { + previousImage = ""; + } + s += text; + } + else if (part is IMessageImage image) + { + if ((n < maxImages) && (!skipSameImage || !string.Equals(previousImage, image.Alt))) + { + s += image.Alt; + n++; + } + previousImage = image.Alt; + } + else if(part is IMessageRemoteSvg remoteSvg) + { + if ((n < maxImages) && (!skipSameImage || !string.Equals(previousImage, remoteSvg.Alt))) + { + s += remoteSvg.Alt; + n++; + } + previousImage = remoteSvg.Alt; + } + else + { + + } + } + } + return s; + } } [Export(typeof(IPlugin))] public class BouyomiPlugin : IPlugin, IDisposable @@ -291,7 +334,14 @@ private static (string name, string comment) GetData(ISiteMessage message, Optio { name = (twitchMessage as ITwitchComment).DisplayName; } - comment = (twitchMessage as ITwitchComment).CommentItems.ToText(); + if (options.IsTwitchCommentEmoteId) + { + comment = (twitchMessage as ITwitchComment).CommentItems.ToTextWithImageAlt(options.TwitchMaxEmotes, options.IsTwitchSkipSameEmote); + } + else + { + comment = (twitchMessage as ITwitchComment).CommentItems.ToText(); + } } break; }