OSDN Git Service

各タブのOldestIdの型にPostIdを使用する
authorKimura Youichi <kim.upsilon@bucyou.net>
Mon, 20 Nov 2023 16:39:47 +0000 (01:39 +0900)
committerKimura Youichi <kim.upsilon@bucyou.net>
Mon, 20 Nov 2023 16:40:53 +0000 (01:40 +0900)
OpenTween.Tests/Api/TwitterApiTest.cs
OpenTween.Tests/Api/TwitterV2/GetTimelineRequestTest.cs
OpenTween/Api/TwitterApi.cs
OpenTween/Api/TwitterV2/GetTimelineRequest.cs
OpenTween/Models/HomeTabModel.cs
OpenTween/Models/ListTimelineTabModel.cs
OpenTween/Models/MentionsTabModel.cs
OpenTween/Models/PublicSearchTabModel.cs
OpenTween/Models/UserTimelineTabModel.cs
OpenTween/Twitter.cs

index 3144b0c..27ad41e 100644 (file)
@@ -104,7 +104,7 @@ namespace OpenTween.Api
             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
             twitterApi.ApiConnection = mock.Object;
 
-            await twitterApi.StatusesHomeTimeline(200, maxId: 900L, sinceId: 100L)
+            await twitterApi.StatusesHomeTimeline(200, maxId: new("900"), sinceId: new("100"))
                 .ConfigureAwait(false);
 
             mock.VerifyAll();
@@ -133,7 +133,7 @@ namespace OpenTween.Api
             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
             twitterApi.ApiConnection = mock.Object;
 
-            await twitterApi.StatusesMentionsTimeline(200, maxId: 900L, sinceId: 100L)
+            await twitterApi.StatusesMentionsTimeline(200, maxId: new("900"), sinceId: new("100"))
                 .ConfigureAwait(false);
 
             mock.VerifyAll();
@@ -164,7 +164,7 @@ namespace OpenTween.Api
             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
             twitterApi.ApiConnection = mock.Object;
 
-            await twitterApi.StatusesUserTimeline("twitterapi", count: 200, maxId: 900L, sinceId: 100L)
+            await twitterApi.StatusesUserTimeline("twitterapi", count: 200, maxId: new("900"), sinceId: new("100"))
                 .ConfigureAwait(false);
 
             mock.VerifyAll();
@@ -366,7 +366,7 @@ namespace OpenTween.Api
             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
             twitterApi.ApiConnection = mock.Object;
 
-            await twitterApi.SearchTweets("from:twitterapi", "en", count: 200, maxId: 900L, sinceId: 100L)
+            await twitterApi.SearchTweets("from:twitterapi", "en", count: 200, maxId: new("900"), sinceId: new("100"))
                 .ConfigureAwait(false);
 
             mock.VerifyAll();
@@ -553,7 +553,7 @@ namespace OpenTween.Api
             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
             twitterApi.ApiConnection = mock.Object;
 
-            await twitterApi.ListsStatuses(12345L, count: 200, maxId: 900L, sinceId: 100L, includeRTs: true)
+            await twitterApi.ListsStatuses(12345L, count: 200, maxId: new("900"), sinceId: new("100"), includeRTs: true)
                 .ConfigureAwait(false);
 
             mock.VerifyAll();
index 82ed7e5..bf99006 100644 (file)
@@ -53,8 +53,8 @@ namespace OpenTween.Api.TwitterV2
             var request = new GetTimelineRequest(userId: 100L)
             {
                 MaxResults = 200,
-                SinceId = "100",
-                UntilId = "900",
+                SinceId = new("100"),
+                UntilId = new("900"),
             };
 
             await request.Send(mock.Object).ConfigureAwait(false);
index 30b8cfb..157cc2d 100644 (file)
@@ -75,7 +75,7 @@ namespace OpenTween.Api
             this.CurrentScreenName = screenName;
         }
 
