OSDN Git Service

StatusTextHistoryを追加
authorKimura Youichi <kim.upsilon@bucyou.net>
Sun, 7 Jan 2024 21:17:22 +0000 (06:17 +0900)
committerKimura Youichi <kim.upsilon@bucyou.net>
Mon, 8 Jan 2024 00:12:54 +0000 (09:12 +0900)
OpenTween.Tests/Models/StatusTextHistoryTest.cs [new file with mode: 0644]
OpenTween/Models/StatusTextHistory.cs [new file with mode: 0644]
OpenTween/Tween.cs

diff --git a/OpenTween.Tests/Models/StatusTextHistoryTest.cs b/OpenTween.Tests/Models/StatusTextHistoryTest.cs
new file mode 100644 (file)
index 0000000..922522c
--- /dev/null
@@ -0,0 +1,115 @@
+// OpenTween - Client of Twitter
+// Copyright (c) 2024 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
+// All rights reserved.
+//
+// This file is part of OpenTween.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program 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 General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
+// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+using Xunit;
+
+namespace OpenTween.Models
+{
+    public class StatusTextHistoryTest
+    {
+        [Fact]
+        public void Initialize_Test()
+        {
+            var history = new StatusTextHistory();
+            Assert.Single(history.Items);
+            Assert.Equal(new("", null), history.Items[0]);
+            Assert.Equal(0, history.HistoryIndex);
+        }
+
+        [Fact]
+        public void Back_NoItemsTest()
+        {
+            var history = new StatusTextHistory();
+            history.Back("@hoge aaa", (new TwitterStatusId("111"), "hoge"));
+            Assert.Single(history.Items);
+            Assert.Equal(new("@hoge aaa", (new TwitterStatusId("111"), "hoge")), history.Items[0]);
+            Assert.Equal(0, history.HistoryIndex);
+        }
+
+        [Fact]
+        public void Back_HasItemsTest()
+        {
+            var history = new StatusTextHistory();
+            history.SetLastItem("@hoge aaa", (new TwitterStatusId("111"), "hoge"));
+            history.AddLast();
+            history.Back("@foo bbb", (new TwitterStatusId("222"), "foo"));
+
+            Assert.Equal(2, history.Items.Count);
+            Assert.Equal(new("@hoge aaa", (new TwitterStatusId("111"), "hoge")), history.Items[0]);
+            Assert.Equal(new("@foo bbb", (new TwitterStatusId("222"), "foo")), history.Items[1]);
+            Assert.Equal(0, history.HistoryIndex);
+        }
+
+        [Fact]
+        public void Forward_NoItemsTest()
+        {
+            var history = new StatusTextHistory();
+            history.Forward("@hoge aaa", (new TwitterStatusId("111"), "hoge"));
+            Assert.Single(history.Items);
+            Assert.Equal(new("@hoge aaa", (new TwitterStatusId("111"), "hoge")), history.Items[0]);
+            Assert.Equal(0, history.HistoryIndex);
+        }
+
+        [Fact]
+        public void Forward_HasItemsTest()
+        {
+            var history = new StatusTextHistory();
+            history.SetLastItem("@hoge aaa", (new TwitterStatusId("111"), "hoge"));
+            history.AddLast();
+            history.Back("@foo bbb", (new TwitterStatusId("222"), "foo"));
+            history.Forward("@hoge aaa 123", (new TwitterStatusId("111"), "hoge"));
+
+            Assert.Equal(2, history.Items.Count);
+            Assert.Equal(new("@hoge aaa 123", (new TwitterStatusId("111"), "hoge")), history.Items[0]);
+            Assert.Equal(new("@foo bbb", (new TwitterStatusId("222"), "foo")), history.Items[1]);
+            Assert.Equal(1, history.HistoryIndex);
+        }
+
+        [Fact]
+        public void AddLast_Test()
+        {
+            var history = new StatusTextHistory();
+            history.SetLastItem("@hoge aaa", (new TwitterStatusId("111"), "hoge"));
+            history.AddLast();
+            Assert.Equal(2, history.Items.Count);
+            Assert.Equal(new("@hoge aaa", (new TwitterStatusId("111"), "hoge")), history.Items[0]);
+            Assert.Equal(new("", null), history.Items[1]);
+            Assert.Equal(1, history.HistoryIndex);
+        }
+
+        [Fact]
+        public void Peek_EmptyTest()
+        {
+            var history = new StatusTextHistory();
+            Assert.Null(history.Peek());
+        }
+
+        [Fact]
+        public void Peek_HasItemsTest()
+        {
+            var history = new StatusTextHistory();
+            history.SetLastItem("@hoge aaa", (new TwitterStatusId("111"), "hoge"));
+            history.AddLast();
+
+            Assert.Equal(new("@hoge aaa", (new TwitterStatusId("111"), "hoge")), history.Peek());
+        }
+    }
+}
diff --git a/OpenTween/Models/StatusTextHistory.cs b/OpenTween/Models/StatusTextHistory.cs
new file mode 100644 (file)
index 0000000..ec1d8fe
--- /dev/null
@@ -0,0 +1,88 @@
+// OpenTween - Client of Twitter
+// Copyright (c) 2024 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
+// All rights reserved.
+//
+// This file is part of OpenTween.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program 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 General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
+// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#nullable enable
+
+using System.Collections.Generic;
+
+namespace OpenTween.Models
+{
+    public class StatusTextHistory
+    {
+        public readonly record struct HistoryItem(
+            string Status,
+            (PostId StatusId, string ScreenName)? InReplyTo = null
+        );
+
+        internal IReadOnlyList<HistoryItem> Items
+            => this.items;
+
+        internal int HistoryIndex
+            => this.historyIndex;
+
+        private readonly List<HistoryItem> items = new();
+        private int historyIndex = 0;
+
+        public StatusTextHistory()
+            => this.items.Add(new(""));
+
+        public HistoryItem Back(string text, (PostId StatusId, string ScreenName)? inReplyTo)
+        {
+            if (!string.IsNullOrWhiteSpace(text))
+                this.items[this.historyIndex] = new(text, inReplyTo);
+
+            this.historyIndex -= 1;
+            if (this.historyIndex < 0)
+                this.historyIndex = 0;
+
+            return this.items[this.historyIndex];
+        }
+
+        public HistoryItem Forward(string text, (PostId StatusId, string ScreenName)? inReplyTo)
+        {
+            if (!string.IsNullOrWhiteSpace(text))
+                this.items[this.historyIndex] = new(text, inReplyTo);
+
+            this.historyIndex += 1;
+            if (this.historyIndex > this.items.Count - 1)
+                this.historyIndex = this.items.Count - 1;
+
+            return this.items[this.historyIndex];
+        }
+
+        public void SetLastItem(string text, (PostId StatusId, string ScreenName)? inReplyTo)
+            => this.items[this.items.Count - 1] = new(text, inReplyTo);
+
+        public void AddLast()
+        {
+            this.items.Add(new(""));
+            this.historyIndex = this.items.Count - 1;
+        }
+
+        public HistoryItem? Peek()
+        {
+            if (this.items.Count < 2)
+                return null;
+
+            return this.items[this.items.Count - 2];
+        }
+    }
+}
index 7124676..7d924e3 100644 (file)
@@ -140,10 +140,7 @@ namespace OpenTween
         private readonly ThumbnailGenerator thumbGenerator;
 
         /// <summary>発言履歴</summary>
