OSDN Git Service

関連発言表示でconversation_idによる検索結果を含める機能を追加
authorKimura Youichi <kim.upsilon@bucyou.net>
Sat, 2 Apr 2022 22:17:15 +0000 (07:17 +0900)
committerKimura Youichi <kim.upsilon@bucyou.net>
Fri, 22 Apr 2022 13:13:48 +0000 (22:13 +0900)
OpenTween/Resources/ChangeLog.txt
OpenTween/Twitter.cs

index 1fe0ad6..e420afd 100644 (file)
@@ -8,6 +8,7 @@
    - 高DPI環境で表示した場合により高解像度のプロフィール画像が取得されるようになります
    - リストのアイコンサイズを none に設定した場合、発言が選択されるまでプロフィール画像のダウンロードを行わなくなります
  * NEW: 発言のダブルクリック時の動作に「Reply All」(@返信ALL)を追加
+ * NEW: 関連発言表示で会話ツリーの最新の発言を取得する機能を追加
  * CHG: ツイートの投稿者とRTしたユーザーに関するメニュー項目を整理
  * CHG: DMが選択されている時は「@返信」「@返信ALL」のどちらも「DM送信」と同じ動作となるように変更
  * CHG: 複数のユーザー宛のリプライ時にツイートの先頭にピリオドを加える仕様を廃止
index f14179b..0070f48 100644 (file)
@@ -1077,6 +1077,29 @@ namespace OpenTween
                 }
             }
 
+            try
+            {
+                var firstPost = nextPost;
+                var posts = await this.GetConversationPosts(firstPost, targetPost)
+                    .ConfigureAwait(false);
+
+                foreach (var post in posts.OrderBy(x => x.StatusId))
+                {
+                    if (relPosts.ContainsKey(post.StatusId))
+                        continue;
+
+                    // リプライチェーンが繋がらないツイートは除外
+                    if (post.InReplyToStatusId == null || !relPosts.ContainsKey(post.InReplyToStatusId.Value))
+                        continue;
+
+                    relPosts.Add(post.StatusId, post);
+                }
+            }
+            catch (WebException ex)
+            {
+                lastException = ex;
+            }
+
             relPosts.Values.ToList().ForEach(p =>
             {
                 var post = p.Clone();
@@ -1092,6 +1115,22 @@ namespace OpenTween
                 throw new WebApiException(lastException.Message, lastException);
         }
 
+        private async Task<PostClass[]> GetConversationPosts(PostClass firstPost, PostClass targetPost)
+        {
+            var conversationId = firstPost.StatusId;
+            var query = $"conversation_id:{conversationId}";
+
+            if (targetPost.InReplyToUser != null && targetPost.InReplyToUser != targetPost.ScreenName)
+                query += $" (from:{targetPost.ScreenName} to:{targetPost.InReplyToUser}) OR (from:{targetPost.InReplyToUser} to:{targetPost.ScreenName})";
+            else
+                query += $" from:{targetPost.ScreenName} to:{targetPost.ScreenName}";
+
+            var statuses = await this.Api.SearchTweets(query, count: 100)
+                .ConfigureAwait(false);
+
+            return statuses.Statuses.Select(x => this.CreatePostsFromStatusData(x)).ToArray();
+        }
+
         public async Task GetSearch(bool read, PublicSearchTabModel tab, bool more)
         {
             var count = GetApiResultCount(MyCommon.WORKERTYPE.PublicSearch, more, false);