-        public Task<TwitterStatus[]> StatusesHomeTimeline(int? count = null, long? maxId = null, long? sinceId = null)
+        public Task<TwitterStatus[]> StatusesHomeTimeline(int? count = null, TwitterStatusId? maxId = null, TwitterStatusId? sinceId = null)
         {
             var endpoint = new Uri("statuses/home_timeline.json", UriKind.Relative);
             var param = new Dictionary<string, string>
@@ -88,14 +88,14 @@ namespace OpenTween.Api
             if (count != null)
                 param["count"] = count.ToString();
             if (maxId != null)
-                param["max_id"] = maxId.ToString();
+                param["max_id"] = maxId.Id;
             if (sinceId != null)
-                param["since_id"] = sinceId.ToString();
+                param["since_id"] = sinceId.Id;
 
             return this.Connection.GetAsync<TwitterStatus[]>(endpoint, param, "/statuses/home_timeline");
         }
 
-        public Task<TwitterStatus[]> StatusesMentionsTimeline(int? count = null, long? maxId = null, long? sinceId = null)
+        public Task<TwitterStatus[]> StatusesMentionsTimeline(int? count = null, TwitterStatusId? maxId = null, TwitterStatusId? sinceId = null)
         {
             var endpoint = new Uri("statuses/mentions_timeline.json", UriKind.Relative);
             var param = new Dictionary<string, string>
@@ -108,14 +108,14 @@ namespace OpenTween.Api
             if (count != null)
                 param["count"] = count.ToString();
             if (maxId != null)
-                param["max_id"] = maxId.ToString();
+                param["max_id"] = maxId.Id;
             if (sinceId != null)
-                param["since_id"] = sinceId.ToString();
+                param["since_id"] = sinceId.Id;
 
             return this.Connection.GetAsync<TwitterStatus[]>(endpoint, param, "/statuses/mentions_timeline");
         }
 
-        public Task<TwitterStatus[]> StatusesUserTimeline(string screenName, int? count = null, long? maxId = null, long? sinceId = null)
+        public Task<TwitterStatus[]> StatusesUserTimeline(string screenName, int? count = null, TwitterStatusId? maxId = null, TwitterStatusId? sinceId = null)
         {
             var endpoint = new Uri("statuses/user_timeline.json", UriKind.Relative);
             var param = new Dictionary<string, string>
@@ -130,9 +130,9 @@ namespace OpenTween.Api
             if (count != null)
                 param["count"] = count.ToString();
             if (maxId != null)
-                param["max_id"] = maxId.ToString();
+                param["max_id"] = maxId.Id;
             if (sinceId != null)
-                param["since_id"] = sinceId.ToString();
+                param["since_id"] = sinceId.Id;
 
             return this.Connection.GetAsync<TwitterStatus[]>(endpoint, param, "/statuses/user_timeline");
         }
@@ -221,7 +221,7 @@ namespace OpenTween.Api
             return this.Connection.PostLazyAsync<TwitterStatus>(endpoint, param);
         }
 
-        public Task<TwitterSearchResult> SearchTweets(string query, string? lang = null, int? count = null, long? maxId = null, long? sinceId = null)
+        public Task<TwitterSearchResult> SearchTweets(string query, string? lang = null, int? count = null, TwitterStatusId? maxId = null, TwitterStatusId? sinceId = null)
         {
             var endpoint = new Uri("search/tweets.json", UriKind.Relative);
             var param = new Dictionary<string, string>
@@ -238,9 +238,9 @@ namespace OpenTween.Api
             if (count != null)
                 param["count"] = count.ToString();
             if (maxId != null)
-                param["max_id"] = maxId.ToString();
+                param["max_id"] = maxId.Id;
             if (sinceId != null)
-                param["since_id"] = sinceId.ToString();
+                param["since_id"] = sinceId.Id;
 
             return this.Connection.GetAsync<TwitterSearchResult>(endpoint, param, "/search/tweets");
         }
@@ -340,7 +340,7 @@ namespace OpenTween.Api
             return this.Connection.PostLazyAsync<TwitterList>(endpoint, param);
         }
 
