diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 993f956b5..ef9d46d85 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,9 @@ 更新履歴 +==== Ver 3.7.1(2023/07/20) + * FIX: Cookie使用時に複数回ツイートを投稿するとDelaying?のエラーが表示される不具合を修正 + * FIX: 自己リプライのスレッドに含まれるツイートを発言一覧で選択するとエラーが発生する不具合を修正 + ==== Ver 3.7.0(2023/07/19) * NEW: Cookie使用時のツイート投稿・削除に対応 * NEW: Cookie使用時のリツイートおよびリツイートの取消に対応 diff --git a/OpenTween.Tests/Api/GraphQL/TimelineTweetTest.cs b/OpenTween.Tests/Api/GraphQL/TimelineTweetTest.cs index da6720b3a..0d6cb1287 100644 --- a/OpenTween.Tests/Api/GraphQL/TimelineTweetTest.cs +++ b/OpenTween.Tests/Api/GraphQL/TimelineTweetTest.cs @@ -123,5 +123,18 @@ public void ToStatus_WithTwitterPostFactory_TweetWithVisibility_Test() Assert.Equal("1602775353088524288", post.StatusId.Id); Assert.Equal(357750891L, post.UserId); } + + [Fact] + public void ToStatus_WithTwitterPostFactory_SelfThread_Test() + { + var rootElm = this.LoadResponseDocument("TimelineTweet_SelfThread.json"); + var timelineTweet = new TimelineTweet(rootElm); + var status = timelineTweet.ToTwitterStatus(); + var postFactory = new TwitterPostFactory(this.CreateTabInfo()); + var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet()); + + Assert.Equal("1511751702684499968", post.StatusId.Id); + Assert.Equal(40480664L, post.UserId); + } } } diff --git a/OpenTween.Tests/OpenTween.Tests.csproj b/OpenTween.Tests/OpenTween.Tests.csproj index 950a2a344..3ba9bc30f 100644 --- a/OpenTween.Tests/OpenTween.Tests.csproj +++ b/OpenTween.Tests/OpenTween.Tests.csproj @@ -82,5 +82,8 @@ PreserveNewest + + PreserveNewest + diff --git a/OpenTween.Tests/Resources/Responses/TimelineTweet_SelfThread.json b/OpenTween.Tests/Resources/Responses/TimelineTweet_SelfThread.json new file mode 100644 index 000000000..489d46851 --- /dev/null +++ b/OpenTween.Tests/Resources/Responses/TimelineTweet_SelfThread.json @@ -0,0 +1,124 @@ +{ + "itemType": "TimelineTweet", + "__typename": "TimelineTweet", + "tweet_results": { + "result": { + "__typename": "Tweet", + "rest_id": "1511751702684499968", + "has_birdwatch_notes": false, + "core": { + "user_results": { + "result": { + "__typename": "User", + "id": "VXNlcjo0MDQ4MDY2NA==", + "rest_id": "40480664", + "affiliates_highlighted_label": {}, + "has_graduated_access": true, + "is_blue_verified": false, + "profile_image_shape": "Circle", + "legacy": { + "followed_by": true, + "following": true, + "can_dm": true, + "can_media_tag": true, + "created_at": "Sat May 16 15:20:01 +0000 2009", + "default_profile": false, + "default_profile_image": false, + "description": "OpenTween Project 言い出しっぺ", + "entities": { + "description": { + "urls": [] + }, + "url": { + "urls": [ + { + "display_url": "m.upsilo.net/@upsilon", + "expanded_url": "https://m.upsilo.net/@upsilon", + "url": "https://t.co/vNMmyHHOQD", + "indices": [ + 0, + 23 + ] + } + ] + } + }, + "fast_followers_count": 0, + "favourites_count": 216205, + "followers_count": 1304, + "friends_count": 917, + "has_custom_timelines": false, + "is_translator": false, + "listed_count": 92, + "location": "Funabashi, Chiba, Japan", + "media_count": 1040, + "name": "upsilon", + "normal_followers_count": 1304, + "pinned_tweet_ids_str": [], + "possibly_sensitive": false, + "profile_banner_url": "https://pbs.twimg.com/profile_banners/40480664/1349188016", + "profile_image_url_https": "https://pbs.twimg.com/profile_images/719076434/____normal.png", + "profile_interstitial_type": "", + "screen_name": "kim_upsilon", + "statuses_count": 10096, + "translator_type": "regular", + "url": "https://t.co/vNMmyHHOQD", + "verified": false, + "want_retweets": true, + "withheld_in_countries": [] + } + } + } + }, + "edit_control": { + "edit_tweet_ids": [ + "1511751702684499968" + ], + "editable_until_msecs": "1649266467565", + "is_edit_eligible": true, + "edits_remaining": "5" + }, + "edit_perspective": { + "favorited": false, + "retweeted": false + }, + "is_translatable": true, + "views": { + "state": "Enabled" + }, + "source": "OpenTween (dev)", + "legacy": { + "bookmark_count": 0, + "bookmarked": false, + "created_at": "Wed Apr 06 17:04:27 +0000 2022", + "conversation_id_str": "1511751702684499968", + "display_text_range": [ + 0, + 45 + ], + "entities": { + "user_mentions": [], + "urls": [], + "hashtags": [], + "symbols": [] + }, + "favorite_count": 1, + "favorited": false, + "full_text": "OpenTweenそろそろ次のリリースしたいんだけど今のAPI規制下で出してもねえ、という", + "is_quote_status": false, + "lang": "ja", + "quote_count": 0, + "reply_count": 1, + "retweet_count": 0, + "retweeted": false, + "user_id_str": "40480664", + "id_str": "1511751702684499968" + }, + "quick_promote_eligibility": { + "eligibility": "IneligibleNotProfessional" + } + } + }, + "tweetDisplayType": "SelfThread", + "hasModeratedReplies": false +} diff --git a/OpenTween/Api/GraphQL/TimelineTweet.cs b/OpenTween/Api/GraphQL/TimelineTweet.cs index 77dc06809..9cf3bfffc 100644 --- a/OpenTween/Api/GraphQL/TimelineTweet.cs +++ b/OpenTween/Api/GraphQL/TimelineTweet.cs @@ -156,7 +156,7 @@ private static Exception CreateParseError() public static TimelineTweet[] ExtractTimelineTweets(XElement element) { - return element.XPathSelectElements($"//itemContent[itemType[text()='{TypeName}']][tweetDisplayType[text()='Tweet']]") + return element.XPathSelectElements($"//itemContent[itemType[text()='{TypeName}']][tweetDisplayType[text()='Tweet' or text()='SelfThread']]") .Select(x => new TimelineTweet(x)) .ToArray(); } diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index 36a6020f2..81765f798 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -22,7 +22,7 @@ // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です [assembly: Guid("2d0ae0ba-adac-49a2-9b10-26fd69e695bf")] -[assembly: AssemblyVersion("3.7.0.0")] +[assembly: AssemblyVersion("3.7.1.0")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index 66a944eac..8943de108 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -580,6 +580,10 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// /// 更新履歴 /// + ///==== Ver 3.7.1(2023/07/20) + /// * FIX: Cookie使用時に複数回ツイートを投稿するとDelaying?のエラーが表示される不具合を修正 + /// * FIX: 自己リプライのスレッドに含まれるツイートを発言一覧で選択するとエラーが発生する不具合を修正 + /// ///==== Ver 3.7.0(2023/07/19) /// * NEW: Cookie使用時のツイート投稿・削除に対応 /// * NEW: Cookie使用時のリツイートおよびリツイートの取消に対応 @@ -589,12 +593,7 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// * CHG: Google画像検索のURLの変更に対応 /// * FIX: 発言一覧でDMを選択中に発言詳細部の日時ラベルをクリックするとエラーが発生する不具合を修正 /// * FIX: Cookie使用時に「Listの発言取得に公式RTを含める」の設定が適用されない不具合を修正 - /// - ///==== Ver 3.6.2(2023/07/07) - /// * FIX: リプライ制限されたツイートのRTがリストのタイムラインに含まれているとエラーになる不具合を修正 - /// - ///==== Ver 3.6.1(2023/07/07) - /// * CHG: graphqlエンドポイントからのレス [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + /// [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 /// internal static string ChangeLog { get { diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index ccf4a92b2..b4c2a0cd4 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -174,7 +174,7 @@ public class Twitter : IDisposable private readonly TwitterPostFactory postFactory; - private long previousStatusId = -1L; + private string? previousStatusId = null; public Twitter(TwitterApi api) { @@ -286,10 +286,10 @@ await this.SendDirectMessage(param.Text, mediaId) this.UpdateUserStats(status.User); - if (status.Id == this.previousStatusId) + if (status.IdStr == this.previousStatusId) throw new WebApiException("OK:Delaying?"); - this.previousStatusId = status.Id; + this.previousStatusId = status.IdStr; // 投稿したものを返す var post = this.CreatePostsFromStatusData(status); @@ -689,7 +689,9 @@ public async Task GetStatusApi(bool read, TwitterStatusId id) FocalTweetId = id, }; var tweets = await request.Send(this.Api.Connection).ConfigureAwait(false); - status = tweets.Select(x => x.ToTwitterStatus()).Where(x => x.IdStr == id.Id).First(); + status = tweets.Select(x => x.ToTwitterStatus()) + .Where(x => x.IdStr == id.Id) + .FirstOrDefault() ?? throw new WebApiException("Empty result set"); } else { diff --git a/appveyor.yml b/appveyor.yml index d9710991a..8637eb1c6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 3.6.2.{build} +version: 3.7.0.{build} os: Visual Studio 2022