-        private readonly List<StatusTextHistory> history = new();
-
-        /// <summary>発言履歴カレントインデックス</summary>
-        private int hisIdx;
+        private readonly StatusTextHistory history = new();
 
         // 発言投稿時のAPI引数(発言編集時に設定。手書きreplyでは設定されない)
 
@@ -239,11 +236,6 @@ namespace OpenTween
             PrevSearch,
         }
 
-        private readonly record struct StatusTextHistory(
-            string Status,
-            (PostId StatusId, string ScreenName)? InReplyTo = null
-        );
-
         private readonly HookGlobalHotkey hookGlobalHotkey;
 
         public TweenMain(
@@ -347,8 +339,6 @@ namespace OpenTween
 
             this.recommendedStatusFooter = " [TWNv" + Regex.Replace(MyCommon.FileVersion.Replace(".", ""), "^0*", "") + "]";
 
-            this.history.Add(new StatusTextHistory(""));
-            this.hisIdx = 0;
             this.inReplyTo = null;
 
             // 各種ダイアログ設定
@@ -1098,14 +1088,7 @@ namespace OpenTween
 
         private void StatusTextHistoryBack()
         {
-            if (!string.IsNullOrWhiteSpace(this.StatusText.Text))
-                this.history[this.hisIdx] = new StatusTextHistory(this.StatusText.Text, this.inReplyTo);
-
-            this.hisIdx -= 1;
-            if (this.hisIdx < 0)
-                this.hisIdx = 0;
-
-            var historyItem = this.history[this.hisIdx];
+            var historyItem = this.history.Back(this.StatusText.Text, this.inReplyTo);
             this.inReplyTo = historyItem.InReplyTo;
             this.StatusText.Text = historyItem.Status;
             this.StatusText.SelectionStart = this.StatusText.Text.Length;
@@ -1113,14 +1096,7 @@ namespace OpenTween
 
         private void StatusTextHistoryForward()
         {
-            if (!string.IsNullOrWhiteSpace(this.StatusText.Text))
-                this.history[this.hisIdx] = new StatusTextHistory(this.StatusText.Text, this.inReplyTo);
-
-            this.hisIdx += 1;
-            if (this.hisIdx > this.history.Count - 1)
-                this.hisIdx = this.history.Count - 1;
-
-            var historyItem = this.history[this.hisIdx];
+            var historyItem = this.history.Forward(this.StatusText.Text, this.inReplyTo);
             this.inReplyTo = historyItem.InReplyTo;
             this.StatusText.Text = historyItem.Status;
             this.StatusText.SelectionStart = this.StatusText.Text.Length;
@@ -1164,7 +1140,7 @@ namespace OpenTween
                     return;
             }
 
-            this.history[this.history.Count - 1] = new StatusTextHistory(this.StatusText.Text, this.inReplyTo);
+            this.history.SetLastItem(this.StatusText.Text, this.inReplyTo);
 
             if (this.settings.Common.Nicoms)
             {
@@ -1227,8 +1203,7 @@ namespace OpenTween
 
             this.inReplyTo = null;
             this.StatusText.Text = "";
-            this.history.Add(new StatusTextHistory(""));
-            this.hisIdx = this.history.Count - 1;
+            this.history.AddLast();
             if (!this.settings.Common.FocusLockToStatusText)
                 this.CurrentListView.Focus();
             this.urlUndoBuffer = null;
@@ -6903,8 +6878,8 @@ namespace OpenTween
                     ttl.Append("Ver:").Append(MyCommon.GetReadableVersion());
                     break;
                 case MyCommon.DispTitleEnum.Post:
-                    if (this.history != null && this.history.Count > 1)
-                        ttl.Append(this.history[this.history.Count - 2].Status.Replace("\r\n", " "));
+                    if (this.history.Peek() is { } lastItem)
+                        ttl.Append(lastItem.Status.Replace("\r\n", " "));
                     break;
                 case MyCommon.DispTitleEnum.UnreadRepCount:
                     ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText1, this.statuses.MentionTab.UnreadCount + this.statuses.DirectMessageTab.UnreadCount);