-        public Task<TwitterStatus[]> ListsStatuses(long listId, int? count = null, long? maxId = null, long? sinceId = null, bool? includeRTs = null)
+        public Task<TwitterStatus[]> ListsStatuses(long listId, int? count = null, TwitterStatusId? maxId = null, TwitterStatusId? sinceId = null, bool? includeRTs = null)
         {
             var endpoint = new Uri("lists/statuses.json", UriKind.Relative);
             var param = new Dictionary<string, string>
@@ -354,9 +354,9 @@ namespace OpenTween.Api
             if (count != null)
                 param["count"] = count.ToString();
             if (maxId != null)
-                param["max_id"] = maxId.ToString();
+                param["max_id"] = maxId.Id;
             if (sinceId != null)
-                param["since_id"] = sinceId.ToString();
+                param["since_id"] = sinceId.Id;
             if (includeRTs != null)
                 param["include_rts"] = includeRTs.Value ? "true" : "false";
 
index fcc537d..6ff98cf 100644 (file)
@@ -28,6 +28,7 @@ using System.Text;
 using System.Threading.Tasks;
 using OpenTween.Api.DataModel;
 using OpenTween.Connection;
+using OpenTween.Models;
 
 namespace OpenTween.Api.TwitterV2
 {
@@ -39,9 +40,9 @@ namespace OpenTween.Api.TwitterV2
 
         public int? MaxResults { get; set; }
 
-        public string? UntilId { get; set; }
+        public TwitterStatusId? UntilId { get; set; }
 
-        public string? SinceId { get; set; }
+        public TwitterStatusId? SinceId { get; set; }
 
         public GetTimelineRequest(long userId)
             => this.UserId = userId;
@@ -60,10 +61,10 @@ namespace OpenTween.Api.TwitterV2
                 param["max_results"] = this.MaxResults.ToString();
 
             if (this.UntilId != null)
-                param["until_id"] = this.UntilId;
+                param["until_id"] = this.UntilId.Id;
 
             if (this.SinceId != null)
-                param["since_id"] = this.SinceId;
+                param["since_id"] = this.SinceId.Id;
 
             return param;
         }
index 2a666ec..9d1f6fa 100644 (file)
@@ -43,7 +43,7 @@ namespace OpenTween.Models
         public override MyCommon.TabUsageType TabType
             => MyCommon.TabUsageType.Home;
 
-        public long OldestId { get; set; } = long.MaxValue;
+        public PostId? OldestId { get; set; }
 
         public int TweetsPerHour => this.tweetsPerHour;
 
index d1658a6..c792a40 100644 (file)
@@ -43,7 +43,7 @@ namespace OpenTween.Models
 
         public ListElement ListInfo { get; set; }
 
-        public long OldestId { get; set; } = long.MaxValue;
+        public PostId? OldestId { get; set; }
 
         public string? CursorBottom { get; set; }
 
index e3c410d..1792b16 100644 (file)
@@ -41,7 +41,7 @@ namespace OpenTween.Models
         public override MyCommon.TabUsageType TabType
             => MyCommon.TabUsageType.Mentions;
 
-        public long OldestId { get; set; } = long.MaxValue;
+        public PostId? OldestId { get; set; }
 
         public MentionsTabModel()
             : this(MyCommon.DEFAULTTAB.REPLY)
index 7d47190..ce609f3 100644 (file)
@@ -41,9 +41,9 @@ namespace OpenTween.Models
         public override MyCommon.TabUsageType TabType
             => MyCommon.TabUsageType.PublicSearch;
 
-        public long OldestId { get; set; } = long.MaxValue;
+        public PostId? OldestId { get; set; }
 
-        public long SinceId { get; set; }
+        public PostId? SinceId { get; set; }
 
         public string? CursorBottom { get; set; }
 
@@ -101,8 +101,8 @@ namespace OpenTween.Models
         /// </summary>
         public void ResetFetchIds()
         {
-            this.SinceId = 0L;
-            this.OldestId = long.MaxValue;
+            this.SinceId = null;
+            this.OldestId = null;
         }
     }
 }
index c000811..1d876ec 100644 (file)
@@ -43,7 +43,7 @@ namespace OpenTween.Models
 
         public string ScreenName { get; }
 
-        public long OldestId { get; set; } = long.MaxValue;
+        public PostId? OldestId { get; set; }
 
         public UserTimelineTabModel(string tabName, string screenName)
             : base(tabName)
index d8edf34..83c9506 100644 (file)
@@ -588,7 +588,7 @@ namespace OpenTween
                 var request = new GetTimelineRequest(this.UserId)
                 {
                     MaxResults = count,
-                    UntilId = more ? tab.OldestId.ToString() : null,
+                    UntilId = more ? tab.OldestId as TwitterStatusId : null,
                 };
 
                 var response = await request.Send(this.Api.Connection)
@@ -604,15 +604,15 @@ namespace OpenTween
             }
             else
             {
-                var maxId = more ? tab.OldestId : (long?)null;
+                var maxId = more ? tab.OldestId : null;
 
-                statuses = await this.Api.StatusesHomeTimeline(count, maxId)
+                statuses = await this.Api.StatusesHomeTimeline(count, maxId as TwitterStatusId)
                     .ConfigureAwait(false);
             }
 
             var minimumId = this.CreatePostsFromJson(statuses, MyCommon.WORKERTYPE.Timeline, tab, read);
             if (minimumId != null)
-                tab.OldestId = minimumId.Value;
+                tab.OldestId = minimumId;
         }
 
         public async Task GetMentionsTimelineApi(bool read, MentionsTabModel tab, bool more, bool startup)
@@ -624,7 +624,7 @@ namespace OpenTween
             TwitterStatus[] statuses;
             if (more)
             {
-                statuses = await this.Api.StatusesMentionsTimeline(count, maxId: tab.OldestId)
+                statuses = await this.Api.StatusesMentionsTimeline(count, maxId: tab.OldestId as TwitterStatusId)
                     .ConfigureAwait(false);
             }
             else
@@ -635,7 +635,7 @@ namespace OpenTween
 
             var minimumId = this.CreatePostsFromJson(statuses, MyCommon.WORKERTYPE.Reply, tab, read);
             if (minimumId != null)
-                tab.OldestId = minimumId.Value;
+                tab.OldestId = minimumId;
         }
 
         public async Task GetUserTimelineApi(bool read, string userName, UserTimelineTabModel tab, bool more)
@@ -661,7 +661,7 @@ namespace OpenTween
             {
                 if (more)
                 {
-                    statuses = await this.Api.StatusesUserTimeline(userName, count, maxId: tab.OldestId)
+                    statuses = await this.Api.StatusesUserTimeline(userName, count, maxId: tab.OldestId as TwitterStatusId)
                         .ConfigureAwait(false);
                 }
                 else
@@ -674,7 +674,7 @@ namespace OpenTween
             var minimumId = this.CreatePostsFromJson(statuses, MyCommon.WORKERTYPE.UserTimeline, tab, read);
 
             if (minimumId != null)
-                tab.OldestId = minimumId.Value;
+                tab.OldestId = minimumId;
         }
 
         public async Task<PostClass> GetStatusApi(bool read, TwitterStatusId id)
@@ -725,19 +725,21 @@ namespace OpenTween
         private PostClass CreatePostsFromStatusData(TwitterStatus status, bool favTweet)
             => this.postFactory.CreateFromStatus(status, this.UserId, this.followerId, favTweet);
 
-        private long? CreatePostsFromJson(TwitterStatus[] items, MyCommon.WORKERTYPE gType, TabModel? tab, bool read)
+        private PostId? CreatePostsFromJson(TwitterStatus[] items, MyCommon.WORKERTYPE gType, TabModel? tab, bool read)
         {
-            long? minimumId = null;
+            PostId? minimumId = null;
 
-            foreach (var status in items)
+            var posts = items.Select(x => this.CreatePostsFromStatusData(x)).ToArray();
+
+            foreach (var post in posts)
             {
-                if (minimumId == null || minimumId.Value > status.Id)
-                    minimumId = status.Id;
+                if (minimumId == null || minimumId > post.StatusId)
+                    minimumId = post.StatusId;
 
                 // 二重取得回避
                 lock (this.lockObj)
                 {
-                    var id = new TwitterStatusId(status.IdStr);
+                    var id = post.StatusId;
                     if (tab == null)
                     {
                         if (TabInformations.GetInstance().ContainsKey(id)) continue;
@@ -750,9 +752,7 @@ namespace OpenTween
 
                 // RT禁止ユーザーによるもの
                 if (gType != MyCommon.WORKERTYPE.UserTimeline &&
-                    status.RetweetedStatus != null && this.noRTId.Contains(status.User.Id)) continue;
-
-                var post = this.CreatePostsFromStatusData(status);
+                    post.RetweetedByUserId != null && this.noRTId.Contains(post.RetweetedByUserId.Value)) continue;
 
                 post.IsRead = read;
                 if (post.IsMe && !read && this.ReadOwnPost) post.IsRead = true;
@@ -766,25 +766,27 @@ namespace OpenTween
             return minimumId;
         }
 
-        private long? CreatePostsFromSearchJson(TwitterStatus[] statuses, PublicSearchTabModel tab, bool read, bool more)
+        private PostId? CreatePostsFromSearchJson(TwitterStatus[] statuses, PublicSearchTabModel tab, bool read, bool more)
         {
-            long? minimumId = null;
+            PostId? minimumId = null;
+
+            var posts = statuses.Select(x => this.CreatePostsFromStatusData(x)).ToArray();
 
-            foreach (var status in statuses)
+            foreach (var post in posts)
             {
-                if (minimumId == null || minimumId.Value > status.Id)
-                    minimumId = status.Id;
+                if (minimumId == null || minimumId > post.StatusId)
+                    minimumId = post.StatusId;
+
+                if (!more && (tab.SinceId == null || post.StatusId > tab.SinceId))
+                    tab.SinceId = post.StatusId;
 
-                if (!more && status.Id > tab.SinceId) tab.SinceId = status.Id;
                 // 二重取得回避
                 lock (this.lockObj)
                 {
-                    if (tab.Contains(new TwitterStatusId(status.IdStr)))
+                    if (tab.Contains(post.StatusId))
                         continue;
                 }
 
-                var post = this.CreatePostsFromStatusData(status);
-
                 post.IsRead = read;
                 if ((post.IsMe && !read) && this.ReadOwnPost) post.IsRead = true;
 
@@ -845,7 +847,7 @@ namespace OpenTween
             }
             else if (more)
             {
-                statuses = await this.Api.ListsStatuses(tab.ListInfo.Id, count, maxId: tab.OldestId, includeRTs: SettingManager.Instance.Common.IsListsIncludeRts)
+                statuses = await this.Api.ListsStatuses(tab.ListInfo.Id, count, maxId: tab.OldestId as TwitterStatusId, includeRTs: SettingManager.Instance.Common.IsListsIncludeRts)
                     .ConfigureAwait(false);
             }
             else
@@ -857,7 +859,7 @@ namespace OpenTween
             var minimumId = this.CreatePostsFromJson(statuses, MyCommon.WORKERTYPE.List, tab, read);
 
             if (minimumId != null)
-                tab.OldestId = minimumId.Value;
+                tab.OldestId = minimumId;
         }
 
         /// <summary>
@@ -1049,15 +1051,15 @@ namespace OpenTween
             }
             else
             {
-                long? maxId = null;
-                long? sinceId = null;
+                TwitterStatusId? maxId = null;
+                TwitterStatusId? sinceId = null;
                 if (more)
                 {
-                    maxId = tab.OldestId - 1;
+                    maxId = tab.OldestId as TwitterStatusId;
                 }
                 else
                 {
-                    sinceId = tab.SinceId;
+                    sinceId = tab.SinceId as TwitterStatusId;
                 }
 
                 var searchResult = await this.Api.SearchTweets(tab.SearchWords, tab.SearchLang, count, maxId, sinceId)
@@ -1072,7 +1074,7 @@ namespace OpenTween
             var minimumId = this.CreatePostsFromSearchJson(statuses, tab, read, more);
 
             if (minimumId != null)
-                tab.OldestId = minimumId.Value;
+                tab.OldestId = minimumId;
         }
 
         public async Task GetDirectMessageEvents(bool read, DirectMessagesTabModel dmTab, bool backward)